Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4d2144d0d | ||
|
|
134b5d6ebf | ||
|
|
ab78307868 | ||
|
|
3019bba627 | ||
|
|
011a5107c5 |
BIN
.downloads/ncpfs-2.0.3.tgz
Normal file
BIN
.downloads/ncpfs-2.0.3.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.4.tgz
Normal file
BIN
.downloads/ncpfs-2.0.4.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.5.tgz
Normal file
BIN
.downloads/ncpfs-2.0.5.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.6.tgz
Normal file
BIN
.downloads/ncpfs-2.0.6.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.7.tgz
Normal file
BIN
.downloads/ncpfs-2.0.7.tgz
Normal file
Binary file not shown.
14
BUGS
14
BUGS
@@ -5,6 +5,20 @@ But there are really problems that might be fixed in the future.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
You might experience lockups of ncpfs volumes. It happens especially
|
||||
under high network traffic, not necessarily only IPX traffic. I am not
|
||||
able to reproduce this problem on my machine, so I'm sorry I can not
|
||||
do anything about that. When such a lockup happens, you have to shut
|
||||
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!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
'df' returns 0: Free disk space is distributed among the volumes in
|
||||
NetWare. df is only able to report one number per mounted
|
||||
filesystem. As connections are quite expensive for NetWare (with
|
||||
|
||||
55
Changes
55
Changes
@@ -1,6 +1,59 @@
|
||||
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.6 -> ncpfs-2.0.7
|
||||
- Hopefully removed one security problem in ncpumount.
|
||||
- Added command line flag to pserver.c
|
||||
- Heavily reconstructed ncpfs utils. Created the lib/ dir.
|
||||
- Separated the uid utils in sutil
|
||||
- Add nwsfind to enable users to use ncpfs safely without setting
|
||||
the utils setuid root.
|
||||
|
||||
ncpfs-2.0.5 -> ncpfs-2.0.6
|
||||
- Added a short description of a problem that I need help with to the
|
||||
file BUGS. If you know a bit of the linux networking code, please
|
||||
take a look at it. Thanks a lot.
|
||||
- Added canonic output format to nwpbvalues and the command nwbpset. I
|
||||
would like to invite you to help building capable bindery management
|
||||
utilities. For little examples, look at the manual page of nwbpset.
|
||||
- Added some values to ipxparse. Those interested in NDS should take a
|
||||
look at it. It's really not much, but maybe it's a beginning.
|
||||
|
||||
ncpfs-2.0.4 -> ncpfs-2.0.5
|
||||
- Removed another bug in nwbpvalues.
|
||||
- Cleaned up man/Makefile
|
||||
- Some manpage typos fixed. Thanks to Jim Van Zandt
|
||||
<jrv@mbunix.mitre.org>
|
||||
- added nwrights
|
||||
|
||||
ncpfs-2.0.3 -> ncpfs-2.0.4
|
||||
- Changed name of npasswd to nwpasswd, as npasswd collides with
|
||||
RedHat. Thanks to Mike Slater <mslater@nfinity.com> for pointing me
|
||||
at this one.
|
||||
- Put '\r\n' into nwmsg, because sometimes it did not print
|
||||
correctly. Thanks to Petr Vandrovec Ing. VTEI
|
||||
<VANDROVE@vcnet.vc.cvut.cz> for this one.
|
||||
- Improved the ELF Makefile for ELF support. Thanks to Uwe Bonnes
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>.
|
||||
- Removed a very embarassing bug in nwpvalues :-(.
|
||||
- Added a some routines to nwbpvalues.
|
||||
|
||||
ncpfs-2.0.2 -> ncpfs-2.0.3
|
||||
- Removed the kernel-2.0 directory. Linus took the patch into 2.0.8.
|
||||
So, if you want to use long file name support, upgrade to Linux
|
||||
kernel version 2.0.8.
|
||||
- Applied the lfn patch to the kernel-1.2 module with some light
|
||||
testing. If you experience problems, tell it to me, and use the
|
||||
ncpfs-2.0.2 kernel module, or upgrade to Linux 2.0.8.
|
||||
- Added unencrypted login when no crypt key is returned.
|
||||
- Hopefully improved error messages a bit
|
||||
- Added some values to ipxparse
|
||||
- For ELF systems, moved ncplib to /lib/libncp.so.1.x. This saves
|
||||
about 1MB of disk space. As ncpfs grows, the saving will
|
||||
increase. Please look at the Makefile to enable this.
|
||||
- Enhanced nwfsinfo a bit. (Even with a manpage!)
|
||||
- Added nwuserlist.
|
||||
|
||||
ncpfs-2.0.1 -> ncpfs-2.0.2
|
||||
- Added some values to ipxparse.
|
||||
- Added a patch against 2.0.7 for long file names support. I did not
|
||||
@@ -133,4 +186,4 @@ ncpfs-0.12 -> ncpfs-0.13
|
||||
- support for automatic loading of ncpfs.o by kerneld.
|
||||
Thanks to Steven N. Hirsch <hirsch@emba.uvm.edu>.
|
||||
- A subtle problem in the read routines has been removed by Uwe Bonnes
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>. Thanks a lot.
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>. Thanks a lot.
|
||||
|
||||
9
FAQ
9
FAQ
@@ -1,5 +1,5 @@
|
||||
There is certainly not enough material to call this an FAQ, but some
|
||||
questions reach me regularly. Probably the documenation is not clear
|
||||
questions reach me regularly. Probably the documentation is not clear
|
||||
enough.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -37,13 +37,6 @@ packet signatures on the 4.1 server, as ncpfs does not support them.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Q: Does ncpfs support long file names, using the OS/2 namespace?
|
||||
|
||||
Yes. But you will have to patch your kernel. Look at the file
|
||||
kernel-2.0/README for more information.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Q: When I re-export ncpfs-mounted directories via nfs, I get messages like
|
||||
'pwd: cannot get current directory', and other strange things happen to
|
||||
the nfs clients. What's wrong?
|
||||
|
||||
52
Makefile
52
Makefile
@@ -2,29 +2,52 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
VERSION = 2.0.2
|
||||
VERSION = 2.0.7
|
||||
|
||||
# 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
|
||||
HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \
|
||||
grep ELF >/dev/null && echo -n yes )
|
||||
|
||||
TOPDIR = $(shell pwd)
|
||||
BINDIR = /usr/local/bin
|
||||
BINDIR = /usr/bin
|
||||
SBINDIR = /sbin
|
||||
INTERM_BINDIR = $(TOPDIR)/bin
|
||||
SUBDIRS = util ipx-1.0 man
|
||||
SUBDIRS = lib sutil util ipx-1.0 man
|
||||
|
||||
KVERSION=$(shell uname -r | cut -b1-3)
|
||||
|
||||
INCLUDES=-I$(TOPDIR)/include
|
||||
|
||||
ifeq ($(KVERSION),1.2)
|
||||
SUBDIRS += kernel-1.2/src
|
||||
INCLUDES = -I$(TOPDIR)/kernel-1.2
|
||||
INCLUDES += -I$(TOPDIR)/kernel-1.2
|
||||
endif
|
||||
|
||||
export INCLUDES BINDIR INTERM_BINDIR SBINDIR KERNELD VERSION
|
||||
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
|
||||
#CFLAGS += -g
|
||||
CFLAGS += -O2
|
||||
|
||||
export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS
|
||||
|
||||
all:
|
||||
for i in $(SUBDIRS); do make -C $$i all; done
|
||||
@if [ "$(HAVE_ELF)" = yes ] ;\
|
||||
then \
|
||||
echo ; echo ; echo ;\
|
||||
echo Please add \'`pwd`/lib\' to the environment ; \
|
||||
echo variable LD_LIBRARY_PATH by executing ; \
|
||||
echo ;\
|
||||
echo export LD_LIBRARY_PATH=\"\$$LD_LIBRARY_PATH:`pwd`/lib\" ; \
|
||||
echo ;\
|
||||
echo or do a \'make install\'. ;\
|
||||
echo ;\
|
||||
fi
|
||||
|
||||
dep:
|
||||
for i in $(SUBDIRS); do make -C $$i dep; done
|
||||
@@ -32,17 +55,16 @@ dep:
|
||||
install:
|
||||
for i in $(SUBDIRS); do make -C $$i install; done
|
||||
|
||||
clean:
|
||||
rm -f `find . -type f -name '*.o' -print`
|
||||
rm -f `find . -type f -name '*~' -print`
|
||||
rm -f `find . -type f -name '.depend' -print`
|
||||
rm -f `find . -type f -name '*.out' -print`
|
||||
clean_me:
|
||||
rm -f `find -name '*.out'`
|
||||
rm -f `find -name '*~'`
|
||||
rm -f ncpfs.tgz
|
||||
|
||||
clean: clean_me
|
||||
for i in $(SUBDIRS); do make -C $$i clean; done
|
||||
|
||||
mrproper: clean
|
||||
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
|
||||
make -C util mrproper
|
||||
make -C ipxdump mrproper
|
||||
mrproper: clean_me
|
||||
for i in $(SUBDIRS) ipxdump; do make -C $$i mrproper; done
|
||||
|
||||
modules: ncpfs.o
|
||||
|
||||
|
||||
29
README
29
README
@@ -3,11 +3,24 @@ some little utilities it also contains nprint, which enables you to
|
||||
print on NetWare print queues. The opposite side, pserver, is also
|
||||
provided.
|
||||
|
||||
I'm planning major changes in the structure of ncpfs for Linux 2.1.x
|
||||
which will break the binary compatibility. So I changed the numbering
|
||||
scheme for ncpfs. ncpfs-2.0.x will be the version to be used with
|
||||
Linux 2.0.0 and older kernels, and ncpfs-2.1.x will be the version for
|
||||
the development kernels.
|
||||
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
|
||||
CD-ROM servers WinNT 3.51 Server are also NOT supported. This
|
||||
restriction comes from the fact that ncpfs relies heavily on the name
|
||||
space facilities NetWare supports since version 3. When you want to
|
||||
mount volumes that have been exported by mars_nwe, you have to
|
||||
activate the name space calls in mars_nwe's config.h file, although
|
||||
probably it's more clever to use nfs between two Linux machines.
|
||||
|
||||
The user-space utilities such as nprint and the bindery utils should
|
||||
work with all versions of NetWare.
|
||||
|
||||
ncpfs does NOT support access to the NDS, so if you want to mount
|
||||
volumes exported by a NetWare 4.x server, you will have to install the
|
||||
bindery emulation on that server. If you need access to the NDS, ask
|
||||
Caldera for their CND. See http://www.caldera.com for more
|
||||
information.
|
||||
|
||||
|
||||
INSTALLATION
|
||||
|
||||
@@ -39,6 +52,12 @@ ncpfs.
|
||||
If you are running kerneld, please uncomment the corresponding line in
|
||||
the Makefile to reflect this.
|
||||
|
||||
If your system is ELF, please enable the use of the shared ncp-library
|
||||
in the Makefile. This will save at least 1MB of disk space.
|
||||
|
||||
After you adapted your Makefile, type 'make' and, as root, 'make install'.
|
||||
|
||||
|
||||
HELP
|
||||
|
||||
In the meantime my mail volume has grown considerably, so the response
|
||||
|
||||
5
TODO
5
TODO
@@ -1,14 +1,11 @@
|
||||
Here's a list of things I want to do. Feel free to send suggestions,
|
||||
or even help me ;-).
|
||||
|
||||
- Add flags to pserver's command line, so that the print command can
|
||||
find out the name of user who printed the job.
|
||||
|
||||
- do rtt estimation, like tcp does.
|
||||
|
||||
- Do better connection management. I imagine to create a ncpd.
|
||||
|
||||
- When ncp is done, one can think about mounting several volumes over
|
||||
- When ncpd is done, one can think about mounting several volumes over
|
||||
a single NCP connection. This should make the trade-off mentioned in
|
||||
ncpmount.8 unnecessary.
|
||||
|
||||
|
||||
24
bin/nwbpsecurity
Executable file
24
bin/nwbpsecurity
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
SECURITY=`nwbpvalues $* -c | head -3 | tail -1`
|
||||
WRITE=`echo $SECURITY | cut -b1`
|
||||
READ=`echo $SECURITY | cut -b2`
|
||||
|
||||
function print_sec () {
|
||||
case "$1" in
|
||||
0 ) echo "Everyone"
|
||||
;;
|
||||
1 ) echo "Logged in"
|
||||
;;
|
||||
2 ) echo "Object"
|
||||
;;
|
||||
3 ) echo "Supervisor"
|
||||
;;
|
||||
* ) echo "Bindery"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo -n "Write security: "
|
||||
print_sec $WRITE
|
||||
echo -n "Read security : "
|
||||
print_sec $READ
|
||||
@@ -121,6 +121,10 @@ ncp_find_permanent(const struct ncp_conn_spec *spec);
|
||||
struct sockaddr_ipx *
|
||||
ncp_find_fileserver(const char *server_name, long *err);
|
||||
|
||||
/* Find the address of a server */
|
||||
struct sockaddr_ipx *
|
||||
ncp_find_server(const char **server_name, int type, long *err);
|
||||
|
||||
/* Detach from a permanent connection or destroy a temporary
|
||||
connection */
|
||||
long
|
||||
@@ -155,11 +159,48 @@ ncp_get_file_server_description_strings(struct ncp_conn *conn,
|
||||
long
|
||||
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target);
|
||||
|
||||
struct ncp_file_server_info {
|
||||
__u8 ServerName[48] __attribute__ ((packed));
|
||||
__u8 FileServiceVersion __attribute__ ((packed));
|
||||
__u8 FileServiceSubVersion __attribute__ ((packed));
|
||||
__u16 MaximumServiceConnections __attribute__ ((packed));
|
||||
__u16 ConnectionsInUse __attribute__ ((packed));
|
||||
__u16 NumberMountedVolumes __attribute__ ((packed));
|
||||
__u8 Revision __attribute__ ((packed));
|
||||
__u8 SFTLevel __attribute__ ((packed));
|
||||
__u8 TTSLevel __attribute__ ((packed));
|
||||
__u16 MaxConnectionsEverUsed __attribute__ ((packed));
|
||||
__u8 AccountVersion __attribute__ ((packed));
|
||||
__u8 VAPVersion __attribute__ ((packed));
|
||||
__u8 QueueVersion __attribute__ ((packed));
|
||||
__u8 PrintVersion __attribute__ ((packed));
|
||||
__u8 VirtualConsoleVersion __attribute__ ((packed));
|
||||
__u8 RestrictionLevel __attribute__ ((packed));
|
||||
__u8 InternetBridge __attribute__ ((packed));
|
||||
__u8 Reserved[60] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
long
|
||||
ncp_get_file_server_information(struct ncp_conn *conn,
|
||||
struct ncp_file_server_info *target);
|
||||
|
||||
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_stations_logged_info(struct ncp_conn *conn,
|
||||
__u32 connection,
|
||||
struct ncp_bindery_object *target,
|
||||
time_t *login_time);
|
||||
|
||||
long
|
||||
ncp_get_internet_address(struct ncp_conn *conn,
|
||||
__u32 connection,
|
||||
struct sockaddr_ipx *target,
|
||||
__u8 *conn_type);
|
||||
|
||||
long
|
||||
ncp_send_broadcast(struct ncp_conn *conn,
|
||||
__u8 no_conn, const __u8 *connections,
|
||||
@@ -198,6 +239,12 @@ ncp_change_object_security(struct ncp_conn *conn,
|
||||
const char *object_name,
|
||||
__u8 security);
|
||||
|
||||
struct ncp_station_addr {
|
||||
__u32 NetWork __attribute__ ((packed));
|
||||
__u8 Node[6] __attribute__ ((packed));
|
||||
__u16 Socket __attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct ncp_prop_login_control {
|
||||
__u8 AccountExpireDate[3] __attribute__ ((packed));
|
||||
__u8 Disabled __attribute__ ((packed));
|
||||
@@ -214,7 +261,7 @@ struct ncp_prop_login_control {
|
||||
__u32 MaxDiskUsage __attribute__ ((packed));
|
||||
__u16 BadLoginCount __attribute__ ((packed));
|
||||
__u32 BadLoginCountDown __attribute__ ((packed));
|
||||
__u8 LastIntruder[8] __attribute__ ((packed));
|
||||
struct ncp_station_addr LastIntruder __attribute__ ((packed));
|
||||
};
|
||||
|
||||
long
|
||||
@@ -259,12 +306,33 @@ ncp_write_property_value(struct ncp_conn *conn,
|
||||
const char *property_name,
|
||||
__u8 segment,
|
||||
struct nw_property *property_value);
|
||||
|
||||
/* Bit masks for security flag */
|
||||
#define NCP_SEC_CHECKSUMMING_REQUESTED (1)
|
||||
#define NCP_SEC_SIGNATURE_REQUESTED (2)
|
||||
#define NCP_SEC_COMPLETE_SIGNATURES_REQUESTED (4)
|
||||
#define NCP_SEC_ENCRYPTION_REQUESTED (8)
|
||||
#define NCP_SEC_LIP_DISABLED (128)
|
||||
|
||||
long
|
||||
ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn,
|
||||
__u16 proposed_max_size,
|
||||
__u8 proposed_security_flag,
|
||||
__u16 *accepted_max_size,
|
||||
__u16 *echo_socket,
|
||||
__u8 *accepted_security_flag);
|
||||
|
||||
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_unencrypted(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const unsigned char *passwd);
|
||||
|
||||
long
|
||||
ncp_change_login_passwd(struct ncp_conn *conn,
|
||||
const struct ncp_bindery_object *object,
|
||||
@@ -373,6 +441,30 @@ ncp_copy_file(struct ncp_conn *conn,
|
||||
__u32 count,
|
||||
__u32 *copied_count);
|
||||
|
||||
long
|
||||
ncp_obtain_file_or_subdir_info(struct ncp_conn *conn,
|
||||
__u8 source_ns, __u8 target_ns,
|
||||
__u16 search_attribs, __u32 rim,
|
||||
__u8 vol, __u32 dirent, const char *path,
|
||||
struct nw_info_struct *target);
|
||||
|
||||
#define NCP_PERM_READ (0x001)
|
||||
#define NCP_PERM_WRITE (0x002)
|
||||
#define NCP_PERM_OPEN (0x004)
|
||||
#define NCP_PERM_CREATE (0x008)
|
||||
#define NCP_PERM_DELETE (0x010)
|
||||
#define NCP_PERM_OWNER (0x020)
|
||||
#define NCP_PERM_SEARCH (0x040)
|
||||
#define NCP_PERM_MODIFY (0x080)
|
||||
#define NCP_PERM_SUPER (0x100)
|
||||
|
||||
long
|
||||
ncp_get_eff_directory_rights(struct ncp_conn *conn,
|
||||
__u8 source_ns, __u8 target_ns,
|
||||
__u16 search_attribs,
|
||||
__u8 vol, __u32 dirent, const char *path,
|
||||
__u16 *my_effective_rights);
|
||||
|
||||
long
|
||||
ncp_do_lookup(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir,
|
||||
@@ -1,24 +0,0 @@
|
||||
CFLAGS = -O2 -Wall
|
||||
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
|
||||
all: $(UTILS)
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install --strip $$i /sbin; \
|
||||
install $$i.8 /usr/man/man8; \
|
||||
done
|
||||
install init.ipx /etc/rc.d/init.d/ipx
|
||||
install -m 0644 config.ipx /etc/sysconfig/ipx
|
||||
rm -f /etc/rc.d/rc2.d/S15ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc2.d/S15ipx
|
||||
rm -f /etc/rc.d/rc3.d/S15ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc3.d/S15ipx
|
||||
rm -f /etc/rc.d/rc5.d/S15ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc5.d/S15ipx
|
||||
rm -f /etc/rc.d/rc6.d/K55ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc6.d/K55ipx
|
||||
|
||||
@@ -1,30 +1,19 @@
|
||||
CFLAGS = -O2 -Wall
|
||||
UTILS = $(INTERM_BINDIR)/ipx_configure $(INTERM_BINDIR)/ipx_interface \
|
||||
$(INTERM_BINDIR)/ipx_internal_net $(INTERM_BINDIR)/ipx_route
|
||||
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
|
||||
|
||||
all: $(UTILS)
|
||||
|
||||
$(INTERM_BINDIR)/ipx_configure: ipx_configure.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_interface: ipx_interface.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_interface ipx_interface.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_internal_net: ipx_internal_net.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_internal_net ipx_internal_net.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_route: ipx_route.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_route ipx_route.o
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
mrproper: clean
|
||||
rm -f .depend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install $$i $(BINDIR); \
|
||||
done
|
||||
|
||||
|
||||
@@ -329,9 +329,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;
|
||||
@@ -339,6 +340,10 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
int data_length = 0;
|
||||
int i;
|
||||
|
||||
static struct sockaddr_ipx request_source;
|
||||
static struct ncp_request_header request_header;
|
||||
static char request_data[5];
|
||||
|
||||
if (ntohs(rq->type) == NCP_REQUEST)
|
||||
{
|
||||
/* Request */
|
||||
@@ -346,11 +351,19 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
rq->conn_low + 256 * rq->conn_high,
|
||||
rq->sequence, rq->task);
|
||||
|
||||
memcpy(&request_source, source, sizeof(request_source));
|
||||
memcpy(&request_header, rq, sizeof(request_header));
|
||||
memcpy(request_data, rq+1, sizeof(request_data));
|
||||
|
||||
data = buf + sizeof(struct ncp_request_header);
|
||||
data_length = length - sizeof(struct ncp_request_header);
|
||||
|
||||
switch(rq->function)
|
||||
{
|
||||
case 18:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Get Volume Info with Number\n");
|
||||
break;
|
||||
case 20:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Get File Server Date and Time\n");
|
||||
@@ -381,6 +394,9 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
case 01:
|
||||
printf("Get Directory Path\n");
|
||||
break;
|
||||
case 02:
|
||||
printf("Scan Directory Information\n");
|
||||
break;
|
||||
case 03:
|
||||
printf("Get Effective Directory Rights\n");
|
||||
break;
|
||||
@@ -390,6 +406,9 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
case 06:
|
||||
printf("Get Volume Name\n");
|
||||
break;
|
||||
case 10:
|
||||
printf("Create directory\n");
|
||||
break;
|
||||
case 18:
|
||||
printf("Allocate Permanent Dir Handle\n");
|
||||
break;
|
||||
@@ -399,6 +418,9 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
case 21:
|
||||
printf("Get Volume Info with handle\n");
|
||||
break;
|
||||
case 39:
|
||||
printf("Add ext. Trustee to Dir or File\n");
|
||||
break;
|
||||
case 48:
|
||||
printf("Get Name Space Directory Entry\n");
|
||||
break;
|
||||
@@ -426,21 +448,54 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
case 28:
|
||||
printf("Get Connection Information\n");
|
||||
break;
|
||||
case 50:
|
||||
printf("Create Bindery Object\n");
|
||||
break;
|
||||
case 53:
|
||||
printf("Get Bindery Object ID\n");
|
||||
break;
|
||||
case 54:
|
||||
printf("Get Bindery Object Name\n");
|
||||
break;
|
||||
case 55:
|
||||
printf("Scan Bindery Object\n");
|
||||
break;
|
||||
case 57:
|
||||
printf("Create Property\n");
|
||||
break;
|
||||
case 59:
|
||||
printf("Change Property Security\n");
|
||||
break;
|
||||
case 60:
|
||||
printf("Scan Property\n");
|
||||
break;
|
||||
case 61:
|
||||
printf("Read Property Value\n");
|
||||
break;
|
||||
case 62:
|
||||
printf("Write Property Value\n");
|
||||
break;
|
||||
case 65:
|
||||
printf("Add Bindery Object to Set\n");
|
||||
break;
|
||||
case 67:
|
||||
printf("Is Bindery Object in Set\n");
|
||||
break;
|
||||
case 70:
|
||||
printf("Get Bindery Access Level\n");
|
||||
break;
|
||||
case 72:
|
||||
printf("Get Bindery Object Access Level\n");
|
||||
break;
|
||||
case 75:
|
||||
printf("Keyed change password\n");
|
||||
break;
|
||||
case 113:
|
||||
printf("Service Queue Job (old)\n");
|
||||
break;
|
||||
case 124:
|
||||
printf("Service Queue Job \n");
|
||||
break;
|
||||
}
|
||||
|
||||
data += 3;
|
||||
@@ -476,6 +531,10 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Close File\n");
|
||||
break;
|
||||
case 67:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Create File\n");
|
||||
break;
|
||||
case 72:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Read from File\n");
|
||||
@@ -488,6 +547,11 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Set File Time Date Stamp\n");
|
||||
break;
|
||||
case 76:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Open File (old)\n");
|
||||
break;
|
||||
|
||||
case 87:
|
||||
printf("fn: %-3d, subfn: %-3d\n",
|
||||
rq->function, data[0]);
|
||||
@@ -528,13 +592,343 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
data_length -= 1;
|
||||
break;
|
||||
case 97:
|
||||
{
|
||||
struct INPUT
|
||||
{
|
||||
__u16 proposed_max_size;
|
||||
__u8 security_flag;
|
||||
} *i = (struct INPUT *)data;
|
||||
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Get Big Packet NCP Max Packet Size\n");
|
||||
printf("proposed_max_size: %x\n",
|
||||
ntohs(i->proposed_max_size));
|
||||
printf("security_flag: %x\n",
|
||||
i->security_flag);
|
||||
break;
|
||||
}
|
||||
case 101:
|
||||
{
|
||||
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;
|
||||
|
||||
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));
|
||||
}
|
||||
break;
|
||||
case 104:
|
||||
{
|
||||
printf("fn: %-3d, subfn: %-3d, NDS call\n",
|
||||
rq->function, data[0]);
|
||||
|
||||
/* I took this information from the (german!!)
|
||||
book 'Einf"uhrung in die NetWare LAN
|
||||
Analyse', Laura A. Chappell, Dan E. Hakes,
|
||||
Novell Press, Markt & Technik, ISBN
|
||||
3-8272-5084-6, and from the book mentioned
|
||||
in the ncpfs README. I'm not sure it is
|
||||
correct, because I do not have NW 4.x. If
|
||||
you have the time, could you watch a NW4
|
||||
workstation, and tell me whether anything
|
||||
of this makes sense at all. */
|
||||
|
||||
switch(data[0])
|
||||
{
|
||||
case 1:
|
||||
printf("Ping for NDS\n");
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
struct INPUT
|
||||
{
|
||||
__u8 subfunction_code;
|
||||
__u32 fragger_handle;
|
||||
__u32 max_fragment_size;
|
||||
__u32 message_size;
|
||||
__u32 fragment_flag;
|
||||
__u32 verb;
|
||||
} *i = (struct INPUT *)data;
|
||||
printf("Send NDS Fragment Request/Reply\n");
|
||||
printf("fragger_handle: %lx\n",
|
||||
(unsigned long)i->fragger_handle);
|
||||
printf("max_fragment_size: %lx\n",
|
||||
(unsigned long)i->max_fragment_size);
|
||||
printf("message_size: %lx\n",
|
||||
(unsigned long)i->message_size);
|
||||
printf("fragment_flag: %lx\n",
|
||||
(unsigned long)i->fragment_flag);
|
||||
printf("verb: %d\n", i->verb);
|
||||
|
||||
switch (i->verb)
|
||||
{
|
||||
case 1:
|
||||
printf("Resolve Name\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("Read Entry Information\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("Read\n");
|
||||
break;
|
||||
case 4:
|
||||
printf("Compare\n");
|
||||
break;
|
||||
case 5:
|
||||
printf("List\n");
|
||||
break;
|
||||
case 6:
|
||||
printf("Search Entries\n");
|
||||
break;
|
||||
case 7:
|
||||
printf("Add Entry\n");
|
||||
break;
|
||||
case 8:
|
||||
printf("Remove Entry\n");
|
||||
break;
|
||||
case 9:
|
||||
printf("Modify Entry\n");
|
||||
break;
|
||||
case 10:
|
||||
printf("Modify RDN\n");
|
||||
break;
|
||||
case 11:
|
||||
printf("Create Attribute\n");
|
||||
break;
|
||||
case 12:
|
||||
printf("Read Attribute Definition\n");
|
||||
break;
|
||||
case 13:
|
||||
printf("Remove Attribute Definition\n");
|
||||
break;
|
||||
case 14:
|
||||
printf("Define Class\n");
|
||||
break;
|
||||
case 15:
|
||||
printf("Read Class Definition\n");
|
||||
break;
|
||||
case 16:
|
||||
printf("Modify Class Definition\n");
|
||||
break;
|
||||
case 17:
|
||||
printf("Remove Class Definition\n");
|
||||
break;
|
||||
case 18:
|
||||
printf("List Containable Classes\n");
|
||||
break;
|
||||
case 19:
|
||||
printf("Get Effective Rights\n");
|
||||
break;
|
||||
case 20:
|
||||
printf("Add Partition\n");
|
||||
break;
|
||||
case 21:
|
||||
printf("Remove Partition\n");
|
||||
break;
|
||||
case 22:
|
||||
printf("List Partitions\n");
|
||||
break;
|
||||
case 23:
|
||||
printf("Split Partition\n");
|
||||
break;
|
||||
case 24:
|
||||
printf("Join Partitions\n");
|
||||
break;
|
||||
case 25:
|
||||
printf("Add Replica\n");
|
||||
break;
|
||||
case 26:
|
||||
printf("Remove Replica\n");
|
||||
break;
|
||||
case 27:
|
||||
printf("Open Stream\n");
|
||||
break;
|
||||
case 28:
|
||||
printf("Search Filter\n");
|
||||
break;
|
||||
case 29:
|
||||
printf("Create Subordinate Reference\n");
|
||||
break;
|
||||
case 30:
|
||||
printf("Link Replica\n");
|
||||
break;
|
||||
case 31:
|
||||
printf("Change Replica Type\n");
|
||||
break;
|
||||
case 32:
|
||||
printf("Start Update Schema\n");
|
||||
break;
|
||||
case 33:
|
||||
printf("End Update Schema\n");
|
||||
break;
|
||||
case 34:
|
||||
printf("Update Schema\n");
|
||||
break;
|
||||
case 35:
|
||||
printf("Start Update Replica\n");
|
||||
break;
|
||||
case 36:
|
||||
printf("End Update Replica\n");
|
||||
break;
|
||||
case 37:
|
||||
printf("Update Replica\n");
|
||||
break;
|
||||
case 38:
|
||||
printf("Synchronize Partition\n");
|
||||
break;
|
||||
case 39:
|
||||
printf("Synchronize Schema\n");
|
||||
break;
|
||||
case 40:
|
||||
printf("Read Syntaxes\n");
|
||||
break;
|
||||
case 41:
|
||||
printf("Get Replica Root ID\n");
|
||||
break;
|
||||
case 42:
|
||||
printf("Begin Move Entry\n");
|
||||
break;
|
||||
case 43:
|
||||
printf("Finish Move Entry\n");
|
||||
break;
|
||||
case 44:
|
||||
printf("Release Moved Entry\n");
|
||||
break;
|
||||
case 45:
|
||||
printf("Backup Entry\n");
|
||||
break;
|
||||
case 46:
|
||||
printf("Restore Entry\n");
|
||||
break;
|
||||
case 47:
|
||||
printf("Save DIB\n");
|
||||
break;
|
||||
case 48:
|
||||
case 49:
|
||||
printf("Unused\n");
|
||||
break;
|
||||
case 50:
|
||||
printf("Close Iteration\n");
|
||||
break;
|
||||
case 51:
|
||||
printf("Unused\n");
|
||||
break;
|
||||
case 52:
|
||||
printf("Audit Skulking\n");
|
||||
break;
|
||||
case 53:
|
||||
printf("Get Server Address\n");
|
||||
break;
|
||||
case 54:
|
||||
printf("Set Keys\n");
|
||||
break;
|
||||
case 55:
|
||||
printf("Change Password\n");
|
||||
break;
|
||||
case 56:
|
||||
printf("Verify Password\n");
|
||||
break;
|
||||
case 57:
|
||||
printf("Begin Login\n");
|
||||
break;
|
||||
case 58:
|
||||
printf("Finish Login\n");
|
||||
break;
|
||||
case 59:
|
||||
printf("Begin Authentication\n");
|
||||
break;
|
||||
case 60:
|
||||
printf("Finish Authentication\n");
|
||||
break;
|
||||
case 61:
|
||||
printf("Logout\n");
|
||||
break;
|
||||
case 62:
|
||||
printf("Repair Ring\n");
|
||||
break;
|
||||
case 63:
|
||||
printf("Repair Timestamps\n");
|
||||
break;
|
||||
case 64:
|
||||
printf("Create Back Link\n");
|
||||
break;
|
||||
case 65:
|
||||
printf("Delete External Reference\n");
|
||||
break;
|
||||
case 66:
|
||||
printf("Rename External Reference\n");
|
||||
break;
|
||||
case 67:
|
||||
printf("Create Directory Entry\n");
|
||||
break;
|
||||
case 68:
|
||||
printf("Remove Directory Entry\n");
|
||||
break;
|
||||
case 69:
|
||||
printf("Designate New Master\n");
|
||||
break;
|
||||
case 70:
|
||||
printf("Change Tree Name\n");
|
||||
break;
|
||||
case 71:
|
||||
printf("Partition Entry Count\n");
|
||||
break;
|
||||
case 72:
|
||||
printf("Check Login Restrictions\n");
|
||||
break;
|
||||
case 73:
|
||||
printf("Start Join\n");
|
||||
break;
|
||||
case 74:
|
||||
printf("Low Level Split\n");
|
||||
break;
|
||||
case 75:
|
||||
printf("Low Level Join\n");
|
||||
break;
|
||||
case 76:
|
||||
printf("Abort Low Level Join\n");
|
||||
break;
|
||||
case 77:
|
||||
printf("Get All Servers\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Verb: %d\n",
|
||||
data[0]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
printf("Close NDS Fragment\n");
|
||||
break;
|
||||
case 4:
|
||||
printf("Return Bindery Context\n");
|
||||
break;
|
||||
case 5:
|
||||
printf("Monitor NDS connection\n");
|
||||
break;
|
||||
case 200:
|
||||
printf("NDS Auditing\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
}
|
||||
@@ -550,6 +944,70 @@ void handle_ncp (struct sockaddr_ipx *source,
|
||||
|
||||
data = buf + sizeof(struct ncp_reply_header);
|
||||
data_length = length - sizeof(struct ncp_reply_header);
|
||||
|
||||
if ( (memcmp(&request_source, target,
|
||||
sizeof(request_source)) == 0)
|
||||
&& (request_header.sequence == rs->sequence))
|
||||
{
|
||||
switch (request_header.function)
|
||||
{
|
||||
case 22:
|
||||
switch (request_data[2])
|
||||
{
|
||||
case 18:
|
||||
{
|
||||
struct XDATA
|
||||
{
|
||||
__u8 new_directory_handle;
|
||||
__u8 access_rights_mask;
|
||||
} *x = (struct XDATA *)data;
|
||||
printf("new_directory_handle: %x\n",
|
||||
x->new_directory_handle);
|
||||
printf("access_rights_mask: %x\n",
|
||||
x->access_rights_mask);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 72:
|
||||
printf("Read data\n");
|
||||
data_length = 0;
|
||||
break;
|
||||
case 97:
|
||||
{
|
||||
struct XDATA
|
||||
{
|
||||
__u16 accepted_max_size;
|
||||
__u16 echo_socket;
|
||||
__u8 security_flag;
|
||||
} *x = (struct XDATA *)data;
|
||||
printf("accepted_max_size: %x\n",
|
||||
ntohs(x->accepted_max_size));
|
||||
printf("echo_socket: %x\n",
|
||||
ntohs(x->echo_socket));
|
||||
printf("security_flag: %x\n",
|
||||
(x->security_flag));
|
||||
}
|
||||
break;
|
||||
case 101:
|
||||
{
|
||||
struct XDATA
|
||||
{
|
||||
__u8 completion_code;
|
||||
__u32 remote_target_id;
|
||||
__u32 remote_max_packet_size;
|
||||
} *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));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (data == NULL)
|
||||
|
||||
@@ -116,6 +116,12 @@ struct ncp_file_info {
|
||||
__u16 update_time;
|
||||
};
|
||||
|
||||
/* Defines for Name Spaces */
|
||||
#define NW_NS_DOS 0
|
||||
#define NW_NS_MAC 1
|
||||
#define NW_NS_NFS 2
|
||||
#define NW_NS_FTAM 3
|
||||
#define NW_NS_OS2 4
|
||||
|
||||
/* Defines for ReturnInformationMask */
|
||||
#define RIM_NAME (0x0001L)
|
||||
|
||||
@@ -21,6 +21,8 @@ struct ncp_server {
|
||||
interest for us later, so we store
|
||||
it completely. */
|
||||
|
||||
__u8 name_space[NCP_NUMBER_OF_VOLUMES];
|
||||
|
||||
struct file *ncp_filp; /* File pointer to ncp socket */
|
||||
struct file *wdog_filp; /* File pointer to wdog socket */
|
||||
void *data_ready; /* The wdog socket gets a new
|
||||
|
||||
@@ -97,6 +97,20 @@ str_lower(char *name)
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
ncp_namespace(struct inode *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)
|
||||
{
|
||||
return (ncp_namespace(i) == NW_NS_OS2);
|
||||
}
|
||||
|
||||
static struct file_operations ncp_dir_operations = {
|
||||
NULL, /* lseek - default */
|
||||
ncp_dir_read, /* read - bad */
|
||||
@@ -133,7 +147,7 @@ struct inode_operations ncp_dir_inode_operations = {
|
||||
/* Here we encapsulate the inode number handling that depends upon the
|
||||
* mount mode: When we mount a complete server, the memory address of
|
||||
* the npc_inode_info is used as an inode. When only a single volume
|
||||
* is mounted, then the DosDirNum is used as the inode number. As this
|
||||
* is mounted, then the dirEntNum is used as the inode number. As this
|
||||
* is unique for the complete volume, this should enable the NFS
|
||||
* exportability of a ncpfs-mounted volume.
|
||||
*/
|
||||
@@ -148,7 +162,7 @@ inline ino_t
|
||||
ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
|
||||
{
|
||||
return ncp_single_volume(server)
|
||||
? info->finfo.i.DosDirNum : (ino_t)info;
|
||||
? info->finfo.i.dirEntNum : (ino_t)info;
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -351,9 +365,12 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
c_last_returned_index = 0;
|
||||
index = 0;
|
||||
|
||||
for (i = 0; i < c_size; i++)
|
||||
if (!ncp_preserve_case(inode))
|
||||
{
|
||||
str_lower(c_entry[i].i.entryName);
|
||||
for (i = 0; i < c_size; i++)
|
||||
{
|
||||
str_lower(c_entry[i].i.entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,7 +392,7 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
|
||||
if (ncp_single_volume(server))
|
||||
{
|
||||
ino = (ino_t)(entry->i.DosDirNum);
|
||||
ino = (ino_t)(entry->i.dirEntNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -671,7 +688,7 @@ ncp_init_root(struct ncp_server *server)
|
||||
root->finfo.opened = 0;
|
||||
i->attributes = aDIR;
|
||||
i->dataStreamSize = 1024;
|
||||
i->DosDirNum = 0;
|
||||
i->dirEntNum = i->DosDirNum = 0;
|
||||
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));
|
||||
@@ -748,7 +765,7 @@ ncp_find_dir_inode(struct inode *dir, const char *name)
|
||||
|
||||
do
|
||||
{
|
||||
if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
|
||||
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
|
||||
@@ -776,7 +793,7 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
struct ncp_server *server;
|
||||
struct ncp_inode_info *result_info;
|
||||
int found_in_cache;
|
||||
|
||||
int down_case = 0;
|
||||
char name[len+1];
|
||||
|
||||
*result = NULL;
|
||||
@@ -887,20 +904,26 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
if (found_in_cache == 0)
|
||||
{
|
||||
int res;
|
||||
str_upper(name);
|
||||
|
||||
DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
|
||||
NCP_ISTRUCT(dir)->entryName, name);
|
||||
|
||||
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))
|
||||
{
|
||||
str_upper(name);
|
||||
down_case = 1;
|
||||
}
|
||||
res = ncp_obtain_info(server,
|
||||
NCP_ISTRUCT(dir)->volNumber,
|
||||
NCP_ISTRUCT(dir)->DosDirNum,
|
||||
NCP_ISTRUCT(dir)->dirEntNum,
|
||||
name, &(finfo.i));
|
||||
}
|
||||
if (res != 0)
|
||||
@@ -912,7 +935,11 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
}
|
||||
|
||||
finfo.opened = 0;
|
||||
str_lower(finfo.i.entryName);
|
||||
|
||||
if (down_case != 0)
|
||||
{
|
||||
str_lower(finfo.i.entryName);
|
||||
}
|
||||
|
||||
if (!(*result = ncp_iget(dir, &finfo)))
|
||||
{
|
||||
@@ -949,7 +976,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
|
||||
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
str_upper(_name);
|
||||
|
||||
if (!ncp_preserve_case(dir))
|
||||
{
|
||||
str_upper(_name);
|
||||
}
|
||||
|
||||
lock_super(dir->i_sb);
|
||||
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
|
||||
@@ -966,7 +997,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
|
||||
|
||||
ncp_invalid_dir_cache(dir);
|
||||
|
||||
str_lower(finfo.i.entryName);
|
||||
if (!ncp_preserve_case(dir))
|
||||
{
|
||||
str_lower(finfo.i.entryName);
|
||||
}
|
||||
|
||||
finfo.access = O_RDWR;
|
||||
|
||||
if (!(*result = ncp_iget(dir, &finfo)) < 0)
|
||||
@@ -1000,7 +1035,11 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
|
||||
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
str_upper(_name);
|
||||
|
||||
if (!ncp_preserve_case(dir))
|
||||
{
|
||||
str_upper(_name);
|
||||
}
|
||||
|
||||
if (!dir || !S_ISDIR(dir->i_mode))
|
||||
{
|
||||
@@ -1058,7 +1097,11 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
|
||||
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
str_upper(_name);
|
||||
|
||||
if (!ncp_preserve_case(dir))
|
||||
{
|
||||
str_upper(_name);
|
||||
}
|
||||
|
||||
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
|
||||
NCP_ISTRUCT(dir),
|
||||
@@ -1101,7 +1144,11 @@ ncp_unlink(struct inode *dir, const char *name, int len)
|
||||
{
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
str_upper(_name);
|
||||
|
||||
if (!ncp_preserve_case(dir))
|
||||
{
|
||||
str_upper(_name);
|
||||
}
|
||||
|
||||
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
|
||||
NCP_ISTRUCT(dir),
|
||||
@@ -1155,11 +1202,19 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
|
||||
|
||||
strncpy(_old_name, old_name, old_len);
|
||||
_old_name[old_len] = '\0';
|
||||
str_upper(_old_name);
|
||||
|
||||
if (!ncp_preserve_case(old_dir))
|
||||
{
|
||||
str_upper(_old_name);
|
||||
}
|
||||
|
||||
strncpy(_new_name, new_name, new_len);
|
||||
_new_name[new_len] = '\0';
|
||||
str_upper(_new_name);
|
||||
|
||||
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,
|
||||
|
||||
@@ -188,25 +188,6 @@ ncp_get_volume_info_with_number(struct ncp_server *server, int n,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(server, 5);
|
||||
ncp_add_pstring(server, name);
|
||||
|
||||
if ((result = ncp_request(server, 22)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
*target = ncp_reply_byte(server, 0);
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_close_file(struct ncp_server *server, const char *file_id)
|
||||
{
|
||||
@@ -282,8 +263,8 @@ ncp_obtain_info(struct ncp_server *server,
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 6); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, 0); /* dos name space as dest */
|
||||
ncp_add_byte(server, server->name_space[vol_num]);
|
||||
ncp_add_byte(server, server->name_space[vol_num]);
|
||||
ncp_add_word(server, 0xff); /* get all */
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
ncp_add_handle_path(server, vol_num, dir_base, 1, path);
|
||||
@@ -299,20 +280,57 @@ ncp_obtain_info(struct ncp_server *server,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
|
||||
{
|
||||
int result;
|
||||
__u8 *namespace;
|
||||
__u16 no_namespaces;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
|
||||
ncp_add_word(server, 0);
|
||||
ncp_add_byte(server, volume);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
no_namespaces = ncp_reply_word(server, 0);
|
||||
namespace = ncp_reply_data(server, 2);
|
||||
|
||||
while (no_namespaces > 0)
|
||||
{
|
||||
DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
|
||||
|
||||
if (*namespace == 4)
|
||||
{
|
||||
DPRINTK("get_namespaces: found OS2\n");
|
||||
ncp_unlock_server(server);
|
||||
return 1;
|
||||
}
|
||||
namespace += 1;
|
||||
no_namespaces -= 1;
|
||||
}
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_lookup_volume(struct ncp_server *server,
|
||||
char *volname,
|
||||
struct nw_info_struct *target)
|
||||
{
|
||||
int result;
|
||||
__u8 vol_num;
|
||||
__u32 dir_base;
|
||||
int volnum;
|
||||
|
||||
DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
|
||||
ncp_add_byte(server, 0); /* DOS name space */
|
||||
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 */
|
||||
@@ -329,20 +347,19 @@ ncp_lookup_volume(struct ncp_server *server,
|
||||
return result;
|
||||
}
|
||||
|
||||
dir_base = ncp_reply_dword(server, 4);
|
||||
vol_num = ncp_reply_byte(server, 8);
|
||||
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);
|
||||
|
||||
if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
|
||||
target)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
|
||||
|
||||
DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
|
||||
DPRINTK("lookup_vol: namespace[%d] = %d\n",
|
||||
volnum, server->name_space[volnum]);
|
||||
|
||||
target->nameLen = strlen(volname);
|
||||
strcpy(target->entryName, volname);
|
||||
target->attributes = aDIR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -356,14 +373,14 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 7); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, server->name_space[file->volNumber]);
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_word(server, 0x8006); /* search attribs: all */
|
||||
|
||||
ncp_add_dword(server, info_mask);
|
||||
ncp_add_mem(server, info, sizeof(*info));
|
||||
ncp_add_handle_path(server, file->volNumber,
|
||||
file->DosDirNum, 1, NULL);
|
||||
file->dirEntNum, 1, NULL);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
@@ -383,11 +400,11 @@ ncp_del_file_or_subdir(struct ncp_server *server,
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 8); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, server->name_space[dir->volNumber]);
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_word(server, 0x8006); /* search attribs: all */
|
||||
ncp_add_handle_path(server, dir->volNumber,
|
||||
dir->DosDirNum, 1, name);
|
||||
dir->dirEntNum, 1, name);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
@@ -420,15 +437,16 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
|
||||
{
|
||||
int result;
|
||||
__u16 search_attribs = 0x0006;
|
||||
__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
|
||||
|
||||
if ((create_attributes & aDIR) != 0)
|
||||
{
|
||||
search_attribs |= 0x8000;
|
||||
}
|
||||
search_attribs |= 0x8000;
|
||||
}
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 1); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, server->name_space[volume]);
|
||||
ncp_add_byte(server, open_create_mode);
|
||||
ncp_add_word(server, search_attribs);
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
@@ -439,13 +457,11 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
ncp_add_handle_path(server, dir->volNumber,
|
||||
dir->DosDirNum, 1, name);
|
||||
ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ncp_add_handle_path(server,
|
||||
target->i.volNumber, target->i.DosDirNum,
|
||||
ncp_add_handle_path(server, volume, target->i.dirEntNum,
|
||||
1, NULL);
|
||||
}
|
||||
|
||||
@@ -481,9 +497,9 @@ ncp_initialize_search(struct ncp_server *server,
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 2); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, server->name_space[dir->volNumber]);
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
|
||||
ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
@@ -507,7 +523,7 @@ ncp_search_for_file_or_subdir(struct ncp_server *server,
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 3); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
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 */
|
||||
@@ -542,19 +558,19 @@ ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 4); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, server->name_space[old_dir->volNumber]);
|
||||
ncp_add_byte(server, 1); /* rename flag */
|
||||
ncp_add_word(server, 0x8006); /* search attributes */
|
||||
|
||||
/* source Handle Path */
|
||||
ncp_add_byte(server, old_dir->volNumber);
|
||||
ncp_add_dword(server, old_dir->DosDirNum);
|
||||
ncp_add_dword(server, old_dir->dirEntNum);
|
||||
ncp_add_byte(server, 1);
|
||||
ncp_add_byte(server, 1); /* 1 source component */
|
||||
|
||||
/* dest Handle Path */
|
||||
ncp_add_byte(server, new_dir->volNumber);
|
||||
ncp_add_dword(server, new_dir->DosDirNum);
|
||||
ncp_add_dword(server, new_dir->dirEntNum);
|
||||
ncp_add_byte(server, 1);
|
||||
ncp_add_byte(server, 1); /* 1 destination component */
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
This directory contains the patch you have to apply to the Linux
|
||||
kernel if you want to use the support for long file names using the
|
||||
OS/2 namespace on the NetWare server. It did not make it into 2.0, but
|
||||
patching your kernel is really no problem.
|
||||
|
||||
To apply this patch, please take a clean Linux kernel. This patch is
|
||||
against Linux 2.0.7, but any later kernel version in the 2.0.x series
|
||||
should also work fine. Please perform the following two steps:
|
||||
|
||||
cd /usr/src/linux
|
||||
patch -p1 </path_to_ncpfs/kernel-2.0/lfn-2.0.7.diff
|
||||
|
||||
Please do not forget the -p1 flag for patch. Here I assumed that your
|
||||
linux kernel resides in /usr/src/linux. After these two steps, you
|
||||
should recompile your kernel the normal way. If anything goes wrong,
|
||||
PLEASE first consult the file /usr/src/linux/README for more
|
||||
information.
|
||||
|
||||
@@ -1,498 +0,0 @@
|
||||
diff -urN 2.0.7/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
|
||||
--- 2.0.7/fs/ncpfs/dir.c Mon Jul 8 17:19:03 1996
|
||||
+++ linux/fs/ncpfs/dir.c Tue Jul 16 17:35:07 1996
|
||||
@@ -92,6 +92,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+ncp_namespace(struct inode *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)
|
||||
+{
|
||||
+ return (ncp_namespace(i) == NW_NS_OS2);
|
||||
+}
|
||||
+
|
||||
static struct file_operations ncp_dir_operations = {
|
||||
NULL, /* lseek - default */
|
||||
ncp_dir_read, /* read - bad */
|
||||
@@ -128,7 +142,7 @@
|
||||
/* Here we encapsulate the inode number handling that depends upon the
|
||||
* mount mode: When we mount a complete server, the memory address of
|
||||
* the ncp_inode_info is used as the inode number. When only a single
|
||||
- * volume is mounted, then the DosDirNum is used as the inode
|
||||
+ * volume is mounted, then the dirEntNum is used as the inode
|
||||
* number. As this is unique for the complete volume, this should
|
||||
* enable the NFS exportability of a ncpfs-mounted volume.
|
||||
*/
|
||||
@@ -143,7 +157,7 @@
|
||||
ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
|
||||
{
|
||||
return ncp_single_volume(server)
|
||||
- ? info->finfo.i.DosDirNum : (ino_t)info;
|
||||
+ ? info->finfo.i.dirEntNum : (ino_t)info;
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -177,8 +191,6 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-
|
||||
-
|
||||
static int
|
||||
ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count)
|
||||
{
|
||||
@@ -326,9 +338,12 @@
|
||||
c_last_returned_index = 0;
|
||||
index = 0;
|
||||
|
||||
- for (i = 0; i < c_size; i++)
|
||||
+ if (!ncp_preserve_case(inode))
|
||||
{
|
||||
- str_lower(c_entry[i].i.entryName);
|
||||
+ for (i = 0; i < c_size; i++)
|
||||
+ {
|
||||
+ str_lower(c_entry[i].i.entryName);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,7 +360,7 @@
|
||||
|
||||
if (ncp_single_volume(server))
|
||||
{
|
||||
- ino = (ino_t)(entry->i.DosDirNum);
|
||||
+ ino = (ino_t)(entry->i.dirEntNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -652,7 +667,7 @@
|
||||
root->finfo.opened = 0;
|
||||
i->attributes = aDIR;
|
||||
i->dataStreamSize = 1024;
|
||||
- i->DosDirNum = 0;
|
||||
+ i->dirEntNum = i->DosDirNum = 0;
|
||||
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));
|
||||
@@ -729,7 +744,7 @@
|
||||
|
||||
do
|
||||
{
|
||||
- if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
|
||||
+ 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
|
||||
@@ -757,6 +772,7 @@
|
||||
struct ncp_server *server;
|
||||
struct ncp_inode_info *result_info;
|
||||
int found_in_cache;
|
||||
+ int down_case = 0;
|
||||
char name[len+1];
|
||||
|
||||
*result = NULL;
|
||||
@@ -867,20 +883,26 @@
|
||||
if (found_in_cache == 0)
|
||||
{
|
||||
int res;
|
||||
- str_upper(name);
|
||||
|
||||
DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
|
||||
NCP_ISTRUCT(dir)->entryName, name);
|
||||
|
||||
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))
|
||||
+ {
|
||||
+ str_upper(name);
|
||||
+ down_case = 1;
|
||||
+ }
|
||||
res = ncp_obtain_info(server,
|
||||
NCP_ISTRUCT(dir)->volNumber,
|
||||
- NCP_ISTRUCT(dir)->DosDirNum,
|
||||
+ NCP_ISTRUCT(dir)->dirEntNum,
|
||||
name, &(finfo.i));
|
||||
}
|
||||
if (res != 0)
|
||||
@@ -892,7 +914,11 @@
|
||||
}
|
||||
|
||||
finfo.opened = 0;
|
||||
- str_lower(finfo.i.entryName);
|
||||
+
|
||||
+ if (down_case != 0)
|
||||
+ {
|
||||
+ str_lower(finfo.i.entryName);
|
||||
+ }
|
||||
|
||||
if (!(*result = ncp_iget(dir, &finfo)))
|
||||
{
|
||||
@@ -929,7 +955,11 @@
|
||||
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
- str_upper(_name);
|
||||
+
|
||||
+ if (!ncp_preserve_case(dir))
|
||||
+ {
|
||||
+ str_upper(_name);
|
||||
+ }
|
||||
|
||||
lock_super(dir->i_sb);
|
||||
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
|
||||
@@ -946,7 +976,11 @@
|
||||
|
||||
ncp_invalid_dir_cache(dir);
|
||||
|
||||
- str_lower(finfo.i.entryName);
|
||||
+ if (!ncp_preserve_case(dir))
|
||||
+ {
|
||||
+ str_lower(finfo.i.entryName);
|
||||
+ }
|
||||
+
|
||||
finfo.access = O_RDWR;
|
||||
|
||||
if (!(*result = ncp_iget(dir, &finfo)) < 0)
|
||||
@@ -980,7 +1014,11 @@
|
||||
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
- str_upper(_name);
|
||||
+
|
||||
+ if (!ncp_preserve_case(dir))
|
||||
+ {
|
||||
+ str_upper(_name);
|
||||
+ }
|
||||
|
||||
if (!dir || !S_ISDIR(dir->i_mode))
|
||||
{
|
||||
@@ -1038,7 +1076,11 @@
|
||||
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
- str_upper(_name);
|
||||
+
|
||||
+ if (!ncp_preserve_case(dir))
|
||||
+ {
|
||||
+ str_upper(_name);
|
||||
+ }
|
||||
|
||||
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
|
||||
NCP_ISTRUCT(dir),
|
||||
@@ -1081,7 +1123,11 @@
|
||||
{
|
||||
strncpy(_name, name, len);
|
||||
_name[len] = '\0';
|
||||
- str_upper(_name);
|
||||
+
|
||||
+ if (!ncp_preserve_case(dir))
|
||||
+ {
|
||||
+ str_upper(_name);
|
||||
+ }
|
||||
|
||||
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
|
||||
NCP_ISTRUCT(dir),
|
||||
@@ -1136,11 +1182,19 @@
|
||||
|
||||
strncpy(_old_name, old_name, old_len);
|
||||
_old_name[old_len] = '\0';
|
||||
- str_upper(_old_name);
|
||||
+
|
||||
+ if (!ncp_preserve_case(old_dir))
|
||||
+ {
|
||||
+ str_upper(_old_name);
|
||||
+ }
|
||||
|
||||
strncpy(_new_name, new_name, new_len);
|
||||
_new_name[new_len] = '\0';
|
||||
- str_upper(_new_name);
|
||||
+
|
||||
+ 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,
|
||||
diff -urN 2.0.7/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
|
||||
--- 2.0.7/fs/ncpfs/ncplib_kernel.c Thu Apr 18 08:40:28 1996
|
||||
+++ linux/fs/ncpfs/ncplib_kernel.c Tue Jul 16 10:52:33 1996
|
||||
@@ -190,25 +190,6 @@
|
||||
}
|
||||
|
||||
int
|
||||
-ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
|
||||
-{
|
||||
- int result;
|
||||
-
|
||||
- ncp_init_request_s(server, 5);
|
||||
- ncp_add_pstring(server, name);
|
||||
-
|
||||
- if ((result = ncp_request(server, 22)) != 0)
|
||||
- {
|
||||
- ncp_unlock_server(server);
|
||||
- return result;
|
||||
- }
|
||||
-
|
||||
- *target = ncp_reply_byte(server, 0);
|
||||
- ncp_unlock_server(server);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int
|
||||
ncp_close_file(struct ncp_server *server, const char *file_id)
|
||||
{
|
||||
int result;
|
||||
@@ -278,8 +259,8 @@
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 6); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
- ncp_add_byte(server, 0); /* dos name space as dest */
|
||||
+ ncp_add_byte(server, server->name_space[vol_num]);
|
||||
+ ncp_add_byte(server, server->name_space[vol_num]);
|
||||
ncp_add_word(server, 0xff); /* get all */
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
ncp_add_handle_path(server, vol_num, dir_base, 1, path);
|
||||
@@ -295,20 +276,57 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
|
||||
+{
|
||||
+ int result;
|
||||
+ __u8 *namespace;
|
||||
+ __u16 no_namespaces;
|
||||
+
|
||||
+ ncp_init_request(server);
|
||||
+ ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
|
||||
+ ncp_add_word(server, 0);
|
||||
+ ncp_add_byte(server, volume);
|
||||
+
|
||||
+ if ((result = ncp_request(server, 87)) != 0)
|
||||
+ {
|
||||
+ ncp_unlock_server(server);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ no_namespaces = ncp_reply_word(server, 0);
|
||||
+ namespace = ncp_reply_data(server, 2);
|
||||
+
|
||||
+ while (no_namespaces > 0)
|
||||
+ {
|
||||
+ DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
|
||||
+
|
||||
+ if (*namespace == 4)
|
||||
+ {
|
||||
+ DPRINTK("get_namespaces: found OS2\n");
|
||||
+ ncp_unlock_server(server);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ namespace += 1;
|
||||
+ no_namespaces -= 1;
|
||||
+ }
|
||||
+ ncp_unlock_server(server);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int
|
||||
ncp_lookup_volume(struct ncp_server *server,
|
||||
char *volname,
|
||||
struct nw_info_struct *target)
|
||||
{
|
||||
int result;
|
||||
- __u8 vol_num;
|
||||
- __u32 dir_base;
|
||||
+ int volnum;
|
||||
|
||||
DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
|
||||
- ncp_add_byte(server, 0); /* DOS name space */
|
||||
+ 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 */
|
||||
@@ -325,20 +343,19 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
- dir_base = ncp_reply_dword(server, 4);
|
||||
- vol_num = ncp_reply_byte(server, 8);
|
||||
+ 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);
|
||||
|
||||
- if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
|
||||
- target)) != 0)
|
||||
- {
|
||||
- return result;
|
||||
- }
|
||||
+ server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
|
||||
|
||||
- DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
|
||||
+ DPRINTK("lookup_vol: namespace[%d] = %d\n",
|
||||
+ volnum, server->name_space[volnum]);
|
||||
|
||||
target->nameLen = strlen(volname);
|
||||
strcpy(target->entryName, volname);
|
||||
+ target->attributes = aDIR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -352,14 +369,14 @@
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 7); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
+ ncp_add_byte(server, server->name_space[file->volNumber]);
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_word(server, 0x8006); /* search attribs: all */
|
||||
|
||||
ncp_add_dword(server, info_mask);
|
||||
ncp_add_mem(server, info, sizeof(*info));
|
||||
ncp_add_handle_path(server, file->volNumber,
|
||||
- file->DosDirNum, 1, NULL);
|
||||
+ file->dirEntNum, 1, NULL);
|
||||
|
||||
result = ncp_request(server, 87);
|
||||
ncp_unlock_server(server);
|
||||
@@ -374,11 +391,11 @@
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 8); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
+ ncp_add_byte(server, server->name_space[dir->volNumber]);
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_word(server, 0x8006); /* search attribs: all */
|
||||
ncp_add_handle_path(server, dir->volNumber,
|
||||
- dir->DosDirNum, 1, name);
|
||||
+ dir->dirEntNum, 1, name);
|
||||
|
||||
result = ncp_request(server, 87);
|
||||
ncp_unlock_server(server);
|
||||
@@ -406,15 +423,16 @@
|
||||
{
|
||||
int result;
|
||||
__u16 search_attribs = 0x0006;
|
||||
+ __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
|
||||
|
||||
if ((create_attributes & aDIR) != 0)
|
||||
{
|
||||
- search_attribs |= 0x8000;
|
||||
- }
|
||||
+ search_attribs |= 0x8000;
|
||||
+}
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 1); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
+ ncp_add_byte(server, server->name_space[volume]);
|
||||
ncp_add_byte(server, open_create_mode);
|
||||
ncp_add_word(server, search_attribs);
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
@@ -425,13 +443,11 @@
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
- ncp_add_handle_path(server, dir->volNumber,
|
||||
- dir->DosDirNum, 1, name);
|
||||
+ ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
- ncp_add_handle_path(server,
|
||||
- target->i.volNumber, target->i.DosDirNum,
|
||||
+ ncp_add_handle_path(server, volume, target->i.dirEntNum,
|
||||
1, NULL);
|
||||
}
|
||||
|
||||
@@ -467,9 +483,9 @@
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 2); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
+ ncp_add_byte(server, server->name_space[dir->volNumber]);
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
- ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
|
||||
+ ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
@@ -493,7 +509,7 @@
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 3); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
+ 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 */
|
||||
@@ -528,19 +544,19 @@
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 4); /* subfunction */
|
||||
- ncp_add_byte(server, 0); /* dos name space */
|
||||
+ ncp_add_byte(server, server->name_space[old_dir->volNumber]);
|
||||
ncp_add_byte(server, 1); /* rename flag */
|
||||
ncp_add_word(server, 0x8006); /* search attributes */
|
||||
|
||||
/* source Handle Path */
|
||||
ncp_add_byte(server, old_dir->volNumber);
|
||||
- ncp_add_dword(server, old_dir->DosDirNum);
|
||||
+ ncp_add_dword(server, old_dir->dirEntNum);
|
||||
ncp_add_byte(server, 1);
|
||||
ncp_add_byte(server, 1); /* 1 source component */
|
||||
|
||||
/* dest Handle Path */
|
||||
ncp_add_byte(server, new_dir->volNumber);
|
||||
- ncp_add_dword(server, new_dir->DosDirNum);
|
||||
+ ncp_add_dword(server, new_dir->dirEntNum);
|
||||
ncp_add_byte(server, 1);
|
||||
ncp_add_byte(server, 1); /* 1 destination component */
|
||||
|
||||
diff -urN 2.0.7/include/linux/ncp.h linux/include/linux/ncp.h
|
||||
--- 2.0.7/include/linux/ncp.h Thu Apr 18 08:40:36 1996
|
||||
+++ linux/include/linux/ncp.h Tue Jul 16 17:27:45 1996
|
||||
@@ -116,6 +116,12 @@
|
||||
__u16 update_time;
|
||||
};
|
||||
|
||||
+/* Defines for Name Spaces */
|
||||
+#define NW_NS_DOS 0
|
||||
+#define NW_NS_MAC 1
|
||||
+#define NW_NS_NFS 2
|
||||
+#define NW_NS_FTAM 3
|
||||
+#define NW_NS_OS2 4
|
||||
|
||||
/* Defines for ReturnInformationMask */
|
||||
#define RIM_NAME (0x0001L)
|
||||
diff -urN 2.0.7/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h
|
||||
--- 2.0.7/include/linux/ncp_fs_sb.h Thu Apr 18 08:40:36 1996
|
||||
+++ linux/include/linux/ncp_fs_sb.h Tue Jul 16 17:35:17 1996
|
||||
@@ -21,6 +21,8 @@
|
||||
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 */
|
||||
76
lib/Makefile
Normal file
76
lib/Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
#
|
||||
# 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)
|
||||
|
||||
install:
|
||||
$(INSTALL_LIB)
|
||||
|
||||
ncplib.o: ncplib.c ncplib_err.h
|
||||
$(CC) $(CFLAGS) -finline-functions -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
|
||||
|
||||
clean:
|
||||
make -C com_err clean
|
||||
rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h
|
||||
rm -f libncp.*
|
||||
|
||||
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
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
#
|
||||
|
||||
OBJECTS = com_err.o error_message.o et_name.o init_et.o
|
||||
CFLAGS = -Wall -O2
|
||||
CFLAGS = -Wall -O2 $(PIC_FLAG)
|
||||
|
||||
all: $(OBJECTS)
|
||||
all: ../libcom_err.a
|
||||
|
||||
../libcom_err.a: $(OBJECTS)
|
||||
ar r ../libcom_err.a $(OBJECTS)
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f *.o ../libcom_err.a
|
||||
|
||||
mrproper: clean
|
||||
rm -f .depend
|
||||
40
lib/com_err/com_err.h
Normal file
40
lib/com_err/com_err.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Header file for common error description library.
|
||||
*
|
||||
* Copyright 1988, Student Information Processing Board of the
|
||||
* Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copyright and distribution info, see the documentation supplied
|
||||
* with this package.
|
||||
*/
|
||||
|
||||
#ifndef __COM_ERR_H
|
||||
|
||||
typedef long errcode_t;
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
|
||||
/* ANSI C -- use prototypes etc */
|
||||
void com_err (const char *, long, const char *, ...);
|
||||
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
|
||||
va_list args);
|
||||
char const *error_message (long);
|
||||
extern void (*com_err_hook) (const char *, long, const char *, va_list);
|
||||
void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
|
||||
(const char *, long, const char *, va_list);
|
||||
void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
|
||||
int init_error_table(const char * const *msgs, int base, int count);
|
||||
#else
|
||||
/* no prototypes */
|
||||
void com_err ();
|
||||
void com_err_va ();
|
||||
char *error_message ();
|
||||
extern void (*com_err_hook) ();
|
||||
void (*set_com_err_hook ()) ();
|
||||
void (*reset_com_err_hook ()) ();
|
||||
int init_error_table();
|
||||
#endif
|
||||
|
||||
#define __COM_ERR_H
|
||||
#endif /* ! defined(__COM_ERR_H) */
|
||||
@@ -161,6 +161,43 @@ ipx_sscanf_node(char *buf, unsigned char node[6])
|
||||
return 6;
|
||||
}
|
||||
|
||||
static int
|
||||
ipx_sscanf_saddr(char *buf, struct sockaddr_ipx *target)
|
||||
{
|
||||
char *p;
|
||||
struct sockaddr_ipx addr;
|
||||
|
||||
addr.sipx_family = AF_IPX;
|
||||
addr.sipx_type = NCP_PTYPE;
|
||||
|
||||
if (sscanf(buf, "%lx", &addr.sipx_network) != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
addr.sipx_network = htonl(addr.sipx_network);
|
||||
if ((p = strchr(buf, ':')) == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
p += 1;
|
||||
if (ipx_sscanf_node(p, addr.sipx_node) != 6)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ((p = strchr(p, ':')) == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
p += 1;
|
||||
if (sscanf(p, "%hx", &addr.sipx_port) != 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
addr.sipx_port = htons(addr.sipx_port);
|
||||
*target = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ipx_assign_node(IPXNode dest, IPXNode src)
|
||||
{
|
||||
@@ -222,224 +259,6 @@ ipx_recv(int sock, void *buf, int len, unsigned int flags, int timeout,
|
||||
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;
|
||||
}
|
||||
|
||||
*(unsigned short *)data = htons(IPX_SAP_NEAREST_QUERY);
|
||||
*(unsigned short *)&(data[2]) = htons(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)
|
||||
{
|
||||
@@ -680,6 +499,40 @@ ncp_temp_request(struct ncp_conn *conn, int function)
|
||||
return r->completion_code == 0 ? 0 : NCPL_ET_REQUEST_ERROR;
|
||||
}
|
||||
|
||||
#ifdef PACKET_SIGNATURES
|
||||
static long
|
||||
ncp_setup_security(struct ncp_conn *conn)
|
||||
{
|
||||
__u8 security;
|
||||
__u8 accepted_security;
|
||||
__u16 socket, size;
|
||||
|
||||
conn->want_signatures = 0;
|
||||
if (ncp_get_big_ncp_max_packet_size(conn, 576, 0, &size, &socket,
|
||||
&accepted_security) != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((accepted_security & NCP_SEC_SIGNATURE_REQUESTED) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static long
|
||||
ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
|
||||
int wdog_needed)
|
||||
@@ -746,13 +599,8 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
|
||||
|
||||
if ((err = do_ncp_call(conn, sizeof(*h))) != 0)
|
||||
{
|
||||
if ( (err != ENETUNREACH)
|
||||
|| (ipx_make_reachable(htonl(target->sipx_network)) != 0)
|
||||
|| ((err = do_ncp_call(conn, sizeof(*h))) != 0))
|
||||
{
|
||||
close(ncp_sock); close(wdog_sock);
|
||||
return err;
|
||||
}
|
||||
close(ncp_sock); close(wdog_sock);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (wdog_needed != 0)
|
||||
@@ -783,103 +631,82 @@ ncp_connect_addr(struct ncp_conn *conn, const struct sockaddr_ipx *target,
|
||||
static long
|
||||
ncp_connect_any(struct ncp_conn *conn, int wdog_needed)
|
||||
{
|
||||
struct sockaddr_ipx addr;
|
||||
char name[NCP_BINDERY_NAME_LEN];
|
||||
struct sockaddr_ipx *addr;
|
||||
long result;
|
||||
const char *server = NULL;
|
||||
long err;
|
||||
|
||||
if ((result = ipx_sap_find_nearest(IPX_SAP_FILE_SERVER,
|
||||
&addr, name)) != 0)
|
||||
if ((addr = ncp_find_server(&server,NCP_BINDERY_FSERVER,&err)) == NULL)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((result = ncp_connect_addr(conn, addr, wdog_needed)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((result = ncp_connect_addr(conn, &addr, wdog_needed)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
strcpy(conn->server, name);
|
||||
strcpy(conn->server, server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sockaddr_ipx *
|
||||
ncp_find_fileserver(const char *server_name, long *err)
|
||||
{
|
||||
char server[NCP_BINDERY_NAME_LEN];
|
||||
char nearest[NCP_BINDERY_NAME_LEN];
|
||||
struct nw_property prop;
|
||||
struct prop_net_address *n_addr = (struct prop_net_address *)∝
|
||||
struct ncp_conn conn;
|
||||
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;
|
||||
FILE *p;
|
||||
int res;
|
||||
char *n;
|
||||
|
||||
initialize_NCPL_error_table();
|
||||
if (strlen(server_name) >= sizeof(server))
|
||||
memset(server, 0, sizeof(server));
|
||||
|
||||
if (*server_name != NULL)
|
||||
{
|
||||
*err = NCPL_ET_NAMETOOLONG;
|
||||
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;
|
||||
}
|
||||
|
||||
strcpy(server, server_name);
|
||||
str_upper(server);
|
||||
fgets(buf, sizeof(buf), p);
|
||||
|
||||
if ((*err = ipx_sap_find_nearest(IPX_SAP_FILE_SERVER,
|
||||
&result, nearest)) != 0)
|
||||
if (buf[strlen(buf)] - 1 == '\n');
|
||||
{
|
||||
buf[strlen(buf)] = '\0';
|
||||
}
|
||||
|
||||
if (((res = pclose(p)) != 0) || (ipx_sscanf_saddr(buf, &result) != 0))
|
||||
{
|
||||
*err = (*server_name != NULL)
|
||||
? NCPL_ET_HOST_UNKNOWN : NCPL_ET_NO_SERVER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We have to ask the nearest server for our wanted server */
|
||||
|
||||
memzero(conn);
|
||||
if ((*err = ncp_connect_addr(&conn, &result, 0)) != 0)
|
||||
if (*server_name == NULL)
|
||||
{
|
||||
return NULL;
|
||||
if ((n = strchr(buf, ' ')) == NULL)
|
||||
{
|
||||
*err = NCPL_ET_HOST_UNKNOWN;
|
||||
return NULL;
|
||||
}
|
||||
*server_name = n;
|
||||
}
|
||||
|
||||
/* 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, NCP_BINDERY_FSERVER, 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;
|
||||
}
|
||||
|
||||
@@ -1085,6 +912,15 @@ ncp_open_mount(const char *mount_point, long *err)
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1149,6 +985,11 @@ long
|
||||
ncp_close(struct ncp_conn *conn)
|
||||
{
|
||||
long result;
|
||||
if (conn == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((result = ncp_do_close(conn)) != 0)
|
||||
{
|
||||
return result;
|
||||
@@ -1292,7 +1133,7 @@ ncp_get_nwc_ent(FILE *nwc)
|
||||
}
|
||||
|
||||
FILE *
|
||||
ncp_fopen_nwc(const char *user, const char *mode)
|
||||
ncp_fopen_nwc(const char *user, const char *mode, long *err)
|
||||
{
|
||||
char path[MAXPATHLEN];
|
||||
char *home = NULL;
|
||||
@@ -1320,7 +1161,7 @@ ncp_fopen_nwc(const char *user, const char *mode)
|
||||
if ( (home == NULL)
|
||||
|| (strlen(home) + sizeof(NWCLIENT) + 2 > sizeof(path)))
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
*err = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1330,12 +1171,13 @@ ncp_fopen_nwc(const char *user, const char *mode)
|
||||
|
||||
if (stat(path, &st) != 0)
|
||||
{
|
||||
*err = errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((st.st_mode & (S_IRWXO | S_IRWXG)) != 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
*err = NCPL_ET_INVALID_MODE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1371,11 +1213,9 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
}
|
||||
else
|
||||
{
|
||||
nwc = ncp_fopen_nwc(NULL, NULL);
|
||||
|
||||
if (nwc == NULL)
|
||||
if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) == NULL)
|
||||
{
|
||||
*err = NCPL_ET_NO_SPEC;
|
||||
*err = NCPL_ET_NO_SERVER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1391,6 +1231,15 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
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))
|
||||
@@ -1401,7 +1250,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
strcpy(spec.user, user);
|
||||
}
|
||||
|
||||
str_upper(spec.server);
|
||||
str_upper(spec.user);
|
||||
spec.login_type = NCP_BINDERY_USER;
|
||||
|
||||
@@ -1422,7 +1270,7 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((nwc = ncp_fopen_nwc(NULL, NULL)) != NULL)
|
||||
if ((nwc = ncp_fopen_nwc(NULL, NULL, err)) != NULL)
|
||||
{
|
||||
while ((nwc_ent = ncp_get_nwc_ent(nwc)) != NULL)
|
||||
{
|
||||
@@ -1442,15 +1290,10 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
}
|
||||
}
|
||||
|
||||
if (login_necessary == 0)
|
||||
{
|
||||
memset(spec.user, 0, sizeof(spec.user));
|
||||
memset(spec.password, 0, sizeof(spec.password));
|
||||
}
|
||||
|
||||
if (strlen(spec.user) == 0)
|
||||
{
|
||||
return &spec;
|
||||
*err = NCPL_ET_NO_USER;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((strlen(spec.password) == 0) && (password == NULL))
|
||||
@@ -1817,6 +1660,31 @@ ncp_get_file_server_time(struct ncp_conn *conn, time_t *target)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(target, ncp_reply_data(conn, 0), sizeof(*target));
|
||||
target->MaximumServiceConnections
|
||||
= htons(target->MaximumServiceConnections);
|
||||
target->ConnectionsInUse
|
||||
= htons(target->ConnectionsInUse);
|
||||
target->MaxConnectionsEverUsed
|
||||
= htons(target->MaxConnectionsEverUsed);
|
||||
target->NumberMountedVolumes
|
||||
= htons(target->NumberMountedVolumes);
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_get_connlist(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
@@ -1840,6 +1708,57 @@ 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 result;
|
||||
ncp_init_request_s(conn, 28);
|
||||
ncp_add_dword(conn, connection);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
memset(target, 0, sizeof(*target));
|
||||
target->object_id = ntohl(ncp_reply_dword(conn, 0));
|
||||
target->object_type = ntohs(ncp_reply_word(conn, 4));
|
||||
memcpy(target->object_name, ncp_reply_data(conn, 6),
|
||||
sizeof(target->object_name));
|
||||
*login_time = nw_to_ctime((struct nw_time_buffer *)
|
||||
ncp_reply_data(conn, 54));
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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(conn, connection);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
memset(target, 0, sizeof(*target));
|
||||
target->sipx_network = ncp_reply_dword(conn, 0);
|
||||
memcpy(&(target->sipx_node), ncp_reply_data(conn, 4), 6);
|
||||
target->sipx_port = ncp_reply_word(conn, 10);
|
||||
*conn_type = ncp_reply_byte(conn, 12);
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_send_broadcast(struct ncp_conn *conn,
|
||||
__u8 no_conn, const __u8 *connections,
|
||||
@@ -2172,6 +2091,31 @@ 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 result;
|
||||
ncp_init_request(conn);
|
||||
ncp_add_word(conn, htons(proposed_max_size));
|
||||
ncp_add_byte(conn, proposed_security_flag);
|
||||
|
||||
if ((result = ncp_request(conn, 97)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
*accepted_max_size = ntohs(ncp_reply_word(conn, 0));
|
||||
*echo_socket = ntohs(ncp_reply_word(conn, 2));
|
||||
*accepted_security_flag = ncp_reply_byte(conn, 4);
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_login_encrypted(struct ncp_conn *conn,
|
||||
const struct ncp_bindery_object *object,
|
||||
@@ -2196,6 +2140,21 @@ ncp_login_encrypted(struct ncp_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(conn, htons(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_change_login_passwd(struct ncp_conn *conn,
|
||||
const struct ncp_bindery_object *object,
|
||||
@@ -2252,7 +2211,8 @@ ncp_login_object(struct ncp_conn *conn,
|
||||
struct ncp_bindery_object user;
|
||||
|
||||
if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) {
|
||||
return result;
|
||||
return ncp_login_unencrypted(conn, login_type, username,
|
||||
password);
|
||||
}
|
||||
|
||||
if ((result = ncp_get_bindery_object_id(conn, login_type,
|
||||
@@ -2672,7 +2632,7 @@ static void
|
||||
ncp_add_handle_path(struct ncp_conn *conn,
|
||||
__u8 vol_num,
|
||||
__u32 dir_base, int have_dir_base,
|
||||
char *path)
|
||||
const char *path)
|
||||
{
|
||||
ncp_add_byte(conn, vol_num);
|
||||
ncp_add_dword(conn, dir_base);
|
||||
@@ -2705,6 +2665,61 @@ ncp_extract_file_info(void *structure, struct nw_info_struct *target)
|
||||
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)
|
||||
{
|
||||
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(conn, search_attribs);
|
||||
ncp_add_dword(conn, rim);
|
||||
ncp_add_handle_path(conn, vol, dirent, 1, path);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 29);
|
||||
ncp_add_byte(conn, source_ns);
|
||||
ncp_add_byte(conn, target_ns);
|
||||
ncp_add_word(conn, search_attribs);
|
||||
ncp_add_dword(conn, 0);
|
||||
ncp_add_handle_path(conn, vol, dirent, 1, path);
|
||||
|
||||
if ((result = ncp_request(conn, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
*my_effective_rights = ncp_reply_word(conn, 0);
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
ncp_do_lookup(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir,
|
||||
@@ -2893,7 +2908,7 @@ ncp_initialize_search(struct ncp_conn *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(&(target->s), ncp_reply_data(conn, 0), sizeof(target->s));
|
||||
memcpy(&(target->s), ncp_reply_data(conn, 0), 9);
|
||||
target->namespace = namespace;
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
@@ -3,6 +3,9 @@ error_table NCPL
|
||||
ec NCPL_ET_NO_SERVER,
|
||||
"No server found"
|
||||
|
||||
ec NCPL_ET_NO_USER,
|
||||
"No username found"
|
||||
|
||||
ec NCPL_ET_HOST_UNKNOWN,
|
||||
"Server Unknown"
|
||||
|
||||
@@ -19,7 +22,7 @@ ec NCPL_ET_NO_SPEC,
|
||||
"Could not find valid connection spec"
|
||||
|
||||
ec NCPL_ET_INVALID_MODE,
|
||||
"$HOME/.nwclient has invalid mode"
|
||||
"$HOME/.nwclient has invalid mode, must be 600"
|
||||
|
||||
ec NCPL_ET_LOGIN_DENIED,
|
||||
"Login denied"
|
||||
@@ -34,6 +37,9 @@ ec NCPL_ET_PWD_TOO_LONG,
|
||||
"Password too long"
|
||||
|
||||
ec NCPL_ET_NO_IPX,
|
||||
"Could not alloc IPX socket. Probably no IPX support in kernel."
|
||||
"Could not alloc IPX socket. Probably no IPX support in kernel"
|
||||
|
||||
ec NCPL_ET_NO_NCPFS_FILE,
|
||||
"The file is probably not on a ncpfs mounted directory"
|
||||
|
||||
end
|
||||
16
man/Makefile
16
man/Makefile
@@ -1,20 +1,12 @@
|
||||
MAN1= slist nprint pqlist nsend pserver ncopy npasswd
|
||||
MAN1 += nwbols nwboprops nwbpvalues
|
||||
MAN5= nwclient
|
||||
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net \
|
||||
ipx_route nwmsg
|
||||
MAN8 += nwbocreate nwborm nwbpadd nwbpcreate nwbprm
|
||||
MAN8 += nwgrant nwrevoke
|
||||
|
||||
|
||||
|
||||
all:
|
||||
|
||||
dep:
|
||||
|
||||
install:
|
||||
for i in $(MAN1); do install $$i.1 -m 755 /usr/local/man/man1; done
|
||||
for i in $(MAN5); do install $$i.5 -m 755 /usr/local/man/man5; done
|
||||
for i in $(MAN8); do install $$i.8 -m 755 /usr/local/man/man8; done
|
||||
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
|
||||
|
||||
clean:
|
||||
rm -f *~
|
||||
@@ -90,7 +90,7 @@ option to
|
||||
.B ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
ncopy was written by Brian G. Reid (breid@tim.com) and
|
||||
Tom C. Henderson (thenderson@tim.com).
|
||||
Many thanks to Volker Lendecke (lendecke@namu01.gwdg.de) for the ncpfs
|
||||
and ncplib which made ncopy possible.
|
||||
ncopy was written by Brian G. Reid (breid@tim.com) and Tom
|
||||
C. Henderson (thenderson@tim.com). Many thanks to Volker Lendecke
|
||||
(lendecke@math.uni-goettingen.de) for the ncpfs and ncplib which made
|
||||
ncopy possible.
|
||||
|
||||
@@ -57,7 +57,7 @@ protocol Novell NetWare clients use to talk to NetWare servers. ncpfs
|
||||
was inspired by
|
||||
.B lwared,
|
||||
a free NetWare emulator for Linux written by Ales Dryak. See
|
||||
ftp://klokan.sh.cvut.cz/pub/linux for this very intersting program.
|
||||
ftp://klokan.sh.cvut.cz/pub/linux for this very interesting program.
|
||||
|
||||
.B ncpmount
|
||||
when invoked with all appropriate arguments attaches, logs in and
|
||||
@@ -83,7 +83,7 @@ If the real uid of the caller is not root,
|
||||
checks whether the user is allowed to mount a filesystem on the
|
||||
mount-point. So it should be safe to make
|
||||
.B ncpmount
|
||||
setuid root. The filesystem stores the uid of the user who called
|
||||
setuid root. The filesystem stores the uid of the user who called
|
||||
ncpmount. So
|
||||
.B ncpumount
|
||||
can check whether the caller is allowed to unmount the filesystem.
|
||||
@@ -271,7 +271,7 @@ of your server.
|
||||
.B USER / LOGNAME
|
||||
.RS 3
|
||||
The variables USER or LOGNAME may contain the username of the person
|
||||
using the client. USER is tried first. If it's emtpy, LOGNAME is
|
||||
using the client. USER is tried first. If it's empty, LOGNAME is
|
||||
tried.
|
||||
.RE
|
||||
|
||||
@@ -291,5 +291,5 @@ The encryption code was taken from Dr. Dobbs's Journal 11/93. There
|
||||
Pawel Szczerbina described it in an article on NCP.
|
||||
|
||||
The ncpfs code was initially hacked from smbfs by Volker Lendecke
|
||||
(lendecke@namu01.gwdg.de). smbfs was put together by Paal-Kr. Engstad
|
||||
(lendecke@math.uni-goettingen.de). smbfs was put together by Paal-Kr. Engstad
|
||||
(pke@engstad.ingok.hitos.no) and later polished by Volker.
|
||||
|
||||
@@ -219,4 +219,4 @@ printed if a printer operator has put in the correct form.
|
||||
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
nprint was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
nprint was written by Volker Lendecke (lendecke@math.uni-goettingen.de)
|
||||
|
||||
@@ -65,14 +65,14 @@ is the name of the server you want to use.
|
||||
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 you NetWare user name.
|
||||
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 to use passwords in scripts.
|
||||
command line. You should be careful about using passwords in scripts.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
|
||||
69
man/nwauth.1
Normal file
69
man/nwauth.1
Normal file
@@ -0,0 +1,69 @@
|
||||
.TH NWAUTH 1 10/27/1996 nwauth nwauth
|
||||
.SH NAME
|
||||
nwauth \- Verify username/password
|
||||
.SH SYNOPSIS
|
||||
.B nwauth
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.B nwauth
|
||||
does nothing but logging into a NetWare server. If the login was
|
||||
successful, an error code of 0 is returned. If the login was not
|
||||
successful, an error code of 1 is returned. It was designed for
|
||||
use by other programs who want authenticate users via a NetWare
|
||||
server.
|
||||
|
||||
nwauth
|
||||
.B always
|
||||
expects a password on stdin. If the stdin is a tty, then the user is
|
||||
prompted for a password. Otherwise nwauth simply reads stdin for a
|
||||
password.
|
||||
|
||||
.B nwauth
|
||||
looks up the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server and a user name. See nwclient(5) for more
|
||||
information. Please note that the access permissions of .nwclient MUST
|
||||
be 600, for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
.B -h
|
||||
is used to print a short help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
.B server
|
||||
is the name of the server you want to use.
|
||||
.RE
|
||||
|
||||
.B -U
|
||||
.I user 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
|
||||
|
||||
.SH SEE ALSO
|
||||
.B nwclient(5)
|
||||
|
||||
.SH CREDITS
|
||||
nwauth was written by Volker Lendecke (lendecke@math.uni-goettingen.de)
|
||||
@@ -22,9 +22,10 @@ nwbols \- List NetWare Bindery Objects
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -v
|
||||
.B -o
|
||||
.I pattern
|
||||
] [
|
||||
.B pattern
|
||||
.B -v
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
@@ -95,7 +96,8 @@ objects to be listed.
|
||||
must be given as a decimal number.
|
||||
.RE
|
||||
|
||||
.B pattern
|
||||
.B -o
|
||||
.I pattern
|
||||
.RS 3
|
||||
Specifying a pattern is another way to restrict the objects
|
||||
listed. Please note that this pattern is evaluated by the NetWare
|
||||
|
||||
107
man/nwbpset.1
Normal file
107
man/nwbpset.1
Normal file
@@ -0,0 +1,107 @@
|
||||
.TH NWBPSET 1 8/7/1996 nwbpset nwbpset
|
||||
.SH NAME
|
||||
nwbpset \- Create a bindery property or set its value
|
||||
.SH SYNOPSIS
|
||||
.B nwbpset
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbpset
|
||||
Reads a property specification from the standard input and creates and
|
||||
sets the corresponding property. The format is determined by the
|
||||
output of 'nwbpvalues -c'. nwbpset will hopefully become an important
|
||||
part of the bindery management suite of ncpfs, together with
|
||||
'nwbpvalues -c'. See util/nwbpsecurity for an example.
|
||||
|
||||
As another example, look at the following command line:
|
||||
|
||||
nwbpvalues -t 1 -o supervisor -p user_defaults -c |\\
|
||||
sed '2s/.*/ME/'|\\
|
||||
sed '3s/.*/LOGIN_CONTROL/'|\\
|
||||
nwbpset
|
||||
|
||||
With this command, the property user_defaults of the user object
|
||||
\'supervisor\' is copied into the property login_control of the user
|
||||
object \'me\'.
|
||||
|
||||
nwbpvalues -t 1 -o me -p login_control -c |\\
|
||||
sed '9s/.*/ff/'|\\
|
||||
nwbpset
|
||||
|
||||
This command disables the user object me.
|
||||
|
||||
Feel free to contribute other examples!
|
||||
|
||||
.B nwbpset
|
||||
looks up the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password. See
|
||||
nwclient(5) for more information. Please note that the access
|
||||
permissions of $HOME/.nwclient MUST be 600 for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
.B -h
|
||||
is used to print out a short help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
.B server
|
||||
is the name of the server you want to use.
|
||||
.RE
|
||||
|
||||
.B -U
|
||||
.I user
|
||||
.RS 3
|
||||
.B user
|
||||
is the user name to use for login.
|
||||
.RE
|
||||
|
||||
.B -P
|
||||
.I password
|
||||
.RS 3
|
||||
.B password
|
||||
is the password to use for login. If neither
|
||||
.B -n
|
||||
nor
|
||||
.B -P
|
||||
are given, and the user has no open connection to the server, nwbpset
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbpset was written by Volker Lendecke. See the Changes file of ncpfs
|
||||
for other contributors.
|
||||
@@ -29,6 +29,8 @@ nwbpvalues \- Print a NetWare Bindery Propery's contents
|
||||
.I property
|
||||
] [
|
||||
.B -v
|
||||
] [
|
||||
.B -c
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
@@ -122,6 +124,11 @@ the object flags, its security byte and the properties flag is also
|
||||
listed.
|
||||
.RE
|
||||
|
||||
.B -c
|
||||
.RS 3
|
||||
Use canonical output, to be used with nwbpset.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbpvalues was written by Volker Lendecke with the corresponding
|
||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH NWCLIENT 5 12/27/1995 nwmount nwmount
|
||||
.TH NWCLIENT 5 12/27/1995 nwclient nwclient
|
||||
.SH NAME
|
||||
nwclient \- configuration file for NWClient program suite
|
||||
.SH DESCRIPTION
|
||||
@@ -35,11 +35,11 @@ An example might be the following:
|
||||
# And a passwordless account on another server
|
||||
CD-SERV/GUEST -
|
||||
|
||||
With these lines in $HOME/.nwclient, calling 'nwmount /mnt' will mount
|
||||
With these lines in $HOME/.nwclient, calling 'ncpmount /mnt' will mount
|
||||
the the file server FS311 with user name ME on /mnt after asking the
|
||||
user for a password.
|
||||
|
||||
\'nwmount -S cd-serv /cd' will silently mount the server cd-serv on /cd.
|
||||
\'ncpmount -S cd-serv /cd' will silently mount the server cd-serv on /cd.
|
||||
|
||||
.B nprint
|
||||
,
|
||||
|
||||
52
man/nwfsinfo.1
Normal file
52
man/nwfsinfo.1
Normal file
@@ -0,0 +1,52 @@
|
||||
.TH NWFSINFO 1 07/22/1996 nwfsinfo nwfsinfo
|
||||
.SH NAME
|
||||
nwfsinfo \- Print some information about the file server
|
||||
.SH SYNOPSIS
|
||||
.B nwfsinfo
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -t
|
||||
] [
|
||||
.B -i
|
||||
] [
|
||||
.B -d
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwfsinfo
|
||||
prints some of the information the NetWare servers present without
|
||||
logging in. The options control what is printed. You should try the
|
||||
different options to find out what is printed when.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
With -h nwfsinfo prints a little help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
is the name of the server you want to know something about.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.RS 3
|
||||
Print what the file server believes to be the current time.
|
||||
.RE
|
||||
|
||||
.B -d
|
||||
.RS 3
|
||||
Print the so-called file server description strings.
|
||||
.RE
|
||||
|
||||
.B -i
|
||||
.RS 3
|
||||
Print the extended file server information such as NetWare version,
|
||||
maximum connections an others.
|
||||
.RE
|
||||
@@ -1,8 +1,8 @@
|
||||
.TH NPASSWD 1 06/22/1996 npasswd npasswd
|
||||
.TH NWPASSWD 1 06/22/1996 nwpasswd nwpasswd
|
||||
.SH NAME
|
||||
npasswd \- Change a user's password
|
||||
nwpasswd \- Change a user's password
|
||||
.SH SYNOPSIS
|
||||
.B npasswd
|
||||
.B nwpasswd
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
@@ -18,9 +18,9 @@ npasswd \- Change a user's password
|
||||
|
||||
.SH DESCRIPTION
|
||||
With
|
||||
.B npasswd,
|
||||
.B nwpasswd,
|
||||
you can change your password on a NetWare server.
|
||||
.B npasswd
|
||||
.B nwpasswd
|
||||
asks for the old password and twice for the new password. Then it
|
||||
changes the password on the server.
|
||||
|
||||
@@ -28,7 +28,7 @@ changes the password on the server.
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
With -h npasswd prints a little help text.
|
||||
With -h nwpasswd prints a little help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
@@ -51,5 +51,5 @@ changed.
|
||||
.RE
|
||||
|
||||
.SH CREDITS
|
||||
npasswd would not have been possible without the work of Guntram
|
||||
nwpasswd would not have been possible without the work of Guntram
|
||||
Blom. Look at nwcrypt.c for his work.
|
||||
41
man/nwrights.1
Normal file
41
man/nwrights.1
Normal file
@@ -0,0 +1,41 @@
|
||||
.TH NWRIGHTS 1 8/1/1996 nwrights nwrights
|
||||
.SH NAME
|
||||
nwrights \- Show effective rights for file or directory
|
||||
.SH SYNOPSIS
|
||||
.B nwrights
|
||||
[
|
||||
.B -h
|
||||
]
|
||||
.B file/directory
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwrights
|
||||
asks the NetWare server for the effective rights the user has for a
|
||||
specific file or directory. The rights the server grants are the
|
||||
definitive restriction for what you may do with files or
|
||||
directories. The Linux permission bits are not really relevant, they
|
||||
can only restrict the possibilities further.
|
||||
|
||||
.B nwrights
|
||||
operates on the current directory or the file or directory that is
|
||||
given as an argument. Certainly the file or directory you specify has
|
||||
to reside on a ncpfs mounted directory for nwrights to work properly.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
.B -h
|
||||
is used to print out a short help text.
|
||||
.RE
|
||||
|
||||
.B file/directory
|
||||
.RS 3
|
||||
You can specify the file or directory you want information about. The
|
||||
default is the current working directory.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwrights was written by Volker Lendecke with the corresponding NetWare
|
||||
utility in mind. See the Changes file of ncpfs for other contributors.
|
||||
|
||||
36
man/nwsfind.1
Normal file
36
man/nwsfind.1
Normal file
@@ -0,0 +1,36 @@
|
||||
.TH NWSFIND 1 10/27/1996 nwsfind nwsfind
|
||||
.SH NAME
|
||||
nwsfind \- Find a NetWare Server
|
||||
.SH SYNOPSIS
|
||||
.B nwsfind
|
||||
[
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.I name
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.B nwsfind
|
||||
searches for a NetWare server and finds a route to this
|
||||
server. nwsfind was written to be setuid root. It is called from
|
||||
within the ncp library, so that it is possible that normal users use
|
||||
the utilities.
|
||||
|
||||
.SH OPTIONS
|
||||
.B name
|
||||
.RS 3
|
||||
If you look for a specific server, you should give nwsfind this
|
||||
argument. If you omit it, nwsfind looks for the server nearest to you.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I type
|
||||
.RS 3
|
||||
By default nwsfind looks for file servers. In case you want to look up
|
||||
another server type, you have to specify its numerical type as
|
||||
.B type.
|
||||
.RE
|
||||
|
||||
|
||||
.SH CREDITS
|
||||
nwsfind was written by Volker Lendecke (lendecke@math.uni-goettingen.de)
|
||||
93
man/nwuserlist.1
Normal file
93
man/nwuserlist.1
Normal file
@@ -0,0 +1,93 @@
|
||||
.TH NWUSERLIST 1 7/22/1996 nwuserlist nwuserlist
|
||||
.SH NAME
|
||||
nwuserlist \- List Users logged in at a NetWare server
|
||||
.SH SYNOPSIS
|
||||
.B nwuserlist
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -a
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwuserlist
|
||||
lists the users logged in at a NetWare server, together with their
|
||||
connection number and their login time.
|
||||
|
||||
.B nwuserlist
|
||||
looks up the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password. See
|
||||
nwclient(5) for more information. Please note that the access
|
||||
permissions of $HOME/.nwclient MUST be 600 for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
.B -h
|
||||
is used to print out a short help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
.B server
|
||||
is the name of the server you want to use.
|
||||
.RE
|
||||
|
||||
.B -U
|
||||
.I user
|
||||
.RS 3
|
||||
.B user
|
||||
is the user name to use for login.
|
||||
.RE
|
||||
|
||||
.B -P
|
||||
.I password
|
||||
.RS 3
|
||||
.B password
|
||||
is the password to use for login. If neither
|
||||
.B -n
|
||||
nor
|
||||
.B -P
|
||||
are given, and the user has no open connection to the server, nwuserlist
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -a
|
||||
.RS 3
|
||||
With option -a the IPX address of the station the user is logged in
|
||||
from is printed as well.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwuserlist was written by Volker Lendecke. See the Changes file of ncpfs
|
||||
for other contributors.
|
||||
@@ -68,14 +68,14 @@ is the name of the server you want to use.
|
||||
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 you NetWare user name.
|
||||
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 to use passwords in scripts.
|
||||
command line. You should be careful about using passwords in scripts.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
@@ -102,4 +102,4 @@ this conversion by
|
||||
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
pqlist was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
pqlist was written by Volker Lendecke (lendecke@math.uni-goettingen.de)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH PSERVER 1 02/10/1996 pserver pserver
|
||||
.TH PSERVER 1 10/22/1996 pserver pserver
|
||||
.SH NAME
|
||||
pserver \- NetWare print server
|
||||
.SH SYNOPSIS
|
||||
@@ -101,6 +101,13 @@ process, and feeds the job file to stdin.
|
||||
.I command
|
||||
is the printing command that is executed for each job. The default
|
||||
command is 'lpr'.
|
||||
|
||||
You can insert several flags into the command, preceded by %. These
|
||||
are replaced with values retrieved from the queue structure for the
|
||||
print job.
|
||||
|
||||
%u: This field will be replaced by the name of the user who posted
|
||||
this print job.
|
||||
.RE
|
||||
|
||||
.B -j
|
||||
@@ -139,4 +146,4 @@ diagnostic messages that are printed when a error occurs.
|
||||
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
pserver was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
pserver was written by Volker Lendecke (lendecke@math.uni-goettingen.de)
|
||||
|
||||
@@ -40,4 +40,4 @@ List all available Netware servers on your Network, that begin with an "I".
|
||||
.B ncpmount(8), ncpumount(8), pqlist(1), nprint(1)
|
||||
|
||||
.SH CREDITS
|
||||
slist was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
slist was written by Volker Lendecke (lendecke@math.uni-goettingen.de)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Begin3
|
||||
Title: ncpfs
|
||||
Version: 2.0.2
|
||||
Entered-date: 18. July 1996
|
||||
Version: 2.0.7
|
||||
Entered-date: 27. October 1996
|
||||
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
|
||||
@@ -12,8 +12,8 @@ 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)
|
||||
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
|
||||
Alternate-site: sunsite.unc.edu:/pub/system/Filesystems/ncpfs
|
||||
~124k ncpfs-2.0.2.tgz
|
||||
~ 1k ncpfs-2.0.2.lsm
|
||||
Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs
|
||||
~148k ncpfs-2.0.7.tgz
|
||||
~ 1k ncpfs-2.0.7.lsm
|
||||
Copying-policy: GPL
|
||||
End
|
||||
42
sutil/Makefile
Normal file
42
sutil/Makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
UTILS = ncpmount ncpumount nwsfind
|
||||
|
||||
CC = gcc
|
||||
|
||||
default:
|
||||
make -C ..
|
||||
|
||||
all: $(UTILS)
|
||||
|
||||
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
|
||||
|
||||
ncplib.o: ncplib.c ncplib.h
|
||||
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
|
||||
|
||||
libncp.a: ncplib.o ../lib/ncplib_err.o
|
||||
ar r libncp.a ncplib.o ../lib/ncplib_err.o
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ libncp.a $(UTILS)
|
||||
|
||||
mrproper: clean
|
||||
rm -f .depend
|
||||
|
||||
#
|
||||
# include a dependency file if one exists
|
||||
#
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
|
||||
93
sutil/ipxlib.h
Normal file
93
sutil/ipxlib.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* ipxlib.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IPXLIB_H
|
||||
#define _IPXLIB_H
|
||||
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ncp.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned long IPXNet;
|
||||
typedef unsigned short IPXPort;
|
||||
typedef unsigned char IPXNode[IPX_NODE_LEN];
|
||||
|
||||
#define IPX_USER_PTYPE (0x00)
|
||||
#define IPX_RIP_PTYPE (0x01)
|
||||
#define IPX_SAP_PTYPE (0x04)
|
||||
#define IPX_AUTO_PORT (0x0000)
|
||||
#define IPX_SAP_PORT (0x0452)
|
||||
#define IPX_RIP_PORT (0x0453)
|
||||
|
||||
#define IPX_SAP_GENERAL_QUERY (0x0001)
|
||||
#define IPX_SAP_GENERAL_RESPONSE (0x0002)
|
||||
#define IPX_SAP_NEAREST_QUERY (0x0003)
|
||||
#define IPX_SAP_NEAREST_RESPONSE (0x0004)
|
||||
|
||||
#define IPX_SAP_FILE_SERVER (0x0004)
|
||||
|
||||
struct sap_query {
|
||||
unsigned short query_type; /* net order */
|
||||
unsigned short server_type; /* net order */
|
||||
};
|
||||
|
||||
struct sap_server_ident {
|
||||
unsigned short server_type __attribute__ ((packed));
|
||||
char server_name[48] __attribute__ ((packed));
|
||||
IPXNet server_network __attribute__ ((packed));
|
||||
IPXNode server_node __attribute__ ((packed));
|
||||
IPXPort server_port __attribute__ ((packed));
|
||||
unsigned short intermediate_network __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define IPX_RIP_REQUEST (0x1)
|
||||
#define IPX_RIP_RESPONSE (0x2)
|
||||
|
||||
struct ipx_rip_packet {
|
||||
__u16 operation __attribute__ ((packed));
|
||||
struct ipx_rt_def {
|
||||
__u32 network __attribute__ ((packed));
|
||||
__u16 hops __attribute__ ((packed));
|
||||
__u16 ticks __attribute__ ((packed));
|
||||
} rt[1] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff")
|
||||
#define IPX_THIS_NODE ("\0\0\0\0\0\0")
|
||||
#define IPX_THIS_NET (0)
|
||||
|
||||
#ifndef IPX_NODE_LEN
|
||||
#define IPX_NODE_LEN (6)
|
||||
#endif
|
||||
|
||||
void
|
||||
ipx_print_node(IPXNode node);
|
||||
void
|
||||
ipx_print_network(IPXNet net);
|
||||
void
|
||||
ipx_print_port(IPXPort port);
|
||||
void
|
||||
ipx_print_saddr(struct sockaddr_ipx* sipx);
|
||||
void
|
||||
ipx_fprint_node(FILE *file, IPXNode node);
|
||||
void
|
||||
ipx_fprint_network(FILE *file, IPXNet net);
|
||||
void
|
||||
ipx_fprint_port(FILE *file, IPXPort port);
|
||||
void
|
||||
ipx_fprint_saddr(FILE *file, struct sockaddr_ipx* sipx);
|
||||
int
|
||||
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
|
||||
void
|
||||
ipx_assign_node(IPXNode dest, IPXNode src);
|
||||
int
|
||||
ipx_node_equal(IPXNode n1,IPXNode n2);
|
||||
|
||||
#endif /* _IPXLIB_H */
|
||||
1927
sutil/ncplib.c
Normal file
1927
sutil/ncplib.c
Normal file
File diff suppressed because it is too large
Load Diff
198
sutil/ncplib.h
Normal file
198
sutil/ncplib.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* ncplib.h
|
||||
*
|
||||
* Copyright (C) 1995, 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NCPLIB_H
|
||||
#define _NCPLIB_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ncp.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ipxlib.h"
|
||||
#include "com_err.h"
|
||||
|
||||
#ifndef memzero
|
||||
#include <string.h>
|
||||
#define memzero(object) memset(&(object), 0, sizeof(object))
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#endif /* _NCPLIB_H */
|
||||
@@ -201,7 +201,7 @@ main(int argc, char *argv[])
|
||||
|
||||
upcase_password = 1;
|
||||
|
||||
while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nhvV:t:r:"))
|
||||
while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:"))
|
||||
!= EOF)
|
||||
{
|
||||
switch (opt)
|
||||
@@ -310,6 +310,7 @@ main(int argc, char *argv[])
|
||||
data.retry_count = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
exit(1);
|
||||
case 'v':
|
||||
@@ -86,6 +86,11 @@ canonicalize (const char *path)
|
||||
if (realpath (path, canonical))
|
||||
return canonical;
|
||||
|
||||
if (strlen(path) > PATH_MAX)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (canonical, path);
|
||||
return canonical;
|
||||
}
|
||||
@@ -116,7 +121,15 @@ main(int argc, char *argv[])
|
||||
|
||||
mount_point = canonicalize(argv[1]);
|
||||
|
||||
if (mount_point == NULL)
|
||||
{
|
||||
fprintf(stderr, "Invalid mount point: %s\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (umount_ok(mount_point) != 0) {
|
||||
fprintf(stderr, "You are not allowed to umount %s\n",
|
||||
mount_point);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
209
sutil/nwcrypt.c
Normal file
209
sutil/nwcrypt.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*$*********************************************************
|
||||
$*
|
||||
$* This code has been taken from DDJ 11/93, from an
|
||||
$* article by Pawel Szczerbina.
|
||||
$*
|
||||
$* Password encryption routines follow.
|
||||
$* Converted to C from Barry Nance's Pascal
|
||||
$* prog published in the March -93 issue of Byte.
|
||||
$*
|
||||
$* Adapted to be useable for ncpfs by
|
||||
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
|
||||
$* October 1995.
|
||||
$*
|
||||
$**********************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
I read that Novell is not very open when it comes to technical details
|
||||
of the Netware Core Protocol. This might be especially true for the
|
||||
encryption stuff. I took the necessary code from Dr. Dobb's Journal
|
||||
11/93, Undocumented Corner. I asked Jon Erickson <jon@ddj.com> about
|
||||
the legal status of this piece of code:
|
||||
|
||||
|
||||
---
|
||||
Date: Thu, 12 Oct 1995 13:44:18 +0100
|
||||
From: Volker Lendecke <lendecke>
|
||||
To: jon@ddj.com
|
||||
Subject: legal status of your source code?
|
||||
|
||||
|
||||
Hello!
|
||||
|
||||
I hope that you're the right one to write to, you are the first on your WWW
|
||||
server. If you are not, could you please forward this message to the right
|
||||
person? Thanks.
|
||||
|
||||
I'm currently exploring the possibility to write a free (in the GNU GPL
|
||||
sense) NCP filesystem, which would allow me to access a novell server
|
||||
transparently. For that I would like to use the encryption functions you
|
||||
published in DDJ 11/93, Undocumented Corner. I would make some cosmetic
|
||||
changes, such as other indentations, minor code changes and so on. But I do
|
||||
not know if that allows me to publish this code under GPL. One alternative
|
||||
would be to publish a diff against your listing, but that would probably
|
||||
contain much of your code as well, and it would be very inconvenient for
|
||||
the average user.
|
||||
|
||||
I think that you have some kind of standard procedure for such a
|
||||
case. Please tell me what I should do.
|
||||
|
||||
Many thanks in advance,
|
||||
|
||||
Volker
|
||||
|
||||
+=================================================================+
|
||||
! Volker Lendecke Internet: lendecke@namu01.gwdg.de !
|
||||
! D-37081 Goettingen, Germany !
|
||||
+=================================================================+
|
||||
|
||||
--
|
||||
|
||||
|
||||
I got the following answer:
|
||||
|
||||
---
|
||||
From: Jon Erickson <jon@ddj.com>
|
||||
X-Mailer: SCO System V Mail (version 3.2)
|
||||
To: lendecke@namu01.gwdg.de
|
||||
Subject: Re: legal status of your source code?
|
||||
Date: Thu, 12 Oct 95 5:42:56 PDT
|
||||
|
||||
Volker,
|
||||
Code from Dr. Dobb's Journal related articles is provided for
|
||||
anyone to use. Clearly, the author of the article should be
|
||||
given credit.
|
||||
Jon Erickson
|
||||
|
||||
---
|
||||
|
||||
With this answer in mind, I took the code and made it a bit more
|
||||
C-like. The original seemed to be translated by a mechanical pascal->c
|
||||
translator. Jon's answer encouraged me to publish nwcrypt.c under the
|
||||
GPL. If anybody who knows more about copyright and sees any problems
|
||||
with this, please tell me.
|
||||
****************************************************************************/
|
||||
|
||||
/******************* Data types ***************************/
|
||||
typedef unsigned char buf32[32];
|
||||
typedef unsigned char buf16[16];
|
||||
typedef unsigned char buf8[8];
|
||||
typedef unsigned char buf4[4];
|
||||
|
||||
static unsigned char encrypttable[256] =
|
||||
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
|
||||
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
|
||||
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
|
||||
0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
|
||||
0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
|
||||
0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
|
||||
0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
|
||||
0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
|
||||
0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
|
||||
0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
|
||||
0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
|
||||
0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
|
||||
0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
|
||||
0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
|
||||
0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
|
||||
0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
|
||||
|
||||
static buf32 encryptkeys =
|
||||
{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
|
||||
0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
|
||||
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
||||
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
||||
|
||||
|
||||
static void
|
||||
shuffle1(buf32 temp, unsigned char *target)
|
||||
{
|
||||
short b4;
|
||||
unsigned char b3;
|
||||
int s, b2, i;
|
||||
|
||||
b4 = 0;
|
||||
|
||||
for (b2 = 0; b2 <= 1; ++b2)
|
||||
{
|
||||
for (s = 0; s <= 31; ++s)
|
||||
{
|
||||
b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]);
|
||||
b4 = b4 + b3;
|
||||
temp[s] = b3;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i <= 15; ++i) {
|
||||
target[i] = encrypttable[temp[ 2*i ]]
|
||||
| (encrypttable[temp[ 2*i + 1]] << 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
|
||||
unsigned char *target)
|
||||
{
|
||||
int b2, d, s;
|
||||
buf32 temp;
|
||||
|
||||
while ( (buflen > 0)
|
||||
&& (buf[buflen - 1] == 0)) {
|
||||
buflen = buflen - 1;
|
||||
}
|
||||
|
||||
for (s = 0; s < 32; s++) {
|
||||
temp[s] = 0;
|
||||
}
|
||||
|
||||
d = 0;
|
||||
while (buflen >= 32)
|
||||
{
|
||||
for (s = 0; s <= 31; ++s)
|
||||
{
|
||||
temp[s] = temp[s] ^ buf[d];
|
||||
d = d + 1;
|
||||
}
|
||||
buflen = buflen - 32;
|
||||
}
|
||||
b2 = d;
|
||||
if (buflen > 0)
|
||||
{
|
||||
for (s = 0; s <= 31; ++s)
|
||||
{
|
||||
if (d + buflen == b2)
|
||||
{
|
||||
b2 = d;
|
||||
temp[s] = temp[s] ^ encryptkeys[s];
|
||||
} else {
|
||||
temp[s] = temp[s] ^ buf[b2];
|
||||
b2 = b2 + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (s = 0; s <= 31; ++s)
|
||||
temp[s] = temp[s] ^ lon[s & 3];
|
||||
|
||||
shuffle1(temp,target);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nw_encrypt(const unsigned char *fra,
|
||||
const unsigned char *buf,
|
||||
unsigned char *til)
|
||||
{
|
||||
buf32 k;
|
||||
int s;
|
||||
|
||||
shuffle(&(fra[0]), buf, 16, &(k[ 0]));
|
||||
shuffle(&(fra[4]), buf, 16, &(k[16]));
|
||||
|
||||
for (s = 0; s <= 15; ++s)
|
||||
k[s] = k[s] ^ k[31 - s];
|
||||
|
||||
for (s = 0; s <= 7; ++s)
|
||||
til[s] = k[s] ^ k[15 - s];
|
||||
}
|
||||
102
sutil/nwsfind.c
Normal file
102
sutil/nwsfind.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* nwsfind.c
|
||||
*
|
||||
* Find a NetWare server and open a route to it.
|
||||
* This tool can safely be setuid root, if normal users should be able to
|
||||
* access any NetWare server.
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ncplib.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [server]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s [server]\n", progname);
|
||||
printf("\n"
|
||||
"-t Server type, default: File server\n"
|
||||
"-h Print this help text\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static void
|
||||
swallow_error(const char * name, long code, const char *format, va_list arg)
|
||||
{
|
||||
printf("%s ", error_message(code));
|
||||
vfprintf(stdout, format, arg);
|
||||
putchar('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *server = NULL;
|
||||
int object_type = NCP_BINDERY_FSERVER;
|
||||
struct sockaddr_ipx *result;
|
||||
long err;
|
||||
|
||||
int opt;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
set_com_err_hook(swallow_error);
|
||||
|
||||
while ((opt = getopt(argc, argv, "t:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 't':
|
||||
object_type = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
exit(1);
|
||||
default:
|
||||
usage();
|
||||
exit(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");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
result = ncp_find_server(&server, object_type, &err);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "when trying to find server");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ipx_print_saddr(result);
|
||||
printf(" %s\n", server);
|
||||
return 0;
|
||||
}
|
||||
@@ -2,71 +2,45 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy npasswd
|
||||
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd
|
||||
USERUTILS += nwbols nwbocreate nwborm nwboprops
|
||||
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd
|
||||
USERUTILS += nwgrant nwrevoke
|
||||
UIDUTILS = ncpmount ncpumount
|
||||
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd nwbpset
|
||||
USERUTILS += nwgrant nwrevoke nwuserlist nwrights nwauth
|
||||
SBINUTILS = nwmsg
|
||||
|
||||
UTIL_EXECS = $(USERUTILS) $(UIDUTILS) $(SBINUTILS)
|
||||
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
|
||||
UTILS = $(USERUTILS) $(SBINUTILS) ncptest
|
||||
|
||||
#CFLAGS = -Wall $(INCLUDES) $(KERNELD) -g -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -O2 -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
CC = gcc
|
||||
|
||||
ifeq ($(HAVE_ELF),yes)
|
||||
NCP_LIB = libncp.so.1.0
|
||||
else
|
||||
NCP_LIB = libncp.a
|
||||
LIBDEP = ../lib/libncp.a
|
||||
endif
|
||||
|
||||
default:
|
||||
make -C ..
|
||||
|
||||
all: $(UTILS) ncptest
|
||||
|
||||
install: all
|
||||
for i in $(UTIL_EXECS); \
|
||||
do install $(INTERM_BINDIR)/$$i -m 755 $(BINDIR); done
|
||||
for i in $(UIDUTILS); \
|
||||
do install $(INTERM_BINDIR)/$$i -m 4755 $(BINDIR); done
|
||||
for i in $(USERUTILS); \
|
||||
do install $$i -m 755 $(BINDIR); done
|
||||
for i in $(SBINUTILS); \
|
||||
do install $(INTERM_BINDIR)/$$i -m 755 $(SBINDIR); done
|
||||
do install $$i -m 755 $(SBINDIR); done
|
||||
|
||||
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) libncp.a
|
||||
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) -L. -lncp
|
||||
$(UTILS): %: %.o $(LIBDEP)
|
||||
$(CC) -o $@ $(addsuffix .o,$@) -L../lib -lncp
|
||||
|
||||
ncplib.o: ncplib.c ncplib.h ncplib_err.h
|
||||
$(CC) $(CFLAGS) -finline-functions -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
|
||||
|
||||
libncp.a: ncplib.o ncplib_err.o $(COM_ERR_CFILES)
|
||||
make -C com_err
|
||||
ar r libncp.a ncplib.o ncplib_err.o \
|
||||
com_err/com_err.o com_err/error_message.o com_err/et_name.o \
|
||||
com_err/init_et.o
|
||||
|
||||
ncplib_err.h: ncplib_err.et
|
||||
com_err/compile_et ncplib_err
|
||||
|
||||
ncplib_err.c: ncplib_err.et
|
||||
com_err/compile_et ncplib_err
|
||||
|
||||
test: test.o ncplib.o
|
||||
$(CC) -o test test.o ncplib.o
|
||||
|
||||
ncptest: ncptest.o libncp.a
|
||||
$(CC) -o ncptest ncptest.o -L. -lncp
|
||||
|
||||
dep: ncplib_err.h
|
||||
make -C com_err dep
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
make -C com_err clean
|
||||
rm -f *.o *~ slist test ncptest ncplib_err.[ch] libncp.a
|
||||
rm -f *.o *~ $(UTILS)
|
||||
|
||||
mrproper: clean
|
||||
make -C com_err mrproper
|
||||
rm -f $(UTILS) .depend $(DISTFILE)
|
||||
rm -f .depend
|
||||
|
||||
#
|
||||
# include a dependency file if one exists
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
com_err/com_err.h
|
||||
@@ -131,6 +131,95 @@ test_change(struct ncp_conn *conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
printf("lookup error\n");
|
||||
return;
|
||||
}
|
||||
if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0)
|
||||
{
|
||||
printf("lookup blub error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
0x8006, RIM_ALL,
|
||||
entry.volNumber,
|
||||
entry.DosDirNum,
|
||||
NULL,
|
||||
&nfs) == 0)
|
||||
{
|
||||
printf("nfs name: %s\n", nfs.entryName);
|
||||
}
|
||||
if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_OS2,
|
||||
0x8006, RIM_ALL,
|
||||
entry.volNumber,
|
||||
entry.DosDirNum,
|
||||
NULL,
|
||||
&nfs) == 0)
|
||||
{
|
||||
printf("os2 name: %s\n", nfs.entryName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
printf("lookup error\n");
|
||||
return;
|
||||
}
|
||||
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)
|
||||
{
|
||||
printf("get sys rights error\n");
|
||||
return;
|
||||
}
|
||||
printf("sys right: %4.4x\n", rights);
|
||||
|
||||
if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006,
|
||||
me.volNumber, me.DosDirNum, NULL,
|
||||
&rights) != 0)
|
||||
{
|
||||
printf("get me rights error\n");
|
||||
return;
|
||||
}
|
||||
printf("me right: %4.4x\n", rights);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@@ -143,7 +232,7 @@ main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_change(conn);
|
||||
test_rights(conn);
|
||||
ncp_close(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing connection");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -78,10 +78,11 @@ main(int argc, char *argv[])
|
||||
pj.Rows = htons(80);
|
||||
strcpy(pj.FnameHeader, "stdin");
|
||||
|
||||
while ((opt = getopt(argc, argv, "hq:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
|
||||
while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
|
||||
{
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
ncp_close(conn);
|
||||
exit(1);
|
||||
|
||||
@@ -25,7 +25,7 @@ main(int argc, char **argv)
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
127
util/nwauth.c
Normal file
127
util/nwauth.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* nwauth.c
|
||||
*
|
||||
* Check a user/passwd against a NetWare server
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ncplib.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [options]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s [options]\n", progname);
|
||||
printf("\n"
|
||||
"-h Print this help text\n"
|
||||
"-S server Server name to be used\n"
|
||||
"-U username Username sent to server\n"
|
||||
"-t type Object type (decimal value)\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static void
|
||||
swallow_error(const char * s, long x, const char *t, va_list arg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
long err;
|
||||
|
||||
char *str;
|
||||
|
||||
int opt;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
if (!isatty(0))
|
||||
{
|
||||
set_com_err_hook(swallow_error);
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'S':
|
||||
server = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
object_name = optarg;
|
||||
break;
|
||||
case 't':
|
||||
object_type = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
exit(1);
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
spec = ncp_find_conn_spec(server, object_name, "",
|
||||
1, getuid(), &err);
|
||||
|
||||
if (spec == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "when trying to find server");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ncp_find_fileserver(spec->server, &err) == NULL)
|
||||
{
|
||||
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))
|
||||
{
|
||||
str = getpass("Enter password: ");
|
||||
if (strlen(str) >= sizeof(spec->password))
|
||||
{
|
||||
printf("Password too long\n");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(spec->password, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
fgets(spec->password, sizeof(spec->password), stdin);
|
||||
}
|
||||
|
||||
str_upper(spec->password);
|
||||
|
||||
if ((conn = ncp_open(spec, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "when trying to open connection");
|
||||
exit(1);
|
||||
}
|
||||
ncp_close(conn);
|
||||
return 0;
|
||||
}
|
||||
@@ -83,11 +83,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:r:w:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -122,6 +122,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
@@ -36,6 +36,7 @@ help(void)
|
||||
"-C Don't convert password to uppercase\n"
|
||||
"\n"
|
||||
"-t type Object type to be listed (decimal)\n"
|
||||
"-o object Object pattern\n"
|
||||
"-v Verbose listing\n"
|
||||
"\n");
|
||||
}
|
||||
@@ -59,19 +60,23 @@ main(int argc, char **argv)
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "hvt:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
exit(1);
|
||||
case 't':
|
||||
type = atoi(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
pattern = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
@@ -81,17 +86,12 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc-1)
|
||||
if (optind < argc)
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (optind == argc-1)
|
||||
{
|
||||
pattern = argv[optind];
|
||||
}
|
||||
|
||||
for (p = pattern; *p != '\0'; p++)
|
||||
{
|
||||
*p = toupper(*p);
|
||||
|
||||
@@ -56,11 +56,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:v")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -74,6 +74,7 @@ main(int argc, char *argv[])
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
@@ -53,11 +53,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -68,6 +68,7 @@ main(int argc, char *argv[])
|
||||
object_type = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
@@ -63,11 +63,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:p:v:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -91,6 +91,7 @@ main(int argc, char *argv[])
|
||||
value = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
@@ -87,11 +87,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:p:sr:w:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -139,6 +139,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
@@ -55,11 +55,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:p:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:p:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -80,6 +80,7 @@ main(int argc, char *argv[])
|
||||
str_upper(property_name);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
238
util/nwbpset.c
Normal file
238
util/nwbpset.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* nwbpset.c
|
||||
*
|
||||
* Create a property and set its values
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ncplib.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [options]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s [options] [values]\n", progname);
|
||||
printf("\n"
|
||||
"-h Print this help text\n"
|
||||
"-S server Server name to be used\n"
|
||||
"-U username Username sent to server\n"
|
||||
"-P password Use this password\n"
|
||||
"-n Do not use any password\n"
|
||||
"-C Don't convert password to uppercase\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static char *
|
||||
get_line(char *buf, int len, FILE *stream)
|
||||
{
|
||||
char *result = fgets(buf, len, stream);
|
||||
if (result != NULL)
|
||||
{
|
||||
buf[strlen(buf)-1] = '\0'; /* remove newline */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ncp_conn *conn;
|
||||
char object_name[49];
|
||||
int object_type = -1;
|
||||
char property_name[17];
|
||||
int property_flag, property_security;
|
||||
struct ncp_property_info info;
|
||||
long err;
|
||||
int result = 1;
|
||||
char buf[512];
|
||||
int opt;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
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) {
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
usage();
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
fprintf(stderr, "Illegal format on stdin\n");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* Property already exists */
|
||||
|
||||
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 (ncp_change_property_security(conn, object_type,
|
||||
object_name,
|
||||
property_name,
|
||||
property_security)!=0)
|
||||
{
|
||||
fprintf(stderr, "Could not change "
|
||||
"property security\n");
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ncp_create_property(conn, object_type, object_name,
|
||||
property_name, property_flag,
|
||||
property_security) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not create property\n");
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
if ((property_flag & 2) == 0)
|
||||
{
|
||||
/* ITEM property */
|
||||
int 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)
|
||||
{
|
||||
break;
|
||||
}
|
||||
property_value[i] = strtoul(buf, NULL, 16);
|
||||
}
|
||||
length = i-1;
|
||||
|
||||
for (segno = 1; segno <= 255; segno++)
|
||||
{
|
||||
struct nw_property segment;
|
||||
int offset = (segno-1)*128;
|
||||
|
||||
if ( offset > length )
|
||||
{
|
||||
/* everything written */
|
||||
break;
|
||||
}
|
||||
memcpy(segment.value, &(property_value[offset]), 128);
|
||||
segment.more_flag = segno*128 < length;
|
||||
if (ncp_write_property_value(conn, object_type,
|
||||
object_name,
|
||||
property_name,
|
||||
segno, &segment) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not write property\n");
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* SET property */
|
||||
|
||||
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)
|
||||
{
|
||||
fprintf(stderr, "Illegal format on stdin\n");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (ncp_add_object_to_set(conn, object_type,
|
||||
object_name, property_name,
|
||||
element_type,
|
||||
element_name) != 0)
|
||||
{
|
||||
if (conn->completion != 0xE9) /* object already
|
||||
in set */
|
||||
{
|
||||
fprintf(stderr, "Could not add object "
|
||||
"to set\n");
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
finished:
|
||||
ncp_close(conn);
|
||||
return result;
|
||||
}
|
||||
@@ -40,6 +40,7 @@ help(void)
|
||||
"-t type Object type (decimal value)\n"
|
||||
"-p property Name of property to be listed\n"
|
||||
"-v Verbose object listing\n"
|
||||
"-c Canonical output, for use with nwbpadd\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
@@ -53,6 +54,7 @@ main(int argc, char *argv[])
|
||||
__u8 property_value[255*128];
|
||||
int segno;
|
||||
int verbose = 0;
|
||||
int canonical = 0;
|
||||
struct nw_property segment;
|
||||
struct ncp_property_info info;
|
||||
long err;
|
||||
@@ -65,11 +67,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:p:v")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:p:vc")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -92,7 +94,11 @@ main(int argc, char *argv[])
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'c':
|
||||
canonical = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
@@ -138,31 +144,59 @@ main(int argc, char *argv[])
|
||||
{
|
||||
break;
|
||||
}
|
||||
segno += 1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
print_property(property_name, property_value, segno);
|
||||
/* ITEM property */
|
||||
if (canonical != 0)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < segno*128; i++)
|
||||
{
|
||||
printf("%-2.2x\n", property_value[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print_property(property_name, property_value, segno);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int objects = 32 * segno;
|
||||
__u32 *value = (__u32 *)property_value;
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < objects; i++)
|
||||
while (i < objects)
|
||||
{
|
||||
struct ncp_bindery_object o;
|
||||
|
||||
if ((*value == 0) || (*value == 0xffffffff))
|
||||
if ((value[i] == 0) || (value[i] == 0xffffffff))
|
||||
{
|
||||
break;
|
||||
/* Continue with next segment */
|
||||
i = ((i/32) + 1) * 32;
|
||||
continue;
|
||||
}
|
||||
if (ncp_get_bindery_object_name(conn, ntohl(*value),
|
||||
if (ncp_get_bindery_object_name(conn, ntohl(value[i]),
|
||||
&o) == 0)
|
||||
{
|
||||
if (verbose != 0)
|
||||
if (canonical != 0)
|
||||
{
|
||||
printf("%-4.4x\n%s\n",
|
||||
(unsigned int) o.object_type,
|
||||
o.object_name);
|
||||
}
|
||||
else if (verbose != 0)
|
||||
{
|
||||
printf("%s %08X %04X\n",
|
||||
o.object_name,
|
||||
@@ -174,7 +208,7 @@ main(int argc, char *argv[])
|
||||
printf("%s\n", o.object_name);
|
||||
}
|
||||
}
|
||||
value += 1;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
result = 0;
|
||||
@@ -217,6 +251,174 @@ print_string(__u8 *val)
|
||||
puts(val);
|
||||
}
|
||||
|
||||
static char *
|
||||
print_station_addr(char *fmt, struct ncp_station_addr *addr, char *buff)
|
||||
{
|
||||
char *ret = buff;
|
||||
|
||||
while ( *fmt != 0 )
|
||||
{
|
||||
switch ( *fmt )
|
||||
{
|
||||
case '%':
|
||||
switch ( *(++fmt) )
|
||||
{
|
||||
case 'N': /* node */
|
||||
{
|
||||
int i ;
|
||||
for ( i = 0 ; i < 6 ; buff += 2 , i++ )
|
||||
{
|
||||
sprintf(buff, "%02X",addr->Node[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'S': /* Socket */
|
||||
sprintf(buff, "%04X", htons(addr->Socket));
|
||||
buff += 4 ;
|
||||
break ;
|
||||
case 'L': /* Lan */
|
||||
sprintf(buff, "%08lX", htonl(addr->NetWork));
|
||||
buff += 8 ;
|
||||
break ;
|
||||
case '%':
|
||||
*buff++ = '%';
|
||||
default:
|
||||
break ;
|
||||
}
|
||||
if (*fmt)
|
||||
{
|
||||
fmt++ ;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
*buff++ = *fmt++ ;
|
||||
}
|
||||
}
|
||||
*buff = 0 ;
|
||||
return ret ;
|
||||
}
|
||||
|
||||
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[]
|
||||
= { "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])
|
||||
{
|
||||
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
|
||||
{
|
||||
printf("Never logged in\n");
|
||||
}
|
||||
if (a->Disabled != 0)
|
||||
{
|
||||
printf(" --- Account disabled ---\n");
|
||||
}
|
||||
if (a->AccountExpireDate[2] || a->AccountExpireDate[1] ||
|
||||
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])
|
||||
{
|
||||
printf("Password expires on: %d.%d.%d\n" ,
|
||||
a->PasswordExpireDate[2],
|
||||
a->PasswordExpireDate[1],
|
||||
a->PasswordExpireDate[0]);
|
||||
printf("GraceLogins left: %d\nof max. : %d\n",
|
||||
a->GraceLogins, a->MaxGraceLogins);
|
||||
printf("PasswortChangeInterval : %d days\n",
|
||||
ntohs(a->PasswordExpireInterval));
|
||||
}
|
||||
if ((a->RestrictionMask & 2) != 0)
|
||||
{
|
||||
printf("New password must be different when changing\n");
|
||||
}
|
||||
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)
|
||||
{
|
||||
printf("Maximum no of connections: %d\n",
|
||||
ntohs(a->MaxConnections));
|
||||
}
|
||||
|
||||
if ( a->MaxDiskUsage != 0xFFFFFF7FL )
|
||||
{
|
||||
printf("Maximum DiskQuota : %8ld blocks\n",
|
||||
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->LastIntruder.NetWork != 0L)
|
||||
{
|
||||
printf("Last \'intruder\' address: %s\n" ,
|
||||
print_station_addr("(%L): %N[%S]" ,
|
||||
&(a->LastIntruder),buff));
|
||||
}
|
||||
if ( a->RestrictionMask & 0xFC )
|
||||
{
|
||||
printf("RestrictionMask : %02X\n", a->RestrictionMask);
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 42 ; i++ )
|
||||
{
|
||||
if ( a->ConnectionTimeMask[i] != 0xFF )
|
||||
{
|
||||
i = 101;
|
||||
}
|
||||
}
|
||||
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++ )
|
||||
{
|
||||
printf (" %s [" , days[i]);
|
||||
for ( j = 0 ; j < 6 ; j++ )
|
||||
{
|
||||
for ( mask = 1 ; mask < 0x100 ; mask <<= 1 )
|
||||
{
|
||||
putchar ( (*val & mask) ? '*' : ' ' ) ;
|
||||
}
|
||||
val++ ;
|
||||
}
|
||||
printf ( "]\n" ) ;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_addr( __u8 *val)
|
||||
{
|
||||
char buff[50];
|
||||
print_station_addr("(%L): %N[%S]",
|
||||
(struct ncp_station_addr *)val, buff);
|
||||
printf("%s\n", buff);
|
||||
}
|
||||
|
||||
static struct {
|
||||
char *pname ;
|
||||
void (*func)(__u8 *) ;
|
||||
@@ -227,6 +429,8 @@ static struct {
|
||||
{ "DESCRIPTION" , print_string } ,
|
||||
{ "IDENTIFICATION" , print_string } ,
|
||||
{ "Q_DIRECTORY" , print_string } ,
|
||||
{ "LOGIN_CONTROL" , print_login_control } ,
|
||||
{ "NET_ADDRESS" , print_addr } ,
|
||||
{ NULL , NULL }
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,64 @@
|
||||
#include <unistd.h>
|
||||
#include "ncplib.h"
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [pattern]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s [options]\n", progname);
|
||||
printf("\n"
|
||||
"-h Print this help text\n"
|
||||
"-S server Server name to be used\n"
|
||||
"\n"
|
||||
"-d Print Description Strings\n"
|
||||
"-t Print File Server's time\n"
|
||||
"-i Print File Server Information\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static void
|
||||
print_info(struct ncp_file_server_info *info)
|
||||
{
|
||||
printf ( "\n" ) ;
|
||||
printf ( "Fileservername %-48.48s\n" , info->ServerName ) ;
|
||||
printf ( "\n" ) ;
|
||||
printf ( "Version %d.%d Revision %c\n" ,
|
||||
info->FileServiceVersion , info->FileServiceSubVersion,
|
||||
info->Revision + 'A' ) ;
|
||||
printf ( "Max. Connections %d\n" ,
|
||||
info->MaximumServiceConnections ) ;
|
||||
printf ( "currently in use %d\n" ,
|
||||
info->ConnectionsInUse ) ;
|
||||
printf ( "peak connections %d\n" ,
|
||||
info->MaxConnectionsEverUsed ) ;
|
||||
printf ( "Max. Volumes %d\n" ,
|
||||
info->NumberMountedVolumes ) ;
|
||||
printf ( "SFTLevel %d\n" ,
|
||||
info->SFTLevel ) ;
|
||||
printf ( "TTSLevel %d\n" ,
|
||||
info->TTSLevel ) ;
|
||||
printf ( "Accountversion %d\n" ,
|
||||
info->AccountVersion ) ;
|
||||
printf ( "Queueversion %d\n" ,
|
||||
info->QueueVersion ) ;
|
||||
printf ( "Printversion %d\n" ,
|
||||
info->PrintVersion ) ;
|
||||
printf ( "Virt.Consolvers. %d\n" ,
|
||||
info->VirtualConsoleVersion ) ;
|
||||
printf ( "RestrictionLevel %d\n" ,
|
||||
info->RestrictionLevel ) ;
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -18,16 +76,22 @@ main(int argc, char **argv)
|
||||
int opt;
|
||||
long err;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "dt")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?dti")) != EOF)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
char strings[512];
|
||||
@@ -68,12 +132,26 @@ main(int argc, char **argv)
|
||||
fputs(ctime(&t), stdout);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("unknown option: %c\n", opt);
|
||||
case 'i':
|
||||
{
|
||||
struct ncp_file_server_info info;
|
||||
if (ncp_get_file_server_information(conn, &info) != 0)
|
||||
{
|
||||
perror("Could not get server information");
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
print_info(&info);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
usage();
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
finished:
|
||||
ncp_close(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:r:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:r:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -75,6 +75,7 @@ main(int argc, char *argv[])
|
||||
rights = strtol(optarg, NULL, 16);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
@@ -130,9 +130,9 @@ main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(tty_file, "\r\n\007\007\007Message from NetWare Server: %s\n",
|
||||
fprintf(tty_file,"\r\n\007\007\007Message from NetWare Server: %s\r\n",
|
||||
mnt->mnt_fsname);
|
||||
fprintf(tty_file, "%s\n", message);
|
||||
fprintf(tty_file, "%s\r\n", message);
|
||||
fclose(tty_file);
|
||||
fclose(mtab);
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* npasswd.c
|
||||
* nwpasswd.c
|
||||
*
|
||||
* Change a bindery object's password
|
||||
*
|
||||
@@ -53,7 +53,7 @@ main(int argc, char *argv[])
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
while ((opt = getopt(argc, argv, "hS:U:t:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'S':
|
||||
@@ -66,6 +66,7 @@ main(int argc, char *argv[])
|
||||
object_type = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
exit(1);
|
||||
default:
|
||||
@@ -55,11 +55,11 @@ main(int argc, char *argv[])
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "ho:t:")) != EOF)
|
||||
while ((opt = getopt(argc, argv, "h?o:t:")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
@@ -70,6 +70,7 @@ main(int argc, char *argv[])
|
||||
object_type = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
|
||||
141
util/nwrights.c
Normal file
141
util/nwrights.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* nwrights.c
|
||||
*
|
||||
* Show effective rights for dir or file.
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ncplib.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [options]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s [options] file/directory\n", progname);
|
||||
printf("\n"
|
||||
"-h Print this help text\n"
|
||||
"\n"
|
||||
"file/directory\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ncp_conn *conn = NULL;
|
||||
char *path = ".";
|
||||
long err;
|
||||
int result = 1;
|
||||
int opt;
|
||||
__u16 rights;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
while ((opt = getopt(argc, argv, "h?")) != EOF)
|
||||
{
|
||||
switch(opt) {
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
default:
|
||||
usage();
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind > argc)
|
||||
{
|
||||
usage();
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (optind == argc-1)
|
||||
{
|
||||
path = argv[optind];
|
||||
}
|
||||
|
||||
if ((conn = ncp_open_mount(path, &err)) == NULL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
com_err(argv[0], err, "when finding rights");
|
||||
goto finished;
|
||||
}
|
||||
|
||||
printf("Your effective rights for %s are: [%c%c%c%c%c%c%c%c]\n",
|
||||
path,
|
||||
((rights & NCP_PERM_SUPER ) != 0) ? 'S' : ' ',
|
||||
((rights & NCP_PERM_READ ) != 0) ? 'R' : ' ',
|
||||
((rights & NCP_PERM_WRITE ) != 0) ? 'W' : ' ',
|
||||
((rights & NCP_PERM_CREATE) != 0) ? 'C' : ' ',
|
||||
((rights & NCP_PERM_DELETE) != 0) ? 'E' : ' ',
|
||||
((rights & NCP_PERM_MODIFY) != 0) ? 'M' : ' ',
|
||||
((rights & NCP_PERM_SEARCH) != 0) ? 'F' : ' ',
|
||||
((rights & NCP_PERM_OWNER ) != 0) ? 'A' : ' ');
|
||||
|
||||
if ((rights & NCP_PERM_SUPER ) != 0)
|
||||
{
|
||||
printf("(S): You have SUPERVISOR rights\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_READ ) != 0)
|
||||
{
|
||||
printf("(R): You may READ from files\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_WRITE ) != 0)
|
||||
{
|
||||
printf("(W): You may WRITE to files\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_CREATE) != 0)
|
||||
{
|
||||
printf("(C): You may CREATE files\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_DELETE) != 0)
|
||||
{
|
||||
printf("(E): You may ERASE files\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_MODIFY) != 0)
|
||||
{
|
||||
printf("(M): You may MODIFY directory\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_SEARCH) != 0)
|
||||
{
|
||||
printf("(F): You may SCAN for files\n");
|
||||
}
|
||||
|
||||
if ((rights & NCP_PERM_OWNER ) != 0)
|
||||
{
|
||||
printf("(A): You may change ACCESS control\n");
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
finished:
|
||||
ncp_close(conn);
|
||||
return result;
|
||||
}
|
||||
143
util/nwuserlist.c
Normal file
143
util/nwuserlist.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* nwfsinfo.c
|
||||
*
|
||||
* Print the info strings of a server, maybe sometime more.
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "ncplib.h"
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [pattern]\n", progname);
|
||||
}
|
||||
|
||||
static void
|
||||
str_trim_right(char *s, char c)
|
||||
{
|
||||
int len = strlen(s) - 1;
|
||||
|
||||
while ((len > 0) && (s[len] == c))
|
||||
{
|
||||
s[len] = '\0';
|
||||
len -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("usage: %s [options]\n", progname);
|
||||
printf("\n"
|
||||
"-h Print this help text\n"
|
||||
"-S server Server name to be used\n"
|
||||
"-a Print Station's addr\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct ncp_conn *conn;
|
||||
int opt;
|
||||
long err;
|
||||
struct ncp_file_server_info info;
|
||||
struct ncp_bindery_object user;
|
||||
time_t login_time;
|
||||
int i;
|
||||
int print_addr = 0;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
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)
|
||||
{
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
goto finished;
|
||||
case 'a':
|
||||
print_addr = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
printf("\n%-6s%-21s%-12s\n"
|
||||
"---------------------------------------------"
|
||||
"------\n",
|
||||
"Conn",
|
||||
"User name",
|
||||
"Login time");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n%-6s%-21s%-27s%-12s\n"
|
||||
"---------------------------------------------"
|
||||
"---------------------------------\n",
|
||||
"Conn",
|
||||
"User name",
|
||||
"Station Address",
|
||||
"Login time");
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
memcpy(name, user.object_name, 48);
|
||||
str_trim_right(name, ' ');
|
||||
printf("%4d: %-20s ", i, name);
|
||||
|
||||
if (print_addr != 0)
|
||||
{
|
||||
struct sockaddr_ipx addr;
|
||||
__u8 conn_type;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
ncp_get_internet_address(conn, i, &addr, &conn_type);
|
||||
ipx_print_saddr(&addr);
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
printf("%s", ctime(&login_time));
|
||||
}
|
||||
|
||||
finished:
|
||||
ncp_close(conn);
|
||||
return 0;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ main(int argc, char **argv)
|
||||
|
||||
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ main(int argc, char *argv[])
|
||||
if ((conn = ncp_initialize_as(&argc, argv, 1,
|
||||
NCP_BINDERY_PSERVER, &err)) == NULL)
|
||||
{
|
||||
com_err(argv[0], err, "in ncp_initialize");
|
||||
com_err(argv[0], err, "when initializing");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -260,6 +260,70 @@ 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)
|
||||
{
|
||||
char *s = q->command;
|
||||
char *target_end = target+target_size;
|
||||
|
||||
void add_string(char *s)
|
||||
{
|
||||
int len = strlen(s);
|
||||
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 != '%')
|
||||
{
|
||||
*target = *s;
|
||||
target += 1;
|
||||
s += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*(s+1))
|
||||
{
|
||||
case '%':
|
||||
*target = '%';
|
||||
target += 1;
|
||||
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);
|
||||
}
|
||||
default:
|
||||
*target = '%';
|
||||
*(target+1) = *(s+1);
|
||||
target += 2;
|
||||
}
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
poll_queue(struct nw_queue *q)
|
||||
{
|
||||
@@ -316,6 +380,8 @@ poll_queue(struct nw_queue *q)
|
||||
{
|
||||
/* child */
|
||||
|
||||
char command[2048];
|
||||
|
||||
close(fd[1]); /* close write end */
|
||||
|
||||
if (fd[0] != STDIN_FILENO)
|
||||
@@ -329,7 +395,9 @@ poll_queue(struct nw_queue *q)
|
||||
close(fd[0]);
|
||||
}
|
||||
|
||||
execl("/bin/sh", "sh", "-c", q->command, NULL);
|
||||
build_command(q, &job, command, sizeof(command));
|
||||
|
||||
execl("/bin/sh", "sh", "-c", command, NULL);
|
||||
syslog(LOG_ERR, "exec error: %m\n");
|
||||
close(fd[0]);
|
||||
exit(1);
|
||||
|
||||
Reference in New Issue
Block a user