Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
011a5107c5 | ||
|
|
7179281575 | ||
|
|
b8d830f9a3 | ||
|
|
b36a27bedb | ||
|
|
7d0e3d011b | ||
|
|
84cb1f167d | ||
|
|
64f006632a | ||
|
|
92f749a943 | ||
|
|
6cb56005ea | ||
|
|
0520c1d2f7 | ||
|
|
d5ac4601b1 | ||
|
|
1fa124bd7c | ||
|
|
5753870858 | ||
|
|
b8ce93c8bd | ||
|
|
7bef99df0f |
BIN
.downloads/ncpfs-0.14.tgz
Normal file
BIN
.downloads/ncpfs-0.14.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.15.tgz
Normal file
BIN
.downloads/ncpfs-0.15.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.16.tgz
Normal file
BIN
.downloads/ncpfs-0.16.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.17.tgz
Normal file
BIN
.downloads/ncpfs-0.17.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.18.tgz
Normal file
BIN
.downloads/ncpfs-0.18.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.19.tgz
Normal file
BIN
.downloads/ncpfs-0.19.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.20.tgz
Normal file
BIN
.downloads/ncpfs-0.20.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.21.tgz
Normal file
BIN
.downloads/ncpfs-0.21.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.22.tgz
Normal file
BIN
.downloads/ncpfs-0.22.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.23.tgz
Normal file
BIN
.downloads/ncpfs-0.23.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.24.tgz
Normal file
BIN
.downloads/ncpfs-0.24.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.0.tgz
Normal file
BIN
.downloads/ncpfs-2.0.0.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.1.tgz
Normal file
BIN
.downloads/ncpfs-2.0.1.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.2.tgz
Normal file
BIN
.downloads/ncpfs-2.0.2.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.3.tgz
Normal file
BIN
.downloads/ncpfs-2.0.3.tgz
Normal file
Binary file not shown.
21
BUGS
21
BUGS
@@ -3,17 +3,20 @@ them to be bugs.
|
||||
|
||||
But there are really problems that might be fixed in the future.
|
||||
|
||||
'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 lwared that might change ...), I
|
||||
rejected the alternative to mount only a single volume for a unix
|
||||
mount point. So I simply return 0.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
'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
|
||||
mars_nwe and lwared that might change ...), I rejected the alternative
|
||||
to mount only a single volume for a unix mount point. So I simply
|
||||
return 0.
|
||||
|
||||
In your kernel log, there will appear messages like
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
If you use Linux 1.2.x, In your kernel log there will appear messages
|
||||
like
|
||||
|
||||
Nov 25 16:09:08 lx01 kernel: alloc_skb called nonatomically from interrupt 0000002e
|
||||
|
||||
These are a bit annoying, but completely harmless. Maybe this will be
|
||||
fixed in the future.
|
||||
These are a bit annoying, but completely harmless.
|
||||
|
||||
147
Changes
147
Changes
@@ -1,9 +1,152 @@
|
||||
I only began this file with ncpfs-0.12. If you're interested in older
|
||||
versions, you can find them on linux01.gwdg.de:/pub/ncpfs/old.
|
||||
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
|
||||
|
||||
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
|
||||
apply this change to the 1.2-module. Please upgrade to 2.0.7 if you
|
||||
want to use long file names.
|
||||
- nwbpvalues can print ITEM properties
|
||||
|
||||
ncpfs-2.0.0 -> ncpfs-2.0.1
|
||||
- Added some values to ipxparse.
|
||||
- Added the little bindery utilities. Maybe someone has the time to
|
||||
write a shellscript named 'nwadduser' ?
|
||||
- Fixed a bug that made the __255 message reappear. Many thanks to
|
||||
Guntram Blom for his detailed bug report.
|
||||
- Fixed a bug that made ncpfs incompatible with W95's server
|
||||
capabilities. Thanks to Tomasz Babczynski
|
||||
<faster@dino.ict.pwr.wroc.pl> for this one.
|
||||
|
||||
ncpfs-0.24 -> ncpfs-2.0.0
|
||||
- Changed the numbering scheme :-).
|
||||
- Added npasswd. Many thanks to Guntram Blom for his work!
|
||||
- Hopefully improved error messages a bit
|
||||
- Hopefully made slist a bit more robust
|
||||
|
||||
ncpfs-0.23 -> ncpfs-0.24
|
||||
- Fixed a bug that made it impossible to umount a filesystem after you
|
||||
tried 'mkdir .' or 'mkdir ..'.
|
||||
- Fixed a bad race condition when opening files.
|
||||
- Made the default timeout values more robust.
|
||||
|
||||
ncpfs-0.22 -> ncpfs-0.23
|
||||
- Fixed a memory allocation problem in nwmsg.c. Thanks to
|
||||
Andrew Ross <anr1001@hermes.cam.ac.uk>
|
||||
- slist hopefully does not ask for a password anymore.
|
||||
- cleaned up error messages a bit.
|
||||
- ncpmount now calls modprobe instead of insmod.
|
||||
|
||||
ncpfs-0.21 -> ncpfs-0.22
|
||||
- removed a bad race condition in kernel-1.2/src/dir.c.
|
||||
- handle 0x9999-responses from the ncp server correctly.
|
||||
- Bindery functions in ncplib.c by Brian G. Reid (breid@tim.com)
|
||||
- set blocksize to 512 to satisfy 'du -k'
|
||||
|
||||
ncpfs-0.20 -> ncpfs-0.21
|
||||
- Included two bugfixes in ncplib.c found by Jeff Buhrt
|
||||
<buhrt@iquest.net>.
|
||||
- Included a bugfix in kernel code that could only show for servers
|
||||
that do not support namespace calls. I should have tried ncpfs
|
||||
against lwared... Thanks to Neil Turton <ndt1001@chu.cam.ac.uk> for
|
||||
this fix.
|
||||
|
||||
ncpfs-0.19 -> ncpfs-0.20
|
||||
- Changed the home site for ncpfs from linux01.gwdg.de:/pub/ncpfs
|
||||
to ftp.gwdg.de:/pub/linux/misc/ncpfs. linux01 will remain available,
|
||||
but we would like to reduce the load on that machine. Sites
|
||||
mirroring linux01 please redirect your mirror software to
|
||||
ftp.gwdg.de. Thanks.
|
||||
- Removed a bug in ncplib.c that made slist require a full
|
||||
login. Thanks to Neil Turton <ndt1001@chu.cam.ac.uk> for the hint.
|
||||
- The first real user contribution: ncopy by Brian G. Reid
|
||||
(breid@tim.com) and Tom C. Henderson (thenderson@tim.com). Many
|
||||
thanks to you! If you find bugs in ncopy, tell them, not me ;-)
|
||||
- Handle expired passwords. Thanks to "Mathew Lim" <M.Lim@sp.ac.sg>
|
||||
for the hint.
|
||||
|
||||
ncpfs-0.18 -> ncpfs-0.19
|
||||
|
||||
- hacked around in ncplib.[ch] quite heavily.
|
||||
- SAP handling in ipxparse.c. Thanks to Jeff Buhrt <buhrt@iquest.net>
|
||||
- Changed error handling to use the com_err library. This should
|
||||
eventually provide better error messages, because it's now much
|
||||
easier to define nice messages.
|
||||
- If no server is active, report this correctly
|
||||
- added nsend
|
||||
|
||||
ncpfs-0.17 -> ncpfs-0.18
|
||||
|
||||
- Another attempt at solving the problem that -n is not working.
|
||||
- Forgot nprint in 0.17 util/Makefile.
|
||||
- nprint left connections open when it fails
|
||||
- added options -r and -t to ncpmount to tune ncpfs connections.
|
||||
|
||||
ncpfs-0.16 -> ncpfs-0.17
|
||||
|
||||
- Changed the name of fsinfo to nwfsinfo, to avoid a name clash with
|
||||
the X windows utility. Thanks to Henning Brockfeld
|
||||
<Henning.Brockfeld@lrz.uni-muenchen.de> for this hint. (still
|
||||
waiting for your scripts.. :-))
|
||||
- made nwmsg available. This enables you to receive NetWare user
|
||||
broadcast messages. Please note that you need at least kernel 1.3.68
|
||||
for this feature.
|
||||
- pserver now prints debugging output via syslog().
|
||||
- Included ipxdump, a nice little utility, that has helped some
|
||||
people.
|
||||
|
||||
- And now the big one: you can re-export ncpfs-mounted directories
|
||||
with nfsd! You have to mount single volumes by specifying -V volume
|
||||
to ncpmount, and call nfsd and mountd with the option --re-export.
|
||||
See the manual page of ncpmount for more information. Please note
|
||||
that I will send Linus the required patch on 1. March 1996, so you
|
||||
will have to use kernel 1.2.13 or wait at least for 1.3.70.
|
||||
|
||||
ncpfs-0.15 -> ncpfs-0.16
|
||||
|
||||
- Included ipx-1.0, made available by Greg Page <greg@caldera.com>,
|
||||
Caldera
|
||||
- Made -n work for password-less accounts. Thanks to Alexander Jolk
|
||||
<jolk@ap-pc513b.physik.uni-karlsruhe.de>.
|
||||
- Fixed the kerneld support.
|
||||
- Fixed the NetWare 4.1 problem. Many thanks to
|
||||
Chatchai JANTARAPRIM <chat@ratree.psu.ac.th> and
|
||||
hitesh.soneji@industry.net for their patience.
|
||||
|
||||
ncpfs-0.14 -> ncpfs-0.15
|
||||
|
||||
- A bug fixed that made normal mounting impossible. It was too late
|
||||
yesterday. Sorry
|
||||
- Manpage for pserver.c
|
||||
|
||||
ncpfs-0.13 -> ncpfs-0.14
|
||||
|
||||
- Improvements of manual pages by B. Galliart <bgallia@luc.edu> and
|
||||
Terry Dawson <terry@perf.no.itg.telecom.com.au>
|
||||
- fsinfo
|
||||
- pserver.c. Please see this as ALPHA software. There is no
|
||||
documentation, and it is not tested enough. But it might be useful for
|
||||
you.
|
||||
|
||||
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.
|
||||
|
||||
67
FAQ
Normal file
67
FAQ
Normal file
@@ -0,0 +1,67 @@
|
||||
There is certainly not enough material to call this an FAQ, but some
|
||||
questions reach me regularly. Probably the documenation is not clear
|
||||
enough.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Q: The ncpfs utilities like slist or ncpmount tell me that they can
|
||||
not find a server, although I'm sure there are servers on my
|
||||
net. What's wrong?
|
||||
|
||||
You probably used
|
||||
|
||||
ipx_configure --auto_interface=on --auto_primary=on
|
||||
|
||||
and you have Windows (95?) workstations on your network. Windows 95
|
||||
makes Linux configure IPX interfaces for non-existent frame types. To
|
||||
solve this problem, you have to configure your IPX interface manually
|
||||
with the command
|
||||
|
||||
ipx_interface add -p <device> <frame>
|
||||
|
||||
For <device> use eth0, eth1 or whatever you network adapter is
|
||||
called. The value for <frame> must match the frame type used on your
|
||||
network. Possible values are 802.2, 802.3, SNAP and EtherII.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Q: I have difficulties with NetWare 4.1. What can I do?
|
||||
|
||||
To be honest, I do not really know. Currently my only test equipment
|
||||
is a NetWare 3.11 server. You should make your 4.1 Server as
|
||||
3.x-compatible as it can be. As I do not know 4.1, you are on your own
|
||||
doing this.
|
||||
|
||||
A promising hint that has already helped some people is to switch off
|
||||
packet signatures on the 4.1 server, as ncpfs does not support them.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
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?
|
||||
|
||||
When you want to export a directory via NFS, you have to do two things:
|
||||
|
||||
- You have to invoke mountd and nfsd with the option --re-export. On my
|
||||
computer, both are invoked at system startup from the file
|
||||
/etc/rc.d/rc.inet2.
|
||||
|
||||
- You can not export a complete NetWare server hierarchy with all volumes
|
||||
under a single mount point. You have to mount a single server volume to
|
||||
make it re-exportable. Invoke ncpmount with the option -V volume to do
|
||||
this.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Q: When I compile ncpfs, I get a message like the following:
|
||||
|
||||
make[1]: Entering directory `/home/me/netware/ncpfs/kernel-1.2/src'
|
||||
gcc -D__KERNEL__ -I. -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer -I/home/me/netware/ncpfs/kernel-1.2 -DNCPFS_VERSION=\"0.17\" -c dir.c
|
||||
dir.c:36: warning: `struct dirent' declared inside parameter list
|
||||
dir.c:36: warning: its scope is only this definition or declaration,
|
||||
...
|
||||
|
||||
You try to compile the part of ncpfs that is meant for kernel 1.2.13 under
|
||||
kernel 1.3.x. Please look at the Makefile and comment out the
|
||||
corresponding lines.
|
||||
52
Makefile
52
Makefile
@@ -2,31 +2,32 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
# KERNEL = 1.2
|
||||
|
||||
TOPDIR = $(shell pwd)
|
||||
|
||||
BINDIR = /usr/local/bin
|
||||
INTERM_BINDIR = $(TOPDIR)/bin
|
||||
SUBDIRS = util ipx-0.75 man
|
||||
|
||||
#
|
||||
# The following 2 lines are for those who use Kernel version 1.2.x.
|
||||
# If you have a kernel later than 1.3.53, please comment out the
|
||||
# the following lines. You have to recompile your kernel
|
||||
# and say 'y' when 'make config' asks you for IPX and ncpfs.
|
||||
#
|
||||
SUBDIRS += kernel-1.2/src
|
||||
INCLUDES = -I$(TOPDIR)/kernel-1.2
|
||||
VERSION = 2.0.3
|
||||
|
||||
# If you are using kerneld to autoload ncp support,
|
||||
# uncomment this (kerneld is in linux since about 1.3.57):
|
||||
# KERNELD = -DHAVE_KERNELD
|
||||
#KERNELD = -DHAVE_KERNELD
|
||||
|
||||
export INCLUDES BINDIR INTERM_BINDIR KERNELD
|
||||
# If your system is ELF, please uncomment the following line:
|
||||
#HAVE_ELF=yes
|
||||
|
||||
TOPDIR = $(shell pwd)
|
||||
BINDIR = /usr/local/bin
|
||||
SBINDIR = /sbin
|
||||
INTERM_BINDIR = $(TOPDIR)/bin
|
||||
SUBDIRS = util ipx-1.0 man
|
||||
|
||||
KVERSION=$(shell uname -r | cut -b1-3)
|
||||
|
||||
ifeq ($(KVERSION),1.2)
|
||||
SUBDIRS += kernel-1.2/src
|
||||
INCLUDES = -I$(TOPDIR)/kernel-1.2
|
||||
endif
|
||||
|
||||
export INCLUDES BINDIR INTERM_BINDIR SBINDIR KERNELD VERSION HAVE_ELF
|
||||
|
||||
all:
|
||||
for i in $(SUBDIRS); do make -C $$i; done
|
||||
for i in $(SUBDIRS); do make -C $$i all; done
|
||||
|
||||
dep:
|
||||
for i in $(SUBDIRS); do make -C $$i dep; done
|
||||
@@ -41,9 +42,10 @@ clean:
|
||||
rm -f `find . -type f -name '*.out' -print`
|
||||
for i in $(SUBDIRS); do make -C $$i clean; done
|
||||
|
||||
realclean: clean
|
||||
mrproper: clean
|
||||
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
|
||||
make -C util realclean
|
||||
make -C util mrproper
|
||||
make -C ipxdump mrproper
|
||||
|
||||
modules: ncpfs.o
|
||||
|
||||
@@ -51,11 +53,15 @@ SRCPATH=$(shell pwd)
|
||||
SRCDIR=$(shell basename $(SRCPATH))
|
||||
DISTFILE=$(SRCDIR).tgz
|
||||
|
||||
dist: tgz
|
||||
dist: mrproper
|
||||
(cd ..; \
|
||||
tar cvf - $(SRCDIR) | \
|
||||
gzip -9 > $(DISTFILE); \
|
||||
mv $(DISTFILE) $(SRCDIR))
|
||||
make dep
|
||||
make all
|
||||
|
||||
tgz: realclean
|
||||
tgz: mrproper
|
||||
(cd ..; \
|
||||
tar cvf - $(SRCDIR) | \
|
||||
gzip -9 > $(DISTFILE); \
|
||||
|
||||
81
README
81
README
@@ -1,9 +1,24 @@
|
||||
This is ncpfs, a free NetWare client filesystem for Linux. Besides
|
||||
some little utilities it also contains nprint, which enables you to
|
||||
print on NetWare print queues.
|
||||
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.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
Before you start the installation, make sure that your kernel has IPX
|
||||
support compiled in. When 'make config' asks you for
|
||||
|
||||
The IPX protocol (CONFIG_IPX) [N/y/m/?]
|
||||
|
||||
simply answer 'y'. Probably you do not need the full internal net that
|
||||
you are asked for next.
|
||||
|
||||
The installation of ncpfs depends on the kernel version you are
|
||||
using. For kernel 1.2, you should simply type 'make' and look at
|
||||
what's in the bin/ directory after that. Please be sure that your
|
||||
@@ -11,10 +26,9 @@ kernel resides in /usr/src/linux, because the file
|
||||
kernel-1.2/src/sock.c has to refer directly to it.
|
||||
|
||||
If you use Kernel 1.3, please be sure that you use at least
|
||||
1.3.54. ncpfs does NOT work with any earlier 1.3.x kernel, especially
|
||||
not with 1.3.53, although this one has a fs/ncpfs/ subdirectory.
|
||||
1.3.71. ncpfs does NOT work with any earlier 1.3.x kernel.
|
||||
|
||||
If you use Kernel 1.3.54 or later, you might have to recompile your
|
||||
If you use Kernel 1.3.71 or later, you might have to recompile your
|
||||
kernel. With these kernels, the kernel part of ncpfs is already
|
||||
included in the main source tree. If you want to use ncpfs, you should
|
||||
say 'y' to 'make config' when you are asked for IPX, and again when it
|
||||
@@ -22,10 +36,32 @@ asks for ncpfs. After you have rebooted with the new kernel, 'cat
|
||||
/proc/filesystems' should show you a line saying that the kernel knows
|
||||
ncpfs.
|
||||
|
||||
With Kernel 1.3.54 or later you also have to modify the Makefile in the
|
||||
directory you found this README in. Please see the Makefile for the
|
||||
necessary modifications. Then typing 'make' should work with no
|
||||
problem.
|
||||
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
|
||||
time might be better at the LinWare mailing list than at my personal
|
||||
email address. You can mail to and/or subscribe to the LinWare mailing
|
||||
list:
|
||||
|
||||
Topics for the list:
|
||||
- discussing LinWare server, its features, installation problems and bugs
|
||||
- using IPX protocol under Linux
|
||||
- IPX routing and router daemons under Linux
|
||||
- mars_nwe
|
||||
- ncpfs
|
||||
|
||||
You can subscribe to the list by sending the command "add linware" in
|
||||
the mail message body to address: "listserv@sh.cvut.cz". Your
|
||||
postings should be sent to: "linware@sh.cvut.cz".
|
||||
|
||||
|
||||
USING NCPFS
|
||||
@@ -77,6 +113,8 @@ Ales Dyrak has written lwared, which was the initial start for ncpfs.
|
||||
|
||||
Alan Cox has found some bugs I would probably never have found.
|
||||
|
||||
Look at the file Changes for others.
|
||||
|
||||
|
||||
LIMITATIONS (compare these with smbfs :-)
|
||||
|
||||
@@ -86,27 +124,10 @@ limitation is the lack of uid, gid and permission information per
|
||||
file. You have to assign those values once for a complete mounted
|
||||
directory.
|
||||
|
||||
The second limitation is just as annoying as the first: You cannot
|
||||
re-export a ncp-mounted directory by nfs. It is not possible because
|
||||
the NFS protocol defines access to files through unique file handles,
|
||||
which can be mapped to the device and inode numbers in unix NFS
|
||||
servers. NCP does not have unique numbers per file, you only have the
|
||||
path name. I implemented a caching scheme for inode numbers, which
|
||||
gives unique inode numbers for every open file in the system. This is
|
||||
just sufficient for local use of the files, because you can tell when
|
||||
an inode number can be discarded. With NFS the situation is
|
||||
different. You can never know when the client will access the file-id
|
||||
you offered, so you would have to cache the inode numbers
|
||||
indefinitely long. I think this should not be done in kernel mode, as
|
||||
it would require an unlimited amount of RAM.
|
||||
|
||||
Those who looked at the kernel code a bit closer will have found out
|
||||
that the last section is a little white lie. As I found out after the
|
||||
first version of ncpfs, NetWare does indeed offer something like inode
|
||||
numbers, although are only unique per volume. So one way to make ncpfs
|
||||
re-exportable by nfs is to allocate a superblock per volume and show
|
||||
the inode numbers to the user. I was just too lazy to do this
|
||||
yet. Maybe once we will force Novell to make NetWare NFS
|
||||
affordable... ;-)
|
||||
You will not be able to access servers that require packet
|
||||
signatures. This seems to be one of Novell's bigger secrets :-(.
|
||||
|
||||
Have fun with ncpfs!
|
||||
|
||||
Volker
|
||||
lendecke@namu01.gwdg.de
|
||||
|
||||
15
TODO
Normal file
15
TODO
Normal file
@@ -0,0 +1,15 @@
|
||||
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
|
||||
a single NCP connection. This should make the trade-off mentioned in
|
||||
ncpmount.8 unnecessary.
|
||||
|
||||
- Do some kind of mapping of NCP uid's to unix uid's
|
||||
9
ipx-1.0/COPYING
Normal file
9
ipx-1.0/COPYING
Normal file
@@ -0,0 +1,9 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the original work is
|
||||
properly attributed to Greg Page and Caldera, Inc.
|
||||
Neither the name of Greg Page nor Caldera, Inc. may be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
This software is provided by Greg Page and Caldera, Inc. "AS IS"
|
||||
and without any express or implied warranties.
|
||||
|
||||
24
ipx-1.0/Gregs.Makefile
Normal file
24
ipx-1.0/Gregs.Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
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
|
||||
|
||||
@@ -5,16 +5,16 @@ UTILS = $(INTERM_BINDIR)/ipx_configure $(INTERM_BINDIR)/ipx_interface \
|
||||
all: $(UTILS)
|
||||
|
||||
$(INTERM_BINDIR)/ipx_configure: ipx_configure.o
|
||||
$(CC) -s -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_interface: ipx_interface.o
|
||||
$(CC) -s -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) -s -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) -s -o $(INTERM_BINDIR)/ipx_route ipx_route.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_route ipx_route.o
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
@@ -25,6 +25,6 @@ clean:
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install --strip $$i $(BINDIR); \
|
||||
install $$i $(BINDIR); \
|
||||
done
|
||||
|
||||
@@ -47,7 +47,7 @@ This program is used to read/write two configuration parameters:
|
||||
|
||||
By default, these are both turned off.
|
||||
|
||||
The following are sample IPX programs:
|
||||
The following are sample IPX programs (found in directory Samples):
|
||||
|
||||
ipxrcv.c and ipxsend.c
|
||||
ipxsend will send a single packet to an instance of ipxrcv running on the
|
||||
@@ -51,7 +51,7 @@ main(int argc, char **argv)
|
||||
htonl(sipx.sipx_network),
|
||||
sipx.sipx_node[0], sipx.sipx_node[1],
|
||||
sipx.sipx_node[2], sipx.sipx_node[3],
|
||||
sipx.sipx_node[4], sipx.sipx_node[5]);
|
||||
sipx.sipx_node[6], sipx.sipx_node[5]);
|
||||
bptr += 2;
|
||||
rp = (struct rip_data *) bptr;
|
||||
while (result >= sizeof(struct rip_data)) {
|
||||
7
ipx-1.0/config.ipx
Normal file
7
ipx-1.0/config.ipx
Normal file
@@ -0,0 +1,7 @@
|
||||
IPX_AUTO_PRIMARY=on
|
||||
IPX_AUTO_INTERFACE=on
|
||||
IPX_CONFIGURED=no
|
||||
IPX_DEVICE=eth0
|
||||
IPX_FRAME=802.2
|
||||
IPX_INTERNAL_NET=no
|
||||
IPX_NETNUM=0
|
||||
41
ipx-1.0/init.ipx
Normal file
41
ipx-1.0/init.ipx
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# ipx Bring up/down IPX networking
|
||||
#
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
. /etc/sysconfig/network
|
||||
. /etc/sysconfig/ipx
|
||||
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 0
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
if [ ${IPX_CONFIGURED} = "yes" ]; then
|
||||
if [ ${IPX_INTERNAL_NET} = "yes" ]; then
|
||||
/sbin/ipx_internal_net add ${IPX_NETNUM}
|
||||
else
|
||||
/sbin/ipx_interface add -p ${IPX_DEVICE} \
|
||||
${IPX_FRAME} ${IPX_NETNUM}
|
||||
fi
|
||||
fi
|
||||
ipx_configure \
|
||||
--auto_primary=${IPX_AUTO_PRIMARY} \
|
||||
--auto_interface=${IPX_AUTO_INTERFACE}
|
||||
touch /var/lock/subsys/ipx
|
||||
;;
|
||||
stop)
|
||||
ipx_configure --auto_primary=off --auto_interface=off
|
||||
ipx_interface delall
|
||||
rm -f /var/lock/subsys/ipx
|
||||
;;
|
||||
*)
|
||||
echo "Usage: network {start|stop}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
@@ -7,6 +12,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
struct option options[] = {
|
||||
{ "auto_primary", required_argument, NULL, 1 },
|
||||
@@ -61,8 +67,14 @@ main(int argc, char **argv)
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
int old_errno = errno;
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
if (old_errno == -EINVAL)
|
||||
{
|
||||
fprintf(stderr, "Probably you have no IPX support in "
|
||||
"your kernel\n");
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@@ -10,6 +15,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static struct ifreq id;
|
||||
static char *progname;
|
||||
@@ -19,7 +25,8 @@ usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s add [-p] device frame_type [net_number]\n\
|
||||
Usage: %s del device frame_type\n\
|
||||
Usage: %s check device frame_type\n", progname, progname, progname);
|
||||
Usage: %s delall\n\
|
||||
Usage: %s check device frame_type\n", progname, progname, progname, progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -28,6 +35,9 @@ struct frame_type {
|
||||
unsigned char ft_val;
|
||||
} frame_types[] = {
|
||||
{"802.2", IPX_FRAME_8022},
|
||||
#ifdef IPX_FRAME_TR_8022
|
||||
{"802.2TR", IPX_FRAME_TR_8022},
|
||||
#endif
|
||||
{"802.3", IPX_FRAME_8023},
|
||||
{"SNAP", IPX_FRAME_SNAP},
|
||||
{"EtherII", IPX_FRAME_ETHERII}
|
||||
@@ -109,8 +119,14 @@ ipx_add_interface(int argc, char **argv)
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
int old_errno = errno;
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
if (old_errno == -EINVAL)
|
||||
{
|
||||
fprintf(stderr, "Probably you have no IPX support in "
|
||||
"your kernel\n");
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -162,6 +178,76 @@ ipx_add_interface(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_delall_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
char buffer[80];
|
||||
char device[20];
|
||||
char frame_type[20];
|
||||
int fti;
|
||||
FILE *fp;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fp = fopen("/proc/net/ipx_interface", "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: Unable to open \"/proc/net/ipx_interface.\"\n",
|
||||
progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fgets(buffer, 80, fp);
|
||||
while (fscanf(fp, "%s %s %s %s %s", buffer, buffer, buffer,
|
||||
device, frame_type) == 5) {
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
if (strcasecmp(device, "Internal") == 0) {
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
} else {
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
strcpy(id.ifr_name, device);
|
||||
fti = lookup_frame_type(frame_type);
|
||||
if (fti < 0) continue;
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
}
|
||||
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
if (result == 0) continue;
|
||||
switch (errno) {
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_type);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n",
|
||||
progname, device);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "%s: No such IPX interface %s %s.\n",
|
||||
progname, device, frame_type);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_del_interface(int argc, char **argv)
|
||||
{
|
||||
@@ -176,6 +262,7 @@ ipx_del_interface(int argc, char **argv)
|
||||
}
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
strcpy(id.ifr_name, argv[1]);
|
||||
fti = lookup_frame_type(argv[2]);
|
||||
if (fti < 0)
|
||||
@@ -289,6 +376,10 @@ main(int argc, char **argv)
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_add_interface(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "delall", 6) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_delall_interface(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
35
ipxdump/Makefile
Normal file
35
ipxdump/Makefile
Normal file
@@ -0,0 +1,35 @@
|
||||
EXEC= ipxdump ipxparse
|
||||
|
||||
CFLAGS= -Wall -O2
|
||||
OBJECTS= ipxutil.o
|
||||
|
||||
all: $(EXEC)
|
||||
|
||||
ipxdump: ipxdump.o $(OBJECTS)
|
||||
$(CC) -o $@ ipxdump.o $(CFLAGS) $(OBJECTS)
|
||||
|
||||
ipxparse: ipxparse.o $(OBJECTS)
|
||||
$(CC) -o $@ ipxparse.o $(CFLAGS) $(OBJECTS)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(EXEC) *~
|
||||
|
||||
|
||||
modules: ncpfs.o
|
||||
|
||||
SRCPATH=$(shell pwd)
|
||||
SRCDIR=$(shell basename $(SRCPATH))
|
||||
DISTFILE=$(SRCDIR).tgz
|
||||
|
||||
mrproper: clean
|
||||
rm -f $(DISTFILE)
|
||||
|
||||
dist: tgz
|
||||
make all
|
||||
|
||||
tgz: mrproper
|
||||
(cd ..; \
|
||||
tar cvf - $(SRCDIR) | \
|
||||
gzip -9 > $(DISTFILE); \
|
||||
mv $(DISTFILE) $(SRCDIR))
|
||||
|
||||
45
ipxdump/README
Normal file
45
ipxdump/README
Normal file
@@ -0,0 +1,45 @@
|
||||
This is a VERY stupid packet sniffer for IPX ethernet packets.
|
||||
|
||||
=============================================
|
||||
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|
||||
! ! ! S E C U R I T Y W A R N I N G ! ! !
|
||||
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|
||||
=============================================
|
||||
|
||||
If you are using unencrypted passwords, and use this tool to send a
|
||||
dump to somebody else or store it on a computer, you might very well
|
||||
store passwords there. So, be VERY careful! This is exactly the kind
|
||||
of tools Novell designed the encrypted passwords for (or against).
|
||||
|
||||
|
||||
|
||||
I hacked it together to be able to help people with problems with
|
||||
ncpfs. The socket handling was taken from Statnet-2.0.
|
||||
|
||||
You can use it to watch commercial NetWare clients when they talk to
|
||||
servers. I divided the program into 2 parts, ipxdump and ipxparse.
|
||||
|
||||
ipxdump simply pumps all the IPX frames it receives to stdout.
|
||||
|
||||
If you use ipxdump to watch a workstation, you can use the simple
|
||||
filter function ipxdump provides. You can call ipxdump with the node
|
||||
address of the workstation you want to watch. This way only the
|
||||
packets this workstation sends and receives are monitored. As an
|
||||
example, I call ipxdump as
|
||||
|
||||
./ipxdump 00001B038B11
|
||||
|
||||
to look at my 286/10MHz test 'workstation'. ipxdump still generates
|
||||
huge amounts of data, so you should be very careful to start it just
|
||||
before you perform the operation (such as file creation for OS/2
|
||||
clients with NW4.1 as a server, or a 'dir' on a directory with long
|
||||
and short file names, or an encrypted password change ;-)) and stop it
|
||||
directly after that. And, please gzip -9 and uuencode it before you
|
||||
send it to anybody.
|
||||
|
||||
ipxparse will eventually take apart the dump that ipxdump
|
||||
generates. They can as well be used in a pipe. Currently ipxparse does
|
||||
not do anything sensible, but that will definitely change.
|
||||
|
||||
Volker Lendecke
|
||||
<lendecke@namu01.gwdg.de>
|
||||
245
ipxdump/ipxdump.c
Normal file
245
ipxdump/ipxdump.c
Normal file
@@ -0,0 +1,245 @@
|
||||
/* ipxdump.c */
|
||||
|
||||
/* Copyright 1996 Volker Lendecke, Goettingen, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#include <signal.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <netinet/protocols.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include "ipxutil.h"
|
||||
|
||||
struct ipx_address
|
||||
{
|
||||
unsigned long net;
|
||||
unsigned char node[IPX_NODE_LEN];
|
||||
unsigned short sock;
|
||||
};
|
||||
|
||||
struct ipx_packet
|
||||
{
|
||||
unsigned short ipx_checksum;
|
||||
#define IPX_NO_CHECKSUM 0xFFFF
|
||||
unsigned short ipx_pktsize;
|
||||
unsigned char ipx_tctrl;
|
||||
unsigned char ipx_type;
|
||||
#define IPX_TYPE_UNKNOWN 0x00
|
||||
#define IPX_TYPE_RIP 0x01 /* may also be 0 */
|
||||
#define IPX_TYPE_SAP 0x04 /* may also be 0 */
|
||||
#define IPX_TYPE_SPX 0x05 /* Not yet implemented */
|
||||
#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
|
||||
#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast [Not supported] */
|
||||
struct ipx_address ipx_dest __attribute__ ((packed));
|
||||
struct ipx_address ipx_source __attribute__ ((packed));
|
||||
};
|
||||
|
||||
|
||||
void handle_frame (unsigned char *buf, int length, struct sockaddr *saddr);
|
||||
void handle_ipx(char *frame, unsigned char *buf);
|
||||
|
||||
static int filter = 0;
|
||||
static IPXNode filter_node;
|
||||
|
||||
static int exit_request = 0;
|
||||
static void
|
||||
int_handler()
|
||||
{
|
||||
exit_request = 1;
|
||||
}
|
||||
|
||||
void
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int sd;
|
||||
struct ifreq ifr, oldifr;
|
||||
char *device = "eth0";
|
||||
struct sockaddr saddr;
|
||||
int sizeaddr;
|
||||
unsigned char buf[4096];
|
||||
int length;
|
||||
|
||||
signal(SIGINT, int_handler);
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
if (ipx_sscanf_node(argv[1], filter_node) != 0)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [node]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
filter = 1;
|
||||
}
|
||||
|
||||
if ((sd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_ALL))) < 0)
|
||||
{
|
||||
perror ("Can't get socket");
|
||||
fprintf(stderr, "You must run %s as root\n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* SET PROMISC */
|
||||
|
||||
strcpy (oldifr.ifr_name, device);
|
||||
if (ioctl (sd, SIOCGIFFLAGS, &oldifr) < 0)
|
||||
{
|
||||
close (sd);
|
||||
perror ("Can't get flags");
|
||||
exit (2);
|
||||
}
|
||||
|
||||
/* This should be rewritten to cooperate with other net tools */
|
||||
ifr = oldifr;
|
||||
ifr.ifr_flags |= IFF_PROMISC;
|
||||
|
||||
if (ioctl (sd, SIOCSIFFLAGS, &ifr) < 0)
|
||||
{
|
||||
close (sd);
|
||||
perror ("Can't set flags");
|
||||
exit (3);
|
||||
}
|
||||
|
||||
while ( exit_request == 0 )
|
||||
{
|
||||
/* This is the main data-gathering loop; keep it small
|
||||
and fast */
|
||||
sizeaddr = sizeof(saddr);
|
||||
length = recvfrom (sd, buf, sizeof(buf), 0,
|
||||
&saddr, &sizeaddr);
|
||||
if (length < 0 ) continue;
|
||||
handle_frame (buf, length, &saddr);
|
||||
}
|
||||
|
||||
/* This should be rewritten to cooperate with other net tools */
|
||||
if (ioctl (sd, SIOCSIFFLAGS, &oldifr) < 0)
|
||||
{
|
||||
close (sd);
|
||||
perror ("Can't set flags");
|
||||
exit (4);
|
||||
}
|
||||
|
||||
close (sd);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void
|
||||
handle_ipx (char *frame, unsigned char *buf)
|
||||
{
|
||||
int i;
|
||||
struct ipx_packet *h = (struct ipx_packet *)buf;
|
||||
struct sockaddr_ipx s_addr;
|
||||
struct sockaddr_ipx d_addr;
|
||||
int length = ntohs(h->ipx_pktsize);
|
||||
|
||||
|
||||
memset(&s_addr, 0, sizeof(s_addr));
|
||||
memset(&d_addr, 0, sizeof(d_addr));
|
||||
|
||||
memcpy(s_addr.sipx_node, h->ipx_source.node, sizeof(s_addr.sipx_node));
|
||||
s_addr.sipx_port = h->ipx_source.sock;
|
||||
s_addr.sipx_network = h->ipx_source.net;
|
||||
|
||||
memcpy(d_addr.sipx_node, h->ipx_dest.node, sizeof(d_addr.sipx_node));
|
||||
d_addr.sipx_port = h->ipx_dest.sock;
|
||||
d_addr.sipx_network = h->ipx_dest.net;
|
||||
|
||||
if (filter != 0)
|
||||
{
|
||||
if ( (memcmp(filter_node, s_addr.sipx_node,
|
||||
sizeof(filter_node)) != 0)
|
||||
&& (memcmp(filter_node, d_addr.sipx_node,
|
||||
sizeof(filter_node)) != 0))
|
||||
{
|
||||
/* Not for us */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s ", frame);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
printf("%2.2X", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
if (!isatty(STDOUT_FILENO))
|
||||
{
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_other (unsigned char *buf, int length, struct sockaddr *saddr)
|
||||
{
|
||||
struct ethhdr *eth = (struct ethhdr *)buf;
|
||||
unsigned char *p = &(buf[sizeof(struct ethhdr)]);
|
||||
|
||||
if (ntohs(eth->h_proto) < 1536)
|
||||
{
|
||||
/* This is a magic hack to spot IPX packets. Older
|
||||
* Novell breaks the protocol design and runs IPX over
|
||||
* 802.3 without an 802.2 LLC layer. We look for FFFF
|
||||
* which isnt a used 802.2 SSAP/DSAP. This won't work
|
||||
* for fault tolerant netware but does for the rest.
|
||||
*/
|
||||
|
||||
if (*(unsigned short *)p == 0xffff)
|
||||
{
|
||||
handle_ipx("802.3", p);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (*(unsigned short *)p == htons(0xe0e0))
|
||||
&& (p[2] == 0x03))
|
||||
{
|
||||
handle_ipx("802.2", p+3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0)
|
||||
{
|
||||
handle_ipx("snap", p+8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
handle_frame (unsigned char *buf, int length, struct sockaddr *saddr)
|
||||
{
|
||||
/* Ethernet packet type ID field */
|
||||
unsigned short packet_type = ((struct ethhdr *)buf)->h_proto;
|
||||
switch( packet_type )
|
||||
{
|
||||
case __constant_ntohs(ETH_P_IPX):
|
||||
handle_ipx("EtherII", &(buf[sizeof(struct ethhdr)]));
|
||||
break;
|
||||
default:
|
||||
handle_other(buf, length, saddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
693
ipxdump/ipxparse.c
Normal file
693
ipxdump/ipxparse.c
Normal file
@@ -0,0 +1,693 @@
|
||||
/* ipxparse.c */
|
||||
|
||||
/* Copyright 1996 Volker Lendecke, Goettingen, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#include <signal.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <netinet/protocols.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include "ipxutil.h"
|
||||
|
||||
#define DUMPALLSAPS /* #define if you want to dump all SAP's */
|
||||
|
||||
struct ipx_address
|
||||
{
|
||||
unsigned long net;
|
||||
unsigned char node[IPX_NODE_LEN];
|
||||
unsigned short sock;
|
||||
};
|
||||
|
||||
struct ipx_packet
|
||||
{
|
||||
unsigned short ipx_checksum;
|
||||
#define IPX_NO_CHECKSUM 0xFFFF
|
||||
unsigned short ipx_pktsize;
|
||||
unsigned char ipx_tctrl;
|
||||
unsigned char ipx_type;
|
||||
#define IPX_TYPE_UNKNOWN 0x00
|
||||
#define IPX_TYPE_RIP 0x01 /* may also be 0 */
|
||||
#define IPX_TYPE_SAP 0x04 /* may also be 0 */
|
||||
#define IPX_TYPE_SPX 0x05 /* Not yet implemented */
|
||||
#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
|
||||
#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast [Not supported] */
|
||||
struct ipx_address ipx_dest __attribute__ ((packed));
|
||||
struct ipx_address ipx_source __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define NCP_ALLOC_SLOT_REQUEST (0x1111)
|
||||
#define NCP_REQUEST (0x2222)
|
||||
#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
|
||||
|
||||
struct ncp_request_header {
|
||||
__u16 type __attribute__ ((packed));
|
||||
__u8 sequence __attribute__ ((packed));
|
||||
__u8 conn_low __attribute__ ((packed));
|
||||
__u8 task __attribute__ ((packed));
|
||||
__u8 conn_high __attribute__ ((packed));
|
||||
__u8 function __attribute__ ((packed));
|
||||
__u8 data[0] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define NCP_REPLY (0x3333)
|
||||
#define NCP_POSITIVE_ACK (0x9999)
|
||||
|
||||
struct ncp_reply_header {
|
||||
__u16 type __attribute__ ((packed));
|
||||
__u8 sequence __attribute__ ((packed));
|
||||
__u8 conn_low __attribute__ ((packed));
|
||||
__u8 task __attribute__ ((packed));
|
||||
__u8 conn_high __attribute__ ((packed));
|
||||
__u8 completion_code __attribute__ ((packed));
|
||||
__u8 connection_state __attribute__ ((packed));
|
||||
__u8 data[0] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define NCP_BURST_PACKET (0x7777)
|
||||
|
||||
struct ncp_burst_header {
|
||||
__u16 type __attribute__ ((packed));
|
||||
__u8 system_flags __attribute__ ((packed));
|
||||
__u8 stream_type __attribute__ ((packed));
|
||||
__u32 source_conn __attribute__ ((packed));
|
||||
__u32 dest_conn __attribute__ ((packed));
|
||||
__u32 packet_sequence __attribute__ ((packed));
|
||||
__u32 send_delay __attribute__ ((packed));
|
||||
__u16 burst_sequence __attribute__ ((packed));
|
||||
__u16 ack_sequence __attribute__ ((packed));
|
||||
__u32 burst_length __attribute__ ((packed));
|
||||
__u32 data_offset __attribute__ ((packed));
|
||||
__u16 data_bytes __attribute__ ((packed));
|
||||
__u16 missing_frags __attribute__ ((packed));
|
||||
};
|
||||
|
||||
void handle_ipx (unsigned char *buf, int length, char *frame, int no);
|
||||
void handle_ncp (struct sockaddr_ipx *source,
|
||||
struct sockaddr_ipx *target,
|
||||
unsigned char *buf, int length, int no);
|
||||
int handle_burst(struct sockaddr_ipx *source,
|
||||
struct sockaddr_ipx *target,
|
||||
unsigned char *buf, int length, int no);
|
||||
|
||||
#define SAP_MAX_SERVER_NAME_LENGTH 48 /* in network packets */
|
||||
#define SAP_MAX_SAPS_PER_PACKET 7
|
||||
#define SAP_SHUTDOWN 16 /* Magic "hops" value to stop SAP advertising */
|
||||
|
||||
/* SAP Query structure (returned in sap_packet as an array)
|
||||
* NBO == Network Byte Order)
|
||||
*/
|
||||
typedef struct saps {
|
||||
__u16 serverType __attribute__ ((packed)); /* NBO */
|
||||
__u8 serverName[SAP_MAX_SERVER_NAME_LENGTH] __attribute__ ((packed));
|
||||
struct ipx_address serverAddress __attribute__ ((packed));
|
||||
__u16 serverHops __attribute__ ((packed)); /* NBO */
|
||||
} SAPS;
|
||||
|
||||
/* General Service/Nearest Server Response SAP packet */
|
||||
union sap_packet {
|
||||
unsigned short sapOperation;
|
||||
struct sap_query {
|
||||
__u16 sapOperation __attribute__ ((packed));
|
||||
__u16 serverType __attribute__ ((packed));
|
||||
} query;
|
||||
struct sap_response {
|
||||
__u16 sapOperation __attribute__ ((packed));
|
||||
/* each SAP can has a max of SAP_MAX_SAPS_PER_PACKET packets */
|
||||
SAPS sap[SAP_MAX_SAPS_PER_PACKET] __attribute__ ((packed));
|
||||
} response;
|
||||
};
|
||||
|
||||
/* print out one SAP record */
|
||||
static void
|
||||
print_sap(FILE *file, SAPS *sapp)
|
||||
{
|
||||
fprintf(file, " Name:%s, serverType 0x%x, ",
|
||||
sapp->serverName,
|
||||
ntohs(sapp->serverType));
|
||||
ipx_fprint_network(file, ntohl(sapp->serverAddress.net));
|
||||
fprintf(file, ":");
|
||||
ipx_fprint_node(file, sapp->serverAddress.node);
|
||||
fprintf(file, ":");
|
||||
ipx_fprint_port(file, ntohs(sapp->serverAddress.sock));
|
||||
fprintf(file, " (Hops %d)\n", ntohs(sapp->serverHops));
|
||||
}
|
||||
|
||||
void
|
||||
handle_ipx (unsigned char *buf, int length, char *frame, int no)
|
||||
{
|
||||
struct ipx_packet *h = (struct ipx_packet *)buf;
|
||||
struct sockaddr_ipx s_addr;
|
||||
struct sockaddr_ipx d_addr;
|
||||
union sap_packet *sappacket;
|
||||
int hbo_dsock; /* Host Byte Order of Destination SOCKet */
|
||||
int hbo_sapop; /* Host Byte Order of SAP OPeration */
|
||||
|
||||
memset(&s_addr, 0, sizeof(s_addr));
|
||||
memset(&d_addr, 0, sizeof(d_addr));
|
||||
|
||||
memcpy(s_addr.sipx_node, h->ipx_source.node, sizeof(s_addr.sipx_node));
|
||||
s_addr.sipx_port = h->ipx_source.sock;
|
||||
s_addr.sipx_network = h->ipx_source.net;
|
||||
|
||||
memcpy(d_addr.sipx_node, h->ipx_dest.node, sizeof(d_addr.sipx_node));
|
||||
d_addr.sipx_port = h->ipx_dest.sock;
|
||||
d_addr.sipx_network = h->ipx_dest.net;
|
||||
|
||||
printf("%6.6d %s from ", no, frame);
|
||||
|
||||
ipx_print_saddr(&s_addr);
|
||||
printf(" to ");
|
||||
ipx_print_saddr(&d_addr);
|
||||
printf("\n");
|
||||
|
||||
if (handle_burst(&s_addr, &d_addr, buf + sizeof(struct ipx_packet),
|
||||
length - sizeof(struct ipx_packet), no) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (ntohs(s_addr.sipx_port) == 0x451)
|
||||
|| (ntohs(d_addr.sipx_port) == 0x451))
|
||||
{
|
||||
handle_ncp(&s_addr, &d_addr, buf + sizeof(struct ipx_packet),
|
||||
length - sizeof(struct ipx_packet), no);
|
||||
}
|
||||
else /* next 3 handle IPX by type vs by socket (one or other) */
|
||||
/* Note: most things use either ipx_type OR socket, not both */
|
||||
if (h->ipx_type == 0x01)
|
||||
printf(" type 0x01 (RIP packet (router))\n");
|
||||
else
|
||||
if (h->ipx_type == 0x05)
|
||||
printf(" type 0x05 (SPX sequenced packet)\n");
|
||||
else
|
||||
if (h->ipx_type == 0x14)
|
||||
printf(" type 0x14 (propogated Client-NetBios)\n");
|
||||
else
|
||||
{
|
||||
hbo_dsock = ntohs(d_addr.sipx_port);
|
||||
if (hbo_dsock == 0x452) /* SAP */
|
||||
{
|
||||
sappacket = (union sap_packet *)
|
||||
(buf + sizeof(struct ipx_packet));
|
||||
hbo_sapop = ntohs(sappacket->sapOperation);
|
||||
if ((hbo_sapop == 0x01) || (hbo_sapop == 0x03))
|
||||
{
|
||||
printf(" type 0x%x, SAP op:0x%x %s Query, "
|
||||
"serverType 0x%x wanted\n",
|
||||
h->ipx_type, hbo_sapop,
|
||||
(hbo_sapop == 0x01)?"General Service" :
|
||||
(hbo_sapop == 0x03)?"Nearest Server" :
|
||||
"Error",
|
||||
ntohs(sappacket->query.serverType));
|
||||
}
|
||||
else
|
||||
{
|
||||
int hops;
|
||||
|
||||
hops = ntohs(sappacket->
|
||||
response.sap[0].serverHops);
|
||||
printf(" type 0x%x, SAP op:0x%x %s %s\n",
|
||||
h->ipx_type, hbo_sapop,
|
||||
(hbo_sapop == 0x02)
|
||||
? "General Service Response" :
|
||||
(hbo_sapop == 0x04)
|
||||
? "Nearest Server Response" :
|
||||
"Unknown",
|
||||
(hops >= SAP_SHUTDOWN)
|
||||
? "[Shutdown]" : "");
|
||||
|
||||
/* Service ending */
|
||||
if (hops >= SAP_SHUTDOWN)
|
||||
{
|
||||
print_sap(stdout,
|
||||
sappacket->response.sap);
|
||||
}
|
||||
#ifdef DUMPALLSAPS
|
||||
/* If you want to dump all SAP's */
|
||||
else
|
||||
{ int num_saps;
|
||||
SAPS *sapp;
|
||||
|
||||
num_saps = (length
|
||||
- sizeof(struct ipx_packet)
|
||||
- 2) / sizeof(SAPS);
|
||||
|
||||
sapp = sappacket->response.sap;
|
||||
for(; num_saps > 0; sapp++, num_saps--)
|
||||
print_sap(stdout, sapp);
|
||||
}
|
||||
#endif /* DUMPALLSAPS */
|
||||
}
|
||||
|
||||
}
|
||||
else /* Other IPX types */
|
||||
printf(" type 0x%x, Socket 0x%x (%s)\n", h->ipx_type,
|
||||
hbo_dsock,
|
||||
(hbo_dsock == 0x451) ? "NCP" :
|
||||
/* (hbo_dsock == 0x452) ? "SAP" :*/
|
||||
(hbo_dsock == 0x453) ? "RIP" :
|
||||
(hbo_dsock == 0x455) ? "Client-NetBios" :
|
||||
(hbo_dsock == 0x456) ? "Diags" :
|
||||
(hbo_dsock == 0x002) ? "Xecho" :
|
||||
(hbo_dsock == 0x8063) ? "NVT2" : "Other");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int handle_burst(struct sockaddr_ipx *source,
|
||||
struct sockaddr_ipx *target,
|
||||
unsigned char *buf, int length, int no)
|
||||
{
|
||||
struct ncp_burst_header *rq = (struct ncp_burst_header *)buf;
|
||||
|
||||
if (rq->type != NCP_BURST_PACKET)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Burst Packet\n");
|
||||
printf("Stream Type: %02X, System Flags: %02X\n",
|
||||
rq->stream_type, rq->system_flags);
|
||||
printf("Source Conn: %08X, Dest Conn: %08X, Packet Seq: %08X\n",
|
||||
rq->source_conn, rq->dest_conn,
|
||||
(unsigned int)ntohl(rq->packet_sequence));
|
||||
printf("Send Delay: %08X, Burst Seq: %04X, Ack Seq: %04X\n",
|
||||
(unsigned int)ntohl(rq->send_delay), ntohs(rq->burst_sequence),
|
||||
ntohs(rq->ack_sequence));
|
||||
printf("Burst Length: %08X\n", (unsigned int)ntohl(rq->burst_length));
|
||||
printf("Data Offset: %08X, Data Bytes: %04X, Missing Frags: %04X\n",
|
||||
(unsigned int)ntohl(rq->data_offset), ntohs(rq->data_bytes),
|
||||
ntohs(rq->missing_frags));
|
||||
|
||||
if (ntohs(rq->data_bytes) == 24)
|
||||
{
|
||||
struct ncp_burst_request
|
||||
{
|
||||
struct ncp_burst_header h __attribute__ ((packed));
|
||||
__u32 function __attribute__ ((packed));
|
||||
__u32 file_handle __attribute__ ((packed));
|
||||
__u8 reserved[8] __attribute__ ((packed));
|
||||
__u32 file_offset __attribute__ ((packed));
|
||||
__u32 number_of_bytes __attribute__ ((packed));
|
||||
} *brq = (struct ncp_burst_request *)rq;
|
||||
|
||||
printf("Assuming Burst Request:\n");
|
||||
printf("%s: Handle %08X, Offset %08X, Bytes %08X\n",
|
||||
brq->function == 1 ? "Read " : "Write",
|
||||
brq->file_handle,
|
||||
(unsigned int)ntohl(brq->file_offset),
|
||||
(unsigned int)ntohl(brq->number_of_bytes));
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned char *data = NULL;
|
||||
int data_length = 0;
|
||||
int i;
|
||||
|
||||
if (ntohs(rq->type) == NCP_REQUEST)
|
||||
{
|
||||
/* Request */
|
||||
printf("NCP request: conn: %-5d, seq: %-3d, task: %-3d, ",
|
||||
rq->conn_low + 256 * rq->conn_high,
|
||||
rq->sequence, rq->task);
|
||||
|
||||
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");
|
||||
break;
|
||||
case 21:
|
||||
printf("fn: %-3d, subfn: %-3d\n",
|
||||
rq->function, data[2]);
|
||||
switch(data[2])
|
||||
{
|
||||
case 0:
|
||||
printf("Send Broadcast Message\n");
|
||||
break;
|
||||
case 1:
|
||||
printf("Get Broadcast Message\n");
|
||||
break;
|
||||
}
|
||||
data += 3;
|
||||
data_length -= 3;
|
||||
break;
|
||||
case 22:
|
||||
printf("fn: %-3d, subfn: %-3d\n",
|
||||
rq->function, data[2]);
|
||||
switch(data[2])
|
||||
{
|
||||
case 00:
|
||||
printf("Set Directory Handle\n");
|
||||
break;
|
||||
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;
|
||||
case 05:
|
||||
printf("Get Volume Number\n");
|
||||
break;
|
||||
case 06:
|
||||
printf("Get Volume Name\n");
|
||||
break;
|
||||
case 10:
|
||||
printf("Create directory\n");
|
||||
break;
|
||||
case 18:
|
||||
printf("Allocate Permanent Dir Handle\n");
|
||||
break;
|
||||
case 20:
|
||||
printf("Deallocate Directory Handle\n");
|
||||
break;
|
||||
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;
|
||||
}
|
||||
data += 3;
|
||||
data_length -= 3;
|
||||
break;
|
||||
case 23:
|
||||
printf("fn: %-3d, subfn: %-3d\n", rq->function,
|
||||
data[2]);
|
||||
switch(data[2])
|
||||
{
|
||||
case 17:
|
||||
printf("Get Fileserver Information\n");
|
||||
break;
|
||||
case 22:
|
||||
printf("Get Station's logged Info (old)\n");
|
||||
break;
|
||||
case 23:
|
||||
printf("Get Crypt Key\n");
|
||||
break;
|
||||
case 24:
|
||||
printf("Encrypted Login\n");
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
data += 3;
|
||||
data_length -= 3;
|
||||
break;
|
||||
case 24:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("End of Job\n");
|
||||
break;
|
||||
case 33:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Negotiate Buffer size\n");
|
||||
break;
|
||||
case 34:
|
||||
printf("fn: %-3d, subfn: %-3d\n", rq->function,
|
||||
data[2]);
|
||||
data += 3;
|
||||
data_length -= 3;
|
||||
break;
|
||||
case 62:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("File Search Initialize\n");
|
||||
break;
|
||||
case 63:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("File Search Continue\n");
|
||||
break;
|
||||
case 64:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Search for a file\n");
|
||||
break;
|
||||
case 66:
|
||||
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");
|
||||
break;
|
||||
case 73:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Write to File\n");
|
||||
break;
|
||||
case 75:
|
||||
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]);
|
||||
switch(data[0])
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
unsigned char *p = &(data[0]);
|
||||
printf("Open Create File or Subdirectory\n");
|
||||
printf("Name Space: %d\n", p[1]);
|
||||
printf("Open Create Mode: %x\n", p[2]);
|
||||
printf("Search Attributes: %x\n",
|
||||
*(__u16 *)&(p[3]));
|
||||
printf("Return Information Mask: %x\n",
|
||||
(unsigned int)(*(__u32 *)&(p[5])));
|
||||
printf("Desired Access Rights: %x\n",
|
||||
*(__u16 *)&(p[9]));
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
printf("Initialize Search\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("Search for File or Subdirectory\n");
|
||||
break;
|
||||
case 6:
|
||||
printf("Obtain File Or Subdirectory "
|
||||
"Information\n");
|
||||
break;
|
||||
case 8:
|
||||
printf("Delete a File Or Subdirectory\n");
|
||||
break;
|
||||
case 12:
|
||||
printf("Allocate Short Directory Handle\n");
|
||||
break;
|
||||
}
|
||||
data += 1;
|
||||
data_length -= 1;
|
||||
break;
|
||||
case 97:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Get Big Packet NCP Max Packet Size\n");
|
||||
break;
|
||||
case 101:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
printf("Packet Burst Connection Request\n");
|
||||
break;
|
||||
default:
|
||||
printf("fn: %-3d\n", rq->function);
|
||||
}
|
||||
}
|
||||
|
||||
if (ntohs(rs->type) == NCP_REPLY)
|
||||
{
|
||||
printf("NCP respons: conn: %-5d, seq: %-3d, task: %-3d, ",
|
||||
rs->conn_low + 256 * rs->conn_high,
|
||||
rs->sequence, rs->task);
|
||||
printf("compl: %-3d, conn_st: %-3d\n",
|
||||
rs->completion_code, rs->connection_state);
|
||||
|
||||
data = buf + sizeof(struct ncp_reply_header);
|
||||
data_length = length - sizeof(struct ncp_reply_header);
|
||||
}
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
data = buf;
|
||||
data_length = length;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < data_length)
|
||||
{
|
||||
int j;
|
||||
for (j = i; j < i+16; j++)
|
||||
{
|
||||
if (j >= data_length)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%-2.2X", data[j]);
|
||||
}
|
||||
}
|
||||
printf(" ");
|
||||
for (j = i; j < i+16; j++)
|
||||
{
|
||||
if (j >= data_length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (isprint(data[j]))
|
||||
{
|
||||
printf("%c", data[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
i += 16;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
unsigned char buf[16384];
|
||||
unsigned char packet[8192];
|
||||
unsigned char *b;
|
||||
int len;
|
||||
int i = 1;
|
||||
|
||||
while (fgets(buf, sizeof(buf), stdin) != NULL)
|
||||
{
|
||||
if (strlen(buf) == sizeof(buf)-1)
|
||||
{
|
||||
fprintf(stderr, "line too long\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
b = strchr(buf, ' ');
|
||||
if (b == NULL)
|
||||
{
|
||||
fprintf(stderr, "illegal line format\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*b = '\0';
|
||||
b += 1;
|
||||
len = 0;
|
||||
|
||||
while ((b[0] != '\0') && (b[1] != '\0'))
|
||||
{
|
||||
unsigned int value;
|
||||
if (sscanf(b, "%2x", &value) != 1)
|
||||
{
|
||||
fprintf(stderr, "illegal packet\n");
|
||||
exit(1);
|
||||
}
|
||||
packet[len] = value;
|
||||
b += 2;
|
||||
len += 1;
|
||||
}
|
||||
handle_ipx(packet, len, buf, i);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
129
ipxdump/ipxutil.c
Normal file
129
ipxdump/ipxutil.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
IPX support library - general functions
|
||||
|
||||
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
|
||||
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include "ipxutil.h"
|
||||
|
||||
void
|
||||
ipx_fprint_node(FILE *file, IPXNode node)
|
||||
{
|
||||
fprintf(file,"%02X%02X%02X%02X%02X%02X",
|
||||
(unsigned char)node[0],
|
||||
(unsigned char)node[1],
|
||||
(unsigned char)node[2],
|
||||
(unsigned char)node[3],
|
||||
(unsigned char)node[4],
|
||||
(unsigned char)node[5]
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_network(FILE *file, IPXNet net)
|
||||
{
|
||||
fprintf(file,"%08lX",net);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_port(FILE *file, IPXPort port)
|
||||
{
|
||||
fprintf(file,"%04X",port);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_fprint_saddr(FILE *file, struct sockaddr_ipx *sipx)
|
||||
{
|
||||
ipx_fprint_network(file,ntohl(sipx->sipx_network));
|
||||
fprintf(file,":");
|
||||
ipx_fprint_node(file,sipx->sipx_node);
|
||||
fprintf(file,":");
|
||||
ipx_fprint_port(file,ntohs(sipx->sipx_port));
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_node(IPXNode node)
|
||||
{
|
||||
ipx_fprint_node(stdout,node);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_network(IPXNet net)
|
||||
{
|
||||
ipx_fprint_network(stdout,net);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_port(IPXPort port)
|
||||
{
|
||||
ipx_fprint_port(stdout,port);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_print_saddr(struct sockaddr_ipx *sipx)
|
||||
{
|
||||
ipx_fprint_saddr(stdout,sipx);
|
||||
}
|
||||
|
||||
void
|
||||
ipx_assign_node(IPXNode dest, IPXNode src)
|
||||
{
|
||||
memcpy(dest,src,sizeof(IPXNode));
|
||||
}
|
||||
|
||||
int
|
||||
ipx_node_equal(IPXNode n1, IPXNode n2)
|
||||
{
|
||||
return memcmp(n1,n2,sizeof(IPXNode))==0;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_sscanf_node(char *buf, IPXNode node)
|
||||
{
|
||||
int i;
|
||||
int n[6];
|
||||
|
||||
if ((i = sscanf(buf, "%2x%2x%2x%2x%2x%2x",
|
||||
&(n[0]), &(n[1]), &(n[2]),
|
||||
&(n[3]), &(n[4]), &(n[5]))) != 6)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i<6; i++)
|
||||
{
|
||||
node[i] = n[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_sscanf_net(char *buf, IPXNet *target)
|
||||
{
|
||||
if (sscanf(buf, "%8lX", target) == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
IPXNode ipx_this_node={0,0,0,0,0,0};
|
||||
IPXNode ipx_broadcast_node={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
|
||||
char ipx_err_string[IPX_MAX_ERROR+1]="no error detected";
|
||||
65
ipxdump/ipxutil.h
Normal file
65
ipxdump/ipxutil.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
|
||||
IPX support library
|
||||
|
||||
Copyright (C) 1994, 1995 Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
|
||||
Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#ifndef __IPXUTIL_H__
|
||||
|
||||
#define __IPXUTIL_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <linux/ipx.h>
|
||||
|
||||
#define IPX_MAX_ERROR (255)
|
||||
#define IPX_THIS_NET (0)
|
||||
#define IPX_THIS_NODE (ipx_this_node)
|
||||
#define IPX_BROADCAST (ipx_broadcast_node)
|
||||
#define IPX_AUTO_PORT (0)
|
||||
#define IPX_USER_PTYPE (0)
|
||||
#define IPX_IS_INTERNAL (1)
|
||||
|
||||
typedef unsigned char IPXNode[6];
|
||||
typedef unsigned long int IPXNet;
|
||||
typedef unsigned short int IPXPort;
|
||||
typedef unsigned short int hop_t;
|
||||
typedef unsigned short int tick_t;
|
||||
|
||||
void ipx_print_node(IPXNode node);
|
||||
void ipx_print_network(IPXNet net);
|
||||
void ipx_print_port(IPXPort port);
|
||||
void ipx_print_saddr(struct sockaddr_ipx* sipx);
|
||||
|
||||
void ipx_fprint_node(FILE* file,IPXNode node);
|
||||
void ipx_fprint_network(FILE* file,IPXNet net);
|
||||
void ipx_fprint_port(FILE* file,IPXPort port);
|
||||
void ipx_fprint_saddr(FILE* file,struct sockaddr_ipx* sipx);
|
||||
|
||||
int ipx_sscanf_node(char *buf, IPXNode node);
|
||||
int ipx_sscanf_net(char *buf, IPXNet *target);
|
||||
|
||||
void ipx_assign_node(IPXNode dest,IPXNode src);
|
||||
int ipx_node_equal(IPXNode n1,IPXNode n2);
|
||||
|
||||
extern IPXNode ipx_this_node;
|
||||
extern IPXNode ipx_broadcast_node;
|
||||
|
||||
extern char ipx_err_string[IPX_MAX_ERROR+1];
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* ncp_fs.h
|
||||
* ncp.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
@@ -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)
|
||||
|
||||
@@ -34,17 +34,16 @@ struct ncp_fs_info {
|
||||
int buffer_size; /* The negotiated buffer size, to be
|
||||
used for read/write requests! */
|
||||
|
||||
/* Not used yet, but here some day the namespace numbers will be
|
||||
stored. */
|
||||
int volume_number;
|
||||
__u32 directory_id;
|
||||
};
|
||||
|
||||
#define NCP_IOC_NCPREQUEST _IOR('n', 1, unsigned char *)
|
||||
#define NCP_IOC_GETMOUNTUID _IOR('u', 1, uid_t)
|
||||
#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request)
|
||||
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, uid_t)
|
||||
#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3)
|
||||
|
||||
#define NCP_GET_FS_INFO_VERSION (1)
|
||||
#define NCP_IOC_GET_FS_INFO _IOWR('i', 1, unsigned char *)
|
||||
#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info)
|
||||
|
||||
/*
|
||||
* The packet size to allocate. One page should be enough.
|
||||
@@ -62,7 +61,7 @@ struct ncp_fs_info {
|
||||
#define NCP_READDIR_CACHE_SIZE 64
|
||||
|
||||
|
||||
#define NCP_MAX_RPC_TIMEOUT (60) /* 6 seconds */
|
||||
#define NCP_MAX_RPC_TIMEOUT (6*HZ)
|
||||
|
||||
/* Guess, what 0x564c is :-) */
|
||||
#define NCP_SUPER_MAGIC 0x564c
|
||||
@@ -126,9 +125,12 @@ extern struct inode_operations ncp_dir_inode_operations;
|
||||
void ncp_free_inode_info(struct ncp_inode_info *i);
|
||||
void ncp_free_all_inodes(struct ncp_server *server);
|
||||
void ncp_init_root(struct ncp_server *server);
|
||||
int ncp_conn_logged_in(struct ncp_server *server);
|
||||
int ncp_stat_root(struct ncp_server *server);
|
||||
void ncp_init_dir_cache(void);
|
||||
void ncp_invalid_dir_cache(unsigned long ino);
|
||||
void ncp_invalid_dir_cache(struct inode *ino);
|
||||
struct ncp_inode_info *ncp_find_inode(struct inode *inode);
|
||||
ino_t ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info);
|
||||
void ncp_invalidate_all_inodes(struct ncp_server *server);
|
||||
void ncp_free_dir_cache(void);
|
||||
int ncp_date_dos2unix(__u16 time, __u16 date);
|
||||
|
||||
@@ -28,6 +28,7 @@ struct ncp_inode_info {
|
||||
number of references in memory */
|
||||
struct ncp_inode_info *dir;
|
||||
struct ncp_inode_info *next, *prev;
|
||||
struct inode *inode;
|
||||
struct nw_file_info finfo;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,8 +21,9 @@ struct ncp_server {
|
||||
interest for us later, so we store
|
||||
it completely. */
|
||||
|
||||
struct file *ncp_filp; /* File pointer to ncp socket */
|
||||
__u8 name_space[NCP_NUMBER_OF_VOLUMES];
|
||||
|
||||
struct file *ncp_filp; /* File pointer to ncp socket */
|
||||
struct file *wdog_filp; /* File pointer to wdog socket */
|
||||
void *data_ready; /* The wdog socket gets a new
|
||||
data_ready callback. We store the
|
||||
@@ -35,7 +36,8 @@ struct ncp_server {
|
||||
|
||||
u8 completion; /* Status message from server */
|
||||
u8 conn_status; /* Bit 4 = 1 ==> Server going down, no
|
||||
requests allowed anymore */
|
||||
requests allowed anymore.
|
||||
Bit 0 = 1 ==> Server is down. */
|
||||
|
||||
int buffer_size; /* Negotiated bufsize */
|
||||
|
||||
@@ -56,6 +58,18 @@ struct ncp_server {
|
||||
char root_path; /* '\0' */
|
||||
};
|
||||
|
||||
static inline int
|
||||
ncp_conn_valid(struct ncp_server *server)
|
||||
{
|
||||
return ((server->conn_status & 0x11) == 0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ncp_invalidate_conn(struct ncp_server *server)
|
||||
{
|
||||
server->conn_status |= 0x01;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <linux/ncp.h>
|
||||
#include <linux/ncp_fs_i.h>
|
||||
|
||||
#define NCP_MOUNT_VERSION 1
|
||||
#define NCP_MOUNT_VERSION 2
|
||||
|
||||
#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
|
||||
#define NCP_PASSWORD_LEN 20
|
||||
@@ -26,14 +26,14 @@ struct ncp_mount_data {
|
||||
int version;
|
||||
unsigned int ncp_fd; /* The socket to the ncp port */
|
||||
unsigned int wdog_fd; /* Watchdog packets come here */
|
||||
unsigned int message_fd; /* Not used yet, maybe for messages */
|
||||
unsigned int message_fd; /* Message notifications come here */
|
||||
uid_t mounted_uid; /* Who may umount() this filesystem? */
|
||||
|
||||
struct sockaddr_ipx serv_addr;
|
||||
unsigned char server_name[49];
|
||||
unsigned char server_name[NCP_BINDERY_NAME_LEN];
|
||||
|
||||
unsigned char username[NCP_USERNAME_LEN+1];
|
||||
unsigned char password[NCP_PASSWORD_LEN+1];
|
||||
unsigned char mount_point[PATH_MAX+1];
|
||||
unsigned char mounted_vol[NCP_VOLNAME_LEN+1];
|
||||
|
||||
unsigned int time_out; /* How long should I wait after
|
||||
sending a NCP request? */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
CFLAGS = -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer \
|
||||
$(INCLUDES) \
|
||||
$(INCLUDES) -DNCPFS_VERSION=\"$(VERSION)\"\
|
||||
# -DDEBUG_NCP=1 -DDEBUG_NCP_MALLOC
|
||||
# -DDEBUG_NCP_MALLOC
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <asm/segment.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/locks.h>
|
||||
#include "ncplib_kernel.h"
|
||||
|
||||
struct ncp_dirent {
|
||||
@@ -47,7 +48,7 @@ static struct inode *
|
||||
ncp_iget(struct inode *dir, struct nw_file_info *finfo);
|
||||
|
||||
static struct ncp_inode_info *
|
||||
ncp_find_inode(struct inode *dir, const char *name);
|
||||
ncp_find_dir_inode(struct inode *dir, const char *name);
|
||||
|
||||
static int
|
||||
ncp_lookup(struct inode *dir, const char *__name,
|
||||
@@ -96,13 +97,27 @@ 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 */
|
||||
NULL, /* write - bad */
|
||||
ncp_readdir, /* readdir */
|
||||
NULL, /* select - default */
|
||||
ncp_ioctl, /* ioctl - default */
|
||||
ncp_ioctl, /* ioctl */
|
||||
NULL, /* mmap */
|
||||
NULL, /* no special open code */
|
||||
NULL, /* no special release code */
|
||||
@@ -129,6 +144,58 @@ 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 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.
|
||||
*/
|
||||
|
||||
static inline int
|
||||
ncp_single_volume(struct ncp_server *server)
|
||||
{
|
||||
return (server->m.mounted_vol[0] != '\0');
|
||||
}
|
||||
|
||||
inline ino_t
|
||||
ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
|
||||
{
|
||||
return ncp_single_volume(server)
|
||||
? info->finfo.i.dirEntNum : (ino_t)info;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ncp_is_server_root(struct inode *inode)
|
||||
{
|
||||
struct ncp_server *s = NCP_SERVER(inode);
|
||||
|
||||
return ( (!ncp_single_volume(s))
|
||||
&& (inode->i_ino == ncp_info_ino(s, &(s->root))));
|
||||
}
|
||||
|
||||
struct ncp_inode_info *
|
||||
ncp_find_inode(struct inode *inode)
|
||||
{
|
||||
struct ncp_server *server = NCP_SERVER(inode);
|
||||
struct ncp_inode_info *root = &(server->root);
|
||||
struct ncp_inode_info *this = root;
|
||||
|
||||
ino_t ino = inode->i_ino;
|
||||
|
||||
do
|
||||
{
|
||||
if (ino == ncp_info_ino(server, this))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
this = this->next;
|
||||
}
|
||||
while (this != root);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count)
|
||||
{
|
||||
@@ -142,21 +209,40 @@ ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count)
|
||||
all inodes that are in memory. That's why it's enough to index the
|
||||
directory cache by the inode number. */
|
||||
|
||||
static int c_dev = 0;
|
||||
static unsigned long c_ino = 0;
|
||||
static int c_size;
|
||||
static int c_seen_eof;
|
||||
static int c_last_returned_index;
|
||||
static struct ncp_dirent* c_entry = NULL;
|
||||
static int c_lock = 0;
|
||||
static struct wait_queue *c_wait = NULL;
|
||||
|
||||
static inline void
|
||||
ncp_lock_dircache(void)
|
||||
{
|
||||
while (c_lock)
|
||||
sleep_on(&c_wait);
|
||||
c_lock = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ncp_unlock_dircache(void)
|
||||
{
|
||||
c_lock = 0;
|
||||
wake_up(&c_wait);
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_readdir(struct inode *inode, struct file *filp,
|
||||
struct dirent *dirent, int count)
|
||||
{
|
||||
int result, i = 0;
|
||||
int result = 0;
|
||||
int i = 0;
|
||||
int index = 0;
|
||||
struct ncp_dirent *entry = NULL;
|
||||
struct ncp_server *server = NCP_SERVER(inode);
|
||||
struct ncp_inode_info *dir = (struct ncp_inode_info *)(inode->i_ino);
|
||||
struct ncp_inode_info *dir = NCP_INOP(inode);
|
||||
|
||||
int filldir(struct dirent *dirent,
|
||||
const char *name, int len,
|
||||
@@ -170,9 +256,9 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
return 1;
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int)filp->f_pos);
|
||||
DDPRINTK("ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n",
|
||||
inode->i_ino, c_ino);
|
||||
DPRINTK("ncp_readdir: filp->f_pos = %d\n", (int)filp->f_pos);
|
||||
DPRINTK("ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n",
|
||||
inode->i_ino, c_ino);
|
||||
|
||||
if (!inode || !S_ISDIR(inode->i_mode))
|
||||
{
|
||||
@@ -180,6 +266,12 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
if (!ncp_conn_valid(server))
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ncp_lock_dircache();
|
||||
if (c_entry == NULL)
|
||||
{
|
||||
i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
|
||||
@@ -187,32 +279,37 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
if (c_entry == NULL)
|
||||
{
|
||||
printk("ncp_readdir: no MEMORY for cache\n");
|
||||
return -ENOMEM;
|
||||
result = -ENOMEM;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
if (filp->f_pos == 0)
|
||||
{
|
||||
ncp_invalid_dir_cache(inode->i_ino);
|
||||
if (filldir(dirent,".",1, filp->f_pos, (int)dir) < 0)
|
||||
ncp_invalid_dir_cache(inode);
|
||||
if (filldir(dirent,".",1, filp->f_pos,
|
||||
ncp_info_ino(server, dir)) < 0)
|
||||
{
|
||||
return 0;
|
||||
goto finished;
|
||||
}
|
||||
filp->f_pos += 1;
|
||||
return ROUND_UP(NAME_OFFSET(dirent)+i+1);
|
||||
result = ROUND_UP(NAME_OFFSET(dirent)+i+1);
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (filp->f_pos == 1)
|
||||
{
|
||||
if (filldir(dirent,"..",2, filp->f_pos, (int)(dir->dir)) < 0)
|
||||
if (filldir(dirent,"..",2, filp->f_pos,
|
||||
ncp_info_ino(server, dir->dir)) < 0)
|
||||
{
|
||||
return 0;
|
||||
goto finished;
|
||||
}
|
||||
filp->f_pos += 1;
|
||||
return ROUND_UP(NAME_OFFSET(dirent)+i+1);
|
||||
result = ROUND_UP(NAME_OFFSET(dirent)+i+1);
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (inode->i_ino == c_ino)
|
||||
if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino))
|
||||
{
|
||||
for (i = 0; i < c_size; i++)
|
||||
{
|
||||
@@ -226,47 +323,54 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
}
|
||||
if ((entry == NULL) && c_seen_eof)
|
||||
{
|
||||
return 0;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
int entries;
|
||||
DDPRINTK("ncp_readdir: Not found in cache.\n");
|
||||
|
||||
if (inode->i_ino == (int)&(server->root))
|
||||
if (ncp_is_server_root(inode))
|
||||
{
|
||||
result = ncp_read_volume_list(server, filp->f_pos,
|
||||
NCP_READDIR_CACHE_SIZE);
|
||||
DPRINTK("ncp_read_volume_list returned %d\n", result);
|
||||
entries = ncp_read_volume_list(server, filp->f_pos,
|
||||
NCP_READDIR_CACHE_SIZE);
|
||||
DPRINTK("ncp_read_volume_list returned %d\n", entries);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ncp_do_readdir(server, inode, filp->f_pos,
|
||||
NCP_READDIR_CACHE_SIZE,
|
||||
c_entry);
|
||||
DPRINTK("ncp_readdir returned %d\n", result);
|
||||
entries = ncp_do_readdir(server, inode, filp->f_pos,
|
||||
NCP_READDIR_CACHE_SIZE,
|
||||
c_entry);
|
||||
DPRINTK("ncp_readdir returned %d\n", entries);
|
||||
}
|
||||
|
||||
if (result < 0)
|
||||
if (entries < 0)
|
||||
{
|
||||
c_dev = 0;
|
||||
c_ino = 0;
|
||||
return result;
|
||||
result = entries;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (result > 0)
|
||||
if (entries > 0)
|
||||
{
|
||||
c_seen_eof = (result < NCP_READDIR_CACHE_SIZE);
|
||||
c_seen_eof = (entries < NCP_READDIR_CACHE_SIZE);
|
||||
c_dev = inode->i_dev;
|
||||
c_ino = inode->i_ino;
|
||||
c_size = result;
|
||||
c_size = entries;
|
||||
entry = c_entry;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,7 +378,7 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
if (entry == NULL)
|
||||
{
|
||||
/* Nothing found, even from a ncp call */
|
||||
return 0;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (index < c_size)
|
||||
@@ -282,34 +386,48 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
/* We found it. For getwd(), we have to return the
|
||||
correct inode in d_ino if the inode is currently in
|
||||
use. Otherwise the inode number does not
|
||||
matter. (You can argue a lot about this..) */
|
||||
matter. (You can argue a lot about this..) */
|
||||
|
||||
struct ncp_inode_info *ino_info;
|
||||
ino_info = ncp_find_inode(inode, entry->i.entryName);
|
||||
ino_t ino;
|
||||
|
||||
/* Some programs seem to be confused about a zero
|
||||
inode number, so we set it to one. Thanks to
|
||||
Gordon Chaffee for this one. */
|
||||
if (ino_info == NULL)
|
||||
if (ncp_single_volume(server))
|
||||
{
|
||||
ino_info = (struct ncp_inode_info *) 1;
|
||||
}
|
||||
ino = (ino_t)(entry->i.dirEntNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ncp_inode_info *ino_info;
|
||||
ino_info = ncp_find_dir_inode(inode,
|
||||
entry->i.entryName);
|
||||
|
||||
DDPRINTK("ncp_readdir: entry->path= %s\n", entry->i.entryName);
|
||||
DDPRINTK("ncp_readdir: entry->f_pos = %ld\n", entry->f_pos);
|
||||
/* Some programs seem to be confused about a
|
||||
* zero inode number, so we set it to one.
|
||||
* Thanks to Gordon Chaffee for this one. */
|
||||
if (ino_info == NULL)
|
||||
{
|
||||
ino_info = (struct ncp_inode_info *) 1;
|
||||
}
|
||||
ino = (ino_t)(ino_info);
|
||||
}
|
||||
|
||||
DPRINTK("ncp_readdir: entry->path= %s\n", entry->i.entryName);
|
||||
DPRINTK("ncp_readdir: entry->f_pos = %ld\n", entry->f_pos);
|
||||
|
||||
if (filldir(dirent, entry->i.entryName, entry->i.nameLen,
|
||||
entry->f_pos, (ino_t)ino_info) < 0)
|
||||
entry->f_pos, ino) < 0)
|
||||
{
|
||||
return 0;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
filp->f_pos += 1;
|
||||
index += 1;
|
||||
entry += 1;
|
||||
return ROUND_UP(NAME_OFFSET(dirent)+i+1);
|
||||
result = ROUND_UP(NAME_OFFSET(dirent)+i+1);
|
||||
goto finished;
|
||||
}
|
||||
return 0;
|
||||
finished:
|
||||
ncp_unlock_dircache();
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -334,7 +452,7 @@ ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
|
||||
|
||||
if (ncp_get_volume_info_with_number(server, i, &info) != 0)
|
||||
{
|
||||
return total_count;
|
||||
return (total_count - fpos);
|
||||
}
|
||||
|
||||
if (strlen(info.volume_name) > 0)
|
||||
@@ -353,12 +471,12 @@ ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
|
||||
DPRINTK("ncp_read_volumes: found vol: %s\n",
|
||||
info.volume_name);
|
||||
|
||||
if (ncp_do_lookup(server, NULL,
|
||||
info.volume_name,
|
||||
&(entry->i)) != 0)
|
||||
if (ncp_lookup_volume(server,
|
||||
info.volume_name,
|
||||
&(entry->i)) != 0)
|
||||
{
|
||||
printk("ncpfs: could not lookup vol "
|
||||
"%s\n", info.volume_name);
|
||||
DPRINTK("ncpfs: could not lookup vol "
|
||||
"%s\n", info.volume_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -438,15 +556,17 @@ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
|
||||
void
|
||||
ncp_init_dir_cache(void)
|
||||
{
|
||||
c_dev = 0;
|
||||
c_ino = 0;
|
||||
c_entry = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_invalid_dir_cache(unsigned long ino)
|
||||
ncp_invalid_dir_cache(struct inode *inode)
|
||||
{
|
||||
if (ino == c_ino)
|
||||
if ((inode->i_dev == c_dev) && (inode->i_ino == c_ino))
|
||||
{
|
||||
c_dev = 0;
|
||||
c_ino = 0;
|
||||
c_seen_eof = 0;
|
||||
}
|
||||
@@ -517,7 +637,8 @@ ncp_iget(struct inode *dir, struct nw_file_info *finfo)
|
||||
root->next->prev = new_inode_info;
|
||||
root->next = new_inode_info;
|
||||
|
||||
if (!(inode = iget(dir->i_sb, (int)new_inode_info)))
|
||||
if (!(inode = iget(dir->i_sb, ncp_info_ino(NCP_SERVER(dir),
|
||||
new_inode_info))))
|
||||
{
|
||||
printk("ncp_iget: iget failed!");
|
||||
return NULL;
|
||||
@@ -567,6 +688,7 @@ ncp_init_root(struct ncp_server *server)
|
||||
root->finfo.opened = 0;
|
||||
i->attributes = aDIR;
|
||||
i->dataStreamSize = 1024;
|
||||
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));
|
||||
@@ -581,6 +703,25 @@ ncp_init_root(struct ncp_server *server)
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_conn_logged_in(struct ncp_server *server)
|
||||
{
|
||||
if (server->m.mounted_vol[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
str_upper(server->m.mounted_vol);
|
||||
if (ncp_lookup_volume(server, server->m.mounted_vol,
|
||||
&(server->root.finfo.i)) != 0)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
str_lower(server->root.finfo.i.entryName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_free_all_inodes(struct ncp_server *server)
|
||||
{
|
||||
@@ -611,7 +752,7 @@ ncp_free_all_inodes(struct ncp_server *server)
|
||||
complete linear search through the inodes belonging to this
|
||||
filesystem. This has to be fixed. */
|
||||
static struct ncp_inode_info *
|
||||
ncp_find_inode(struct inode *dir, const char *name)
|
||||
ncp_find_dir_inode(struct inode *dir, const char *name)
|
||||
{
|
||||
struct ncp_server *server = NCP_SERVER(dir);
|
||||
struct nw_info_struct *dir_info = NCP_ISTRUCT(dir);
|
||||
@@ -624,9 +765,15 @@ ncp_find_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))
|
||||
&& (strcmp(result->finfo.i.entryName, name) == 0)
|
||||
/* The root dir is never looked up using this
|
||||
* routine. Without the following test a root
|
||||
* directory 'sys' in a volume named 'sys' could
|
||||
* never be looked up, because
|
||||
* server->root->dir==server->root. */
|
||||
&& (result != &(server->root)))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
@@ -646,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;
|
||||
@@ -658,9 +805,14 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_lookup: %s, len %d\n", __name, len);
|
||||
|
||||
server = NCP_SERVER(dir);
|
||||
if (!ncp_conn_valid(server))
|
||||
{
|
||||
iput(dir);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_lookup: %s, len %d\n", __name, len);
|
||||
|
||||
/* Fast cheat for . */
|
||||
if (len == 0 || (len == 1 && __name[0] == '.'))
|
||||
@@ -679,7 +831,7 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
parent->state = NCP_INODE_LOOKED_UP;
|
||||
}
|
||||
|
||||
*result = iget(dir->i_sb, (int)parent);
|
||||
*result = iget(dir->i_sb, ncp_info_ino(server, parent));
|
||||
iput(dir);
|
||||
if (*result == 0)
|
||||
{
|
||||
@@ -693,8 +845,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
|
||||
memcpy(name, __name, len);
|
||||
name[len] = 0;
|
||||
|
||||
result_info = ncp_find_inode(dir, name);
|
||||
lock_super(dir->i_sb);
|
||||
result_info = ncp_find_dir_inode(dir, name);
|
||||
|
||||
if (result_info != 0)
|
||||
{
|
||||
@@ -706,7 +858,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
/* Here we convert the inode_info address into an
|
||||
inode number */
|
||||
|
||||
*result = iget(dir->i_sb, (int)result_info);
|
||||
*result = iget(dir->i_sb, ncp_info_ino(server, result_info));
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
|
||||
if (*result == NULL)
|
||||
@@ -721,8 +874,10 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
server. */
|
||||
|
||||
found_in_cache = 0;
|
||||
|
||||
if (dir->i_ino == c_ino)
|
||||
|
||||
ncp_lock_dircache();
|
||||
|
||||
if ((dir->i_dev == c_dev) && (dir->i_ino == c_ino))
|
||||
{
|
||||
int first = c_last_returned_index;
|
||||
int i;
|
||||
@@ -744,33 +899,56 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
}
|
||||
while (i != first);
|
||||
}
|
||||
ncp_unlock_dircache();
|
||||
|
||||
if (found_in_cache == 0)
|
||||
{
|
||||
str_upper(name);
|
||||
int res;
|
||||
|
||||
DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
|
||||
NCP_ISTRUCT(dir)->entryName, name);
|
||||
|
||||
if (ncp_do_lookup(server,
|
||||
dir->i_ino == (int)&(NCP_SERVER(dir)->root)
|
||||
? NULL : NCP_ISTRUCT(dir),
|
||||
name, &(finfo.i)) != 0)
|
||||
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)->dirEntNum,
|
||||
name, &(finfo.i));
|
||||
}
|
||||
if (res != 0)
|
||||
{
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
finfo.opened = 0;
|
||||
str_lower(finfo.i.entryName);
|
||||
|
||||
if (down_case != 0)
|
||||
{
|
||||
str_lower(finfo.i.entryName);
|
||||
}
|
||||
|
||||
if (!(*result = ncp_iget(dir, &finfo)))
|
||||
{
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
return 0;
|
||||
}
|
||||
@@ -790,33 +968,51 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
|
||||
iput(dir);
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!ncp_conn_valid(NCP_SERVER(dir)))
|
||||
{
|
||||
iput(dir);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
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),
|
||||
NCP_ISTRUCT(dir), _name,
|
||||
OC_MODE_CREATE|OC_MODE_OPEN,
|
||||
OC_MODE_CREATE|OC_MODE_OPEN|
|
||||
OC_MODE_REPLACE,
|
||||
0, AR_READ|AR_WRITE,
|
||||
&finfo) != 0)
|
||||
{
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
ncp_invalid_dir_cache(dir->i_ino);
|
||||
ncp_invalid_dir_cache(dir);
|
||||
|
||||
if (!ncp_preserve_case(dir))
|
||||
{
|
||||
str_lower(finfo.i.entryName);
|
||||
}
|
||||
|
||||
str_lower(finfo.i.entryName);
|
||||
finfo.access = O_RDWR;
|
||||
|
||||
if (!(*result = ncp_iget(dir, &finfo)) < 0)
|
||||
{
|
||||
ncp_close_file(NCP_SERVER(dir), finfo.file_handle);
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
unlock_super(dir->i_sb);
|
||||
iput(dir);
|
||||
return 0;
|
||||
}
|
||||
@@ -833,12 +1029,17 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
|
||||
|| ( (len == 2)
|
||||
&& (name[1] == '.'))))
|
||||
{
|
||||
iput(dir);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
@@ -846,6 +1047,11 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
|
||||
iput(dir);
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!ncp_conn_valid(NCP_SERVER(dir)))
|
||||
{
|
||||
iput(dir);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
|
||||
NCP_ISTRUCT(dir), _name,
|
||||
@@ -857,7 +1063,7 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
|
||||
else
|
||||
{
|
||||
error = 0;
|
||||
ncp_invalid_dir_cache(dir->i_ino);
|
||||
ncp_invalid_dir_cache(dir);
|
||||
}
|
||||
|
||||
iput(dir);
|
||||
@@ -876,8 +1082,14 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
|
||||
iput(dir);
|
||||
return -ENOENT;
|
||||
}
|
||||
if (ncp_find_inode(dir, name) != NULL)
|
||||
if (!ncp_conn_valid(NCP_SERVER(dir)))
|
||||
{
|
||||
iput(dir);
|
||||
return -EIO;
|
||||
}
|
||||
if (ncp_find_dir_inode(dir, name) != NULL)
|
||||
{
|
||||
iput(dir);
|
||||
error = -EBUSY;
|
||||
}
|
||||
else
|
||||
@@ -885,17 +1097,21 @@ 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),
|
||||
_name)) == 0)
|
||||
{
|
||||
ncp_invalid_dir_cache(dir->i_ino);
|
||||
ncp_invalid_dir_cache(dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = -EINVAL;
|
||||
error = -EACCES;
|
||||
}
|
||||
}
|
||||
iput(dir);
|
||||
@@ -914,25 +1130,35 @@ ncp_unlink(struct inode *dir, const char *name, int len)
|
||||
iput(dir);
|
||||
return -ENOENT;
|
||||
}
|
||||
if (ncp_find_inode(dir, name) != NULL)
|
||||
if (!ncp_conn_valid(NCP_SERVER(dir)))
|
||||
{
|
||||
iput(dir);
|
||||
return -EIO;
|
||||
}
|
||||
if (ncp_find_dir_inode(dir, name) != NULL)
|
||||
{
|
||||
iput(dir);
|
||||
error = -EBUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
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),
|
||||
_name)) == 0)
|
||||
{
|
||||
ncp_invalid_dir_cache(dir->i_ino);
|
||||
ncp_invalid_dir_cache(dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = -EINVAL;
|
||||
error = -EACCES;
|
||||
}
|
||||
}
|
||||
iput(dir);
|
||||
@@ -954,6 +1180,12 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (!ncp_conn_valid(NCP_SERVER(old_dir)))
|
||||
{
|
||||
res = -EIO;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (!new_dir || !S_ISDIR(new_dir->i_mode))
|
||||
{
|
||||
printk("ncp_rename: new inode is NULL or not a directory\n");
|
||||
@@ -961,8 +1193,8 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if ( (ncp_find_inode(old_dir, old_name) != NULL)
|
||||
|| (ncp_find_inode(new_dir, new_name) != NULL))
|
||||
if ( (ncp_find_dir_inode(old_dir, old_name) != NULL)
|
||||
|| (ncp_find_dir_inode(new_dir, new_name) != NULL))
|
||||
{
|
||||
res = -EBUSY;
|
||||
goto finished;
|
||||
@@ -970,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,
|
||||
@@ -982,8 +1222,8 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
ncp_invalid_dir_cache(old_dir->i_ino);
|
||||
ncp_invalid_dir_cache(new_dir->i_ino);
|
||||
ncp_invalid_dir_cache(old_dir);
|
||||
ncp_invalid_dir_cache(new_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/stat.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/locks.h>
|
||||
#include "ncplib_kernel.h"
|
||||
#include <linux/malloc.h>
|
||||
|
||||
@@ -50,8 +51,10 @@ ncp_make_open(struct inode *i, int right)
|
||||
|
||||
DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
|
||||
|
||||
lock_super(i->i_sb);
|
||||
if (finfo->opened == 0)
|
||||
{
|
||||
finfo->access = -1;
|
||||
/* tries max. rights */
|
||||
if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
|
||||
NULL, NULL,
|
||||
@@ -69,12 +72,10 @@ ncp_make_open(struct inode *i, int right)
|
||||
{
|
||||
finfo->access = O_RDONLY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
|
||||
unlock_super(i->i_sb);
|
||||
|
||||
if ( ((right == O_RDONLY) && ( (finfo->access == O_RDONLY)
|
||||
|| (finfo->access == O_RDWR)))
|
||||
|| ((right == O_WRONLY) && ( (finfo->access == O_WRONLY)
|
||||
@@ -99,6 +100,10 @@ ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
|
||||
DPRINTK("ncp_file_read: inode = NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!ncp_conn_valid(NCP_SERVER(inode)))
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
{
|
||||
@@ -178,6 +183,10 @@ ncp_file_write(struct inode *inode, struct file *file, char *buf,
|
||||
DPRINTK("ncp_file_write: inode = NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!ncp_conn_valid(NCP_SERVER(inode)))
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
{
|
||||
@@ -239,6 +248,7 @@ ncp_file_write(struct inode *inode, struct file *file, char *buf,
|
||||
if (pos > inode->i_size)
|
||||
{
|
||||
inode->i_size = pos;
|
||||
ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
|
||||
}
|
||||
|
||||
DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
|
||||
|
||||
@@ -61,50 +61,25 @@ ncp_read_inode(struct inode *inode)
|
||||
inode->i_ino. Just to make sure everything went well, we
|
||||
check it's there. */
|
||||
|
||||
struct ncp_inode_info *inode_info
|
||||
= (struct ncp_inode_info *)(inode->i_ino);
|
||||
struct ncp_inode_info *inode_info = ncp_find_inode(inode);
|
||||
|
||||
#if 1
|
||||
struct ncp_inode_info *root = &(NCP_SERVER(inode)->root);
|
||||
struct ncp_inode_info *check_info = root;
|
||||
|
||||
do
|
||||
if (inode_info == NULL)
|
||||
{
|
||||
if (inode_info == check_info)
|
||||
{
|
||||
if (check_info->state == NCP_INODE_LOOKED_UP)
|
||||
{
|
||||
DDPRINTK("ncp_read_inode: found it!\n");
|
||||
goto good;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("ncp_read_inode: "
|
||||
"state != NCP_INODE_LOOKED_UP\n");
|
||||
goto good;
|
||||
}
|
||||
}
|
||||
check_info = check_info->next;
|
||||
}
|
||||
while (check_info != root);
|
||||
/* Ok, now we're in trouble. The inode info is not there. What
|
||||
should we do now??? */
|
||||
printk("ncp_read_inode: inode info not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ok, now we're in trouble. The inode info is not there. What
|
||||
should we do now??? */
|
||||
printk("ncp_read_inode: inode info not found\n");
|
||||
return;
|
||||
|
||||
good:
|
||||
DDPRINTK("ncp_read_inode: read entry %s\n",
|
||||
inode_info->finfo.i.entryName);
|
||||
#endif
|
||||
inode_info->state = NCP_INODE_VALID;
|
||||
|
||||
NCP_INOP(inode) = inode_info;
|
||||
inode_info->inode = inode;
|
||||
|
||||
if (NCP_ISTRUCT(inode)->attributes & aDIR)
|
||||
{
|
||||
inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
|
||||
/* for directories in dataStreamSize seems to be some
|
||||
/* for directories dataStreamSize seems to be some
|
||||
Object ID ??? */
|
||||
inode->i_size = 512;
|
||||
}
|
||||
@@ -119,7 +94,7 @@ ncp_read_inode(struct inode *inode)
|
||||
inode->i_nlink = 1;
|
||||
inode->i_uid = NCP_SERVER(inode)->m.uid;
|
||||
inode->i_gid = NCP_SERVER(inode)->m.gid;
|
||||
inode->i_blksize = 1024;
|
||||
inode->i_blksize = 512;
|
||||
inode->i_rdev = 0;
|
||||
|
||||
if ((inode->i_blksize != 0) && (inode->i_size != 0))
|
||||
@@ -157,7 +132,9 @@ static void
|
||||
ncp_put_inode(struct inode *inode)
|
||||
{
|
||||
struct nw_file_info *finfo = NCP_FINFO(inode);
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
||||
lock_super(sb);
|
||||
if (finfo->opened != 0)
|
||||
{
|
||||
if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
|
||||
@@ -176,10 +153,11 @@ ncp_put_inode(struct inode *inode)
|
||||
{
|
||||
DDPRINTK("ncp_put_inode: put directory %ld\n",
|
||||
inode->i_ino);
|
||||
ncp_invalid_dir_cache(inode->i_ino);
|
||||
ncp_invalid_dir_cache(inode);
|
||||
}
|
||||
|
||||
clear_inode(inode);
|
||||
unlock_super(sb);
|
||||
}
|
||||
|
||||
struct super_block *
|
||||
@@ -204,6 +182,8 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
|
||||
printk("ncp warning: mount version %s than kernel\n",
|
||||
(data->version < NCP_MOUNT_VERSION) ?
|
||||
"older" : "newer");
|
||||
sb->s_dev = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( (data->ncp_fd >= NR_OPEN)
|
||||
@@ -253,6 +233,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
|
||||
server->wait = NULL;
|
||||
server->packet = NULL;
|
||||
server->buffer_size = 0;
|
||||
server->conn_status = 0;
|
||||
|
||||
server->m = *data;
|
||||
server->m.file_mode = (server->m.file_mode &
|
||||
@@ -302,7 +283,7 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
|
||||
|
||||
DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));
|
||||
|
||||
if (!(sb->s_mounted = iget(sb, (int)&(server->root))))
|
||||
if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, &(server->root)))))
|
||||
{
|
||||
sb->s_dev = 0;
|
||||
printk("ncp_read_super: get root inode failed\n");
|
||||
@@ -393,6 +374,11 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
|
||||
int info_mask;
|
||||
struct nw_modify_dos_info info;
|
||||
|
||||
if (!ncp_conn_valid(NCP_SERVER(inode)))
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if ((result = inode_change_ok(inode, attr)) < 0)
|
||||
return result;
|
||||
|
||||
@@ -480,7 +466,7 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
|
||||
result = 0;
|
||||
}
|
||||
|
||||
ncp_invalid_dir_cache((unsigned long)(NCP_INOP(inode)->dir));
|
||||
ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -510,6 +496,7 @@ init_module( void)
|
||||
|
||||
ncp_init_dir_cache();
|
||||
register_filesystem(&ncp_fs_type);
|
||||
printk("ncpfs version %s loaded\n", NCPFS_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,26 @@ ncp_ioctl (struct inode * inode, struct file * filp,
|
||||
struct ncp_fs_info info;
|
||||
struct ncp_server *server = NCP_SERVER(inode);
|
||||
|
||||
/*
|
||||
* Binary compatible with 1.3.XX releases.
|
||||
* Take this out in 2.1.0 development series.
|
||||
* <mec@duracef.shout.net> 12 Mar 1996
|
||||
*/
|
||||
switch(cmd) {
|
||||
case _IOR('n', 1, unsigned char *):
|
||||
cmd = NCP_IOC_NCPREQUEST;
|
||||
break;
|
||||
case _IOR('u', 1, uid_t):
|
||||
cmd = NCP_IOC_GETMOUNTUID;
|
||||
break;
|
||||
case _IO('l', 1):
|
||||
cmd = NCP_IOC_CONN_LOGGED_IN;
|
||||
break;
|
||||
case _IOWR('i', 1, unsigned char *):
|
||||
cmd = NCP_IOC_GET_FS_INFO;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
case NCP_IOC_NCPREQUEST:
|
||||
|
||||
@@ -79,6 +99,16 @@ ncp_ioctl (struct inode * inode, struct file * filp,
|
||||
|
||||
return server->reply_size;
|
||||
|
||||
case NCP_IOC_CONN_LOGGED_IN:
|
||||
|
||||
if ( (permission(inode, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
return ncp_conn_logged_in(server);
|
||||
|
||||
case NCP_IOC_GET_FS_INFO:
|
||||
|
||||
if ( (permission(inode, MAY_WRITE) != 0)
|
||||
@@ -106,6 +136,8 @@ ncp_ioctl (struct inode * inode, struct file * filp,
|
||||
info.mounted_uid = server->m.mounted_uid;
|
||||
info.connection = server->connection;
|
||||
info.buffer_size = server->buffer_size;
|
||||
info.volume_number = NCP_ISTRUCT(inode)->volNumber;
|
||||
info.directory_id = NCP_ISTRUCT(inode)->DosDirNum;
|
||||
|
||||
memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
|
||||
return 0;
|
||||
|
||||
@@ -135,6 +135,11 @@ ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
|
||||
{
|
||||
DPRINTK("ncp_mmap: called\n");
|
||||
|
||||
if (!ncp_conn_valid(NCP_SERVER(inode)))
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* only PAGE_COW or read-only supported now */
|
||||
if (vma->vm_flags & VM_SHARED)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -266,65 +247,27 @@ ncp_extract_file_info(void *structure, struct nw_info_struct *target)
|
||||
target->entryName[*name_len] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_do_lookup(struct ncp_server *server,
|
||||
struct nw_info_struct *dir,
|
||||
char *path, /* may only be one component */
|
||||
struct nw_info_struct *target)
|
||||
ncp_obtain_info(struct ncp_server *server,
|
||||
__u8 vol_num, __u32 dir_base,
|
||||
char *path, /* At most 1 component */
|
||||
struct nw_info_struct *target)
|
||||
{
|
||||
__u8 vol_num;
|
||||
__u32 dir_base;
|
||||
int result;
|
||||
char *volname = NULL;
|
||||
|
||||
if (target == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dir == NULL)
|
||||
{
|
||||
|
||||
DDPRINTK("ncp_do_lookup: looking up vol %s\n", path);
|
||||
|
||||
/* Access a volume's root directory */
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 22); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_handle_path(server, 0, 0, 0, /* no handle */
|
||||
path);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
dir_base = ncp_reply_dword(server, 4);
|
||||
vol_num = ncp_reply_byte (server, 8);
|
||||
ncp_unlock_server(server);
|
||||
volname = path;
|
||||
path = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
vol_num = dir->volNumber;
|
||||
dir_base = dir->DosDirNum;
|
||||
}
|
||||
|
||||
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);
|
||||
ncp_add_handle_path(server, vol_num, dir_base, 1, path);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
@@ -333,17 +276,93 @@ ncp_do_lookup(struct ncp_server *server,
|
||||
}
|
||||
|
||||
ncp_extract_file_info(ncp_reply_data(server, 0), target);
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (volname != NULL)
|
||||
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)
|
||||
{
|
||||
target->nameLen = strlen(volname);
|
||||
strcpy(target->entryName, volname);
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
no_namespaces = ncp_reply_word(server, 0);
|
||||
namespace = ncp_reply_data(server, 2);
|
||||
|
||||
while (no_namespaces > 0)
|
||||
{
|
||||
DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
|
||||
|
||||
if (*namespace == 4)
|
||||
{
|
||||
DPRINTK("get_namespaces: found OS2\n");
|
||||
ncp_unlock_server(server);
|
||||
return 1;
|
||||
}
|
||||
namespace += 1;
|
||||
no_namespaces -= 1;
|
||||
}
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_lookup_volume(struct ncp_server *server,
|
||||
char *volname,
|
||||
struct nw_info_struct *target)
|
||||
{
|
||||
int result;
|
||||
int volnum;
|
||||
|
||||
DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
|
||||
ncp_add_byte(server, 0); /* DOS namespace */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
|
||||
ncp_add_byte(server, 0); /* faked volume number */
|
||||
ncp_add_dword(server, 0); /* faked dir_base */
|
||||
ncp_add_byte(server, 0xff); /* Don't have a dir_base */
|
||||
ncp_add_byte(server, 1); /* 1 path component */
|
||||
ncp_add_pstring(server, volname);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
memset(target, 0, sizeof(*target));
|
||||
target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
|
||||
target->volNumber = volnum = ncp_reply_byte(server, 8);
|
||||
ncp_unlock_server(server);
|
||||
|
||||
server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
|
||||
|
||||
DPRINTK("lookup_vol: namespace[%d] = %d\n",
|
||||
volnum, server->name_space[volnum]);
|
||||
|
||||
target->nameLen = strlen(volname);
|
||||
strcpy(target->entryName, volname);
|
||||
target->attributes = aDIR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
|
||||
struct nw_info_struct *file,
|
||||
@@ -354,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)
|
||||
{
|
||||
@@ -381,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)
|
||||
{
|
||||
@@ -417,12 +436,19 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_file_info *target)
|
||||
{
|
||||
int result;
|
||||
__u16 search_attribs = 0x0006;
|
||||
__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
|
||||
|
||||
if ((create_attributes & aDIR) != 0)
|
||||
{
|
||||
search_attribs |= 0x8000;
|
||||
}
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 1); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, server->name_space[volume]);
|
||||
ncp_add_byte(server, open_create_mode);
|
||||
ncp_add_word(server, 0x8006);
|
||||
ncp_add_word(server, search_attribs);
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
ncp_add_dword(server, create_attributes);
|
||||
/* The desired acc rights seem to be the inherited rights mask
|
||||
@@ -431,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);
|
||||
}
|
||||
|
||||
@@ -473,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)
|
||||
{
|
||||
@@ -499,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 */
|
||||
@@ -534,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 */
|
||||
|
||||
|
||||
@@ -114,10 +114,16 @@ ncp_write(struct ncp_server *server, const char *file_id,
|
||||
const char *source, int *bytes_written);
|
||||
|
||||
int
|
||||
ncp_do_lookup(struct ncp_server *server,
|
||||
struct nw_info_struct *dir,
|
||||
char *path, /* may only be one component */
|
||||
struct nw_info_struct *target);
|
||||
ncp_obtain_info(struct ncp_server *server,
|
||||
__u8 vol_num, __u32 dir_base,
|
||||
char *path, /* At most 1 component */
|
||||
struct nw_info_struct *target);
|
||||
|
||||
int
|
||||
ncp_lookup_volume(struct ncp_server *server,
|
||||
char *volname,
|
||||
struct nw_info_struct *target);
|
||||
|
||||
|
||||
int
|
||||
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
|
||||
|
||||
@@ -222,6 +222,7 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
|
||||
int timeout;
|
||||
int retrans;
|
||||
int major_timeout_seen;
|
||||
int acknowledge_seen;
|
||||
int n;
|
||||
int addrlen;
|
||||
unsigned long old_mask;
|
||||
@@ -243,7 +244,8 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
|
||||
return -EBADF;
|
||||
}
|
||||
init_timeout = server->m.time_out;
|
||||
max_timeout = NCP_MAX_RPC_TIMEOUT*HZ/10;
|
||||
max_timeout = NCP_MAX_RPC_TIMEOUT;
|
||||
acknowledge_seen = 0;
|
||||
retrans = server->m.retry_count;
|
||||
major_timeout_seen = 0;
|
||||
old_mask = current->blocked;
|
||||
@@ -296,11 +298,14 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
|
||||
{
|
||||
if (timeout > max_timeout)
|
||||
{
|
||||
/* JEJB/JSP 2/7/94
|
||||
* This is useful to see if the system is
|
||||
* hanging */
|
||||
printk("NCP max timeout reached\n");
|
||||
timeout = max_timeout;
|
||||
/* JEJB/JSP 2/7/94
|
||||
* This is useful to see if the system is
|
||||
* hanging */
|
||||
if (acknowledge_seen == 0)
|
||||
{
|
||||
printk("NCP max timeout reached\n");
|
||||
}
|
||||
timeout = max_timeout;
|
||||
}
|
||||
current->timeout = jiffies + timeout;
|
||||
schedule();
|
||||
@@ -373,6 +378,9 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
|
||||
sock->ops->recvfrom(sock, (void *)&reply,
|
||||
sizeof(reply), 1, 0,
|
||||
NULL, &addrlen);
|
||||
n = 0;
|
||||
timeout = max_timeout;
|
||||
acknowledge_seen = 1;
|
||||
goto re_select;
|
||||
}
|
||||
|
||||
@@ -401,9 +409,8 @@ do_ncp_rpc_call(struct ncp_server *server, int size)
|
||||
* a null buffer yet. */
|
||||
sock->ops->recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0,
|
||||
NULL, &addrlen);
|
||||
#if 1
|
||||
printk("ncp_rpc_call: reply mismatch\n");
|
||||
#endif
|
||||
|
||||
DPRINTK("ncp_rpc_call: reply mismatch\n");
|
||||
goto re_select;
|
||||
}
|
||||
/*
|
||||
@@ -491,7 +498,7 @@ ncp_request(struct ncp_server *server, int function)
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
DPRINTK("ncp_completion_code: %d\n", result);
|
||||
DPRINTK("ncp_completion_code: %x\n", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
MAN1= slist nprint pqlist
|
||||
MAN1= slist nprint pqlist nsend pserver ncopy npasswd
|
||||
MAN1 += nwbols nwboprops nwbpvalues nwfsinfo nwuserlist
|
||||
MAN5= nwclient
|
||||
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net ipx_route
|
||||
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net \
|
||||
ipx_route nwmsg
|
||||
MAN8 += nwbocreate nwborm nwbpadd nwbpcreate nwbprm
|
||||
MAN8 += nwgrant nwrevoke
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ add [-p] device frame_type [network number]
|
||||
del device frame_type
|
||||
.LP
|
||||
.B ipx_interface
|
||||
delall
|
||||
.LP
|
||||
.B ipx_interface
|
||||
check device frame_type
|
||||
.LP
|
||||
.B ipx_interface
|
||||
@@ -45,6 +48,9 @@ network.
|
||||
.I del
|
||||
This option is used to delete an IPX interface.
|
||||
.TP
|
||||
.I delall
|
||||
This option is used to delete all IPX interfaces.
|
||||
.TP
|
||||
.I check
|
||||
This option is used to display the device, frame type, and network number
|
||||
of an IPX interface.
|
||||
|
||||
96
man/ncopy.1
Normal file
96
man/ncopy.1
Normal file
@@ -0,0 +1,96 @@
|
||||
.\"
|
||||
.\" Man page for the ncopy program
|
||||
.\"
|
||||
.TH NCOPY 1 17/03/1996 ncopy ncopy
|
||||
.SH NAME
|
||||
ncopy \- NetWare file copy
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B ncopy -V
|
||||
|
||||
.B ncopy
|
||||
[
|
||||
.B -vn
|
||||
]
|
||||
[
|
||||
.B -s
|
||||
.I amount
|
||||
]
|
||||
.B file destinationfile|directory
|
||||
|
||||
.B ncopy
|
||||
[
|
||||
.B -vn
|
||||
]
|
||||
[
|
||||
.B -s
|
||||
.I amount
|
||||
]
|
||||
.B file1
|
||||
[
|
||||
.B file2 ...
|
||||
]
|
||||
.B directory
|
||||
|
||||
.SH DESCRIPTION
|
||||
With
|
||||
.B ncopy
|
||||
you can copy files to different locations on a single NetWare file
|
||||
server without generating excess network traffic. The program uses
|
||||
a NetWare function to do the copy rather than transferring the file
|
||||
across the network for both the read and write.
|
||||
|
||||
If the last argument is a directory,
|
||||
.B ncopy
|
||||
will copy the source file(s) into the directory. If only two files
|
||||
are given and the last argument is not a directory, it will copy the
|
||||
source file to the destination file.
|
||||
|
||||
If the source and destination files are not on the same NetWare server
|
||||
(or are not on NetWare servers at all),
|
||||
.B ncopy
|
||||
will do a normal file copy.
|
||||
.SH OPTIONS
|
||||
.B -V
|
||||
.RS 3
|
||||
Show version number and exit
|
||||
.RE
|
||||
|
||||
.B -v
|
||||
.RS 3
|
||||
Verbose copy. Will show current file and percentage completion.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
Nice NetWare copy. Will sleep for a second between copying blocks on
|
||||
the NetWare server. Gives other people a chance to do some work on
|
||||
the NetWare server when you are copying large files. This has no
|
||||
effect if you are not copying on a NetWare server.
|
||||
.RE
|
||||
|
||||
.B -s
|
||||
.I amount
|
||||
.RS 3
|
||||
Nice time slice factor. Used in conjunction with the
|
||||
.B -n
|
||||
option, this specifies the number of 100K blocks to copy before sleeping.
|
||||
Default is 10. (1 Megabyte)
|
||||
.RE
|
||||
|
||||
.SH BUGS
|
||||
.B ncopy
|
||||
cannot recurse into directories.
|
||||
Does not work on NetWare volumes mounted with the
|
||||
.I -V
|
||||
option to
|
||||
.B ncpmount.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.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.
|
||||
190
man/ncpmount.8
190
man/ncpmount.8
@@ -1,27 +1,27 @@
|
||||
.TH NCPMOUNT 8 12/27/1995 ncpmount ncpmount
|
||||
.SH NAME
|
||||
ncpmount \- mount program for ncpfs
|
||||
ncpmount \- mount all volumes of a specified Novell fileserver.
|
||||
.SH SYNOPSIS
|
||||
.B ncpmount
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -h
|
||||
] [
|
||||
.B -n
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -c
|
||||
.I client name
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -u
|
||||
.I uid
|
||||
] [
|
||||
@@ -33,14 +33,26 @@ ncpmount \- mount program for ncpfs
|
||||
] [
|
||||
.B -d
|
||||
.I dir mode
|
||||
]
|
||||
] [
|
||||
.B -V
|
||||
.I volume
|
||||
] [
|
||||
.B -t
|
||||
.I time_out
|
||||
] [
|
||||
.B -r
|
||||
.I retry_count
|
||||
] [
|
||||
.B -v
|
||||
]
|
||||
mount-point
|
||||
|
||||
.SH DESCRIPTION
|
||||
This program is an interface to the NCP filesystem.
|
||||
This program is used to mount all volumes of the specified NetWare Fileserver
|
||||
under the specified mount point.
|
||||
|
||||
.B ncpfs
|
||||
is a filesystem which understands the NCP protocol. This is the
|
||||
is a linux filesystem which understands the NCP protocol. This is the
|
||||
protocol Novell NetWare clients use to talk to NetWare servers. ncpfs
|
||||
was inspired by
|
||||
.B lwared,
|
||||
@@ -48,18 +60,23 @@ a free NetWare emulator for Linux written by Ales Dryak. See
|
||||
ftp://klokan.sh.cvut.cz/pub/linux for this very intersting program.
|
||||
|
||||
.B ncpmount
|
||||
looks up the file
|
||||
when invoked with all appropriate arguments attaches, logs in and
|
||||
mounts all of the volumes associated with the specified fileserver that are
|
||||
readable by the user id under the specified mount point.
|
||||
.B ncpmount
|
||||
when invoked without any arguments specifying the fileserver, user id and
|
||||
password checks the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password. See
|
||||
nwclient(5) for more information. Please note that the access
|
||||
permissions of .nwclient MUST be 600, for security reasons.
|
||||
to find a file server, a user name and possibly a password to use for the
|
||||
specified mount point. See nwclient(5) for more information. Please note
|
||||
that the access permissions of .nwclient MUST be 600, for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
.B mount-point
|
||||
.RS 3
|
||||
.B mount-point
|
||||
is the directory you want to mount the filesystem over. It's the same
|
||||
as in the normal mount command.
|
||||
is the directory you want to mount the filesystem over. Its function is the
|
||||
the same as for a normal mount command.
|
||||
|
||||
If the real uid of the caller is not root,
|
||||
.B ncpmount
|
||||
@@ -87,42 +104,40 @@ is used to print out a short help text.
|
||||
|
||||
.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.
|
||||
By default passwords are converted to uppercase before they are sent
|
||||
to the server because most servers require this. This option disables this
|
||||
feature ensuring that passwords are sent without any case conversion.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given to mount shares which do not require a password to log in.
|
||||
must be specified for logins that do not have a password configured.
|
||||
.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.
|
||||
specifies the password to use for the Netware user id.
|
||||
|
||||
If neither
|
||||
.B -n
|
||||
nor
|
||||
nor the
|
||||
.B -P
|
||||
are given, ncpmount prompts for a password. This makes it difficult to
|
||||
use in scripts such as /etc/rc. But that's not ncpmount's fault, but a
|
||||
general problem with the fact that you need a password on every
|
||||
login. If anybody has a satisfying solution to this problem, please
|
||||
tell me.
|
||||
arguments are specified ncpmount will prompt for a password. This
|
||||
makes it difficult to use in scripts such as /etc/rc. If you want to
|
||||
have ncpmount work automatically from a script you must include the
|
||||
appropriate option and be very careful to ensure that appopriate file
|
||||
permissions are set for the script that includes your password to
|
||||
ensure that others can not read it.
|
||||
.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 you NetWare user name.
|
||||
Specifies the Netware user id to use when logging in to the fileserver. If
|
||||
this option is not specified then ncpmount will attempt to login to the
|
||||
fileserver using the Linux login id of the user invoking ncpmount.
|
||||
.RE
|
||||
|
||||
.B -u
|
||||
@@ -130,9 +145,9 @@ to tell the server about you NetWare user name.
|
||||
.B -g
|
||||
.I gid
|
||||
.RS 3
|
||||
Currently I did not implement a mapping from NetWare users/groups to
|
||||
unix users/groups. Unix requires that each file has an owner
|
||||
and a group it belongs to. With
|
||||
ncpmount does not yet implement a scheme for mapping NetWare users/groups
|
||||
to Linux users/groups. Linux requires that each file has an owner and group id.
|
||||
With
|
||||
.B -u
|
||||
and
|
||||
.B -g
|
||||
@@ -145,19 +160,20 @@ The defaults for these values are the current uid and gid.
|
||||
.B -c
|
||||
.I user name
|
||||
.RS 3
|
||||
This option is only makes sense if root mounts the directory. root can
|
||||
mount directories on behalf of other users.
|
||||
.B -c
|
||||
names the user who is the
|
||||
.I owner
|
||||
of the connection, where owner is not meant in the unix sense (that
|
||||
"owner" is set by -u), but as the one who has mounted the directory.
|
||||
This way it could be possible to mount a public read-only directory,
|
||||
of the connection, where owner does not refer to file ownership (that
|
||||
"owner" is set by the -u argument), but the owner of the mount, ie: who
|
||||
is allowed to call ncpumount on this mount. The default owner of the
|
||||
connection and the mount is the user who called ncpmount. This option
|
||||
allows you to specify that some other user should be set as the owner.
|
||||
|
||||
In this this way it is possible to mount a public read-only directory,
|
||||
but to allow the lp daemon to print on NetWare queues. This is
|
||||
possible, because only users who have write permissions on a directory
|
||||
may issue ncp requests over a connection. An exception is the owner
|
||||
(in the sense mentioned above), who is also given 'request
|
||||
permission'.
|
||||
possible because only users who have write permissions on a directory
|
||||
may issue ncp requests over a connection. The exception to this rule
|
||||
is the 'mount owner', who is also granted 'request permission'.
|
||||
.RE
|
||||
|
||||
.B -f
|
||||
@@ -169,14 +185,11 @@ Like
|
||||
.B -u
|
||||
and
|
||||
.B -g,
|
||||
these options are also used to cover deficiencies in the
|
||||
implementation of ncpfs. I did not implement a scheme to map NetWare
|
||||
permissions to unix permissions. So ncpmount has to be told which
|
||||
permissions it should assign to the mounted files and directories. The
|
||||
values have to be given as octal numbers. The default values are taken
|
||||
from the current umask, where the file mode is the current umask, and
|
||||
the dir mode adds execute permissions where the file mode gives read
|
||||
permissions.
|
||||
these options are used to determine what permissions should be assigned
|
||||
files and directories of the mounted volumes. The values must be specified
|
||||
as octal numbers. The default values are taken from the current umask, where
|
||||
the file mode is the current umask, and the dir mode adds execute permissions
|
||||
where the file mode gives read permissions.
|
||||
|
||||
Note that these permissions can differ from the rights the server
|
||||
gives to us. If you do not have write permissions on the server, you
|
||||
@@ -184,8 +197,75 @@ can very well choose a file mode that tells that you have. This
|
||||
certainly cannot override the restrictions imposed by the server.
|
||||
.RE
|
||||
|
||||
.B -V
|
||||
.I volume
|
||||
.RS 3
|
||||
There are 2 general ways you can mount a NetWare server's disk space:
|
||||
Either you can mount all volumes under one directory, or you can mount
|
||||
only a single volume.
|
||||
|
||||
When you choose to mount the complete disk space at once, you have the
|
||||
advantage that only one Linux mount point and only one
|
||||
NetWare connection is used for all the volumes of this server. Both of
|
||||
these are limited resources. (Although raising the number of Linux
|
||||
mount points is significantly cheaper than raising the number of
|
||||
available NetWare connections ;-))
|
||||
|
||||
When you specify to mount a single volume by using the option
|
||||
.B -V
|
||||
.I volume,
|
||||
you have the big advantage that nfsd is able to re-export this mounted
|
||||
directory. You must invoke
|
||||
.B nfsd
|
||||
and
|
||||
.B mountd
|
||||
with the option
|
||||
.I --re-export
|
||||
to make nfsd re-export ncpfs mounted directories. This uses one Linux
|
||||
mount point and one NetWare connection per mounted volume. Maybe
|
||||
sometime in the future I will make it possible to mount all volumes on
|
||||
different mount points, using only one connection.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I time_out
|
||||
.RS 3
|
||||
With
|
||||
.B -t
|
||||
you can adjust the time ncpfs waits for the server to answer a request
|
||||
it sent. Use the option to raise the timeout value when your ncpfs
|
||||
connections seem to be unstable although your servers are well
|
||||
up. This can happen when you have very busy servers, or servers that
|
||||
are very far away.
|
||||
|
||||
.I time_out
|
||||
is specified in 1/100s, the current default value is 60.
|
||||
.RE
|
||||
|
||||
.B -r
|
||||
.I retry_count
|
||||
.RS 3
|
||||
As
|
||||
.B -t, -r
|
||||
can be used to tune the ncpfs connection to the server. With
|
||||
retry_count you can specify how many times ncpfs will attempt to send
|
||||
a packet to the server before it decides the connection is dead. The
|
||||
current default value is 5.
|
||||
|
||||
Currently ncpfs is not too clever when trying to find out that
|
||||
connections are dead. If anybody knows how to do that correctly, as it
|
||||
is done by commercial workstations, please tell me.
|
||||
.RE
|
||||
|
||||
.B -v
|
||||
.RS 3
|
||||
Print ncpfs version number
|
||||
.RE
|
||||
|
||||
.SH NOTES
|
||||
If you have difficulties in mounting, please make sure that you have configured your ipx subsystem correctly. It is especially important that there is a route to the internal network of your server.
|
||||
You must configure the IPX subsystem before ncpmount will work.
|
||||
It is especially important that there is a route to the internal network
|
||||
of your server.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
.B USER / LOGNAME
|
||||
@@ -201,7 +281,7 @@ Most diagnostics issued by ncpfs are logged by syslogd. Normally
|
||||
nothing is printed, only error situations are logged there.
|
||||
|
||||
.SH SEE ALSO
|
||||
.B syslogd(8), ncpumount(8)
|
||||
.B syslogd(8), ncpumount(8), nfsd(8), mountd(8)
|
||||
|
||||
.SH CREDITS
|
||||
ncpfs would not have been possible without lwared, written by Ales
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
.TH NCPUMOUNT 8 12/27/1995 ncpumount ncpumount
|
||||
.SH NAME
|
||||
ncpumount \- umount for normal users
|
||||
ncpumount \- unmount a NetWare filesystem mounted with ncpmount.
|
||||
.SH SYNOPSIS
|
||||
.B ncpumount
|
||||
.B mount-point
|
||||
|
||||
.SH DESCRIPTION
|
||||
With this program, normal users can unmount ncp-filesystems, provided
|
||||
that it is suid root.
|
||||
This utility unmounts a NetWare filesystem that was previously mounted
|
||||
with the ncpmount utility. If the this utility is made suid root then
|
||||
non-root users will also be able to make use of it.
|
||||
|
||||
.B ncpumount
|
||||
has been written to give normal linux-users more control over their
|
||||
|
||||
55
man/npasswd.1
Normal file
55
man/npasswd.1
Normal file
@@ -0,0 +1,55 @@
|
||||
.TH NPASSWD 1 06/22/1996 npasswd npasswd
|
||||
.SH NAME
|
||||
npasswd \- Change a user's password
|
||||
.SH SYNOPSIS
|
||||
.B npasswd
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
]
|
||||
.B -t
|
||||
.I object type
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
With
|
||||
.B npasswd,
|
||||
you can change your password on a NetWare server.
|
||||
.B npasswd
|
||||
asks for the old password and twice for the new password. Then it
|
||||
changes the password on the server.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
With -h npasswd prints a little help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
is the name of the server you want to use.
|
||||
.RE
|
||||
|
||||
.B -U
|
||||
.I user name
|
||||
.RS 3
|
||||
is the name of the bindery object whose password is to be changed.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
is the bindery object type of the object whose password is to be
|
||||
changed.
|
||||
.RE
|
||||
|
||||
.SH CREDITS
|
||||
npasswd would not have been possible without the work of Guntram
|
||||
Blom. Look at nwcrypt.c for his work.
|
||||
42
man/nprint.1
42
man/nprint.1
@@ -9,18 +9,16 @@ nprint \- NetWare print client
|
||||
] [
|
||||
.B -h
|
||||
] [
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
] [
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -q
|
||||
.I queue name
|
||||
] [
|
||||
@@ -65,6 +63,13 @@ you can print files on print queues of a NetWare file server.
|
||||
There are a lot of options, so you should probably wrap some default
|
||||
configurations into some shell scripts.
|
||||
|
||||
.B nprint
|
||||
looks up the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password. See
|
||||
nwclient(5) for more information. Please note that the access
|
||||
permissions of .nwclient MUST be 600, for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
.B file
|
||||
.RS 3
|
||||
@@ -73,6 +78,12 @@ is the name of the file you want to print. If file is '-', or no
|
||||
filename is given, standard input is used.
|
||||
.RE
|
||||
|
||||
.B -h
|
||||
.RS 3
|
||||
.B -h
|
||||
is used to print out a short help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
@@ -105,12 +116,20 @@ prompts for a password.
|
||||
should be given if no password is required for the print request.
|
||||
.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 -q
|
||||
.I queue name
|
||||
.RS 3
|
||||
.B queue name
|
||||
is the name of the print queue to use at the print server. At
|
||||
present, you must give it in upper case characters.
|
||||
present, you must specify it in upper case characters.
|
||||
.RE
|
||||
|
||||
.B -d
|
||||
@@ -161,6 +180,13 @@ is the number of lines to put on one page. Default: 66
|
||||
is the number of rows to put on one page. Default: 80
|
||||
.RE
|
||||
|
||||
.B -c
|
||||
.I copies
|
||||
.RS 3
|
||||
.B copies
|
||||
tells the print server to the specified number of copies. Default: 1
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I tabs
|
||||
.RS 3
|
||||
@@ -189,4 +215,8 @@ different from the one currently in the printer, your job is only
|
||||
printed if a printer operator has put in the correct form.
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
nprint was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
|
||||
108
man/nsend.1
Normal file
108
man/nsend.1
Normal file
@@ -0,0 +1,108 @@
|
||||
.TH NSEND 1 03/21/1996 nsend nsend
|
||||
.SH NAME
|
||||
nsend \- Send messages to users
|
||||
.SH SYNOPSIS
|
||||
.B nsend
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
]
|
||||
.I user message
|
||||
|
||||
.SH DESCRIPTION
|
||||
With
|
||||
.B nsend,
|
||||
you can send messages to the user's workstations.
|
||||
|
||||
.B nsend
|
||||
looks up the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password. See
|
||||
nwclient(5) for more information. Please note that the access
|
||||
permissions of .nwclient MUST be 600, for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.B user
|
||||
.RS 3
|
||||
.B user
|
||||
is the NetWare User-ID of the user to receive the message.
|
||||
.RE
|
||||
|
||||
.B message
|
||||
.RS 3
|
||||
.B message
|
||||
is the message to be sent. Please note that this has to be a single
|
||||
command line argument. If you want to send a message that contains
|
||||
spaces, you have to quote them on the command line. For example, to
|
||||
annoy your system administrator, you should try
|
||||
|
||||
nsend supervisor 'I know how this works!'
|
||||
.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 you 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.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given to mount shares which do not require a password to log in.
|
||||
|
||||
If neither
|
||||
.B -n
|
||||
nor
|
||||
.B -P
|
||||
are given, nsend prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.SH BUGS
|
||||
nsend only supports servers with up to 255 connections. I do not know
|
||||
the NCP functions for larger servers. If anybody knows them, please
|
||||
tell me!
|
||||
|
||||
.SH SEE ALSO
|
||||
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
nsend was written by looking at mars_nwe's message handling. Thanks to
|
||||
Martin Stover <mstover@freeway.de>
|
||||
133
man/nwbocreate.8
Normal file
133
man/nwbocreate.8
Normal file
@@ -0,0 +1,133 @@
|
||||
.TH NWBOCREATE 8 7/9/1996 nwbocreate nwbocreate
|
||||
.SH NAME
|
||||
nwbocreate \- Create a NetWare Bindery Object
|
||||
.SH SYNOPSIS
|
||||
.B nwbocreate
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -r
|
||||
.I read-flag
|
||||
] [
|
||||
.B -w
|
||||
.I write-flag
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbocreate
|
||||
creates the specified NetWare Bindery Object.
|
||||
|
||||
.B nwbocreate
|
||||
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, nwbocreate
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be created.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -r
|
||||
.I read-flag
|
||||
|
||||
.B -w
|
||||
.I write-flag
|
||||
.RS 3
|
||||
|
||||
Read security and write security may each have one of the following values:
|
||||
|
||||
ANYONE: Anyone may access the object
|
||||
LOGGED: Anyone who is logged in may access the
|
||||
object
|
||||
OBJECT: Anyone who is logged in as the object or
|
||||
SUPERVISOR equivalent may access the
|
||||
object
|
||||
SUPERVISOR: Anyone who is logged in as SUPERVISOR
|
||||
equivalent may access the object
|
||||
NETWARE: Only the Bindery may access the object
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbocreate was written by Volker Lendecke with the corresponding
|
||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||
contributors.
|
||||
117
man/nwbols.1
Normal file
117
man/nwbols.1
Normal file
@@ -0,0 +1,117 @@
|
||||
.TH NWBOLS 1 7/9/1996 nwbols nwbols
|
||||
.SH NAME
|
||||
nwbols \- List NetWare Bindery Objects
|
||||
.SH SYNOPSIS
|
||||
.B nwbols
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -v
|
||||
] [
|
||||
.B pattern
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbols
|
||||
lists the specified NetWare Bindery Objects visible for the user.
|
||||
|
||||
.B nwbols
|
||||
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, nwbols
|
||||
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 -t
|
||||
.I type
|
||||
.RS 3
|
||||
You can restrict the objects listed by specifying the type of the
|
||||
objects to be listed.
|
||||
.I type
|
||||
must be given as a decimal number.
|
||||
.RE
|
||||
|
||||
.B pattern
|
||||
.RS 3
|
||||
Specifying a pattern is another way to restrict the objects
|
||||
listed. Please note that this pattern is evaluated by the NetWare
|
||||
server. grep would be a better candidate for complex patterns.
|
||||
.RE
|
||||
|
||||
.B -v
|
||||
.RS 3
|
||||
By default, the object's name, its ID and its type are listed by
|
||||
.B nwbols.
|
||||
In the verbose mode, activated by
|
||||
.B -v,
|
||||
the object flags, its security byte and the properties flag is also
|
||||
listed.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbols was written by Volker Lendecke. See the Changes file of ncpfs
|
||||
for other contributors.
|
||||
118
man/nwboprops.1
Normal file
118
man/nwboprops.1
Normal file
@@ -0,0 +1,118 @@
|
||||
.TH NWBOPROPS 1 7/9/1996 nwboprops nwboprops
|
||||
.SH NAME
|
||||
nwboprops \- List properies of a NetWare Bindery Object
|
||||
.SH SYNOPSIS
|
||||
.B nwboprops
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -v
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwboprops
|
||||
lists all the properties of the specified NetWare Bindery Objects.
|
||||
|
||||
.B nwboprops
|
||||
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, nwboprops
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be inspected.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -v
|
||||
.RS 3
|
||||
By default, only the property name is listed. In verbose mode,
|
||||
activated by
|
||||
.B -v,
|
||||
the property flag, the property security byte and the value flag are
|
||||
also listed.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwboprops was written by Volker Lendecke with the corresponding
|
||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||
contributors.
|
||||
106
man/nwborm.8
Normal file
106
man/nwborm.8
Normal file
@@ -0,0 +1,106 @@
|
||||
.TH NWBORM 8 7/9/1996 nwborm nwborm
|
||||
.SH NAME
|
||||
nwborm \- Remove a NetWare Bindery Object
|
||||
.SH SYNOPSIS
|
||||
.B nwborm
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwborm
|
||||
removes the specified NetWare Bindery Objects.
|
||||
|
||||
.B nwborm
|
||||
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, nwborm
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be deleted.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwborm was written by Volker Lendecke with the corresponding Caldera
|
||||
utility in mind. See the Changes file of ncpfs for other contributors.
|
||||
145
man/nwbpadd.8
Normal file
145
man/nwbpadd.8
Normal file
@@ -0,0 +1,145 @@
|
||||
.TH NWBPADD 8 7/9/1996 nwbpadd nwbpadd
|
||||
.SH NAME
|
||||
nwbpadd \- Set the value of a NetWare Bindery Property
|
||||
.SH SYNOPSIS
|
||||
.B nwbpadd
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -p
|
||||
.I property
|
||||
]
|
||||
.B value
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbpadd
|
||||
sets the value of a ITEM type property, and adds bindery objects to a
|
||||
SET type property.
|
||||
|
||||
.B nwbpadd
|
||||
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, nwbpadd
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be touched.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -p
|
||||
.I property
|
||||
.RS 3
|
||||
The name of the property to be set.
|
||||
.RE
|
||||
|
||||
.B value
|
||||
.RS 3
|
||||
If property is of type SET, value is an object id in hexadecimal
|
||||
notation. Otherwise, value is either a string value to be written, or
|
||||
a count of bytes to be written. The latter is assumed if more than one
|
||||
value argument is given. The count is decimal, and the following
|
||||
arguments are interpreted as bytes in hexadecimal notation.
|
||||
|
||||
Examples:
|
||||
|
||||
All these examples assume the existence of the file
|
||||
$HOME/.nwclient. Otherwise, the server and user would have to be
|
||||
specified.
|
||||
|
||||
nwbpadd -o linus -t 1 -p groups_i\\'m_in os_hackers
|
||||
|
||||
In this example, user linus is added to the group os_hackers. Please
|
||||
note that the ' has to be quoted.
|
||||
|
||||
nwbpadd -o linus -t 1 -p identification "Linus Torvalds"
|
||||
|
||||
User linus is given his real name :-).
|
||||
|
||||
nwbpadd -o linus -t 1 -p revision -v 04 00 00 01 0b
|
||||
|
||||
A new 4-byte binary value 0x0000010b (hi-lo order, no byte-swapping) is added
|
||||
to the "REVISION" property of the user "linus".
|
||||
|
||||
.SH AUTHORS
|
||||
nwbpadd was written by Volker Lendecke with the corresponding Caldera
|
||||
utility in mind. See the Changes file of ncpfs for other contributors.
|
||||
154
man/nwbpcreate.8
Normal file
154
man/nwbpcreate.8
Normal file
@@ -0,0 +1,154 @@
|
||||
.TH NWBPCREATE 8 7/9/1996 nwbpcreate nwbpcreate
|
||||
.SH NAME
|
||||
nwbpcreate \- Create a NetWare Bindery Propery
|
||||
.SH SYNOPSIS
|
||||
.B nwbpcreate
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -p
|
||||
.I property
|
||||
] [
|
||||
.B -s
|
||||
] [
|
||||
.B -r
|
||||
.I read-flag
|
||||
] [
|
||||
.B -w
|
||||
.I write-flag
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbpcreate
|
||||
creates the specified NetWare Bindery Propery.
|
||||
|
||||
.B nwbpcreate
|
||||
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, nwbpcreate
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be touched.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -p
|
||||
.I property
|
||||
.RS 3
|
||||
The name of the property to be created.
|
||||
.RE
|
||||
|
||||
.B -s
|
||||
.RS 3
|
||||
By default,
|
||||
.B nwbpcreate
|
||||
creates properties of type ITEM. If you want to create a property of
|
||||
type SET, such as groups_i\\'m_in, you must use the
|
||||
.B -s
|
||||
option.
|
||||
.RE
|
||||
|
||||
.B -r
|
||||
.I read-flag
|
||||
|
||||
.B -w
|
||||
.I write-flag
|
||||
.RS 3
|
||||
|
||||
Read security and write security may each have one of the following values:
|
||||
|
||||
ANYONE: Anyone may access the property
|
||||
LOGGED: Anyone who is logged in may access the
|
||||
property
|
||||
OBJECT: Anyone who is logged in as the object or
|
||||
SUPERVISOR equivalent may access the
|
||||
property
|
||||
SUPERVISOR: Anyone who is logged in as SUPERVISOR
|
||||
equivalent may access the property
|
||||
NETWARE: Only the Bindery may access the property
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbpcreate was written by Volker Lendecke with the corresponding
|
||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||
contributors.
|
||||
116
man/nwbprm.8
Normal file
116
man/nwbprm.8
Normal file
@@ -0,0 +1,116 @@
|
||||
.TH NWBPRM 8 7/9/1996 nwbprm nwbprm
|
||||
.SH NAME
|
||||
nwbprm \- Remove a NetWare Bindery Propery
|
||||
.SH SYNOPSIS
|
||||
.B nwbprm
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -p
|
||||
.I property
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbprm
|
||||
removes the specified NetWare Bindery Propery.
|
||||
|
||||
.B nwbprm
|
||||
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, nwbprm
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be touched.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -p
|
||||
.I property
|
||||
.RS 3
|
||||
The name of the property to be removed.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbprm was written by Volker Lendecke with the corresponding
|
||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||
contributors.
|
||||
128
man/nwbpvalues.1
Normal file
128
man/nwbpvalues.1
Normal file
@@ -0,0 +1,128 @@
|
||||
.TH NWBPVALUES 8 7/9/1996 nwbpvalues nwbpvalues
|
||||
.SH NAME
|
||||
nwbpvalues \- Print a NetWare Bindery Propery's contents
|
||||
.SH SYNOPSIS
|
||||
.B nwbpvalues
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -p
|
||||
.I property
|
||||
] [
|
||||
.B -v
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwbpvalues
|
||||
prints the contents of a SET property.
|
||||
|
||||
.B nwbpvalues
|
||||
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, nwbpvalues
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be looked up.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -p
|
||||
.I property
|
||||
.RS 3
|
||||
The name of the property to be printed.
|
||||
.RE
|
||||
|
||||
.B -v
|
||||
.RS 3
|
||||
By default, the object's name, its ID and its type are listed by
|
||||
.B nwbols.
|
||||
In the verbose mode, activated by
|
||||
.B -v,
|
||||
the object flags, its security byte and the properties flag is also
|
||||
listed.
|
||||
.RE
|
||||
|
||||
.SH AUTHORS
|
||||
nwbpvalues was written by Volker Lendecke with the corresponding
|
||||
Caldera utility in mind. See the Changes file of ncpfs for other
|
||||
contributors.
|
||||
@@ -13,8 +13,8 @@ connection. Lines beginning with # and empty lines are ignored as
|
||||
comments.
|
||||
|
||||
Because you can store passwords in .nwclient, the user programs will
|
||||
only scan .nwclient if ONLY the file owner has any access rights to
|
||||
the file.
|
||||
only scan .nwclient when only the file owner has access rights to
|
||||
the file. The file must be have permissions 0600.
|
||||
|
||||
To specify a NWClient connection, the name of the file server, the
|
||||
user name to be used and a password is necessary. The server name and
|
||||
@@ -40,3 +40,16 @@ 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.
|
||||
|
||||
.B nprint
|
||||
,
|
||||
.B pqlist
|
||||
and other user programs that require a valid login also look up
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password.
|
||||
|
||||
Please note that the access permissions of .nwclient MUST be 600, for
|
||||
security reasons.
|
||||
|
||||
.SH SEE ALSO
|
||||
.B ncpmount(8), ncpumount(8), slist(1), pqlist(1), nprint(1)
|
||||
|
||||
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
|
||||
148
man/nwgrant.8
Normal file
148
man/nwgrant.8
Normal file
@@ -0,0 +1,148 @@
|
||||
.TH NWGRANT 8 7/9/1996 nwgrant nwgrant
|
||||
.SH NAME
|
||||
nwgrant \- Add Trustee Rights to a directory
|
||||
.SH SYNOPSIS
|
||||
.B nwgrant
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -r
|
||||
.I rights
|
||||
]
|
||||
.B directory
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwgrant
|
||||
adds the specified bindery object with the corresponding trustee
|
||||
rights to the directory.
|
||||
|
||||
.B nwgrant
|
||||
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, nwgrant
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be added as trustee.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B -r
|
||||
.I rights
|
||||
.RS 3
|
||||
You must tell
|
||||
.B nwgrant
|
||||
which rights it should grant to the bindery object.
|
||||
The new rights for the object is specified by
|
||||
.I rights,
|
||||
which is the sum of the following hexadecimal individual rights values:
|
||||
|
||||
00 = no access
|
||||
01 = read access
|
||||
02 = write access
|
||||
04 = open access
|
||||
08 = create access
|
||||
10 = delete access
|
||||
20 = ownership access
|
||||
40 = search access
|
||||
80 = modify access
|
||||
|
||||
for a possible total of "ff" for all rights.
|
||||
.RE
|
||||
|
||||
.B directory
|
||||
.RS 3
|
||||
You must specify the directory to which to add the object as
|
||||
trustee. This has to be done in fully qualified NetWare notation.
|
||||
|
||||
Example:
|
||||
|
||||
nwgrant -o linus -t 1 -r ff 'data:home\\linus'
|
||||
|
||||
With this example, user linus is given all rights to his home
|
||||
directory on the data volume. This example assumes the existence of
|
||||
the file $HOME/.nwclient.
|
||||
|
||||
.SH AUTHORS
|
||||
nwgrant was written by Volker Lendecke with the corresponding NetWare
|
||||
utility in mind. See the Changes file of ncpfs for other contributors.
|
||||
|
||||
33
man/nwmsg.8
Normal file
33
man/nwmsg.8
Normal file
@@ -0,0 +1,33 @@
|
||||
.TH NWMSG 8 02/29/1996 nwmsg nwmsg
|
||||
.SH NAME
|
||||
nwmsg \- Deliver NetWare user broadcast messages
|
||||
.SH SYNOPSIS
|
||||
.B nwmsg
|
||||
.I mount-point
|
||||
.SH DESCRIPTION
|
||||
.B nwmsg
|
||||
is called by kerneld when a broadcast message arrives from a NetWare
|
||||
server.
|
||||
.B nwmsg
|
||||
fetches this message via the mount point and delivers it to
|
||||
the user using the same way write(1) uses.
|
||||
|
||||
Please note that
|
||||
.I kerneld
|
||||
must run when broadcast messages should be delivered to users.
|
||||
|
||||
NetWare servers can send asynchronous broadcast messages to users,
|
||||
either on explicit request by another user, or when the server is
|
||||
shutdown. The client workstation is informed about this event by an
|
||||
IPX packet on a special socket, the message socket.
|
||||
|
||||
This can happen at any time, so the user has to be informed about this
|
||||
event whenever it appears. I chose to use the kerneld feature of the
|
||||
Linux kernel to call the program nwmsg. For nwmsg, I used the relevant
|
||||
parts of the
|
||||
.I write
|
||||
program, so you can expect the NetWare broadcast
|
||||
messages to appear where user messages would appear.
|
||||
|
||||
.SH SEE ALSO
|
||||
ncpmount(8), kerneld(8), write(1)
|
||||
124
man/nwrevoke.8
Normal file
124
man/nwrevoke.8
Normal file
@@ -0,0 +1,124 @@
|
||||
.TH NWREVOKE 8 7/9/1996 nwrevoke nwrevoke
|
||||
.SH NAME
|
||||
nwrevoke \- Revoke a Trustee Right from a directory
|
||||
.SH SYNOPSIS
|
||||
.B nwrevoke
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -o
|
||||
.I object name
|
||||
] [
|
||||
.B -t
|
||||
.I type
|
||||
] [
|
||||
.B -r
|
||||
.I rights
|
||||
]
|
||||
.B directory
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B nwrevoke
|
||||
revokes the specified bindery object with the corresponding trustee
|
||||
rights from the directory.
|
||||
|
||||
.B nwrevoke
|
||||
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, nwrevoke
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if no password is required for the login.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -o
|
||||
.I object name
|
||||
.RS 3
|
||||
The name of the object to be added as trustee.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I object type
|
||||
.RS 3
|
||||
The type of the object.
|
||||
.I Object type
|
||||
must be specified as a decimal value. Common values are 1 for user
|
||||
objects, 2 for group objects and 3 for print queues. Other values are
|
||||
allowed, but are usually used for specialized applications.
|
||||
.RE
|
||||
|
||||
.B directory
|
||||
.RS 3
|
||||
You must specify the directory from which to remove the object as
|
||||
trustee. This has to be done in fully qualified NetWare notation.
|
||||
|
||||
Example:
|
||||
|
||||
nwrevoke -o linus -t 1 'src:bsd_src'
|
||||
|
||||
With this example, user linus is removed as trustee from the bsd_src
|
||||
directory on the src volume.
|
||||
|
||||
.SH AUTHORS
|
||||
nwrevoke was written by Volker Lendecke with the corresponding NetWare
|
||||
utility in mind. See the Changes file of ncpfs for other contributors.
|
||||
|
||||
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.
|
||||
86
man/pqlist.1
86
man/pqlist.1
@@ -4,25 +4,40 @@ pqlist \- List available NetWare print queues
|
||||
.SH SYNOPSIS
|
||||
.B pqlist
|
||||
[
|
||||
.B -h
|
||||
] [
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -n
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.I pattern
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
With
|
||||
.B pqlist,
|
||||
you can list the NetWare print queues available to you on some
|
||||
server. If you are already connected to some server, this one is
|
||||
used.
|
||||
.B pqlist
|
||||
lists all the NetWare print queues available to you on some server.
|
||||
If you are already connected to some server, this one is used.
|
||||
|
||||
If pqlist does not print to a tty, the decorative header line is
|
||||
not printed, so that you can count the printing queue available
|
||||
on your server by doing
|
||||
|
||||
pqlist -S server | wc -l
|
||||
|
||||
.B pqlist
|
||||
looks up the file
|
||||
.I $HOME/.nwclient
|
||||
to find a file server, a user name and possibly a password. See
|
||||
nwclient(5) for more information. Please note that the access
|
||||
permissions of .nwclient MUST be 600, for security reasons.
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
@@ -34,6 +49,57 @@ pattern, but you have to be careful to prevent shell interpretation of
|
||||
wildcards like '*'.
|
||||
.RE
|
||||
|
||||
See ncpmount(8) for an explanation of the other options. They are
|
||||
necessary because you might have to login into a server before it
|
||||
tells you where you may print.
|
||||
.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 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 you 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.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given to mount shares which do not require a password to log in.
|
||||
|
||||
If neither
|
||||
.B -n
|
||||
nor
|
||||
.B -P
|
||||
are given, pqlist prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
pqlist was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
|
||||
142
man/pserver.1
Normal file
142
man/pserver.1
Normal file
@@ -0,0 +1,142 @@
|
||||
.TH PSERVER 1 02/10/1996 pserver pserver
|
||||
.SH NAME
|
||||
pserver \- NetWare print server
|
||||
.SH SYNOPSIS
|
||||
.B pserver
|
||||
[
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -h
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -q
|
||||
.I queue name
|
||||
] [
|
||||
.B -c
|
||||
.I command
|
||||
] [
|
||||
.B -j
|
||||
.I job type
|
||||
] [
|
||||
.B -t
|
||||
.I timeout
|
||||
] [
|
||||
.B -d
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B pserver
|
||||
is a program that connects to print queues on NetWare servers and
|
||||
feeds incoming print jobs to the Linux printing system.
|
||||
|
||||
.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 print server name at the server.
|
||||
.RE
|
||||
|
||||
.B -P
|
||||
.I password
|
||||
.RS 3
|
||||
.B password
|
||||
is the password to use for the print server at the server. If neither
|
||||
.B -n
|
||||
nor
|
||||
.B -P
|
||||
are given, and the user has no open connection to the server, pserver
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if the print server does not require a password.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -q
|
||||
.I queue name
|
||||
.RS 3
|
||||
.B queue name
|
||||
is the name of the print queue you want to service.
|
||||
.RE
|
||||
|
||||
.B -c
|
||||
.I command
|
||||
.RS 3
|
||||
When a job is received from the print queue, pserver forks off a new
|
||||
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'.
|
||||
.RE
|
||||
|
||||
.B -j
|
||||
.I job type
|
||||
.RS 3
|
||||
Each job in a NetWare print queue has a job type. For print jobs, this
|
||||
corresponds to the number of the form the job should be printed
|
||||
on. You can tell pserver that it should only receive jobs for one
|
||||
specific form from the queue. The default is -1, which means that
|
||||
everything is received.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I timeout
|
||||
.RS 3
|
||||
Pserver is not informed by NetWare servers when new jobs arrive. So a
|
||||
polling scheme has to be used. When there are no jobs to service,
|
||||
.I timeout
|
||||
tells pserver how long to wait between two requests. The default is 30
|
||||
seconds. When a job is finished, pserver asks the NetWare server
|
||||
immediately for a new job, and does not wait
|
||||
.I timeout
|
||||
seconds.
|
||||
.RE
|
||||
|
||||
.B -d
|
||||
.RS 3
|
||||
Normally, pserver daemonizes itself.
|
||||
.B -d
|
||||
tells it not to do so. This is useful if you want to see the
|
||||
diagnostic messages that are printed when a error occurs.
|
||||
.RE
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
pserver was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
25
man/slist.1
25
man/slist.1
@@ -1,16 +1,16 @@
|
||||
.TH SLIST 1 01/07/1996 slist slist
|
||||
.SH NAME
|
||||
slist \- List available NetWare Servers
|
||||
slist \- Lists available NetWare Servers
|
||||
.SH SYNOPSIS
|
||||
.B slist
|
||||
[
|
||||
.I pattern
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
With
|
||||
.B slist,
|
||||
you can get a list of NetWare Servers available in your network. If
|
||||
slist does not print to a tty, the decorative header line is not
|
||||
.B slist
|
||||
lists all NetWare Servers available in your network.
|
||||
|
||||
If slist does not print to a tty, the decorative header line is not
|
||||
printed, so that you can count the servers on your network by doing
|
||||
|
||||
slist | wc -l
|
||||
@@ -20,10 +20,10 @@ slist | wc -l
|
||||
.B pattern
|
||||
.RS 3
|
||||
.B pattern
|
||||
is used to list only selected servers. For a server to be listed, the
|
||||
pattern must match the full server name. You can use wildcards for the
|
||||
pattern, but you must protect these wildcards from any command line
|
||||
expansion by quoting. Case doesn't matter.
|
||||
is used to list only servers whose names match the specified pattern. For a
|
||||
server to be listed, the pattern must match the full server name. You can use
|
||||
wildcards for the pattern, but you must protect these wildcards from any
|
||||
command line expansion by quoting. Case doesn't matter.
|
||||
.RE
|
||||
|
||||
.SH EXAMPLE
|
||||
@@ -34,3 +34,10 @@ or
|
||||
.TP
|
||||
slist "i*"
|
||||
List all available Netware servers on your Network, that begin with an "I".
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
.B ncpmount(8), ncpumount(8), pqlist(1), nprint(1)
|
||||
|
||||
.SH CREDITS
|
||||
slist was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
Begin3
|
||||
Title: ncpfs
|
||||
Version: 0.13
|
||||
Entered-date: 14. January 1996
|
||||
Description: With ncpfs you can mount volumes of your novell
|
||||
server under Linux. You need kernel 1.2.x or
|
||||
1.3.54 and above. ncpfs does NOT work with any 1.3.x
|
||||
kernel below 1.3.54.
|
||||
Keywords: filesystem kernel ncp novell netware
|
||||
Author: lendecke@namu01.gwdg.de (Volker Lendecke)
|
||||
Maintained-by: lendecke@namu01.gwdg.de (Volker Lendecke)
|
||||
Primary-site: linux01.gwdg.de:/pub/ncpfs
|
||||
Alternate-site: sunsite.unc.edu:/pub/system/Filesystems/
|
||||
~67k ncpfs-0.13.tgz
|
||||
~ 1k ncpfs-0.13.lsm
|
||||
Copying-policy: GPL
|
||||
End
|
||||
19
ncpfs-2.0.3.lsm
Normal file
19
ncpfs-2.0.3.lsm
Normal file
@@ -0,0 +1,19 @@
|
||||
Begin3
|
||||
Title: ncpfs
|
||||
Version: 2.0.3
|
||||
Entered-date: 22. July 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
|
||||
Linux printing system. You need kernel 1.2.x or
|
||||
1.3.71 and above. ncpfs does NOT work with any 1.3.x
|
||||
kernel below 1.3.71.
|
||||
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/Linux/system/Filesystems/ncpfs
|
||||
~128k ncpfs-2.0.3.tgz
|
||||
~ 1k ncpfs-2.0.3.lsm
|
||||
Copying-policy: GPL
|
||||
End
|
||||
@@ -2,39 +2,91 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
UTIL_EXECS = ncpmount ncpumount nprint slist pqlist
|
||||
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
|
||||
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy npasswd
|
||||
USERUTILS += nwbols nwbocreate nwborm nwboprops
|
||||
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd
|
||||
USERUTILS += nwgrant nwrevoke nwuserlist
|
||||
UIDUTILS = ncpmount ncpumount
|
||||
SBINUTILS = nwmsg
|
||||
|
||||
CFLAGS = -Wall $(INCLUDES) -O2 $(KERNELD)
|
||||
UTIL_EXECS = $(USERUTILS) $(UIDUTILS) $(SBINUTILS)
|
||||
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
|
||||
|
||||
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
CC = gcc
|
||||
|
||||
#CFLAGS += -g
|
||||
CFLAGS += -O2
|
||||
|
||||
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
|
||||
|
||||
default:
|
||||
make -C ..
|
||||
|
||||
all: $(UTILS) ncptest
|
||||
|
||||
install: all
|
||||
for i in $(UTIL_EXECS); \
|
||||
do install --strip $(INTERM_BINDIR)/$$i -m 755 $(BINDIR); done
|
||||
for i in $(UIDUTILS); do chmod 4755 $(BINDIR)/$$i; done
|
||||
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 $(SBINUTILS); \
|
||||
do install $(INTERM_BINDIR)/$$i -m 755 $(SBINDIR); done
|
||||
$(INSTALL_LIB)
|
||||
|
||||
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) ncplib.o
|
||||
$(CC) -s -o $@ $(addsuffix .o,$(notdir $@)) ncplib.o
|
||||
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) $(NCP_LIB)
|
||||
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) -L. -lncp
|
||||
|
||||
ncplib.o: ncplib.c ncplib.h
|
||||
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
|
||||
ncplib.o: ncplib.c ncplib.h ncplib_err.h
|
||||
$(CC) $(CFLAGS) $(PIC_FLAG) -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
|
||||
|
||||
$(NCP_LIB): ncplib.o ncplib_err.o $(COM_ERR_CFILES)
|
||||
make -C com_err
|
||||
$(LIB_LINK_COMMAND) 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
|
||||
ln -sf libncp.so.1.0 libncp.so.1
|
||||
|
||||
ncplib_err.o: ncplib_err.h ncplib_err.c
|
||||
$(CC) $(CFLAGS) $(PIC_FLAG) -c ncplib_err.c
|
||||
|
||||
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 ncplib.o
|
||||
$(CC) -o ncptest ncptest.o ncplib.o
|
||||
ncptest: ncptest.o $(NCP_LIB)
|
||||
$(CC) -o ncptest ncptest.o -L. -lncp
|
||||
|
||||
dep:
|
||||
dep: ncplib_err.h
|
||||
make -C com_err dep
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ slist test ncptest
|
||||
make -C com_err clean
|
||||
rm -f *.o *~ slist test ncptest ncplib_err.[ch] libncp.a
|
||||
rm -f libncp.so.*
|
||||
|
||||
realclean: clean
|
||||
mrproper: clean
|
||||
make -C com_err mrproper
|
||||
rm -f $(UTILS) .depend $(DISTFILE)
|
||||
|
||||
#
|
||||
|
||||
1
util/com_err.h
Symbolic link
1
util/com_err.h
Symbolic link
@@ -0,0 +1 @@
|
||||
com_err/com_err.h
|
||||
49
util/com_err/ChangeLog
Normal file
49
util/com_err/ChangeLog
Normal file
@@ -0,0 +1,49 @@
|
||||
Wed Jan 31 11:06:08 1996 <tytso@rsts-11.mit.edu>
|
||||
|
||||
* Release of E2fsprogs version 1.02
|
||||
|
||||
Mon Sep 4 21:44:47 1995 Remy Card <card@bbj>
|
||||
|
||||
* Makefile.in: Added support for BSD shared libraries.
|
||||
|
||||
Sat Aug 12 03:11:28 1995 Remy Card <card@bbj>
|
||||
|
||||
* Makefile.in (install): Install static libraries in $(ulibdir)
|
||||
(/usr/lib on Linux) instead of $(libdir) (/lib on Linux).
|
||||
|
||||
Sat Aug 5 11:44:17 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
|
||||
|
||||
* Makefile.in (DLL_INSTALL_DIR, ELF_INSTALL_DIR): Set the
|
||||
installation directories correctly.
|
||||
|
||||
Thu Jun 15 23:39:51 1995 Remy Card <card@bbj>
|
||||
|
||||
* Makefile.in: Added support for ELF shared libraries.
|
||||
Fixed typos in the compilation rules.
|
||||
(distclean): Added compile_et.sh.
|
||||
|
||||
Sat Jun 10 19:56:13 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
|
||||
|
||||
* compile_et.sh.in: Use ET_DIR instead of srcdir to determine the
|
||||
location of the et directory.
|
||||
|
||||
Thu Jun 8 12:45:41 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
|
||||
|
||||
* vfprintf.c (vfprintf): Only compile this function if vfprintf
|
||||
doesn't already exist and _doprnt does.
|
||||
|
||||
* compile_et.sh: Moved to compile_et.sh.in.
|
||||
|
||||
* Makefile.in: Rewritten to conform to GNU coding standards and
|
||||
support separate compilation directories.
|
||||
Don't preprocess compile_et.sh, as this is now done by configure.
|
||||
|
||||
Mon Nov 7 21:17:48 1994 Remy Card <card@bbj>
|
||||
|
||||
* Makefile: Added a dummy install target in case shared libraries
|
||||
are not built.
|
||||
|
||||
Thu Sep 8 22:33:33 1994 (tytso@rsx-11)
|
||||
|
||||
* com_err.c (default_com_err_proc): Reversed order of \n\r to make
|
||||
jik happy.
|
||||
25
util/com_err/Makefile
Normal file
25
util/com_err/Makefile
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Makefile for the com_err library
|
||||
#
|
||||
|
||||
OBJECTS = com_err.o error_message.o et_name.o init_et.o
|
||||
CFLAGS = -Wall -O2 $(PIC_FLAG)
|
||||
|
||||
all: $(OBJECTS)
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
|
||||
mrproper: clean
|
||||
rm -f .depend
|
||||
|
||||
#
|
||||
# include a dependency file if one exists
|
||||
#
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
|
||||
96
util/com_err/com_err.3
Normal file
96
util/com_err/com_err.3
Normal file
@@ -0,0 +1,96 @@
|
||||
.\" Copyright (c) 1988 Massachusetts Institute of Technology,
|
||||
.\" Student Information Processing Board. All rights reserved.
|
||||
.\"
|
||||
.\" $Header: /mit/krb5/.cvsroot/src/util/et/com_err.3,v 1.1 1993/06/03 12:29:34 tytso Exp $
|
||||
.\"
|
||||
.TH COM_ERR 3 "22 Nov 1988" SIPB
|
||||
.SH NAME
|
||||
com_err \- common error display routine
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <com_err.h>
|
||||
.PP
|
||||
void com_err (whoami, code, format, ...);
|
||||
const char *whoami;
|
||||
long code;
|
||||
const char *format;
|
||||
.PP
|
||||
proc = set_com_err_hook (proc);
|
||||
.fi
|
||||
void (*
|
||||
.I proc
|
||||
) (const char *, long, const char *, va_list);
|
||||
.nf
|
||||
.PP
|
||||
proc = reset_com_err_hook ();
|
||||
.PP
|
||||
void initialize_XXXX_error_table ();
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.I Com_err
|
||||
displays an error message on the standard error stream
|
||||
.I stderr
|
||||
(see
|
||||
.IR stdio (3S))
|
||||
composed of the
|
||||
.I whoami
|
||||
string, which should specify the program name or some subportion of
|
||||
a program, followed by an error message generated from the
|
||||
.I code
|
||||
value (derived from
|
||||
.IR compile_et (1)),
|
||||
and a string produced using the
|
||||
.I format
|
||||
string and any following arguments, in the same style as
|
||||
.IR fprintf (3).
|
||||
|
||||
The behavior of
|
||||
.I com_err
|
||||
can be modified using
|
||||
.I set_com_err_hook;
|
||||
this defines a procedure which is called with the arguments passed to
|
||||
.I com_err,
|
||||
instead of the default internal procedure which sends the formatted
|
||||
text to error output. Thus the error messages from a program can all
|
||||
easily be diverted to another form of diagnostic logging, such as
|
||||
.IR syslog (3).
|
||||
.I Reset_com_err_hook
|
||||
may be used to restore the behavior of
|
||||
.I com_err
|
||||
to its default form. Both procedures return the previous ``hook''
|
||||
value. These ``hook'' procedures must have the declaration given for
|
||||
.I proc
|
||||
above in the synopsis.
|
||||
|
||||
The
|
||||
.I initialize_XXXX_error_table
|
||||
routine is generated mechanically by
|
||||
.IR compile_et (1)
|
||||
from a source file containing names and associated strings. Each
|
||||
table has a name of up to four characters, which is used in place of
|
||||
the
|
||||
.B XXXX
|
||||
in the name of the routine. These routines should be called before
|
||||
any of the corresponding error codes are used, so that the
|
||||
.I com_err
|
||||
library will recognize error codes from these tables when they are
|
||||
used.
|
||||
|
||||
The
|
||||
.B com_err.h
|
||||
header file should be included in any source file that uses routines
|
||||
from the
|
||||
.I com_err
|
||||
library; executable files must be linked using
|
||||
.I ``-lcom_err''
|
||||
in order to cause the
|
||||
.I com_err
|
||||
library to be included.
|
||||
|
||||
.\" .IR for manual entries
|
||||
.\" .PP for paragraph breaks
|
||||
|
||||
.SH "SEE ALSO"
|
||||
compile_et (1), syslog (3).
|
||||
|
||||
Ken Raeburn, "A Common Error Description Library for UNIX".
|
||||
114
util/com_err/com_err.c
Normal file
114
util/com_err/com_err.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 1987, 1988 by MIT Student Information Processing Board.
|
||||
*
|
||||
* For copyright info, see mit-sipb-copyright.h.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "com_err.h"
|
||||
#include "mit-sipb-copyright.h"
|
||||
#include "error_table.h"
|
||||
#include "internal.h"
|
||||
|
||||
#if !defined(__STDC__) && !defined(STDARG_PROTOTYPES)
|
||||
#include <varargs.h>
|
||||
#define VARARGS
|
||||
#endif
|
||||
|
||||
static void
|
||||
#ifdef __STDC__
|
||||
default_com_err_proc (const char *whoami, errcode_t code, const
|
||||
char *fmt, va_list args)
|
||||
#else
|
||||
default_com_err_proc (whoami, code, fmt, args)
|
||||
const char *whoami;
|
||||
errcode_t code;
|
||||
const char *fmt;
|
||||
va_list args;
|
||||
#endif
|
||||
{
|
||||
if (whoami) {
|
||||
fputs(whoami, stderr);
|
||||
fputs(": ", stderr);
|
||||
}
|
||||
if (code) {
|
||||
fputs(error_message(code), stderr);
|
||||
fputs(" ", stderr);
|
||||
}
|
||||
if (fmt) {
|
||||
vfprintf (stderr, fmt, args);
|
||||
}
|
||||
/* should do this only on a tty in raw mode */
|
||||
putc('\r', stderr);
|
||||
putc('\n', stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
typedef void (*errf) (const char *, errcode_t, const char *, va_list);
|
||||
#else
|
||||
typedef void (*errf) ();
|
||||
#endif
|
||||
|
||||
errf com_err_hook = default_com_err_proc;
|
||||
|
||||
#ifdef __STDC__
|
||||
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
|
||||
va_list args)
|
||||
#else
|
||||
void com_err_va (whoami, code, fmt, args)
|
||||
const char *whoami;
|
||||
errcode_t code;
|
||||
const char *fmt;
|
||||
va_list args;
|
||||
#endif
|
||||
{
|
||||
(*com_err_hook) (whoami, code, fmt, args);
|
||||
}
|
||||
|
||||
#ifndef VARARGS
|
||||
void com_err (const char *whoami,
|
||||
errcode_t code,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
#else
|
||||
void com_err (va_alist)
|
||||
va_dcl
|
||||
{
|
||||
const char *whoami, *fmt;
|
||||
errcode_t code;
|
||||
#endif
|
||||
va_list pvar;
|
||||
|
||||
if (!com_err_hook)
|
||||
com_err_hook = default_com_err_proc;
|
||||
#ifdef VARARGS
|
||||
va_start (pvar);
|
||||
whoami = va_arg (pvar, const char *);
|
||||
code = va_arg (pvar, errcode_t);
|
||||
fmt = va_arg (pvar, const char *);
|
||||
#else
|
||||
va_start(pvar, fmt);
|
||||
#endif
|
||||
com_err_va (whoami, code, fmt, pvar);
|
||||
va_end(pvar);
|
||||
}
|
||||
|
||||
errf set_com_err_hook (new_proc)
|
||||
errf new_proc;
|
||||
{
|
||||
errf x = com_err_hook;
|
||||
|
||||
if (new_proc)
|
||||
com_err_hook = new_proc;
|
||||
else
|
||||
com_err_hook = default_com_err_proc;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
errf reset_com_err_hook () {
|
||||
errf x = com_err_hook;
|
||||
com_err_hook = default_com_err_proc;
|
||||
return x;
|
||||
}
|
||||
40
util/com_err/com_err.h
Normal file
40
util/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) */
|
||||
554
util/com_err/com_err.texinfo
Normal file
554
util/com_err/com_err.texinfo
Normal file
@@ -0,0 +1,554 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
|
||||
@c $Header: /mit/krb5/.cvsroot/src/util/et/com_err.texinfo,v 1.1 1993/06/03 12:29:38 tytso Exp $
|
||||
@c $Source: /mit/krb5/.cvsroot/src/util/et/com_err.texinfo,v $
|
||||
@c $Locker: $
|
||||
|
||||
@c Note that although this source file is in texinfo format (more
|
||||
@c or less), it is not yet suitable for turning into an ``info''
|
||||
@c file. Sorry, maybe next time.
|
||||
@c
|
||||
@c In order to produce hardcopy documentation from a texinfo file,
|
||||
@c run ``tex com_err.texinfo'' which will load in texinfo.tex,
|
||||
@c provided in this distribution. (texinfo.tex is from the Free
|
||||
@c Software Foundation, and is under different copyright restrictions
|
||||
@c from the rest of this package.)
|
||||
|
||||
@ifinfo
|
||||
@barfo
|
||||
@end ifinfo
|
||||
|
||||
@iftex
|
||||
@tolerance 10000
|
||||
|
||||
@c Mutate section headers...
|
||||
@begingroup
|
||||
@catcode#=6
|
||||
@gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}}
|
||||
@endgroup
|
||||
@end iftex
|
||||
|
||||
@setfilename com_err
|
||||
@settitle A Common Error Description Library for UNIX
|
||||
|
||||
@ifinfo
|
||||
This file documents the use of the Common Error Description library.
|
||||
|
||||
Copyright (C) 1987, 1988 Student Information Processing Board of the
|
||||
Massachusetts Institute of Technology.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted, provided
|
||||
that the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
|
||||
used in advertising or publicity pertaining to distribution of the software
|
||||
without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
|
||||
make no representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied warranty.
|
||||
|
||||
Note that the file texinfo.tex, provided with this distribution, is from
|
||||
the Free Software Foundation, and is under different copyright restrictions
|
||||
from the remainder of this package.
|
||||
|
||||
@end ifinfo
|
||||
|
||||
@ignore
|
||||
Permission is granted to process this file through Tex and print the
|
||||
results, provided the printed document carries copying permission
|
||||
notice identical to this one except for the removal of this paragraph
|
||||
(this paragraph not being relevant to the printed manual).
|
||||
|
||||
@end ignore
|
||||
|
||||
@setchapternewpage odd
|
||||
|
||||
@titlepage
|
||||
@center @titlefont{A Common Error Description}
|
||||
@center @titlefont{Library for UNIX}
|
||||
@sp 2
|
||||
@center Ken Raeburn
|
||||
@center Bill Sommerfeld
|
||||
@sp 1
|
||||
@center MIT Student Information Processing Board
|
||||
@sp 3
|
||||
@center last updated 1 January 1989
|
||||
@center for version 1.2
|
||||
@center ***DRAFT COPY ONLY***
|
||||
|
||||
@vskip 2in
|
||||
|
||||
@center @b{Abstract}
|
||||
|
||||
UNIX has always had a clean and simple system call interface, with a
|
||||
standard set of error codes passed between the kernel and user
|
||||
programs. Unfortunately, the same cannot be said of many of the
|
||||
libraries layered on top of the primitives provided by the kernel.
|
||||
Typically, each one has used a different style of indicating errors to
|
||||
their callers, leading to a total hodgepodge of error handling, and
|
||||
considerable amounts of work for the programmer. This paper describes
|
||||
a library and associated utilities which allows a more uniform way for
|
||||
libraries to return errors to their callers, and for programs to
|
||||
describe errors and exceptional conditions to their users.
|
||||
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
|
||||
Copyright @copyright{} 1987, 1988 by the Student Information Processing
|
||||
Board of the Massachusetts Institute of Technology.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted, provided
|
||||
that the above copyright notice appear in all copies and that both that
|
||||
copyright notice and this permission notice appear in supporting
|
||||
documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
|
||||
used in advertising or publicity pertaining to distribution of the software
|
||||
without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
|
||||
make no representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied warranty.
|
||||
|
||||
Note that the file texinfo.tex, provided with this distribution, is from
|
||||
the Free Software Foundation, and is under different copyright restrictions
|
||||
from the remainder of this package.
|
||||
|
||||
@end titlepage
|
||||
|
||||
@ifinfo
|
||||
@c should put a menu here someday....
|
||||
@end ifinfo
|
||||
|
||||
@page
|
||||
|
||||
@section Why com_err?
|
||||
|
||||
In building application software packages, a programmer often has to
|
||||
deal with a number of libraries, each of which can use a different
|
||||
error-reporting mechanism. Sometimes one of two values is returned,
|
||||
indicating simply SUCCESS or FAILURE, with no description of errors
|
||||
encountered. Sometimes it is an index into a table of text strings,
|
||||
where the name of the table used is dependent on the library being
|
||||
used when the error is generated; since each table starts numbering at
|
||||
0 or 1, additional information as to the source of the error code is
|
||||
needed to determine which table to look at. Sometimes no text messages are
|
||||
supplied at all, and the programmer must supply them at any point at which
|
||||
he may wish to report error conditions.
|
||||
Often, a global variable is assigned some value describing the error, but
|
||||
the programmer has to know in each case whether to look at @code{errno},
|
||||
@code{h_errno}, the return value from @code{hes_err()}, or whatever other
|
||||
variables or routines are specified.
|
||||
And what happens if something
|
||||
in the procedure of
|
||||
examining or reporting the error changes the same variable?
|
||||
|
||||
The package we have developed is an attempt to present a common
|
||||
error-handling mechanism to manipulate the most common form of error code
|
||||
in a fashion that does not have the problems listed above.
|
||||
|
||||
A list of up to 256 text messages is supplied to a translator we have
|
||||
written, along with the three- to four-character ``name'' of the error
|
||||
table. The library using this error table need only call a routine
|
||||
generated from this error-table source to make the table ``known'' to the
|
||||
com_err library, and any error code the library generates can be converted
|
||||
to the corresponding error message. There is also a default format for
|
||||
error codes accidentally returned before making the table known, which is
|
||||
of the form @samp{unknown code foo 32}, where @samp{foo} would be the name
|
||||
of the table.
|
||||
|
||||
@section Error codes
|
||||
|
||||
Error codes themselves are 32 bit (signed) integers, of which the high
|
||||
order 24 bits are an identifier of which error table the error code is
|
||||
from, and the low order 8 bits are a sequential error number within
|
||||
the table. An error code may thus be easily decomposed into its component
|
||||
parts. Only the lowest 32 bits of an error code are considered significant
|
||||
on systems which support wider values.
|
||||
|
||||
Error table 0 is defined to match the UNIX system call error table
|
||||
(@code{sys_errlist}); this allows @code{errno} values to be used directly
|
||||
in the library (assuming that @code{errno} is of a type with the same width
|
||||
as @t{long}). Other error table numbers are formed by compacting together
|
||||
the first four characters of the error table name. The mapping between
|
||||
characters in the name and numeric values in the error code are defined in
|
||||
a system-independent fashion, so that two systems that can pass integral
|
||||
values between them can reliably pass error codes without loss of meaning;
|
||||
this should work even if the character sets used are not the same.
|
||||
(However, if this is to be done, error table 0 should be avoided, since the
|
||||
local system call error tables may differ.)
|
||||
|
||||
Any variable which is to contain an error code should be declared @t{long}.
|
||||
The draft proposed American National Standard for C (as of May, 1988)
|
||||
requires that @t{long} variables be at least 32 bits; any system which does
|
||||
not support 32-bit @t{long} values cannot make use of this package (nor
|
||||
much other software that assumes an ANSI-C environment base) without
|
||||
significant effort.
|
||||
|
||||
@section Error table source file
|
||||
|
||||
The error table source file begins with the declaration of the table name,
|
||||
as
|
||||
|
||||
@example
|
||||
error_table @var{tablename}
|
||||
@end example
|
||||
|
||||
Individual error codes are
|
||||
specified with
|
||||
|
||||
@example
|
||||
error_code @var{ERROR_NAME}, @var{"text message"}
|
||||
@end example
|
||||
|
||||
where @samp{ec} can also be used as a short form of @samp{error_code}. To
|
||||
indicate the end of the table, use @samp{end}. Thus, a (short) sample
|
||||
error table might be:
|
||||
|
||||
@example
|
||||
|
||||
error_table dsc
|
||||
|
||||
error_code DSC_DUP_MTG_NAME,
|
||||
"Meeting already exists"
|
||||
|
||||
ec DSC_BAD_PATH,
|
||||
"A bad meeting pathname was given"
|
||||
|
||||
ec DSC_BAD_MODES,
|
||||
"Invalid mode for this access control list"
|
||||
|
||||
end
|
||||
|
||||
@end example
|
||||
|
||||
@section The error-table compiler
|
||||
|
||||
The error table compiler is named @code{compile_et}. It takes one
|
||||
argument, the pathname of a file (ending in @samp{.et}, e.g.,
|
||||
@samp{dsc_err.et}) containing an error table source file. It parses the
|
||||
error table, and generates two output files -- a C header file
|
||||
(@samp{discuss_err.h}) which contains definitions of the numerical values
|
||||
of the error codes defined in the error table, and a C source file which
|
||||
should be compiled and linked with the executable. The header file must be
|
||||
included in the source of a module which wishes to reference the error
|
||||
codes defined; the object module generated from the C code may be linked in
|
||||
to a program which wishes to use the printed forms of the error codes.
|
||||
|
||||
This translator accepts a @kbd{-language @var{lang}} argument, which
|
||||
determines for which language (or language variant) the output should be
|
||||
written. At the moment, @var{lang} is currently limited to @kbd{ANSI-C}
|
||||
and @kbd{K&R-C}, and some abbreviated forms of each. Eventually, this will
|
||||
be extended to include some support for C++. The default is currently
|
||||
@kbd{K&R-C}, though the generated sources will have ANSI-C code
|
||||
conditionalized on the symbol @t{__STDC__}.
|
||||
|
||||
@section Run-time support routines
|
||||
|
||||
Any source file which uses the routines supplied with or produced by the
|
||||
com_err package should include the header file @file{<com_err.h>}. It
|
||||
contains declarations and definitions which may be needed on some systems.
|
||||
(Some functions cannot be referenced properly without the return type
|
||||
declarations in this file. Some functions may work properly on most
|
||||
architectures even without the header file, but relying on this is not
|
||||
recommended.)
|
||||
|
||||
The run-time support routines and variables provided via this package
|
||||
include the following:
|
||||
|
||||
@example
|
||||
void initialize_@var{xxxx}_error_table (void);
|
||||
@end example
|
||||
|
||||
One of these routines is built by the error compiler for each error table.
|
||||
It makes the @var{xxxx} error table ``known'' to the error reporting
|
||||
system. By convention, this routine should be called in the initialization
|
||||
routine of the @var{xxxx} library. If the library has no initialization
|
||||
routine, some combination of routines which form the core of the library
|
||||
should ensure that this routine is called. It is not advised to leave it
|
||||
the caller to make this call.
|
||||
|
||||
There is no harm in calling this routine more than once.
|
||||
|
||||
@example
|
||||
#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
|
||||
@end example
|
||||
|
||||
This symbol contains the value of the first error code entry in the
|
||||
specified table.
|
||||
This rarely needs be used by the
|
||||
programmer.
|
||||
|
||||
@example
|
||||
const char *error_message (long code);
|
||||
@end example
|
||||
|
||||
This routine returns the character string error message associated
|
||||
with @code{code}; if this is associated with an unknown error table, or
|
||||
if the code is associated with a known error table but the code is not
|
||||
in the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
|
||||
returned, where @var{xxxx} is the error table name produced by
|
||||
reversing the compaction performed on the error table number implied
|
||||
by that error code, and @var{nn} is the offset from that base value.
|
||||
|
||||
Although this routine is available for use when needed, its use should be
|
||||
left to circumstances which render @code{com_err} (below) unusable.
|
||||
|
||||
@example
|
||||
void com_err (const char *whoami, /* module reporting error */
|
||||
long code, /* error code */
|
||||
const char *format, /* format for additional detail */
|
||||
...); /* (extra parameters) */
|
||||
@end example
|
||||
|
||||
This routine provides an alternate way to print error messages to
|
||||
standard error; it allows the error message to be passed in as a
|
||||
parameter, rather than in an external variable. @emph{Provide grammatical
|
||||
context for ``message.''}
|
||||
|
||||
If @var{format} is @code{(char *)NULL}, the formatted message will not be
|
||||
printed. @var{format} may not be omitted.
|
||||
|
||||
@example
|
||||
#include <stdarg.h>
|
||||
|
||||
void com_err_va (const char *whoami,
|
||||
long code,
|
||||
const char *format,
|
||||
va_list args);
|
||||
@end example
|
||||
|
||||
This routine provides an interface, equivalent to @code{com_err} above,
|
||||
which may be used by higher-level variadic functions (functions which
|
||||
accept variable numbers of arguments).
|
||||
|
||||
@example
|
||||
#include <stdarg.h>
|
||||
|
||||
void (*set_com_err_hook (void (*proc) ())) ();
|
||||
|
||||
void (*@var{proc}) (const char *whoami, long code, va_list args);
|
||||
|
||||
void reset_com_err_hook ();
|
||||
@end example
|
||||
|
||||
These two routines allow a routine to be dynamically substituted for
|
||||
@samp{com_err}. After @samp{set_com_err_hook} has been called,
|
||||
calls to @samp{com_err} will turn into calls to the new hook routine.
|
||||
@samp{reset_com_err_hook} turns off this hook. This may intended to
|
||||
be used in daemons (to use a routine which calls @var{syslog(3)}), or
|
||||
in a window system application (which could pop up a dialogue box).
|
||||
|
||||
If a program is to be used in an environment in which simply printing
|
||||
messages to the @code{stderr} stream would be inappropriate (such as in a
|
||||
daemon program which runs without a terminal attached),
|
||||
@code{set_com_err_hook} may be used to redirect output from @code{com_err}.
|
||||
The following is an example of an error handler which uses @var{syslog(3)}
|
||||
as supplied in BSD 4.3:
|
||||
|
||||
@example
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
|
||||
/* extern openlog (const char * name, int logopt, int facility); */
|
||||
/* extern syslog (int priority, char * message, ...); */
|
||||
|
||||
void hook (const char * whoami, long code,
|
||||
const char * format, va_list args)
|
||||
@{
|
||||
char buffer[BUFSIZ];
|
||||
static int initialized = 0;
|
||||
if (!initialized) @{
|
||||
openlog (whoami,
|
||||
LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
|
||||
LOG_DAEMON);
|
||||
initialized = 1;
|
||||
@}
|
||||
vsprintf (buffer, format, args);
|
||||
syslog (LOG_ERR, "%s %s", error_message (code), buffer);
|
||||
@}
|
||||
@end example
|
||||
|
||||
After making the call
|
||||
@code{set_com_err_hook (hook);},
|
||||
any calls to @code{com_err} will result in messages being sent to the
|
||||
@var{syslogd} daemon for logging.
|
||||
The name of the program, @samp{whoami}, is supplied to the
|
||||
@samp{openlog()} call, and the message is formatted into a buffer and
|
||||
passed to @code{syslog}.
|
||||
|
||||
Note that since the extra arguments to @code{com_err} are passed by
|
||||
reference via the @code{va_list} value @code{args}, the hook routine may
|
||||
place any form of interpretation on them, including ignoring them. For
|
||||
consistency, @code{printf}-style interpretation is suggested, via
|
||||
@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
|
||||
the ANSI C library).
|
||||
|
||||
@section Coding Conventions
|
||||
|
||||
The following conventions are just some general stylistic conventions
|
||||
to follow when writing robust libraries and programs. Conventions
|
||||
similar to this are generally followed inside the UNIX kernel and most
|
||||
routines in the Multics operating system. In general, a routine
|
||||
either succeeds (returning a zero error code, and doing some side
|
||||
effects in the process), or it fails, doing minimal side effects; in
|
||||
any event, any invariant which the library assumes must be maintained.
|
||||
|
||||
In general, it is not in the domain of non user-interface library
|
||||
routines to write error messages to the user's terminal, or halt the
|
||||
process. Such forms of ``error handling'' should be reserved for
|
||||
failures of internal invariants and consistancy checks only, as it
|
||||
provides the user of the library no way to clean up for himself in the
|
||||
event of total failure.
|
||||
|
||||
Library routines which can fail should be set up to return an error
|
||||
code. This should usually be done as the return value of the
|
||||
function; if this is not acceptable, the routine should return a
|
||||
``null'' value, and put the error code into a parameter passed by
|
||||
reference.
|
||||
|
||||
Routines which use the first style of interface can be used from
|
||||
user-interface levels of a program as follows:
|
||||
|
||||
@example
|
||||
@{
|
||||
if ((code = initialize_world(getuid(), random())) != 0) @{
|
||||
com_err("demo", code,
|
||||
"when trying to initialize world");
|
||||
exit(1);
|
||||
@}
|
||||
if ((database = open_database("my_secrets", &code))==NULL) @{
|
||||
com_err("demo", code,
|
||||
"while opening my_secrets");
|
||||
exit(1);
|
||||
@}
|
||||
@}
|
||||
@end example
|
||||
|
||||
A caller which fails to check the return status is in error. It is
|
||||
possible to look for code which ignores error returns by using lint;
|
||||
look for error messages of the form ``foobar returns value which is
|
||||
sometimes ignored'' or ``foobar returns value which is always
|
||||
ignored.''
|
||||
|
||||
Since libraries may be built out of other libraries, it is often necessary
|
||||
for the success of one routine to depend on another. When a lower level
|
||||
routine returns an error code, the middle level routine has a few possible
|
||||
options. It can simply return the error code to its caller after doing
|
||||
some form of cleanup, it can substitute one of its own, or it can take
|
||||
corrective action of its own and continue normally. For instance, a
|
||||
library routine which makes a ``connect'' system call to make a network
|
||||
connection may reflect the system error code @code{ECONNREFUSED}
|
||||
(Connection refused) to its caller, or it may return a ``server not
|
||||
available, try again later,'' or it may try a different server.
|
||||
|
||||
Cleanup which is typically necessary may include, but not be limited
|
||||
to, freeing allocated memory which will not be needed any more,
|
||||
unlocking concurrancy locks, dropping reference counts, closing file
|
||||
descriptors, or otherwise undoing anything which the procedure did up
|
||||
to this point. When there are a lot of things which can go wrong, it
|
||||
is generally good to write one block of error-handling code which is
|
||||
branched to, using a goto, in the event of failure. A common source
|
||||
of errors in UNIX programs is failing to close file descriptors on
|
||||
error returns; this leaves a number of ``zombied'' file descriptors
|
||||
open, which eventually causes the process to run out of file
|
||||
descriptors and fall over.
|
||||
|
||||
@example
|
||||
@{
|
||||
FILE *f1=NULL, *f2=NULL, *f3=NULL;
|
||||
int status = 0;
|
||||
|
||||
if ( (f1 = fopen(FILE1, "r")) == NULL) @{
|
||||
status = errno;
|
||||
goto error;
|
||||
@}
|
||||
|
||||
/*
|
||||
* Crunch for a while
|
||||
*/
|
||||
|
||||
if ( (f2 = fopen(FILE2, "w")) == NULL) @{
|
||||
status = errno;
|
||||
goto error;
|
||||
@}
|
||||
|
||||
if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
|
||||
status = errno;
|
||||
goto error;
|
||||
@}
|
||||
|
||||
/*
|
||||
* Do more processing.
|
||||
*/
|
||||
fclose(f1);
|
||||
fclose(f2);
|
||||
fclose(f3);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (f1) fclose(f1);
|
||||
if (f2) fclose(f2);
|
||||
if (f3) fclose(f3);
|
||||
return status;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@section Building and Installation
|
||||
|
||||
The distribution of this package will probably be done as a compressed
|
||||
``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
|
||||
Retrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory
|
||||
@t{profiled} should be created to hold objects compiled for profiling.
|
||||
Running ``make all'' should then be sufficient to build the library and
|
||||
error-table compiler. The files @samp{libcom_err.a},
|
||||
@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
|
||||
installed for use; @samp{com_err.3} and @samp{compile_et.1} can also be
|
||||
installed as manual pages.
|
||||
|
||||
Potential problems:
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item Use of @code{strcasecmp}, a routine provided in BSD for
|
||||
case-insensitive string comparisons. If an equivalent routine is
|
||||
available, you can modify @code{CFLAGS} in the makefile to define
|
||||
@code{strcasecmp} to the name of that routine.
|
||||
|
||||
@item Compilers that defined @code{__STDC__} without providing the header
|
||||
file @code{<stdarg.h>}. One such example is Metaware's High ``C''
|
||||
compiler, as provided at Project Athena on the IBM RT/PC workstation; if
|
||||
@code{__HIGHC__} is defined, it is assumed that @code{<stdarg.h>} is not
|
||||
available, and therefore @code{<varargs.h>} must be used. If the symbol
|
||||
@code{VARARGS} is defined (e.g., in the makefile), @code{<varargs.h>} will
|
||||
be used.
|
||||
|
||||
@item If your linker rejects symbols that are simultaneously defined in two
|
||||
library files, edit @samp{Makefile} to remove @samp{perror.c} from the
|
||||
library. This file contains a version of @var{perror(3)} which calls
|
||||
@code{com_err} instead of calling @code{write} directly.
|
||||
|
||||
@end itemize
|
||||
|
||||
As I do not have access to non-BSD systems, there are probably
|
||||
bugs present that may interfere with building or using this package on
|
||||
other systems. If they are reported to me, they can probably be fixed for
|
||||
the next version.
|
||||
|
||||
@section Bug Reports
|
||||
|
||||
Please send any comments or bug reports to the principal author: Ken
|
||||
Raeburn, @t{Raeburn@@Athena.MIT.EDU}.
|
||||
|
||||
@section Acknowledgements
|
||||
|
||||
I would like to thank: Bill Sommerfeld, for his help with some of this
|
||||
documentation, and catching some of the bugs the first time around;
|
||||
Honeywell Information Systems, for not killing off the @emph{Multics}
|
||||
operating system before I had an opportunity to use it; Honeywell's
|
||||
customers, who persuaded them not to do so, for a while; Ted Anderson of
|
||||
CMU, for catching some problems before version 1.2 left the nest; Stan
|
||||
Zanarotti and several others of MIT's Student Information Processing Board,
|
||||
for getting us started with ``discuss,'' for which this package was
|
||||
originally written; and everyone I've talked into --- I mean, asked to read
|
||||
this document and the ``man'' pages.
|
||||
|
||||
@bye
|
||||
11
util/com_err/compile_et
Executable file
11
util/com_err/compile_et
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
AWK=/usr/bin/awk
|
||||
DIR=com_err/
|
||||
|
||||
ROOT=`echo $1 | sed -e s/.et$//`
|
||||
BASE=`basename $ROOT`
|
||||
|
||||
$AWK -f ${DIR}/et_h.awk outfile=${BASE}.h $ROOT.et
|
||||
$AWK -f ${DIR}/et_c.awk outfile=${BASE}.c $ROOT.et
|
||||
79
util/com_err/compile_et.1
Normal file
79
util/com_err/compile_et.1
Normal file
@@ -0,0 +1,79 @@
|
||||
.\" Copyright (c) 1988 Massachusetts Institute of Technology,
|
||||
.\" Student Information Processing Board. All rights reserved.
|
||||
.\"
|
||||
.\" $Header: /mit/krb5/.cvsroot/src/util/et/compile_et.1,v 1.1 1993/06/03 12:29:46 tytso Exp $
|
||||
.\"
|
||||
.TH COMPILE_ET 1 "22 Nov 1988" SIPB
|
||||
.SH NAME
|
||||
compile_et \- error table compiler
|
||||
.SH SYNOPSIS
|
||||
.B compile_et
|
||||
file
|
||||
.SH DESCRIPTION
|
||||
.B Compile_et
|
||||
converts a table listing error-code names and associated messages into
|
||||
a C source file suitable for use with the
|
||||
.IR com_err (3)
|
||||
library.
|
||||
|
||||
The source file name must end with a suffix of ``.et''; the file
|
||||
consists of a declaration supplying the name (up to four characters
|
||||
long) of the error-code table:
|
||||
|
||||
.B error_table
|
||||
.I name
|
||||
|
||||
followed by up to 256 entries of the form:
|
||||
|
||||
.B error_code
|
||||
.I name,
|
||||
"
|
||||
.I string
|
||||
"
|
||||
|
||||
and a final
|
||||
|
||||
.B end
|
||||
|
||||
to indicate the end of the table.
|
||||
|
||||
The name of the table is used to construct the name of a subroutine
|
||||
.I initialize_XXXX_error_table
|
||||
which must be called in order for the
|
||||
.I com_err
|
||||
library to recognize the error table.
|
||||
|
||||
The various error codes defined are assigned sequentially increasing
|
||||
numbers (starting with a large number computed as a hash function of
|
||||
the name of the table); thus for compatibility it is suggested that
|
||||
new codes be added only to the end of an existing table, and that no
|
||||
codes be removed from tables.
|
||||
|
||||
The names defined in the table are placed into a C header file with
|
||||
preprocessor directives defining them as integer constants of up to
|
||||
32 bits in magnitude.
|
||||
|
||||
A C source file is also generated which should be compiled and linked
|
||||
with the object files which reference these error codes; it contains
|
||||
the text of the messages and the initialization subroutine. Both C
|
||||
files have names derived from that of the original source file, with
|
||||
the ``.et'' suffix replaced by ``.c'' and ``.h''.
|
||||
|
||||
A ``#'' in the source file is treated as a comment character, and all
|
||||
remaining text to the end of the source line will be ignored.
|
||||
|
||||
.SH BUGS
|
||||
|
||||
Since
|
||||
.B compile_et
|
||||
uses a very simple parser based on
|
||||
.IR yacc (1),
|
||||
its error recovery leaves much to be desired.
|
||||
|
||||
.\" .IR for manual entries
|
||||
.\" .PP for paragraph breaks
|
||||
|
||||
.SH "SEE ALSO"
|
||||
com_err (3).
|
||||
|
||||
Ken Raeburn, "A Common Error Description Library for UNIX".
|
||||
82
util/com_err/error_message.c
Normal file
82
util/com_err/error_message.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* $Header: /mit/krb5/.cvsroot/src/util/et/error_message.c,v 5.0 1993/04/13 19:56:17 tytso Exp $
|
||||
* $Source: /mit/krb5/.cvsroot/src/util/et/error_message.c,v $
|
||||
* $Locker: $
|
||||
*
|
||||
* Copyright 1987 by the Student Information Processing Board
|
||||
* of the Massachusetts Institute of Technology
|
||||
*
|
||||
* For copyright info, see "mit-sipb-copyright.h".
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "com_err.h"
|
||||
#include "error_table.h"
|
||||
#include "mit-sipb-copyright.h"
|
||||
#include "internal.h"
|
||||
|
||||
static char buffer[25];
|
||||
|
||||
struct et_list * _et_list = (struct et_list *) NULL;
|
||||
|
||||
|
||||
#ifdef __STDC__
|
||||
const char * error_message (errcode_t code)
|
||||
#else
|
||||
const char * error_message (code)
|
||||
errcode_t code;
|
||||
#endif
|
||||
{
|
||||
int offset;
|
||||
struct et_list *et;
|
||||
int table_num;
|
||||
int started = 0;
|
||||
char *cp;
|
||||
|
||||
offset = code & ((1<<ERRCODE_RANGE)-1);
|
||||
table_num = code - offset;
|
||||
if (!table_num) {
|
||||
#ifdef HAS_SYS_ERRLIST
|
||||
if (offset < sys_nerr)
|
||||
return(sys_errlist[offset]);
|
||||
else
|
||||
goto oops;
|
||||
#else
|
||||
cp = strerror(offset);
|
||||
if (cp)
|
||||
return(cp);
|
||||
else
|
||||
goto oops;
|
||||
#endif
|
||||
}
|
||||
for (et = _et_list; et; et = et->next) {
|
||||
if (et->table->base == table_num) {
|
||||
/* This is the right table */
|
||||
if (et->table->n_msgs <= offset)
|
||||
goto oops;
|
||||
return(et->table->msgs[offset]);
|
||||
}
|
||||
}
|
||||
oops:
|
||||
strcpy (buffer, "Unknown code ");
|
||||
if (table_num) {
|
||||
strcat (buffer, error_table_name (table_num));
|
||||
strcat (buffer, " ");
|
||||
}
|
||||
for (cp = buffer; *cp; cp++)
|
||||
;
|
||||
if (offset >= 100) {
|
||||
*cp++ = '0' + offset / 100;
|
||||
offset %= 100;
|
||||
started++;
|
||||
}
|
||||
if (started || offset >= 10) {
|
||||
*cp++ = '0' + offset / 10;
|
||||
offset %= 10;
|
||||
}
|
||||
*cp++ = '0' + offset;
|
||||
*cp = '\0';
|
||||
return(buffer);
|
||||
}
|
||||
35
util/com_err/error_table.h
Normal file
35
util/com_err/error_table.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 1988 by the Student Information Processing Board of the
|
||||
* Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copyright info, see mit-sipb-copyright.h.
|
||||
*/
|
||||
|
||||
#ifndef _ET_H
|
||||
/* Are we using ANSI C? */
|
||||
#ifndef __STDC__
|
||||
#define const
|
||||
#endif
|
||||
|
||||
struct error_table {
|
||||
char const * const * msgs;
|
||||
long base;
|
||||
int n_msgs;
|
||||
};
|
||||
struct et_list {
|
||||
struct et_list *next;
|
||||
const struct error_table *table;
|
||||
};
|
||||
extern struct et_list * _et_list;
|
||||
|
||||
#define ERRCODE_RANGE 8 /* # of bits to shift table number */
|
||||
#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
|
||||
|
||||
#ifdef __STDC__
|
||||
extern const char *error_table_name(int num);
|
||||
#else
|
||||
extern const char *error_table_name();
|
||||
#endif
|
||||
|
||||
#define _ET_H
|
||||
#endif
|
||||
185
util/com_err/et_c.awk
Normal file
185
util/com_err/et_c.awk
Normal file
@@ -0,0 +1,185 @@
|
||||
BEGIN {
|
||||
char_shift=64
|
||||
## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
|
||||
c2n["A"]=1
|
||||
c2n["B"]=2
|
||||
c2n["C"]=3
|
||||
c2n["D"]=4
|
||||
c2n["E"]=5
|
||||
c2n["F"]=6
|
||||
c2n["G"]=7
|
||||
c2n["H"]=8
|
||||
c2n["I"]=9
|
||||
c2n["J"]=10
|
||||
c2n["K"]=11
|
||||
c2n["L"]=12
|
||||
c2n["M"]=13
|
||||
c2n["N"]=14
|
||||
c2n["O"]=15
|
||||
c2n["P"]=16
|
||||
c2n["Q"]=17
|
||||
c2n["R"]=18
|
||||
c2n["S"]=19
|
||||
c2n["T"]=20
|
||||
c2n["U"]=21
|
||||
c2n["V"]=22
|
||||
c2n["W"]=23
|
||||
c2n["X"]=24
|
||||
c2n["Y"]=25
|
||||
c2n["Z"]=26
|
||||
c2n["a"]=27
|
||||
c2n["b"]=28
|
||||
c2n["c"]=29
|
||||
c2n["d"]=30
|
||||
c2n["e"]=31
|
||||
c2n["f"]=32
|
||||
c2n["g"]=33
|
||||
c2n["h"]=34
|
||||
c2n["i"]=35
|
||||
c2n["j"]=36
|
||||
c2n["k"]=37
|
||||
c2n["l"]=38
|
||||
c2n["m"]=39
|
||||
c2n["n"]=40
|
||||
c2n["o"]=41
|
||||
c2n["p"]=42
|
||||
c2n["q"]=43
|
||||
c2n["r"]=44
|
||||
c2n["s"]=45
|
||||
c2n["t"]=46
|
||||
c2n["u"]=47
|
||||
c2n["v"]=48
|
||||
c2n["w"]=49
|
||||
c2n["x"]=50
|
||||
c2n["y"]=51
|
||||
c2n["z"]=52
|
||||
c2n["0"]=53
|
||||
c2n["1"]=54
|
||||
c2n["2"]=55
|
||||
c2n["3"]=56
|
||||
c2n["4"]=57
|
||||
c2n["5"]=58
|
||||
c2n["6"]=59
|
||||
c2n["7"]=60
|
||||
c2n["8"]=61
|
||||
c2n["9"]=62
|
||||
c2n["_"]=63
|
||||
}
|
||||
/^#/ { next }
|
||||
/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
|
||||
table_number = 0
|
||||
table_name = $2
|
||||
mod_base = 1000000
|
||||
for(i=1; i<=length(table_name); i++) {
|
||||
table_number=(table_number*char_shift)+c2n[substr(table_name,i,1)]
|
||||
}
|
||||
|
||||
# We start playing *_high, *low games here because the some
|
||||
# awk programs do not have the necessary precision (sigh)
|
||||
tab_base_low = table_number % mod_base
|
||||
tab_base_high = int(table_number / mod_base)
|
||||
tab_base_sign = 1;
|
||||
|
||||
# figure out: table_number_base=table_number*256
|
||||
tab_base_low = tab_base_low * 256
|
||||
tab_base_high = (tab_base_high * 256) + \
|
||||
int(tab_base_low / mod_base)
|
||||
tab_base_low = tab_base_low % mod_base
|
||||
|
||||
if (table_number > 128*256*256) {
|
||||
# figure out: table_number_base -= 256*256*256*256
|
||||
# sub_high, sub_low is 256*256*256*256
|
||||
sub_low = 256*256*256 % mod_base
|
||||
sub_high = int(256*256*256 / mod_base)
|
||||
|
||||
sub_low = sub_low * 256
|
||||
sub_high = (sub_high * 256) + int(sub_low / mod_base)
|
||||
sub_low = sub_low % mod_base
|
||||
|
||||
tab_base_low = sub_low - tab_base_low;
|
||||
tab_base_high = sub_high - tab_base_high;
|
||||
tab_base_sign = -1;
|
||||
if (tab_base_low < 0) {
|
||||
tab_base_low = tab_base_low + mod_base
|
||||
tab_base_high--
|
||||
}
|
||||
}
|
||||
print "/*" > outfile
|
||||
print " * " outfile ":" > outfile
|
||||
print " * This file is automatically generated; please do not edit it." > outfile
|
||||
print " */" > outfile
|
||||
|
||||
print "#ifdef __STDC__" > outfile
|
||||
print "#define NOARGS void" > outfile
|
||||
print "#else" > outfile
|
||||
print "#define NOARGS" > outfile
|
||||
print "#define const" > outfile
|
||||
print "#endif" > outfile
|
||||
print "" > outfile
|
||||
print "static const char * const text[] = {" > outfile
|
||||
table_item_count = 0
|
||||
}
|
||||
|
||||
/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ {
|
||||
skipone=1
|
||||
next
|
||||
}
|
||||
|
||||
/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ {
|
||||
text=""
|
||||
for (i=3; i<=NF; i++) {
|
||||
text = text FS $i
|
||||
}
|
||||
text=substr(text,2,length(text)-1);
|
||||
printf "\t%s,\n", text > outfile
|
||||
table_item_count++
|
||||
}
|
||||
|
||||
{
|
||||
if (skipone) {
|
||||
printf "\t%s,\n", $0 > outfile
|
||||
table_item_count++
|
||||
}
|
||||
skipone=0
|
||||
}
|
||||
END {
|
||||
|
||||
|
||||
print " 0" > outfile
|
||||
print "};" > outfile
|
||||
print "" > outfile
|
||||
print "struct error_table {" > outfile
|
||||
print " char const * const * msgs;" > outfile
|
||||
print " long base;" > outfile
|
||||
print " int n_msgs;" > outfile
|
||||
print "};" > outfile
|
||||
print "struct et_list {" > outfile
|
||||
print " struct et_list *next;" > outfile
|
||||
print " const struct error_table * table;" > outfile
|
||||
print "};" > outfile
|
||||
print "extern struct et_list *_et_list;" > outfile
|
||||
print "" > outfile
|
||||
if (tab_base_high == 0) {
|
||||
print "static const struct error_table et = { text, " \
|
||||
sprintf("%dL, %d };", tab_base_sign*tab_base_low, \
|
||||
table_item_count) > outfile
|
||||
} else {
|
||||
print "static const struct error_table et = { text, " \
|
||||
sprintf("%d%06dL, %d };", tab_base_sign*tab_base_high, \
|
||||
tab_base_low, table_item_count) > outfile
|
||||
}
|
||||
print "" > outfile
|
||||
print "static struct et_list link = { 0, 0 };" > outfile
|
||||
print "" > outfile
|
||||
print "void initialize_" table_name "_error_table (NOARGS);" > outfile
|
||||
print "" > outfile
|
||||
print "void initialize_" table_name "_error_table (NOARGS) {" > outfile
|
||||
print " if (!link.table) {" > outfile
|
||||
print " link.next = _et_list;" > outfile
|
||||
print " link.table = &et;" > outfile
|
||||
print " _et_list = &link;" > outfile
|
||||
print " }" > outfile
|
||||
print "}" > outfile
|
||||
|
||||
|
||||
}
|
||||
157
util/com_err/et_h.awk
Normal file
157
util/com_err/et_h.awk
Normal file
@@ -0,0 +1,157 @@
|
||||
BEGIN {
|
||||
char_shift=64
|
||||
## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
|
||||
c2n["A"]=1
|
||||
c2n["B"]=2
|
||||
c2n["C"]=3
|
||||
c2n["D"]=4
|
||||
c2n["E"]=5
|
||||
c2n["F"]=6
|
||||
c2n["G"]=7
|
||||
c2n["H"]=8
|
||||
c2n["I"]=9
|
||||
c2n["J"]=10
|
||||
c2n["K"]=11
|
||||
c2n["L"]=12
|
||||
c2n["M"]=13
|
||||
c2n["N"]=14
|
||||
c2n["O"]=15
|
||||
c2n["P"]=16
|
||||
c2n["Q"]=17
|
||||
c2n["R"]=18
|
||||
c2n["S"]=19
|
||||
c2n["T"]=20
|
||||
c2n["U"]=21
|
||||
c2n["V"]=22
|
||||
c2n["W"]=23
|
||||
c2n["X"]=24
|
||||
c2n["Y"]=25
|
||||
c2n["Z"]=26
|
||||
c2n["a"]=27
|
||||
c2n["b"]=28
|
||||
c2n["c"]=29
|
||||
c2n["d"]=30
|
||||
c2n["e"]=31
|
||||
c2n["f"]=32
|
||||
c2n["g"]=33
|
||||
c2n["h"]=34
|
||||
c2n["i"]=35
|
||||
c2n["j"]=36
|
||||
c2n["k"]=37
|
||||
c2n["l"]=38
|
||||
c2n["m"]=39
|
||||
c2n["n"]=40
|
||||
c2n["o"]=41
|
||||
c2n["p"]=42
|
||||
c2n["q"]=43
|
||||
c2n["r"]=44
|
||||
c2n["s"]=45
|
||||
c2n["t"]=46
|
||||
c2n["u"]=47
|
||||
c2n["v"]=48
|
||||
c2n["w"]=49
|
||||
c2n["x"]=50
|
||||
c2n["y"]=51
|
||||
c2n["z"]=52
|
||||
c2n["0"]=53
|
||||
c2n["1"]=54
|
||||
c2n["2"]=55
|
||||
c2n["3"]=56
|
||||
c2n["4"]=57
|
||||
c2n["5"]=58
|
||||
c2n["6"]=59
|
||||
c2n["7"]=60
|
||||
c2n["8"]=61
|
||||
c2n["9"]=62
|
||||
c2n["_"]=63
|
||||
}
|
||||
/^#/ { next }
|
||||
/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
|
||||
table_number = 0
|
||||
table_name = $2
|
||||
mod_base = 1000000
|
||||
for(i=1; i<=length(table_name); i++) {
|
||||
table_number=(table_number*char_shift)+c2n[substr(table_name,i,1)]
|
||||
}
|
||||
# We start playing *_high, *low games here because the some
|
||||
# awk programs do not have the necessary precision (sigh)
|
||||
tab_base_low = table_number % mod_base
|
||||
tab_base_high = int(table_number / mod_base)
|
||||
tab_base_sign = 1;
|
||||
|
||||
# figure out: table_number_base=table_number*256
|
||||
tab_base_low = tab_base_low * 256
|
||||
tab_base_high = (tab_base_high * 256) + \
|
||||
int(tab_base_low / mod_base)
|
||||
tab_base_low = tab_base_low % mod_base
|
||||
|
||||
if (table_number > 128*256*256) {
|
||||
# figure out: table_number_base -= 256*256*256*256
|
||||
# sub_high, sub_low is 256*256*256*256
|
||||
sub_low = 256*256*256 % mod_base
|
||||
sub_high = int(256*256*256 / mod_base)
|
||||
|
||||
sub_low = sub_low * 256
|
||||
sub_high = (sub_high * 256) + int(sub_low / mod_base)
|
||||
sub_low = sub_low % mod_base
|
||||
|
||||
tab_base_low = sub_low - tab_base_low;
|
||||
tab_base_high = sub_high - tab_base_high;
|
||||
tab_base_sign = -1;
|
||||
if (tab_base_low < 0) {
|
||||
tab_base_low = tab_base_low + mod_base
|
||||
tab_base_high--
|
||||
}
|
||||
}
|
||||
curr_low = tab_base_low
|
||||
curr_high = tab_base_high
|
||||
curr_sign = tab_base_sign
|
||||
print "/*" > outfile
|
||||
print " * " outfile ":" > outfile
|
||||
print " * This file is automatically generated; please do not edit it." > outfile
|
||||
print " */" > outfile
|
||||
print "#ifdef __STDC__" > outfile
|
||||
print "#define NOARGS void" > outfile
|
||||
print "#else" > outfile
|
||||
print "#define NOARGS" > outfile
|
||||
print "#define const" > outfile
|
||||
print "#endif" > outfile
|
||||
print "" > outfile
|
||||
}
|
||||
|
||||
/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,/ {
|
||||
tag=substr($2,1,length($2)-1)
|
||||
if (curr_high == 0) {
|
||||
printf "#define %-40s (%dL)\n", tag, \
|
||||
curr_sign*curr_low > outfile
|
||||
} else {
|
||||
printf "#define %-40s (%d%06dL)\n", tag, curr_high*curr_sign, \
|
||||
curr_low > outfile
|
||||
}
|
||||
curr_low += curr_sign;
|
||||
if (curr_low >= mod_base) {
|
||||
curr_low -= mod_base;
|
||||
curr_high++
|
||||
}
|
||||
if (curr_low < 0) {
|
||||
cur_low += mod_base
|
||||
cur_high--
|
||||
}
|
||||
}
|
||||
|
||||
END {
|
||||
print "extern void initialize_" table_name "_error_table (NOARGS);" > outfile
|
||||
if (tab_base_high == 0) {
|
||||
print "#define ERROR_TABLE_BASE_" table_name " (" \
|
||||
sprintf("%d", tab_base_sign*tab_base_low) \
|
||||
"L)" > outfile
|
||||
} else {
|
||||
print "#define ERROR_TABLE_BASE_" table_name " (" \
|
||||
sprintf("%d%06d", tab_base_sign*tab_base_high, \
|
||||
tab_base_low) "L)" > outfile
|
||||
}
|
||||
print "" > outfile
|
||||
print "/* for compatibility with older versions... */" > outfile
|
||||
print "#define init_" table_name "_err_tbl initialize_" table_name "_error_table" > outfile
|
||||
print "#define " table_name "_err_base ERROR_TABLE_BASE_" table_name > outfile
|
||||
}
|
||||
36
util/com_err/et_name.c
Normal file
36
util/com_err/et_name.c
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 1987 by MIT Student Information Processing Board
|
||||
*
|
||||
* For copyright info, see mit-sipb-copyright.h.
|
||||
*/
|
||||
|
||||
#include "error_table.h"
|
||||
#include "mit-sipb-copyright.h"
|
||||
#include "internal.h"
|
||||
|
||||
static const char char_set[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
|
||||
|
||||
static char buf[6];
|
||||
|
||||
const char * error_table_name(num)
|
||||
int num;
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
|
||||
p = buf;
|
||||
num >>= ERRCODE_RANGE;
|
||||
/* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
|
||||
num &= 077777777;
|
||||
/* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
|
||||
for (i = 4; i >= 0; i--) {
|
||||
ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
|
||||
if (ch != 0)
|
||||
*p++ = char_set[ch-1];
|
||||
}
|
||||
*p = '\0';
|
||||
return(buf);
|
||||
}
|
||||
58
util/com_err/init_et.c
Normal file
58
util/com_err/init_et.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* $Header: /mit/krb5/.cvsroot/src/util/et/init_et.c,v 5.0 1993/04/13 19:56:25 tytso Exp $
|
||||
* $Source: /mit/krb5/.cvsroot/src/util/et/init_et.c,v $
|
||||
* $Locker: $
|
||||
*
|
||||
* Copyright 1986, 1987, 1988 by MIT Information Systems and
|
||||
* the MIT Student Information Processing Board.
|
||||
*
|
||||
* For copyright info, see mit-sipb-copyright.h.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "com_err.h"
|
||||
#include "error_table.h"
|
||||
#include "mit-sipb-copyright.h"
|
||||
|
||||
#ifndef __STDC__
|
||||
#define const
|
||||
#endif
|
||||
|
||||
struct foobar {
|
||||
struct et_list etl;
|
||||
struct error_table et;
|
||||
};
|
||||
|
||||
extern struct et_list * _et_list;
|
||||
|
||||
#ifdef __STDC__
|
||||
int init_error_table(const char * const *msgs, int base, int count)
|
||||
#else
|
||||
int init_error_table(msgs, base, count)
|
||||
const char * const * msgs;
|
||||
int base;
|
||||
int count;
|
||||
#endif
|
||||
{
|
||||
struct foobar * new_et;
|
||||
|
||||
if (!base || !count || !msgs)
|
||||
return 0;
|
||||
|
||||
new_et = (struct foobar *) malloc(sizeof(struct foobar));
|
||||
if (!new_et)
|
||||
return ENOMEM; /* oops */
|
||||
new_et->etl.table = &new_et->et;
|
||||
new_et->et.msgs = msgs;
|
||||
new_et->et.base = base;
|
||||
new_et->et.n_msgs= count;
|
||||
|
||||
new_et->etl.next = _et_list;
|
||||
_et_list = &new_et->etl;
|
||||
return 0;
|
||||
}
|
||||
22
util/com_err/internal.h
Normal file
22
util/com_err/internal.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* internal include file for com_err package
|
||||
*/
|
||||
#include "mit-sipb-copyright.h"
|
||||
#ifndef __STDC__
|
||||
#undef const
|
||||
#define const
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef NEED_SYS_ERRLIST
|
||||
extern char const * const sys_errlist[];
|
||||
extern const int sys_nerr;
|
||||
#endif
|
||||
|
||||
/* AIX and Ultrix have standard conforming header files. */
|
||||
#if !defined(ultrix) && !defined(_AIX)
|
||||
#ifdef __STDC__
|
||||
void perror (const char *);
|
||||
#endif
|
||||
#endif
|
||||
19
util/com_err/mit-sipb-copyright.h
Normal file
19
util/com_err/mit-sipb-copyright.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
|
||||
Copyright 1987, 1988 by the Student Information Processing Board
|
||||
of the Massachusetts Institute of Technology
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is
|
||||
hereby granted, provided that the above copyright notice
|
||||
appear in all copies and that both that copyright notice and
|
||||
this permission notice appear in supporting documentation,
|
||||
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
M.I.T. and the M.I.T. S.I.P.B. make no representations about
|
||||
the suitability of this software for any purpose. It is
|
||||
provided "as is" without express or implied warranty.
|
||||
|
||||
*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user