Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f813517d69 | ||
|
|
915f560f85 | ||
|
|
1a5653d403 | ||
|
|
f88460b2e6 | ||
|
|
fff159f2db | ||
|
|
c4d2144d0d | ||
|
|
134b5d6ebf | ||
|
|
ab78307868 | ||
|
|
3019bba627 | ||
|
|
011a5107c5 | ||
|
|
7179281575 | ||
|
|
b8d830f9a3 | ||
|
|
b36a27bedb | ||
|
|
7d0e3d011b | ||
|
|
84cb1f167d | ||
|
|
64f006632a | ||
|
|
92f749a943 | ||
|
|
6cb56005ea | ||
|
|
0520c1d2f7 | ||
|
|
d5ac4601b1 | ||
|
|
1fa124bd7c | ||
|
|
5753870858 | ||
|
|
b8ce93c8bd | ||
|
|
7bef99df0f | ||
|
|
d31ec2ab61 |
BIN
.downloads/ncpfs-0.13.tgz
Normal file
BIN
.downloads/ncpfs-0.13.tgz
Normal file
Binary file not shown.
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.10.tgz
Normal file
BIN
.downloads/ncpfs-2.0.10.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.11.tgz
Normal file
BIN
.downloads/ncpfs-2.0.11.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.12.tgz
Normal file
BIN
.downloads/ncpfs-2.0.12.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.
BIN
.downloads/ncpfs-2.0.4.tgz
Normal file
BIN
.downloads/ncpfs-2.0.4.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.5.tgz
Normal file
BIN
.downloads/ncpfs-2.0.5.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.6.tgz
Normal file
BIN
.downloads/ncpfs-2.0.6.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.7.tgz
Normal file
BIN
.downloads/ncpfs-2.0.7.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.8.tgz
Normal file
BIN
.downloads/ncpfs-2.0.8.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-2.0.9.tgz
Normal file
BIN
.downloads/ncpfs-2.0.9.tgz
Normal file
Binary file not shown.
34
BUGS
34
BUGS
@@ -3,17 +3,33 @@ 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.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
You might experience lockups of ncpfs volumes. It happens especially
|
||||
under high network traffic, not necessarily only IPX traffic. I am not
|
||||
able to reproduce this problem on my machine, so I'm sorry I can not
|
||||
do anything about that. When such a lockup happens, you have to shut
|
||||
down the complete ipx subsystem by deleting all ipx interfaces,
|
||||
unmounting all ncpfs volumes (in this order!) and restarting all
|
||||
again.
|
||||
|
||||
In your kernel log, there will appear messages like
|
||||
This problem has been solved by Martin Stover (THANKS!!)
|
||||
See patches/lockup-2.0.30.diff for the fix.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
'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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
287
Changes
Normal file
287
Changes
Normal file
@@ -0,0 +1,287 @@
|
||||
I only began this file with ncpfs-0.12. If you're interested in older
|
||||
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
|
||||
|
||||
[Versions ncpfs-2.0.11.x are available at ftp://platan.vc.cvut.cz/pub/linux/ncpfs]
|
||||
|
||||
ncpfs-2.0.11.19 -> ncpfs-2.0.12
|
||||
- Polished for release 2.0.12
|
||||
- Dave: pserver fixes, including addition of %d flag.
|
||||
|
||||
ncpfs-2.0.11.18 -> ncpfs-2.0.11.19
|
||||
- Dave, VANA: new userspace utilities - pqstat and pqrm
|
||||
|
||||
ncpfs-2.0.11.17 -> ncpfs-2.0.11.18 (no userspace change)
|
||||
- Dave: getwd() did not work on 2.1.x
|
||||
- VANA: Volumes are now allways listed lowercased on 2.1.x
|
||||
|
||||
ncpfs-2.0.11.16 -> ncpfs-2.0.11.17
|
||||
- Dave@imladris.demon.co.uk: Patch to pserver, ncp_get_broadcast_message
|
||||
- VANA & Dave: Cleanup for glibc, I hope that complete (xcpt. few warnings
|
||||
about long int vs. u_int32_t
|
||||
|
||||
ncpfs-2.0.11.15 -> ncpfs-2.0.11.16
|
||||
- VANA: Removed symlink latest from archive :-)
|
||||
- VANA: Added ncp_send_broadcast2
|
||||
|
||||
ncpfs-2.0.11.14 -> ncpfs-2.0.11.15
|
||||
- VANA: Fixed bug: wrong completion code returned when login to server without
|
||||
r/w replica of logged-in user
|
||||
- VANA: It is possible to disable NFS and/or OS2 namespace support in mount
|
||||
|
||||
ncpfs-2.0.11.13 -> ncpfs-2.0.11.14
|
||||
- VANA: One source for 2.0 and 2.1 kernels
|
||||
- Chirstian Groessler: Added strong mounts
|
||||
|
||||
ncpfs-2.0.11.12 -> ncpfs-2.0.11.13
|
||||
- Arne: Signatures added to ncpfs-nds-0.06
|
||||
- VANA: Synchronized sources with Arne
|
||||
|
||||
ncpfs-2.0.11.11 -> ncpfs-2.0.11.12
|
||||
- VANA: Fixed compilation error if compiled against kernel without signatures even
|
||||
if SIGNATURES = 0 set
|
||||
|
||||
ncpfs-2.0.11.10 -> ncpfs-2.0.11.11
|
||||
- VANA: Fixed segfault on invalid user name in NDS mode
|
||||
- VANA: Added locking features (through ncpfs-specific ioctl(2))
|
||||
|
||||
ncpfs-2.0.11.9 -> ncpfs-2.0.11.10
|
||||
- VANA: Synchronized with nds-patches-0.05 from Arne@knoware.nl
|
||||
|
||||
ncpfs-2.0.11.8 -> ncpfs-2.0.11.9
|
||||
- VANA: Added call to lock connection (dropped in 2.0.11.7, sorry)
|
||||
|
||||
ncpfs-2.0.11.7 -> ncpfs-2.0.11.8
|
||||
- VANA: Can be correctly compiled without signatures support in kernel (I hope)
|
||||
- VANA: Fix in kernel in setting task number
|
||||
|
||||
ncpfs-2.0.11.6 -> ncpfs-2.0.11.7
|
||||
- VANA: Codebase synchronized with arne@knoware.nl
|
||||
- ARNE: Gracelogins on NDS
|
||||
- VANA: Removed some (one) compilation warnings
|
||||
|
||||
ncpfs-2.0.11.5 -> ncpfs-2.0.11.6
|
||||
- VANA: Support for NDS login accross servers
|
||||
|
||||
ncpfs-2.0.11.4 -> ncpfs-2.0.11.5
|
||||
- VANA: Cleanup in ndscrypt
|
||||
- VANA: Bugfix: empty password for NDS login is now allowed & works
|
||||
|
||||
ncpfs-2.0.11.3 -> ncpfs-2.0.11.4
|
||||
- Enabled some buffer cleaning
|
||||
- Added parameter "-b" to ncpmount for bindery login to NDS server
|
||||
|
||||
ncpfs-2.0.11.2 -> ncpfs-2.0.11.3
|
||||
- Added NDS support by Arne@knoware.nl; small fixes in code; moved sections
|
||||
to do same things as DOS login does.
|
||||
|
||||
ncpfs-2.0.11.1 -> ncpfs-2.0.11.2
|
||||
- VANA: Fixed that some error conditions in LOGIN should start packet signatures
|
||||
|
||||
ncpfs-2.0.11 -> ncpfs-2.0.11.1
|
||||
- VANA: Added packet signatures by ... (Arne?)
|
||||
|
||||
ncpfs-2.0.10 -> ncpfs-2.0.11
|
||||
- Added Martin's patch to Linux 2.0.30 to get rid of the lockups.
|
||||
MANY thanks to Martin Stover!
|
||||
|
||||
ncpfs-2.0.9 -> ncpfs-2.0.10
|
||||
- Made nwtrustee hopefully work ;-)
|
||||
- Made the manpages a little bit prettier
|
||||
|
||||
ncpfs-2.0.8 -> ncpfs-2.0.9
|
||||
- Added patches directory
|
||||
- Added nwvolinfo and nwtrustee. Thanks to Jacek Stepniewski <cunio@gazeta.pl>
|
||||
- nwpasswd can change other's passwords. Thanks to Martin Stover.
|
||||
|
||||
ncpfs-2.0.7 -> ncpfs-2.0.8
|
||||
- Fixed util/Makefile for easier optimization handling. Thanks to Rik
|
||||
Faith <faith@cs.unc.edu> for this one
|
||||
- added nwfstime. You can now set the file server date and time from Linux.
|
||||
- added the contrib directory. Feel free to add more!
|
||||
|
||||
ncpfs-2.0.6 -> ncpfs-2.0.7
|
||||
- Hopefully removed one security problem in ncpumount.
|
||||
- Added command line flag to pserver.c
|
||||
- Heavily reconstructed ncpfs utils. Created the lib/ dir.
|
||||
- Separated the uid utils in sutil
|
||||
- Add nwsfind to enable users to use ncpfs safely without setting
|
||||
the utils setuid root.
|
||||
|
||||
ncpfs-2.0.5 -> ncpfs-2.0.6
|
||||
- Added a short description of a problem that I need help with to the
|
||||
file BUGS. If you know a bit of the linux networking code, please
|
||||
take a look at it. Thanks a lot.
|
||||
- Added canonic output format to nwpbvalues and the command nwbpset. I
|
||||
would like to invite you to help building capable bindery management
|
||||
utilities. For little examples, look at the manual page of nwbpset.
|
||||
- Added some values to ipxparse. Those interested in NDS should take a
|
||||
look at it. It's really not much, but maybe it's a beginning.
|
||||
|
||||
ncpfs-2.0.4 -> ncpfs-2.0.5
|
||||
- Removed another bug in nwbpvalues.
|
||||
- Cleaned up man/Makefile
|
||||
- Some manpage typos fixed. Thanks to Jim Van Zandt
|
||||
<jrv@mbunix.mitre.org>
|
||||
- added nwrights
|
||||
|
||||
ncpfs-2.0.3 -> ncpfs-2.0.4
|
||||
- Changed name of npasswd to nwpasswd, as npasswd collides with
|
||||
RedHat. Thanks to Mike Slater <mslater@nfinity.com> for pointing me
|
||||
at this one.
|
||||
- Put '\r\n' into nwmsg, because sometimes it did not print
|
||||
correctly. Thanks to Petr Vandrovec Ing. VTEI
|
||||
<VANDROVE@vcnet.vc.cvut.cz> for this one.
|
||||
- Improved the ELF Makefile for ELF support. Thanks to Uwe Bonnes
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>.
|
||||
- Removed a very embarassing bug in nwpvalues :-(.
|
||||
- Added a some routines to nwbpvalues.
|
||||
|
||||
ncpfs-2.0.2 -> ncpfs-2.0.3
|
||||
- Removed the kernel-2.0 directory. Linus took the patch into 2.0.8.
|
||||
So, if you want to use long file name support, upgrade to Linux
|
||||
kernel version 2.0.8.
|
||||
- Applied the lfn patch to the kernel-1.2 module with some light
|
||||
testing. If you experience problems, tell it to me, and use the
|
||||
ncpfs-2.0.2 kernel module, or upgrade to Linux 2.0.8.
|
||||
- Added unencrypted login when no crypt key is returned.
|
||||
- Hopefully improved error messages a bit
|
||||
- Added some values to ipxparse
|
||||
- For ELF systems, moved ncplib to /lib/libncp.so.1.x. This saves
|
||||
about 1MB of disk space. As ncpfs grows, the saving will
|
||||
increase. Please look at the Makefile to enable this.
|
||||
- Enhanced nwfsinfo a bit. (Even with a manpage!)
|
||||
- Added nwuserlist.
|
||||
|
||||
ncpfs-2.0.1 -> ncpfs-2.0.2
|
||||
- Added some values to ipxparse.
|
||||
- Added a patch against 2.0.7 for long file names support. I did not
|
||||
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.
|
||||
66
FAQ
Normal file
66
FAQ
Normal file
@@ -0,0 +1,66 @@
|
||||
There is certainly not enough material to call this an FAQ, but some
|
||||
questions reach me regularly. Probably the documentation 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.
|
||||
|
||||
Note: ncpfs, as of 2.0.12, and kernel 2.1.89, does now support packet
|
||||
signatures.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Q: When I re-export ncpfs-mounted directories via nfs, I get messages like
|
||||
'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: I cannot login into server with these utilities. It was possible with an
|
||||
older version.
|
||||
|
||||
A: You are probably connecting into Netware 4.x or IntraNetware. If you want a
|
||||
temporary workaround, add the option "-b" to the ncpmount commandline.
|
||||
For the future you should determine your Directory Services user name and
|
||||
use that instead of your bindery name.
|
||||
86
Makefile
86
Makefile
@@ -2,27 +2,65 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
# KERNEL = 1.2
|
||||
VERSION = 2.0.12
|
||||
|
||||
# If you are using kerneld to autoload ncp support,
|
||||
# uncomment this (kerneld is in linux since about 1.3.57):
|
||||
KERNELD = -DHAVE_KERNELD
|
||||
|
||||
# If your system is ELF, either also do a 'make install', or append the util/
|
||||
# directory where the dynamic library resides to the environment
|
||||
# variable LD_LIBRARY_PATH
|
||||
HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \
|
||||
grep ELF >/dev/null && echo -n yes )
|
||||
|
||||
# If you want to include NDS support for ncpmount uncomment this:
|
||||
# WARNING! NDS support is very beta, uncomment only if you are testing
|
||||
# because anything can happen (like crashing the linux box or nw server).
|
||||
NDS_SUPPORT = 1
|
||||
|
||||
# If you want to include packet signature support uncomment this:
|
||||
# WARNING! packet signature support is in beta stage, uncomment only when you
|
||||
# know what you are doing, anything can happen (like crashing the linux box or
|
||||
# netware server).
|
||||
# When enabling, make sure you have applied the kernel patches too,
|
||||
# otherwise the packet signatures won't work.
|
||||
SIGNATURES = 1
|
||||
|
||||
# Include code for Linux2.0.x
|
||||
MOUNT2 = 1
|
||||
# Include code for Linux2.1.x
|
||||
MOUNT3 = 1
|
||||
|
||||
TOPDIR = $(shell pwd)
|
||||
BINDIR = /usr/bin
|
||||
SBINDIR = /sbin
|
||||
SUBDIRS = lib sutil util ipx-1.0 man
|
||||
|
||||
BINDIR = /usr/local/bin
|
||||
INTERM_BINDIR = $(TOPDIR)/bin
|
||||
SUBDIRS = util ipx-0.75 man
|
||||
KVERSION=$(shell uname -r | cut -b1-3)
|
||||
|
||||
#
|
||||
# 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
|
||||
INCLUDES=-I$(TOPDIR)/include
|
||||
|
||||
export INCLUDES BINDIR INTERM_BINDIR
|
||||
COPT = -O2
|
||||
# COPT += -g
|
||||
CFLAGS = $(COPT) -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
|
||||
export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS NDS_SUPPORT \
|
||||
SIGNATURES MOUNT2 MOUNT3
|
||||
|
||||
all:
|
||||
for i in $(SUBDIRS); do make -C $$i; done
|
||||
set -e; for i in $(SUBDIRS); do make -C $$i all; done
|
||||
@if [ "$(HAVE_ELF)" = yes ] ;\
|
||||
then \
|
||||
echo ; echo ; echo ;\
|
||||
echo Please add \'`pwd`/lib\' to the environment ; \
|
||||
echo variable LD_LIBRARY_PATH by executing ; \
|
||||
echo ;\
|
||||
echo export LD_LIBRARY_PATH=\"\$$LD_LIBRARY_PATH:`pwd`/lib\" ; \
|
||||
echo ;\
|
||||
echo or do a \'make install\'. ;\
|
||||
echo ;\
|
||||
fi
|
||||
|
||||
dep:
|
||||
for i in $(SUBDIRS); do make -C $$i dep; done
|
||||
@@ -30,16 +68,16 @@ dep:
|
||||
install:
|
||||
for i in $(SUBDIRS); do make -C $$i install; done
|
||||
|
||||
clean:
|
||||
rm -f `find . -type f -name '*.o' -print`
|
||||
rm -f `find . -type f -name '*~' -print`
|
||||
rm -f `find . -type f -name '.depend' -print`
|
||||
rm -f `find . -type f -name '*.out' -print`
|
||||
clean_me:
|
||||
rm -f `find -name '*.out'`
|
||||
rm -f `find -name '*~'`
|
||||
rm -f *.tgz
|
||||
|
||||
clean: clean_me
|
||||
for i in $(SUBDIRS); do make -C $$i clean; done
|
||||
|
||||
realclean: clean
|
||||
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
|
||||
make -C util realclean
|
||||
mrproper: clean_me
|
||||
for i in $(SUBDIRS) ipxdump; do make -C $$i mrproper; done
|
||||
|
||||
modules: ncpfs.o
|
||||
|
||||
@@ -51,7 +89,9 @@ dist: tgz
|
||||
make dep
|
||||
make all
|
||||
|
||||
tgz: realclean
|
||||
tgz:
|
||||
indent -kr -i8 `find . -name '*.[ch]'`
|
||||
make mrproper
|
||||
(cd ..; \
|
||||
tar cvf - $(SRCDIR) | \
|
||||
gzip -9 > $(DISTFILE); \
|
||||
|
||||
117
README
117
README
@@ -1,36 +1,70 @@
|
||||
This is version 0.12 of ncpfs, a free NetWare client filesystem for
|
||||
Linux.
|
||||
This is ncpfs, a free NetWare client filesystem for Linux. Besides
|
||||
some little utilities it also contains nprint, which enables you to
|
||||
print on NetWare print queues. The opposite side, pserver, is also
|
||||
provided.
|
||||
|
||||
ncpfs works with NetWare versions 3.x and following. It does NOT work
|
||||
with NetWare version 2.x. Some of the NetWare look-alikes, such as
|
||||
CD-ROM servers WinNT 3.51 Server are also NOT supported. This
|
||||
restriction comes from the fact that ncpfs relies heavily on the name
|
||||
space facilities NetWare supports since version 3. When you want to
|
||||
mount volumes that have been exported by mars_nwe, you have to
|
||||
activate the name space calls in mars_nwe's config.h file, although
|
||||
probably it's more clever to use nfs between two Linux machines.
|
||||
|
||||
The user-space utilities such as nprint and the bindery utils should
|
||||
work with all versions of NetWare.
|
||||
|
||||
ncpfs does NOT support access to the NDS, so if you want to mount
|
||||
volumes exported by a NetWare 4.x server, you will have to install the
|
||||
bindery emulation on that server. If you need access to the NDS, ask
|
||||
Caldera for their CND. See http://www.caldera.com for more
|
||||
information.
|
||||
|
||||
I would like to invite you to write documentation. As those whose
|
||||
native tongue is English might have noticed, my C is better than my
|
||||
English. So I doubt that everything in the man/ subdirectory is
|
||||
written very well. Please feel free to send me any comments about
|
||||
that.
|
||||
|
||||
INSTALLATION
|
||||
|
||||
The installation of ncpfs depends on the kernel version you are
|
||||
using. For kernel 1.2, you should simply type 'make' and look at
|
||||
what's in the bin/ directory after that. Please be sure that your
|
||||
kernel resides in /usr/src/linux, because the file
|
||||
kernel-1.2/src/sock.c has to refer directly to it.
|
||||
Before you start the installation, make sure that your kernel has IPX
|
||||
support compiled in. When 'make config' asks you for
|
||||
|
||||
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.
|
||||
The IPX protocol (CONFIG_IPX) [N/y/m/?]
|
||||
|
||||
If you use Kernel 1.3.54 or later, you might have to recompile your
|
||||
kernel. With these kernels, the kernel part of ncpfs is already
|
||||
included in the main source tree. If you want to use ncpfs, you should
|
||||
say 'y' to 'make config' when you are asked for IPX, and again when it
|
||||
asks for ncpfs. After you have rebooted with the new kernel, 'cat
|
||||
/proc/filesystems' should show you a line saying that the kernel knows
|
||||
ncpfs.
|
||||
simply answer 'y'. Probably you do not need the full internal net that
|
||||
you are asked for next.
|
||||
|
||||
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 not running kerneld, please comment the corresponding line in
|
||||
the Makefile to reflect this.
|
||||
|
||||
If you are not using 2.0.x kernels, you can comment out MOUNT2=1 line
|
||||
in the Makefile.
|
||||
If you are not using 2.1.x kernels, you can comment out MOUNT3=1 line
|
||||
in the Makefile.
|
||||
|
||||
If you are not using NDS access, you can comment out NDS_SUPPORT=1 in
|
||||
the Makefile.
|
||||
If you are not using packet signatures, you can comment out SIGNATURES=1
|
||||
in the Makefile.
|
||||
|
||||
After you adapted your Makefile, type 'make' and, as root, 'make install'.
|
||||
|
||||
|
||||
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
|
||||
@@ -74,7 +108,7 @@ I do not want to leave those unmentioned, who have helped me with
|
||||
ncpfs.
|
||||
|
||||
The most enthusiastic user and tester is certainly Uwe Bonnes
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>. Up to now he's the only one
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>. So far he's the only one
|
||||
who has contributed something, namely manpages and corretions to
|
||||
existing manpages.
|
||||
|
||||
@@ -82,6 +116,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 :-)
|
||||
|
||||
@@ -91,27 +127,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
|
||||
|
||||
18
README.NDS
Normal file
18
README.NDS
Normal file
@@ -0,0 +1,18 @@
|
||||
The NDS login code uses the RSA public key cryptosystem. Because of a patent
|
||||
right on this algorithm (U.S. patent #4,405,829, issued 20 Sep 1983), you
|
||||
are probably not allowed to use this code in the U.S.A. and Canada, and
|
||||
possibly neither in other countries. Check this before you use NDS logins!
|
||||
|
||||
The mpilib.c, mpilib.h, platform.h, and usuals.h in the lib/ directory are
|
||||
taken from the PGP 2.3 source distribution (Copyright 1986-92 by Philip
|
||||
Zimmermann), which is distributed under the GPL, as stated below.
|
||||
|
||||
Excerpt from pgpdoc2.txt (contained in pgp23src.zip):
|
||||
"All the source code for PGP is available for free under the "Copyleft"
|
||||
General Public License from the Free Software Foundation (FSF)."
|
||||
|
||||
For more details on the RSA patent see the pgp23src archive, or more recent
|
||||
PGP packages.
|
||||
|
||||
Arne de Bruijn
|
||||
arne@knoware.nl
|
||||
24
bin/nwbpsecurity
Executable file
24
bin/nwbpsecurity
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
SECURITY=`nwbpvalues $* -c | head -3 | tail -1`
|
||||
WRITE=`echo $SECURITY | cut -b1`
|
||||
READ=`echo $SECURITY | cut -b2`
|
||||
|
||||
function print_sec () {
|
||||
case "$1" in
|
||||
0 ) echo "Everyone"
|
||||
;;
|
||||
1 ) echo "Logged in"
|
||||
;;
|
||||
2 ) echo "Object"
|
||||
;;
|
||||
3 ) echo "Supervisor"
|
||||
;;
|
||||
* ) echo "Bindery"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo -n "Write security: "
|
||||
print_sec $WRITE
|
||||
echo -n "Read security : "
|
||||
print_sec $READ
|
||||
232
contrib/tknwmsg/nwmsg.c
Normal file
232
contrib/tknwmsg/nwmsg.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* nwmsg.c
|
||||
*
|
||||
* Fetch NetWare broadcast messages and write to the user
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <paths.h>
|
||||
#include <utmp.h>
|
||||
#include <mntent.h>
|
||||
#include "ncplib.h"
|
||||
|
||||
static int search_utmp(char *user, char *tty);
|
||||
|
||||
static char *progname;
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ncp_conn *conn;
|
||||
char message[256];
|
||||
|
||||
char *mount_point;
|
||||
struct ncp_fs_info info;
|
||||
struct passwd *pwd;
|
||||
char tty[256];
|
||||
char tty_path[256];
|
||||
FILE *tty_file;
|
||||
FILE *mtab;
|
||||
struct mntent *mnt;
|
||||
long err;
|
||||
|
||||
char tknwmsg_command[256];
|
||||
int error_level;
|
||||
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
openlog("nwmsg", LOG_PID, LOG_LPR);
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "usage: %s mount-point\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
mount_point = argv[1];
|
||||
if ((conn = ncp_open_mount(mount_point, &err)) == NULL)
|
||||
{
|
||||
com_err(progname, err, "in ncp_open_mount");
|
||||
exit(1);
|
||||
}
|
||||
if (ncp_get_broadcast_message(conn, message) != 0)
|
||||
{
|
||||
fprintf(stderr, "%s: could not get broadcast message\n",
|
||||
progname);
|
||||
ncp_close(conn);
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(message) == 0)
|
||||
{
|
||||
syslog(LOG_DEBUG, "no message");
|
||||
exit(0);
|
||||
}
|
||||
#if 0
|
||||
syslog(LOG_DEBUG, "message: %s", message);
|
||||
#endif
|
||||
|
||||
info.version = NCP_GET_FS_INFO_VERSION;
|
||||
if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: could not ioctl on connection: %s\n",
|
||||
progname, strerror(errno));
|
||||
ncp_close(conn);
|
||||
exit(1);
|
||||
}
|
||||
ncp_close(conn);
|
||||
|
||||
if ((pwd = getpwuid(info.mounted_uid)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: user %d not known\n",
|
||||
progname, info.mounted_uid);
|
||||
exit(1);
|
||||
}
|
||||
if ((mtab = fopen(MOUNTED, "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open %s\n",
|
||||
progname, MOUNTED);
|
||||
exit(1);
|
||||
}
|
||||
while ((mnt = getmntent(mtab)) != NULL)
|
||||
{
|
||||
if (strcmp(mnt->mnt_dir, mount_point) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mnt == NULL)
|
||||
{
|
||||
syslog(LOG_DEBUG, "cannot find mtab entry\n");
|
||||
}
|
||||
if (search_utmp(pwd->pw_name, tty) != 0)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
sprintf(tty_path, "/dev/%s", tty);
|
||||
if ((tty_file = fopen(tty_path, "w")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot open %s: %s\n",
|
||||
progname, tty_path, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
fprintf(tty_file, "\r\n\007\007\007Message from NetWare Server: %s\r\n",
|
||||
mnt->mnt_fsname);
|
||||
fprintf(tty_file, "%s\r\n", message);
|
||||
|
||||
|
||||
//formulate the full system command for the X notice...
|
||||
strcat(tknwmsg_command, "/usr/bin/tknwmsg -display :0 ");
|
||||
strcat(tknwmsg_command, "Message from NetWare Server: ");
|
||||
strcat(tknwmsg_command, mnt->mnt_fsname);
|
||||
strcat(tknwmsg_command, " ");
|
||||
strcat(tknwmsg_command, message);
|
||||
strcat(tknwmsg_command, " &");
|
||||
|
||||
//execute this system command...
|
||||
error_level = system(tknwmsg_command);
|
||||
|
||||
|
||||
fclose(tty_file);
|
||||
fclose(mtab);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The following routines have been taken from util-linux-2.5's write.c */
|
||||
|
||||
/*
|
||||
* term_chk - check that a terminal exists, and get the message bit
|
||||
* and the access time
|
||||
*/
|
||||
static int
|
||||
term_chk(char *tty, int *msgsokP, time_t * atimeP, int *showerror)
|
||||
{
|
||||
struct stat s;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
(void) sprintf(path, "/dev/%s", tty);
|
||||
if (stat(path, &s) < 0)
|
||||
{
|
||||
if (showerror)
|
||||
(void) fprintf(stderr,
|
||||
"write: %s: %s\n", path, strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
*msgsokP = (s.st_mode & (S_IWRITE >> 3)) != 0; /* group write bit */
|
||||
*atimeP = s.st_atime;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* search_utmp - search utmp for the "best" terminal to write to
|
||||
*
|
||||
* Ignores terminals with messages disabled, and of the rest, returns
|
||||
* the one with the most recent access time. Returns as value the number
|
||||
* of the user's terminals with messages enabled, or -1 if the user is
|
||||
* not logged in at all.
|
||||
*
|
||||
* Special case for writing to yourself - ignore the terminal you're
|
||||
* writing from, unless that's the only terminal with messages enabled.
|
||||
*/
|
||||
static int
|
||||
search_utmp(char *user, char *tty)
|
||||
{
|
||||
struct utmp u;
|
||||
time_t bestatime, atime;
|
||||
int ufd, nloggedttys, nttys, msgsok, user_is_me;
|
||||
|
||||
char atty[sizeof(u.ut_line) + 1];
|
||||
|
||||
if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0)
|
||||
{
|
||||
perror("utmp");
|
||||
return -1;
|
||||
}
|
||||
nloggedttys = nttys = 0;
|
||||
bestatime = 0;
|
||||
user_is_me = 0;
|
||||
while (read(ufd, (char *) &u, sizeof(u)) == sizeof(u))
|
||||
if (strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0)
|
||||
{
|
||||
++nloggedttys;
|
||||
|
||||
(void) strncpy(atty, u.ut_line, sizeof(u.ut_line));
|
||||
atty[sizeof(u.ut_line)] = '\0';
|
||||
|
||||
if (term_chk(atty, &msgsok, &atime, 0))
|
||||
continue; /* bad term? skip */
|
||||
if (!msgsok)
|
||||
continue; /* skip ttys with msgs off */
|
||||
|
||||
if (u.ut_type != USER_PROCESS)
|
||||
continue; /* it's not a valid entry */
|
||||
|
||||
++nttys;
|
||||
if (atime > bestatime)
|
||||
{
|
||||
bestatime = atime;
|
||||
(void) strcpy(tty, atty);
|
||||
}
|
||||
}
|
||||
(void) close(ufd);
|
||||
if (nloggedttys == 0)
|
||||
{
|
||||
(void) fprintf(stderr, "write: %s is not logged in\n", user);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
57
contrib/tknwmsg/tknwmsg
Executable file
57
contrib/tknwmsg/tknwmsg
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/wish
|
||||
|
||||
#This is a procedure for centering windows...
|
||||
#
|
||||
#
|
||||
proc center {window_to_center} {
|
||||
|
||||
update idletasks
|
||||
|
||||
set width [expr [winfo reqwidth $window_to_center]]
|
||||
set height [expr [winfo reqheight $window_to_center]]
|
||||
|
||||
if {$width < 400} {set width 400}
|
||||
|
||||
set x [expr [winfo screenwidth $window_to_center]/2 - $width/2]
|
||||
set y [expr [winfo screenheight $window_to_center]/2 - $height/2]
|
||||
|
||||
wm geometry $window_to_center $width\x$height+$x+$y
|
||||
|
||||
#update idletasks
|
||||
wm deiconify $window_to_center
|
||||
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#This is the main() proc...
|
||||
|
||||
set argv_exist [string length $argv]
|
||||
if {$argv_exist <= 0} {puts "syntax: tkmesg string\a";exit}
|
||||
|
||||
|
||||
wm withdraw .
|
||||
wm title . "Netware Client for Linux"
|
||||
wm resizable . 0 0
|
||||
|
||||
puts "\a"
|
||||
|
||||
label .mesg -text $argv
|
||||
pack .mesg -padx 5 -pady 5
|
||||
|
||||
button .ok -text "Ok" -command exit -width 5
|
||||
pack .ok -padx 5 -pady 5
|
||||
|
||||
focus .ok
|
||||
bind .ok <Return> exit
|
||||
|
||||
|
||||
center .
|
||||
|
||||
#beep the users console after the window appears...
|
||||
set ofd [open /dev/console w]
|
||||
puts $ofd "\a"
|
||||
close $ofd
|
||||
BIN
contrib/tknwmsg/tknwmsg.gif
Normal file
BIN
contrib/tknwmsg/tknwmsg.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
29
contrib/tknwmsg/tknwmsg.html
Normal file
29
contrib/tknwmsg/tknwmsg.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE></TITLE>
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (X11; I; Linux 2.0.25 i586) [Netscape]">
|
||||
</HEAD>
|
||||
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EF" VLINK="#51188E" ALINK="#FF0000">
|
||||
|
||||
<CENTER><P><FONT SIZE=+3>Tknwmsg</FONT></P></CENTER>
|
||||
|
||||
<P>Recieve NetWare broadcasts in a dialog under Linux.</P>
|
||||
|
||||
<P>The original source was included in the ncpfs package distributed on
|
||||
sunsite.unc.edu. The modified source to nwmsg.c and a tcl/tk script can
|
||||
be downloaded here. The <A HREF="tknwmsg_README">tknwmsg_README</A> is
|
||||
also available for download.</P>
|
||||
|
||||
<P>The only requirements for installation are a system with tcl/tk installed
|
||||
and X running. The system() command will fail if X is not running.</P>
|
||||
|
||||
<P>
|
||||
<HR WIDTH="100%"></P>
|
||||
|
||||
<P><A HREF="mailto:kburto1@umbc.edu">Kevin Burton</A></P>
|
||||
|
||||
<P><A HREF="http://www.gl.umbc.edu/~kburto1/kburto1.html">http://www.gl.umbc.edu/~kburto1/kburto1.html</A></P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
40
contrib/tknwmsg/tknwmsg_README
Normal file
40
contrib/tknwmsg/tknwmsg_README
Normal file
@@ -0,0 +1,40 @@
|
||||
Tknwmsg 1.0 for NCPFS.
|
||||
|
||||
Kevin Burton (kburto1@umbc.edu), Copyright 1996
|
||||
Distributed under GPL (GNU Public License)
|
||||
|
||||
-- INTRO --
|
||||
|
||||
Tknwmesg is a extension for ncpfs for linux that allows users to recived messages
|
||||
while under an X console.
|
||||
|
||||
Essentially it is an extension for nwmsg that comes with ncpfs. The only
|
||||
changes are a system() call to a tk script that will run a dialog with an "ok"
|
||||
button under X.
|
||||
|
||||
-- INSTALLATION --
|
||||
TCL/TK must be installed on your system. If they are not then you will have to
|
||||
get the source for their installation if you want to run tkmesg.
|
||||
|
||||
- Download ncpfs from sunsite.unc.edu
|
||||
- Run "su" to become root if you are not already root.
|
||||
- Unpack ncpfs in a temporary directory.
|
||||
- copy the Tknwmsg nwmsg.c to util/nwmsg.c in your ncpfs directory.
|
||||
- copy tknwmsg to /usr/bin
|
||||
- change to your nwmsg directory.
|
||||
- run "make all;make install" and the new version of tknwmsg will be
|
||||
installed.
|
||||
|
||||
-- USE --
|
||||
|
||||
- At least 1 terminal on the local system must be have "mesg y". Else
|
||||
no GUI dialog will be displayed.
|
||||
|
||||
Using mesg y in a .bashrc will not work. The only way that I have
|
||||
found to do this is to have chmod a+w /dev/ttyp? in Xsession or
|
||||
$HOME/.xsession. Also it may be necessary to have .bashrc do the
|
||||
same thing if users are starting and stopping xterms.
|
||||
|
||||
|
||||
|
||||
|
||||
40
include/com_err.h
Normal file
40
include/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) */
|
||||
22
include/glibstub.h
Normal file
22
include/glibstub.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef __GLIBSTUB_H__
|
||||
#define __GLIBSTUB_H__
|
||||
|
||||
#undef GLIBCHDR
|
||||
#ifdef __GLIBC__
|
||||
#if __GLIBC__ >= 2
|
||||
#define GLIBCHDR
|
||||
#endif
|
||||
#endif
|
||||
#ifdef GLIBCHDR
|
||||
#define HAVE_NETIPX_IPX_H
|
||||
#define HAVE_SYS_MOUNT_H
|
||||
#define HAVE_NET_ROUTE_H
|
||||
#define HAVE_NET_IF_H
|
||||
#else
|
||||
#undef HAVE_NETIPX_IPX_H
|
||||
#undef HAVE_SYS_MOUNT_H
|
||||
#undef HAVE_NET_ROUTE_H
|
||||
#undef HAVE_NET_IF_H
|
||||
#endif
|
||||
#endif /* __GLIBSTUB_H__ */
|
||||
|
||||
100
include/ipxlib.h
Normal file
100
include/ipxlib.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* ipxlib.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IPXLIB_H
|
||||
#define _IPXLIB_H
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "ncp.h"
|
||||
#include "kernel/ipx.h"
|
||||
|
||||
typedef u_int32_t IPXNet;
|
||||
typedef u_int16_t IPXPort;
|
||||
typedef u_int8_t IPXNode[IPX_NODE_LEN];
|
||||
|
||||
#define IPX_USER_PTYPE (0x00)
|
||||
#define IPX_RIP_PTYPE (0x01)
|
||||
#define IPX_SAP_PTYPE (0x04)
|
||||
#define IPX_AUTO_PORT (0x0000)
|
||||
#define IPX_SAP_PORT (0x0452)
|
||||
#define IPX_RIP_PORT (0x0453)
|
||||
|
||||
#define IPX_SAP_GENERAL_QUERY (0x0001)
|
||||
#define IPX_SAP_GENERAL_RESPONSE (0x0002)
|
||||
#define IPX_SAP_NEAREST_QUERY (0x0003)
|
||||
#define IPX_SAP_NEAREST_RESPONSE (0x0004)
|
||||
|
||||
#define IPX_SAP_FILE_SERVER (0x0004)
|
||||
|
||||
struct sap_query
|
||||
{
|
||||
u_int16_t query_type; /* net order */
|
||||
u_int16_t server_type; /* net order */
|
||||
};
|
||||
|
||||
struct sap_server_ident
|
||||
{
|
||||
u_int16_t server_type __attribute__((packed));
|
||||
char server_name[48] __attribute__((packed));
|
||||
IPXNet server_network __attribute__((packed));
|
||||
IPXNode server_node __attribute__((packed));
|
||||
IPXPort server_port __attribute__((packed));
|
||||
u_int16_t intermediate_network __attribute__((packed));
|
||||
};
|
||||
|
||||
#define IPX_RIP_REQUEST (0x1)
|
||||
#define IPX_RIP_RESPONSE (0x2)
|
||||
|
||||
struct ipx_rip_packet
|
||||
{
|
||||
u_int16_t operation __attribute__((packed));
|
||||
struct ipx_rt_def
|
||||
{
|
||||
u_int16_t network __attribute__((packed));
|
||||
u_int16_t hops __attribute__((packed));
|
||||
u_int16_t ticks __attribute__((packed));
|
||||
}
|
||||
rt[1] __attribute__((packed));
|
||||
};
|
||||
|
||||
#define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff")
|
||||
#define IPX_THIS_NODE ("\0\0\0\0\0\0")
|
||||
#define IPX_THIS_NET (0)
|
||||
|
||||
#ifndef IPX_NODE_LEN
|
||||
#define IPX_NODE_LEN (6)
|
||||
#endif
|
||||
|
||||
void
|
||||
ipx_print_node(IPXNode node);
|
||||
void
|
||||
ipx_print_network(IPXNet net);
|
||||
void
|
||||
ipx_print_port(IPXPort port);
|
||||
void
|
||||
ipx_print_saddr(struct sockaddr_ipx *sipx);
|
||||
void
|
||||
ipx_fprint_node(FILE * file, IPXNode node);
|
||||
void
|
||||
ipx_fprint_network(FILE * file, IPXNet net);
|
||||
void
|
||||
ipx_fprint_port(FILE * file, IPXPort port);
|
||||
void
|
||||
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx);
|
||||
int
|
||||
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
|
||||
void
|
||||
ipx_assign_node(IPXNode dest, IPXNode src);
|
||||
int
|
||||
ipx_node_equal(IPXNode n1, IPXNode n2);
|
||||
|
||||
#ifdef __MAKE_NCPMOUNT__
|
||||
int
|
||||
ipx_sscanf_saddr(char* buf, struct sockaddr_ipx* sipx);
|
||||
#endif
|
||||
|
||||
#endif /* _IPXLIB_H */
|
||||
11
include/kernel/fs.h
Normal file
11
include/kernel/fs.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _KERNEL_FS_H
|
||||
#define _KERNEL_FS_H
|
||||
|
||||
#include "glibstub.h"
|
||||
#ifdef HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
#else
|
||||
#include <linux/fs.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
11
include/kernel/if.h
Normal file
11
include/kernel/if.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _KERNEL_IF_H
|
||||
#define _KERNEL_IF_H
|
||||
|
||||
#include "glibstub.h"
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#else
|
||||
#include <linux/if.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
11
include/kernel/ipx.h
Normal file
11
include/kernel/ipx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _KERNEL_IPX_H
|
||||
#define _KERNEL_IPX_H
|
||||
|
||||
#include "glibstub.h"
|
||||
#ifdef HAVE_NETIPX_IPX_H
|
||||
#include <netipx/ipx.h>
|
||||
#else
|
||||
#include <linux/ipx.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
196
include/kernel/ncp.h
Normal file
196
include/kernel/ncp.h
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* ncp.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
* Modified for sparc by J.F. Chadima
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_NCP_H
|
||||
#define _LINUX_NCP_H
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/ipx.h"
|
||||
|
||||
#define NCP_PTYPE (0x11)
|
||||
#define NCP_PORT (0x0451)
|
||||
|
||||
#define NCP_ALLOC_SLOT_REQUEST (0x1111)
|
||||
#define NCP_REQUEST (0x2222)
|
||||
#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
|
||||
|
||||
struct ncp_request_header {
|
||||
u_int16_t type __attribute__((packed));
|
||||
u_int8_t sequence __attribute__((packed));
|
||||
u_int8_t conn_low __attribute__((packed));
|
||||
u_int8_t task __attribute__((packed));
|
||||
u_int8_t conn_high __attribute__((packed));
|
||||
u_int8_t function __attribute__((packed));
|
||||
u_int8_t data[0] __attribute__((packed));
|
||||
};
|
||||
|
||||
#define NCP_REPLY (0x3333)
|
||||
#define NCP_POSITIVE_ACK (0x9999)
|
||||
|
||||
struct ncp_reply_header {
|
||||
__u16 type __attribute__((packed));
|
||||
__u8 sequence __attribute__((packed));
|
||||
__u8 conn_low __attribute__((packed));
|
||||
__u8 task __attribute__((packed));
|
||||
__u8 conn_high __attribute__((packed));
|
||||
__u8 completion_code __attribute__((packed));
|
||||
__u8 connection_state __attribute__((packed));
|
||||
__u8 data[0] __attribute__((packed));
|
||||
};
|
||||
|
||||
#define NCP_VOLNAME_LEN (16)
|
||||
#define NCP_NUMBER_OF_VOLUMES (64)
|
||||
struct ncp_volume_info {
|
||||
__u32 total_blocks;
|
||||
__u32 free_blocks;
|
||||
__u32 purgeable_blocks;
|
||||
__u32 not_yet_purgeable_blocks;
|
||||
__u32 total_dir_entries;
|
||||
__u32 available_dir_entries;
|
||||
__u8 sectors_per_block;
|
||||
char volume_name[NCP_VOLNAME_LEN + 1];
|
||||
};
|
||||
|
||||
/* these define the attribute byte as seen by NCP */
|
||||
#define aRONLY (ntohl(0x01000000))
|
||||
#define aHIDDEN (ntohl(0x02000000))
|
||||
#define aSYSTEM (ntohl(0x04000000))
|
||||
#define aEXECUTE (ntohl(0x08000000))
|
||||
#define aDIR (ntohl(0x10000000))
|
||||
#define aARCH (ntohl(0x20000000))
|
||||
|
||||
#define AR_READ (ntohs(0x0100))
|
||||
#define AR_WRITE (ntohs(0x0200))
|
||||
#define AR_EXCLUSIVE (ntohs(0x2000))
|
||||
|
||||
#define NCP_FILE_ID_LEN 6
|
||||
|
||||
/* Defines for Name Spaces */
|
||||
#define NW_NS_DOS 0
|
||||
#define NW_NS_MAC 1
|
||||
#define NW_NS_NFS 2
|
||||
#define NW_NS_FTAM 3
|
||||
#define NW_NS_OS2 4
|
||||
|
||||
/* Defines for ReturnInformationMask */
|
||||
#define RIM_NAME (ntohl(0x01000000L))
|
||||
#define RIM_SPACE_ALLOCATED (ntohl(0x02000000L))
|
||||
#define RIM_ATTRIBUTES (ntohl(0x04000000L))
|
||||
#define RIM_DATA_SIZE (ntohl(0x08000000L))
|
||||
#define RIM_TOTAL_SIZE (ntohl(0x10000000L))
|
||||
#define RIM_EXT_ATTR_INFO (ntohl(0x20000000L))
|
||||
#define RIM_ARCHIVE (ntohl(0x40000000L))
|
||||
#define RIM_MODIFY (ntohl(0x80000000L))
|
||||
#define RIM_CREATION (ntohl(0x00010000L))
|
||||
#define RIM_OWNING_NAMESPACE (ntohl(0x00020000L))
|
||||
#define RIM_DIRECTORY (ntohl(0x00040000L))
|
||||
#define RIM_RIGHTS (ntohl(0x00080000L))
|
||||
#define RIM_ALL (ntohl(0xFF0F0000L))
|
||||
#define RIM_COMPRESSED_INFO (ntohl(0x00000080L))
|
||||
|
||||
/* open/create modes */
|
||||
#define OC_MODE_OPEN 0x01
|
||||
#define OC_MODE_TRUNCATE 0x02
|
||||
#define OC_MODE_REPLACE 0x02
|
||||
#define OC_MODE_CREATE 0x08
|
||||
|
||||
/* open/create results */
|
||||
#define OC_ACTION_NONE 0x00
|
||||
#define OC_ACTION_OPEN 0x01
|
||||
#define OC_ACTION_CREATE 0x02
|
||||
#define OC_ACTION_TRUNCATE 0x04
|
||||
#define OC_ACTION_REPLACE 0x04
|
||||
|
||||
/* access rights attributes */
|
||||
#ifndef AR_READ_ONLY
|
||||
#define AR_READ_ONLY 0x0001
|
||||
#define AR_WRITE_ONLY 0x0002
|
||||
#define AR_DENY_READ 0x0004
|
||||
#define AR_DENY_WRITE 0x0008
|
||||
#define AR_COMPATIBILITY 0x0010
|
||||
#define AR_WRITE_THROUGH 0x0040
|
||||
#define AR_OPEN_COMPRESSED 0x0100
|
||||
#endif
|
||||
|
||||
struct nw_info_struct {
|
||||
__u32 spaceAlloc __attribute__((packed));
|
||||
__u32 attributes __attribute__((packed));
|
||||
__u16 flags __attribute__((packed));
|
||||
__u32 dataStreamSize __attribute__((packed));
|
||||
__u32 totalStreamSize __attribute__((packed));
|
||||
__u16 numberOfStreams __attribute__((packed));
|
||||
__u16 creationTime __attribute__((packed));
|
||||
__u16 creationDate __attribute__((packed));
|
||||
__u32 creatorID __attribute__((packed));
|
||||
__u16 modifyTime __attribute__((packed));
|
||||
__u16 modifyDate __attribute__((packed));
|
||||
__u32 modifierID __attribute__((packed));
|
||||
__u16 lastAccessDate __attribute__((packed));
|
||||
__u16 archiveTime __attribute__((packed));
|
||||
__u16 archiveDate __attribute__((packed));
|
||||
__u32 archiverID __attribute__((packed));
|
||||
__u16 inheritedRightsMask __attribute__((packed));
|
||||
__u32 dirEntNum __attribute__((packed));
|
||||
__u32 DosDirNum __attribute__((packed));
|
||||
__u32 volNumber __attribute__((packed));
|
||||
__u32 EADataSize __attribute__((packed));
|
||||
__u32 EAKeyCount __attribute__((packed));
|
||||
__u32 EAKeySize __attribute__((packed));
|
||||
__u32 NSCreator __attribute__((packed));
|
||||
__u8 nameLen __attribute__((packed));
|
||||
__u8 entryName[256] __attribute__((packed));
|
||||
};
|
||||
|
||||
/* modify mask - use with MODIFY_DOS_INFO structure */
|
||||
#define DM_ATTRIBUTES (ntohl(0x02000000L))
|
||||
#define DM_CREATE_DATE (ntohl(0x04000000L))
|
||||
#define DM_CREATE_TIME (ntohl(0x08000000L))
|
||||
#define DM_CREATOR_ID (ntohl(0x10000000L))
|
||||
#define DM_ARCHIVE_DATE (ntohl(0x20000000L))
|
||||
#define DM_ARCHIVE_TIME (ntohl(0x40000000L))
|
||||
#define DM_ARCHIVER_ID (ntohl(0x80000000L))
|
||||
#define DM_MODIFY_DATE (ntohl(0x00010000L))
|
||||
#define DM_MODIFY_TIME (ntohl(0x00020000L))
|
||||
#define DM_MODIFIER_ID (ntohl(0x00040000L))
|
||||
#define DM_LAST_ACCESS_DATE (ntohl(0x00080000L))
|
||||
#define DM_INHERITED_RIGHTS_MASK (ntohl(0x00100000L))
|
||||
#define DM_MAXIMUM_SPACE (ntohl(0x00200000L))
|
||||
|
||||
struct nw_modify_dos_info {
|
||||
__u32 attributes __attribute__((packed));
|
||||
__u16 creationDate __attribute__((packed));
|
||||
__u16 creationTime __attribute__((packed));
|
||||
__u32 creatorID __attribute__((packed));
|
||||
__u16 modifyDate __attribute__((packed));
|
||||
__u16 modifyTime __attribute__((packed));
|
||||
__u32 modifierID __attribute__((packed));
|
||||
__u16 archiveDate __attribute__((packed));
|
||||
__u16 archiveTime __attribute__((packed));
|
||||
__u32 archiverID __attribute__((packed));
|
||||
__u16 lastAccessDate __attribute__((packed));
|
||||
__u16 inheritanceGrantMask __attribute__((packed));
|
||||
__u16 inheritanceRevokeMask __attribute__((packed));
|
||||
__u32 maximumSpace __attribute__((packed));
|
||||
};
|
||||
|
||||
struct nw_file_info {
|
||||
struct nw_info_struct i;
|
||||
int opened;
|
||||
int access;
|
||||
__u32 server_file_handle __attribute__((packed));
|
||||
__u8 open_create_action __attribute__((packed));
|
||||
__u8 file_handle[6] __attribute__((packed));
|
||||
};
|
||||
|
||||
struct nw_search_sequence {
|
||||
__u8 volNumber __attribute__((packed));
|
||||
__u32 dirBase __attribute__((packed));
|
||||
__u32 sequence __attribute__((packed));
|
||||
};
|
||||
|
||||
#endif /* _LINUX_NCP_H */
|
||||
88
include/kernel/ncp_fs.h
Normal file
88
include/kernel/ncp_fs.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* ncp_fs.h
|
||||
*
|
||||
* Copyright (C) 1995, 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _KERNEL_NCP_FS_H
|
||||
#define _KERNEL_NCP_FS_H
|
||||
|
||||
#include "kernel/fs.h"
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* ioctl commands
|
||||
*/
|
||||
|
||||
struct ncp_ioctl_request {
|
||||
unsigned int function;
|
||||
unsigned int size;
|
||||
char *data;
|
||||
};
|
||||
|
||||
struct ncp_fs_info {
|
||||
int version;
|
||||
struct sockaddr_ipx addr;
|
||||
__kerXX_uid_t mounted_uid;
|
||||
int connection; /* Connection number the server assigned us */
|
||||
int buffer_size; /* The negotiated buffer size, to be
|
||||
used for read/write requests! */
|
||||
|
||||
int volume_number;
|
||||
__u32 directory_id;
|
||||
};
|
||||
|
||||
struct ncp_sign_init
|
||||
{
|
||||
char sign_root[8];
|
||||
char sign_last[16];
|
||||
};
|
||||
|
||||
struct ncp_lock_ioctl
|
||||
{
|
||||
#define NCP_LOCK_LOG 0
|
||||
#define NCP_LOCK_SH 1
|
||||
#define NCP_LOCK_EX 2
|
||||
#define NCP_LOCK_CLEAR 256
|
||||
int cmd;
|
||||
int origin;
|
||||
unsigned int offset;
|
||||
unsigned int length;
|
||||
#define NCP_LOCK_DEFAULT_TIMEOUT 18
|
||||
#define NCP_LOCK_MAX_TIMEOUT 180
|
||||
int timeout;
|
||||
};
|
||||
|
||||
struct ncp_setroot_ioctl
|
||||
{
|
||||
int volNumber;
|
||||
int namespace;
|
||||
__u32 dirEntNum;
|
||||
};
|
||||
|
||||
#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request)
|
||||
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, __kernel_uid_t)
|
||||
#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3)
|
||||
|
||||
#define NCP_GET_FS_INFO_VERSION (1)
|
||||
#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info)
|
||||
|
||||
#define NCP_IOC_SIGN_INIT _IOR('n', 5, struct ncp_sign_init)
|
||||
#define NCP_IOC_SIGN_WANTED _IOR('n', 6, int)
|
||||
#define NCP_IOC_SET_SIGN_WANTED _IOW('n', 6, int)
|
||||
|
||||
#define NCP_IOC_LOCKUNLOCK _IOR('n', 7, struct ncp_lock_ioctl)
|
||||
|
||||
#define NCP_IOC_GETROOT _IOW('n', 8, struct ncp_setroot_ioctl)
|
||||
#define NCP_IOC_SETROOT _IOR('n', 8, struct ncp_setroot_ioctl)
|
||||
/*
|
||||
* The packet size to allocate. One page should be enough.
|
||||
*/
|
||||
#define NCP_PACKET_SIZE 4070
|
||||
|
||||
#define NCP_MAXPATHLEN 255
|
||||
#define NCP_MAXNAMELEN 14
|
||||
|
||||
#endif /* _LINUX_NCP_FS_H */
|
||||
12
include/kernel/route.h
Normal file
12
include/kernel/route.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __KERNEL_ROUTE_H__
|
||||
#define __KERNEL_ROUTE_H__
|
||||
|
||||
#include "glibstub.h"
|
||||
#ifdef HAVE_NET_ROUTE_H
|
||||
#include <net/route.h>
|
||||
#else
|
||||
#include <linux/route.h>
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL_ROUTE_H__ */
|
||||
|
||||
40
include/kernel/types.h
Normal file
40
include/kernel/types.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef __KERNEL_TYPES_H__
|
||||
#define __KERNEL_TYPES_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#undef __u8
|
||||
#undef __u16
|
||||
#undef __u32
|
||||
#define __u8 u_int8_t
|
||||
#define __u16 u_int16_t
|
||||
#define __u32 u_int32_t
|
||||
|
||||
typedef u_int16_t __kerXX_uid_t;
|
||||
|
||||
#include <asm/posix_types.h>
|
||||
|
||||
typedef __kernel_pid_t __ker20_pid_t;
|
||||
typedef __kernel_uid_t __ker20_uid_t;
|
||||
typedef __kernel_gid_t __ker20_gid_t;
|
||||
typedef __kernel_mode_t __ker20_mode_t;
|
||||
|
||||
typedef __kernel_pid_t __ker21_pid_t;
|
||||
typedef __kernel_uid_t __ker21_uid_t;
|
||||
typedef __kernel_gid_t __ker21_gid_t;
|
||||
typedef __kernel_mode_t __ker21_mode_t;
|
||||
|
||||
#ifdef __GLIBC__
|
||||
/* why is this defined in posix_types ???? dirty hack... */
|
||||
#undef __FD_CLR
|
||||
#undef __FD_SET
|
||||
#undef __FD_ISSET
|
||||
#undef __FD_ZERO
|
||||
#ifdef _SELECTBITS_H
|
||||
#undef _SELECTBITS_H
|
||||
#include <selectbits.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL_TYPES_H__ */
|
||||
|
||||
122
include/ncp.h
Normal file
122
include/ncp.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* ncp.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
* Modified for sparc by J.F. Chadima
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NCP_H
|
||||
#define _NCP_H
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/ipx.h"
|
||||
#include "kernel/ncp.h"
|
||||
#include "kernel/ncp_fs.h"
|
||||
|
||||
#define NCP_BINDERY_USER (0x0001)
|
||||
#define NCP_BINDERY_UGROUP (0x0002)
|
||||
#define NCP_BINDERY_PQUEUE (0x0003)
|
||||
#define NCP_BINDERY_FSERVER (0x0004)
|
||||
#define NCP_BINDERY_NAME_LEN (48)
|
||||
struct ncp_bindery_object {
|
||||
__u32 object_id;
|
||||
__u16 object_type;
|
||||
__u8 object_name[NCP_BINDERY_NAME_LEN];
|
||||
__u8 object_flags;
|
||||
__u8 object_security;
|
||||
__u8 object_has_prop;
|
||||
};
|
||||
|
||||
struct nw_property {
|
||||
__u8 value[128];
|
||||
__u8 more_flag;
|
||||
__u8 property_flag;
|
||||
};
|
||||
|
||||
struct prop_net_address {
|
||||
__u32 network __attribute__((packed));
|
||||
__u8 node[IPX_NODE_LEN] __attribute__((packed));
|
||||
__u16 port __attribute__((packed));
|
||||
};
|
||||
|
||||
struct ncp_filesearch_info {
|
||||
__u8 volume_number;
|
||||
__u16 directory_id;
|
||||
__u16 sequence_no;
|
||||
__u8 access_rights;
|
||||
};
|
||||
|
||||
#define NCP_MAX_FILENAME (14)
|
||||
struct ncp_file_info {
|
||||
__u8 file_id[NCP_FILE_ID_LEN];
|
||||
char file_name[NCP_MAX_FILENAME + 1];
|
||||
__u8 file_attributes;
|
||||
__u8 file_mode;
|
||||
__u32 file_length;
|
||||
__u16 creation_date;
|
||||
__u16 access_date;
|
||||
__u16 update_date;
|
||||
__u16 update_time;
|
||||
};
|
||||
|
||||
struct nw_queue_job_entry {
|
||||
__u16 InUse __attribute__((packed));
|
||||
__u32 prev __attribute__((packed));
|
||||
__u32 next __attribute__((packed));
|
||||
__u32 ClientStation __attribute__((packed));
|
||||
__u32 ClientTask __attribute__((packed));
|
||||
__u32 ClientObjectID __attribute__((packed));
|
||||
__u32 TargetServerID __attribute__((packed));
|
||||
__u8 TargetExecTime[6] __attribute__((packed));
|
||||
__u8 JobEntryTime[6] __attribute__((packed));
|
||||
__u32 JobNumber __attribute__((packed));
|
||||
__u16 JobType __attribute__((packed));
|
||||
__u16 JobPosition __attribute__((packed));
|
||||
__u16 JobControlFlags __attribute__((packed));
|
||||
__u8 FileNameLen __attribute__((packed));
|
||||
char JobFileName[13] __attribute__((packed));
|
||||
__u32 JobFileHandle __attribute__((packed));
|
||||
__u32 ServerStation __attribute__((packed));
|
||||
__u32 ServerTaskNumber __attribute__((packed));
|
||||
__u32 ServerObjectID __attribute__((packed));
|
||||
char JobTextDescription[50] __attribute__((packed));
|
||||
char ClientRecordArea[152] __attribute__((packed));
|
||||
};
|
||||
|
||||
struct queue_job {
|
||||
struct nw_queue_job_entry j;
|
||||
__u8 file_handle[6];
|
||||
};
|
||||
|
||||
#define QJE_OPER_HOLD 0x80
|
||||
#define QJE_USER_HOLD 0x40
|
||||
#define QJE_ENTRYOPEN 0x20
|
||||
#define QJE_SERV_RESTART 0x10
|
||||
#define QJE_SERV_AUTO 0x08
|
||||
|
||||
/* ClientRecordArea for print jobs */
|
||||
|
||||
#define KEEP_ON 0x0400
|
||||
#define NO_FORM_FEED 0x0800
|
||||
#define NOTIFICATION 0x1000
|
||||
#define DELETE_FILE 0x2000
|
||||
#define EXPAND_TABS 0x4000
|
||||
#define PRINT_BANNER 0x8000
|
||||
|
||||
struct print_job_record {
|
||||
__u8 Version __attribute__((packed));
|
||||
__u8 TabSize __attribute__((packed));
|
||||
__u16 Copies __attribute__((packed));
|
||||
__u16 CtrlFlags __attribute__((packed));
|
||||
__u16 Lines __attribute__((packed));
|
||||
__u16 Rows __attribute__((packed));
|
||||
char FormName[16] __attribute__((packed));
|
||||
__u8 Reserved[6] __attribute__((packed));
|
||||
char BannerName[13] __attribute__((packed));
|
||||
char FnameBanner[13] __attribute__((packed));
|
||||
char FnameHeader[14] __attribute__((packed));
|
||||
char Path[80] __attribute__((packed));
|
||||
};
|
||||
|
||||
#endif /* _NCP_H */
|
||||
738
include/ncplib.h
Normal file
738
include/ncplib.h
Normal file
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
* ncplib.h
|
||||
*
|
||||
* Copyright (C) 1995, 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NCPLIB_H
|
||||
#define _NCPLIB_H
|
||||
|
||||
#include "ncp.h"
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef SIGNATURES
|
||||
#ifndef NCP_IOC_SIGN_INIT
|
||||
#undef SIGNATURES
|
||||
#endif /* NCP_IOC_SIGN_INIT */
|
||||
#endif /* SIGNATURES */
|
||||
|
||||
#include "ipxlib.h"
|
||||
#include "com_err.h"
|
||||
|
||||
typedef __u8 byte;
|
||||
typedef __u16 word;
|
||||
typedef __u32 dword;
|
||||
|
||||
#ifndef memzero
|
||||
#include <string.h>
|
||||
#define memzero(object) memset(&(object), 0, sizeof(object))
|
||||
#endif
|
||||
|
||||
#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
|
||||
#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos))
|
||||
#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
|
||||
|
||||
static inline word
|
||||
WVAL_HL(__u8 * buf, int pos)
|
||||
{
|
||||
return PVAL(buf, pos) << 8 | PVAL(buf, pos + 1);
|
||||
}
|
||||
static inline dword
|
||||
DVAL_HL(__u8 * buf, int pos)
|
||||
{
|
||||
return WVAL_HL(buf, pos) << 16 | WVAL_HL(buf, pos + 2);
|
||||
}
|
||||
static inline void
|
||||
WSET_HL(__u8 * buf, int pos, word val)
|
||||
{
|
||||
BSET(buf, pos, val >> 8);
|
||||
BSET(buf, pos + 1, val & 0xff);
|
||||
}
|
||||
static inline void
|
||||
DSET_HL(__u8 * buf, int pos, dword val)
|
||||
{
|
||||
WSET_HL(buf, pos, val >> 16);
|
||||
WSET_HL(buf, pos + 2, val & 0xffff);
|
||||
}
|
||||
|
||||
|
||||
/* we know that the 386 can handle misalignment and has the "right"
|
||||
byteorder */
|
||||
#if defined(__i386__)
|
||||
|
||||
static inline word
|
||||
WVAL_LH(__u8 * buf, int pos)
|
||||
{
|
||||
return *((word *) (buf + pos));
|
||||
}
|
||||
static inline dword
|
||||
DVAL_LH(__u8 * buf, int pos)
|
||||
{
|
||||
return *((dword *) (buf + pos));
|
||||
}
|
||||
static inline void
|
||||
WSET_LH(__u8 * buf, int pos, word val)
|
||||
{
|
||||
*((word *) (buf + pos)) = val;
|
||||
}
|
||||
static inline void
|
||||
DSET_LH(__u8 * buf, int pos, dword val)
|
||||
{
|
||||
*((dword *) (buf + pos)) = val;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline word
|
||||
WVAL_LH(__u8 * buf, int pos)
|
||||
{
|
||||
return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8;
|
||||
}
|
||||
static inline dword
|
||||
DVAL_LH(__u8 * buf, int pos)
|
||||
{
|
||||
return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16;
|
||||
}
|
||||
static inline void
|
||||
WSET_LH(__u8 * buf, int pos, word val)
|
||||
{
|
||||
BSET(buf, pos, val & 0xff);
|
||||
BSET(buf, pos + 1, val >> 8);
|
||||
}
|
||||
static inline void
|
||||
DSET_LH(__u8 * buf, int pos, dword val)
|
||||
{
|
||||
WSET_LH(buf, pos, val & 0xffff);
|
||||
WSET_LH(buf, pos + 2, val >> 16);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
str_upper(char *name);
|
||||
|
||||
enum connect_state
|
||||
{
|
||||
NOT_CONNECTED = 0,
|
||||
CONN_PERMANENT,
|
||||
CONN_TEMPORARY
|
||||
};
|
||||
|
||||
struct ncp_conn
|
||||
{
|
||||
|
||||
enum connect_state is_connected;
|
||||
|
||||
char server[NCP_BINDERY_NAME_LEN];
|
||||
char user[NCP_BINDERY_NAME_LEN];
|
||||
|
||||
struct ncp_fs_info i;
|
||||
|
||||
/* Fields for use with permanent connections */
|
||||
int mount_fid;
|
||||
char mount_point[MAXPATHLEN];
|
||||
|
||||
/* Fields for use with temporary connections */
|
||||
int ncp_sock;
|
||||
int wdog_sock;
|
||||
int wdog_pid;
|
||||
__u8 sequence;
|
||||
int completion;
|
||||
int conn_status;
|
||||
int reply_size;
|
||||
|
||||
/* Fields used to setup ncp requests */
|
||||
int current_size;
|
||||
int has_subfunction;
|
||||
int verbose;
|
||||
int ncp_reply_size;
|
||||
|
||||
int lock;
|
||||
|
||||
char packet[NCP_PACKET_SIZE];
|
||||
#ifdef SIGNATURES
|
||||
/* Fields used to make packet signatures */
|
||||
int sign_wanted;
|
||||
int sign_active;
|
||||
char sign_root[8];
|
||||
char sign_last[16];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ncp_conn_spec
|
||||
{
|
||||
char server[NCP_BINDERY_NAME_LEN];
|
||||
char user[NCP_BINDERY_NAME_LEN];
|
||||
uid_t uid;
|
||||
int login_type; /* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */
|
||||
char password[NCP_BINDERY_NAME_LEN];
|
||||
};
|
||||
|
||||
struct ncp_search_seq
|
||||
{
|
||||
struct nw_search_sequence s;
|
||||
int namespace;
|
||||
};
|
||||
|
||||
struct ncp_property_info
|
||||
{
|
||||
__u8 property_name[16];
|
||||
__u8 property_flags;
|
||||
__u8 property_security;
|
||||
__u32 search_instance;
|
||||
__u8 value_available_flag;
|
||||
__u8 more_properties_flag;
|
||||
};
|
||||
|
||||
/* ncp_initialize is the main entry point for user programs which want
|
||||
to connect to a NetWare Server. It looks for -S, -U, -P and -n in
|
||||
the argument list, opens the connection and removes the arguments
|
||||
from the list. It was designed after the X Windows init
|
||||
functions. */
|
||||
struct ncp_conn *
|
||||
ncp_initialize(int *argc, char **argv,
|
||||
int login_necessary, long *err);
|
||||
|
||||
/* You can login as another object by this procedure. As a first use
|
||||
pserver comes to mind. */
|
||||
struct ncp_conn *
|
||||
ncp_initialize_as(int *argc, char **argv,
|
||||
int login_necessary, int login_type, long *err);
|
||||
|
||||
|
||||
/* Open a connection */
|
||||
struct ncp_conn *
|
||||
ncp_open(const struct ncp_conn_spec *spec, long *err);
|
||||
|
||||
/* Open a connection on an existing mount point */
|
||||
struct ncp_conn *
|
||||
ncp_open_mount(const char *mount_point, long *err);
|
||||
|
||||
/* Find a permanent connection that fits the spec, return NULL if
|
||||
* there is none. */
|
||||
char *
|
||||
ncp_find_permanent(const struct ncp_conn_spec *spec);
|
||||
|
||||
/* Find the address of a file server */
|
||||
struct sockaddr_ipx *
|
||||
ncp_find_fileserver(const char *server_name, long *err);
|
||||
|
||||
/* Find the address of a server */
|
||||
struct sockaddr_ipx *
|
||||
ncp_find_server(const char **server_name, int type, long *err);
|
||||
|
||||
/* Detach from a permanent connection or destroy a temporary
|
||||
connection */
|
||||
long
|
||||
ncp_close(struct ncp_conn *conn);
|
||||
|
||||
/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable
|
||||
connections */
|
||||
|
||||
struct ncp_conn_ent
|
||||
{
|
||||
char server[NCP_BINDERY_NAME_LEN];
|
||||
char user[NCP_BINDERY_NAME_LEN];
|
||||
uid_t uid;
|
||||
char mount_point[MAXPATHLEN];
|
||||
};
|
||||
|
||||
struct ncp_conn_ent *
|
||||
ncp_get_conn_ent(FILE * filep);
|
||||
|
||||
#define NWCLIENT (".nwclient")
|
||||
#define NWC_NOPASSWORD ("-")
|
||||
|
||||
/* find an appropriate connection */
|
||||
|
||||
struct ncp_conn_spec *
|
||||
ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
int login_necessary, uid_t uid, long *err);
|
||||
|
||||
long
|
||||
ncp_get_file_server_description_strings(struct ncp_conn *conn,
|
||||
char target[512]);
|
||||
|
||||
long
|
||||
ncp_get_file_server_time(struct ncp_conn *conn, time_t * target);
|
||||
long
|
||||
ncp_set_file_server_time(struct ncp_conn *conn, time_t * source);
|
||||
|
||||
struct ncp_file_server_info
|
||||
{
|
||||
__u8 ServerName[48] __attribute__((packed));
|
||||
__u8 FileServiceVersion __attribute__((packed));
|
||||
__u8 FileServiceSubVersion __attribute__((packed));
|
||||
__u16 MaximumServiceConnections __attribute__((packed));
|
||||
__u16 ConnectionsInUse __attribute__((packed));
|
||||
__u16 NumberMountedVolumes __attribute__((packed));
|
||||
__u8 Revision __attribute__((packed));
|
||||
__u8 SFTLevel __attribute__((packed));
|
||||
__u8 TTSLevel __attribute__((packed));
|
||||
__u16 MaxConnectionsEverUsed __attribute__((packed));
|
||||
__u8 AccountVersion __attribute__((packed));
|
||||
__u8 VAPVersion __attribute__((packed));
|
||||
__u8 QueueVersion __attribute__((packed));
|
||||
__u8 PrintVersion __attribute__((packed));
|
||||
__u8 VirtualConsoleVersion __attribute__((packed));
|
||||
__u8 RestrictionLevel __attribute__((packed));
|
||||
__u8 InternetBridge __attribute__((packed));
|
||||
__u8 Reserved[60] __attribute__((packed));
|
||||
};
|
||||
|
||||
long
|
||||
ncp_get_file_server_information(struct ncp_conn *conn,
|
||||
struct ncp_file_server_info *target);
|
||||
|
||||
long
|
||||
ncp_get_connlist(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
int *returned_no, __u8 conn_numbers[256]);
|
||||
|
||||
long
|
||||
ncp_get_stations_logged_info(struct ncp_conn *conn,
|
||||
__u32 connection,
|
||||
struct ncp_bindery_object *target,
|
||||
time_t * login_time);
|
||||
|
||||
long
|
||||
ncp_get_internet_address(struct ncp_conn *conn,
|
||||
__u32 connection,
|
||||
struct sockaddr_ipx *target,
|
||||
__u8 * conn_type);
|
||||
|
||||
long
|
||||
ncp_send_broadcast(struct ncp_conn *conn,
|
||||
__u8 no_conn, const __u8 * connections,
|
||||
const char *message);
|
||||
|
||||
long
|
||||
ncp_send_broadcast2(struct ncp_conn *conn,
|
||||
unsigned int conns, const unsigned int* connlist,
|
||||
const char* message);
|
||||
|
||||
long
|
||||
ncp_get_encryption_key(struct ncp_conn *conn,
|
||||
char *target);
|
||||
long
|
||||
ncp_get_bindery_object_id(struct ncp_conn *conn,
|
||||
__u16 object_type,
|
||||
const char *object_name,
|
||||
struct ncp_bindery_object *target);
|
||||
long
|
||||
ncp_get_bindery_object_name(struct ncp_conn *conn,
|
||||
__u32 object_id,
|
||||
struct ncp_bindery_object *target);
|
||||
long
|
||||
ncp_scan_bindery_object(struct ncp_conn *conn,
|
||||
__u32 last_id, __u16 object_type, char *search_string,
|
||||
struct ncp_bindery_object *target);
|
||||
long
|
||||
ncp_create_bindery_object(struct ncp_conn *conn,
|
||||
__u16 object_type,
|
||||
const char *object_name,
|
||||
__u8 object_security,
|
||||
__u8 object_status);
|
||||
long
|
||||
ncp_delete_bindery_object(struct ncp_conn *conn,
|
||||
__u16 object_type,
|
||||
const char *object_name);
|
||||
|
||||
long
|
||||
ncp_change_object_security(struct ncp_conn *conn,
|
||||
__u16 object_type,
|
||||
const char *object_name,
|
||||
__u8 security);
|
||||
|
||||
struct ncp_station_addr
|
||||
{
|
||||
__u32 NetWork __attribute__((packed));
|
||||
__u8 Node[6] __attribute__((packed));
|
||||
__u16 Socket __attribute__((packed));
|
||||
};
|
||||
|
||||
struct ncp_prop_login_control
|
||||
{
|
||||
__u8 AccountExpireDate[3] __attribute__((packed));
|
||||
__u8 Disabled __attribute__((packed));
|
||||
__u8 PasswordExpireDate[3] __attribute__((packed));
|
||||
__u8 GraceLogins __attribute__((packed));
|
||||
__u16 PasswordExpireInterval __attribute__((packed));
|
||||
__u8 MaxGraceLogins __attribute__((packed));
|
||||
__u8 MinPasswordLength __attribute__((packed));
|
||||
__u16 MaxConnections __attribute__((packed));
|
||||
__u8 ConnectionTimeMask[42] __attribute__((packed));
|
||||
__u8 LastLogin[6] __attribute__((packed));
|
||||
__u8 RestrictionMask __attribute__((packed));
|
||||
__u8 reserved __attribute__((packed));
|
||||
__u32 MaxDiskUsage __attribute__((packed));
|
||||
__u16 BadLoginCount __attribute__((packed));
|
||||
__u32 BadLoginCountDown __attribute__((packed));
|
||||
struct ncp_station_addr LastIntruder __attribute__((packed));
|
||||
};
|
||||
|
||||
long
|
||||
ncp_read_property_value(struct ncp_conn *conn,
|
||||
int object_type, const char *object_name,
|
||||
int segment, const char *prop_name,
|
||||
struct nw_property *target);
|
||||
long
|
||||
ncp_scan_property(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
__u32 last_id, char *search_string,
|
||||
struct ncp_property_info *property_info);
|
||||
long
|
||||
ncp_add_object_to_set(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const char *property_name,
|
||||
__u16 member_type,
|
||||
const char *member_name);
|
||||
long
|
||||
ncp_change_property_security(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const char *property_name,
|
||||
__u8 property_security);
|
||||
long
|
||||
ncp_create_property(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const char *property_name,
|
||||
__u8 property_flags, __u8 property_security);
|
||||
long
|
||||
ncp_delete_object_from_set(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const char *property_name,
|
||||
__u16 member_type,
|
||||
const char *member_name);
|
||||
long
|
||||
ncp_delete_property(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const char *property_name);
|
||||
long
|
||||
ncp_write_property_value(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const char *property_name,
|
||||
__u8 segment,
|
||||
struct nw_property *property_value);
|
||||
|
||||
/* Bit masks for security flag */
|
||||
#define NCP_SEC_CHECKSUMMING_REQUESTED (1)
|
||||
#define NCP_SEC_SIGNATURE_REQUESTED (2)
|
||||
#define NCP_SEC_COMPLETE_SIGNATURES_REQUESTED (4)
|
||||
#define NCP_SEC_ENCRYPTION_REQUESTED (8)
|
||||
#define NCP_SEC_LIP_DISABLED (128)
|
||||
|
||||
long
|
||||
ncp_get_big_ncp_max_packet_size(struct ncp_conn *conn,
|
||||
__u16 proposed_max_size,
|
||||
__u8 proposed_security_flag,
|
||||
__u16 * accepted_max_size,
|
||||
__u16 * echo_socket,
|
||||
__u8 * accepted_security_flag);
|
||||
|
||||
long
|
||||
ncp_login_encrypted(struct ncp_conn *conn,
|
||||
const struct ncp_bindery_object *object,
|
||||
const unsigned char *key,
|
||||
const unsigned char *passwd);
|
||||
|
||||
long
|
||||
ncp_login_unencrypted(struct ncp_conn *conn,
|
||||
__u16 object_type, const char *object_name,
|
||||
const unsigned char *passwd);
|
||||
|
||||
long
|
||||
ncp_change_login_passwd(struct ncp_conn *conn,
|
||||
const struct ncp_bindery_object *object,
|
||||
const unsigned char *key,
|
||||
const unsigned char *oldpasswd,
|
||||
const unsigned char *newpasswd);
|
||||
|
||||
#define NWE_SIGNATURE_LEVEL_CONFLICT (0x8861)
|
||||
#define NCP_GRACE_PERIOD (0xdf)
|
||||
|
||||
long
|
||||
ncp_login_user(struct ncp_conn *conn,
|
||||
const unsigned char *username,
|
||||
const unsigned char *password);
|
||||
long
|
||||
ncp_get_volume_info_with_number(struct ncp_conn *conn, int n,
|
||||
struct ncp_volume_info *target);
|
||||
|
||||
long
|
||||
ncp_get_volume_number(struct ncp_conn *conn, const char *name,
|
||||
int *target);
|
||||
|
||||
long
|
||||
ncp_file_search_init(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
struct ncp_filesearch_info *target);
|
||||
|
||||
long
|
||||
ncp_file_search_continue(struct ncp_conn *conn,
|
||||
struct ncp_filesearch_info *fsinfo,
|
||||
int attributes, const char *path,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
long
|
||||
ncp_get_finfo(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path, const char *name,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
long
|
||||
ncp_open_file(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
int attr, int access,
|
||||
struct ncp_file_info *target);
|
||||
long
|
||||
ncp_close_file(struct ncp_conn *conn, const char *file_id);
|
||||
|
||||
long
|
||||
ncp_create_newfile(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
int attr,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
long
|
||||
ncp_create_file(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
int attr,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
long
|
||||
ncp_erase_file(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
int attr);
|
||||
|
||||
long
|
||||
ncp_rename_file(struct ncp_conn *conn,
|
||||
int old_handle, const char *old_path,
|
||||
int attr,
|
||||
int new_handle, const char *new_path);
|
||||
|
||||
long
|
||||
ncp_create_directory(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
int inherit_mask);
|
||||
|
||||
long
|
||||
ncp_delete_directory(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path);
|
||||
|
||||
long
|
||||
ncp_rename_directory(struct ncp_conn *conn,
|
||||
int dir_handle,
|
||||
const char *old_path, const char *new_path);
|
||||
|
||||
long
|
||||
ncp_get_trustee(struct ncp_conn *conn, __u32 object_id,
|
||||
__u8 vol, char *path,
|
||||
__u16 * trustee, __u16 * contin);
|
||||
|
||||
long
|
||||
ncp_add_trustee(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path,
|
||||
__u32 object_id, __u8 rights);
|
||||
|
||||
long
|
||||
ncp_delete_trustee(struct ncp_conn *conn,
|
||||
int dir_handle, const char *path, __u32 object_id);
|
||||
|
||||
long
|
||||
ncp_read(struct ncp_conn *conn, const char *file_id,
|
||||
off_t offset, size_t count, char *target);
|
||||
|
||||
long
|
||||
ncp_write(struct ncp_conn *conn, const char *file_id,
|
||||
off_t offset, size_t count, const char *source);
|
||||
|
||||
long
|
||||
ncp_copy_file(struct ncp_conn *conn,
|
||||
const char source_file[6],
|
||||
const char target_file[6],
|
||||
__u32 source_offset,
|
||||
__u32 target_offset,
|
||||
__u32 count,
|
||||
__u32 * copied_count);
|
||||
|
||||
long
|
||||
ncp_obtain_file_or_subdir_info(struct ncp_conn *conn,
|
||||
__u8 source_ns, __u8 target_ns,
|
||||
__u16 search_attribs, __u32 rim,
|
||||
__u8 vol, __u32 dirent, const char *path,
|
||||
struct nw_info_struct *target);
|
||||
|
||||
#define NCP_PERM_READ (0x001)
|
||||
#define NCP_PERM_WRITE (0x002)
|
||||
#define NCP_PERM_OPEN (0x004)
|
||||
#define NCP_PERM_CREATE (0x008)
|
||||
#define NCP_PERM_DELETE (0x010)
|
||||
#define NCP_PERM_OWNER (0x020)
|
||||
#define NCP_PERM_SEARCH (0x040)
|
||||
#define NCP_PERM_MODIFY (0x080)
|
||||
#define NCP_PERM_SUPER (0x100)
|
||||
|
||||
long
|
||||
ncp_get_eff_directory_rights(struct ncp_conn *conn,
|
||||
__u8 source_ns, __u8 target_ns,
|
||||
__u16 search_attribs,
|
||||
__u8 vol, __u32 dirent, const char *path,
|
||||
__u16 * my_effective_rights);
|
||||
|
||||
long
|
||||
ncp_do_lookup(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir,
|
||||
char *path, /* may only be one component */
|
||||
struct nw_info_struct *target);
|
||||
|
||||
long
|
||||
ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn,
|
||||
struct nw_info_struct *file,
|
||||
__u32 info_mask,
|
||||
struct nw_modify_dos_info *info);
|
||||
|
||||
long
|
||||
ncp_del_file_or_subdir(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir, char *name);
|
||||
|
||||
|
||||
long
|
||||
ncp_open_create_file_or_subdir(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir, char *name,
|
||||
int open_create_mode,
|
||||
__u32 create_attributes,
|
||||
int desired_acc_rights,
|
||||
struct nw_file_info *target);
|
||||
|
||||
long
|
||||
ncp_initialize_search(struct ncp_conn *conn,
|
||||
const struct nw_info_struct *dir,
|
||||
int namespace,
|
||||
struct ncp_search_seq *target);
|
||||
|
||||
long
|
||||
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
|
||||
struct ncp_search_seq *seq,
|
||||
struct nw_info_struct *target);
|
||||
|
||||
long
|
||||
ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn,
|
||||
struct nw_info_struct *old_dir, char *old_name,
|
||||
struct nw_info_struct *new_dir, char *new_name);
|
||||
|
||||
long
|
||||
ncp_create_queue_job_and_file(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
struct queue_job *job);
|
||||
|
||||
long
|
||||
ncp_get_queue_length(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
__u32 *queue_length);
|
||||
|
||||
long
|
||||
ncp_get_queue_job_ids(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
__u32 queue_section,
|
||||
__u32 *length1,
|
||||
__u32 *length2,
|
||||
__u32 ids[]);
|
||||
long
|
||||
ncp_get_queue_job_info(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
__u32 job_id,
|
||||
struct nw_queue_job_entry *jobdata);
|
||||
|
||||
long
|
||||
NWRemoveJobFromQueue2(struct ncp_conn* conn, __u32 queue_id, __u32 job_id);
|
||||
|
||||
long
|
||||
ncp_close_file_and_start_job(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
struct queue_job *job);
|
||||
|
||||
long
|
||||
ncp_attach_to_queue(struct ncp_conn *conn,
|
||||
__u32 queue_id);
|
||||
|
||||
long
|
||||
ncp_detach_from_queue(struct ncp_conn *conn,
|
||||
__u32 queue_id);
|
||||
|
||||
long
|
||||
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
|
||||
struct queue_job *job);
|
||||
|
||||
long
|
||||
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
__u32 job_number, __u32 charge_info);
|
||||
|
||||
long
|
||||
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
__u32 job_number);
|
||||
|
||||
long
|
||||
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
|
||||
|
||||
long
|
||||
ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle);
|
||||
|
||||
#define NCP_ALLOC_PERMANENT (0x0000)
|
||||
#define NCP_ALLOC_TEMPORARY (0x0001)
|
||||
#define NCP_ALLOC_SPECIAL (0x0002)
|
||||
|
||||
long
|
||||
ncp_alloc_short_dir_handle(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir,
|
||||
__u16 alloc_mode,
|
||||
__u8 * target);
|
||||
|
||||
long
|
||||
ncp_get_effective_dir_rights(struct ncp_conn *conn,
|
||||
struct nw_info_struct *file,
|
||||
__u16 * target);
|
||||
|
||||
struct ncp_trustee_struct
|
||||
{
|
||||
__u32 object_id;
|
||||
__u16 rights;
|
||||
};
|
||||
|
||||
long
|
||||
ncp_add_trustee_set(struct ncp_conn *conn,
|
||||
__u8 volume_number, __u32 dir_entry,
|
||||
__u16 rights_mask,
|
||||
int object_count, struct ncp_trustee_struct *rights);
|
||||
#ifdef SIGNATURES
|
||||
long
|
||||
ncp_sign_start(struct ncp_conn *conn, const char *sign_root);
|
||||
#endif
|
||||
#ifdef NDS_SUPPORT
|
||||
long
|
||||
ncp_send_nds_frag(struct ncp_conn *conn,
|
||||
int ndsverb,
|
||||
char *inbuf, int inbuflen,
|
||||
char *outbuf, int outbufsize, int *outbuflen);
|
||||
|
||||
long
|
||||
ncp_send_nds(struct ncp_conn *conn, int fn,
|
||||
char *data_in, int data_in_len,
|
||||
char *data_out, int data_out_max, int *data_out_len);
|
||||
|
||||
long
|
||||
ncp_change_conn_state(struct ncp_conn *conn, int new_state);
|
||||
|
||||
struct ncp_conn *
|
||||
ncp_open_addr(struct sockaddr_ipx *target, long *err);
|
||||
|
||||
int
|
||||
ncp_get_mount_uid(int fid, uid_t* uid);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _NCPLIB_H */
|
||||
18
include/ncpsign.h
Normal file
18
include/ncpsign.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifdef SIGNATURES
|
||||
/*
|
||||
* ncpsign.h
|
||||
*
|
||||
* Arne de Bruijn (arne@knoware.nl), 1997
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NCPSIGN_H
|
||||
#define _NCPSIGN_H
|
||||
|
||||
#include "ncplib.h"
|
||||
|
||||
void sign_init(const char *logindata, char *sign_root);
|
||||
void sign_packet(struct ncp_conn *conn, int *size);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
35
include/ndslib.h
Normal file
35
include/ndslib.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
NDS client for ncpfs
|
||||
Copyright (C) 1997 Arne de Bruijn
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _NDSLIB_H_
|
||||
#define _NDSLIB_H_
|
||||
|
||||
#include "ncplib.h"
|
||||
typedef unsigned short uni_char;
|
||||
|
||||
#define NDS_GRACE_PERIOD -223
|
||||
|
||||
int strlen_u(const uni_char *s);
|
||||
void strcpy_uc(char *d, const uni_char *s);
|
||||
void strcpy_cu(uni_char *d, const char *s);
|
||||
long nds_get_server_name(struct ncp_conn *conn, uni_char **server_name);
|
||||
long nds_get_tree_name(struct ncp_conn *conn, char *name, int name_buf_len);
|
||||
long nds_login_auth(struct ncp_conn *conn, const char *user, const char *pwd);
|
||||
|
||||
#endif /* ifndef _NDSLIB_H_ */
|
||||
@@ -1,30 +0,0 @@
|
||||
CFLAGS = -O2 -Wall
|
||||
UTILS = $(INTERM_BINDIR)/ipx_configure $(INTERM_BINDIR)/ipx_interface \
|
||||
$(INTERM_BINDIR)/ipx_internal_net $(INTERM_BINDIR)/ipx_route
|
||||
|
||||
all: $(UTILS)
|
||||
|
||||
$(INTERM_BINDIR)/ipx_configure: ipx_configure.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_interface: ipx_interface.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_interface ipx_interface.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_internal_net: ipx_internal_net.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_internal_net ipx_internal_net.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_route: ipx_route.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_route ipx_route.o
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install --strip $$i $(BINDIR); \
|
||||
done
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <linux/if.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
static struct ifreq id;
|
||||
static char *progname;
|
||||
|
||||
void
|
||||
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);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
struct frame_type {
|
||||
char *ft_name;
|
||||
unsigned char ft_val;
|
||||
} frame_types[] = {
|
||||
{"802.2", IPX_FRAME_8022},
|
||||
{"802.3", IPX_FRAME_8023},
|
||||
{"SNAP", IPX_FRAME_SNAP},
|
||||
{"EtherII", IPX_FRAME_ETHERII}
|
||||
};
|
||||
|
||||
#define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type))
|
||||
|
||||
int
|
||||
lookup_frame_type(char *frame)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; (j < NFTYPES) &&
|
||||
(strcasecmp(frame_types[j].ft_name, frame));
|
||||
j++)
|
||||
;
|
||||
|
||||
if (j != NFTYPES)
|
||||
return j;
|
||||
|
||||
fprintf(stderr, "%s: Frame type must be", progname);
|
||||
for (j = 0; j < NFTYPES; j++) {
|
||||
fprintf(stderr, "%s%s",
|
||||
(j == NFTYPES-1) ? " or " : " ",
|
||||
frame_types[j].ft_name);
|
||||
}
|
||||
fprintf(stderr, ".\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_add_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
int i, fti = 0;
|
||||
char c;
|
||||
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_type = IPX_FRAME_NONE;
|
||||
while ((c = getopt(argc, argv, "p")) > 0) {
|
||||
switch (c) {
|
||||
case 'p': sipx->sipx_special = IPX_PRIMARY; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((i = (argc - optind)) < 2) || (i > 3)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
for (i = optind; i < argc; i++) {
|
||||
switch (i-optind) {
|
||||
case 0: /* Physical Device - Required */
|
||||
strcpy(id.ifr_name, argv[i]);
|
||||
break;
|
||||
case 1: /* Frame Type - Required */
|
||||
fti = lookup_frame_type(argv[i]);
|
||||
if (fti < 0)
|
||||
exit(-1);
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
break;
|
||||
|
||||
case 2: /* Network Number - Optional */
|
||||
netnum = strtoul(argv[i], (char **)NULL, 16);
|
||||
if (netnum == 0xffffffffL) {
|
||||
fprintf(stderr,
|
||||
"%s: Inappropriate network number %08lX\n",
|
||||
progname, netnum);
|
||||
exit(-1);
|
||||
}
|
||||
sipx->sipx_network = htonl(netnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_CRTITF;
|
||||
do {
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
i++;
|
||||
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
|
||||
if (result == 0) exit(0);
|
||||
|
||||
switch (errno) {
|
||||
case EEXIST:
|
||||
fprintf(stderr, "%s: Primary network already selected.\n",
|
||||
progname);
|
||||
break;
|
||||
case EADDRINUSE:
|
||||
fprintf(stderr, "%s: Network number (%08lX) already in use.\n",
|
||||
progname, htonl(sipx->sipx_network));
|
||||
break;
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_types[fti].ft_name);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case ENETDOWN:
|
||||
fprintf(stderr, "%s: Requested device (%s) is down.\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "%s: Invalid device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EAGAIN:
|
||||
fprintf(stderr,
|
||||
"%s: Insufficient memory to create interface.\n",
|
||||
progname);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_del_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
int fti;
|
||||
|
||||
if (argc != 3) {
|
||||
usage();
|
||||
}
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
strcpy(id.ifr_name, argv[1]);
|
||||
fti = lookup_frame_type(argv[2]);
|
||||
if (fti < 0)
|
||||
exit(-1);
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
if (result == 0) exit(0);
|
||||
|
||||
switch (errno) {
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_types[fti].ft_name);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "%s: No such IPX interface %s %s.\n", progname,
|
||||
id.ifr_name, frame_types[fti].ft_name);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_check_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
int fti;
|
||||
|
||||
if (argc != 3) {
|
||||
usage();
|
||||
}
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
strcpy(id.ifr_name, argv[1]);
|
||||
fti = lookup_frame_type(argv[2]);
|
||||
if (fti < 0)
|
||||
exit(-1);
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
sipx->sipx_family = AF_IPX;
|
||||
result = ioctl(s, SIOCGIFADDR, &id);
|
||||
if (result == 0) {
|
||||
printf(
|
||||
"IPX Address for (%s, %s) is %08lX:%02X%02X%02X%02X%02X%02X.\n",
|
||||
argv[1], frame_types[fti].ft_name,
|
||||
htonl(sipx->sipx_network), sipx->sipx_node[0],
|
||||
sipx->sipx_node[1], sipx->sipx_node[2],
|
||||
sipx->sipx_node[3], sipx->sipx_node[4],
|
||||
sipx->sipx_node[5]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
switch (errno) {
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_types[fti].ft_name);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EADDRNOTAVAIL:
|
||||
fprintf(stderr, "%s: No such IPX interface %s %s.\n", progname,
|
||||
id.ifr_name, frame_types[fti].ft_name);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
progname = argv[0];
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (strncasecmp(argv[1], "add", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_add_interface(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_del_interface(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "check", 5) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_check_interface(argc-1, argv);
|
||||
}
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
int s;
|
||||
int result;
|
||||
char msg[100];
|
||||
int len;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
sipx.sipx_family = AF_IPX;
|
||||
sipx.sipx_network = 0;
|
||||
sipx.sipx_port = htons(0x5000);
|
||||
sipx.sipx_type = 17;
|
||||
len = sizeof(sipx);
|
||||
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
|
||||
if (result < 0) {
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
msg[0] = '\0';
|
||||
result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *)&sipx,
|
||||
&len);
|
||||
if (result < 0) {
|
||||
perror("IPX: recvfrom: ");
|
||||
}
|
||||
|
||||
printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
|
||||
htonl(sipx.sipx_network),
|
||||
sipx.sipx_node[0], sipx.sipx_node[1],
|
||||
sipx.sipx_node[2], sipx.sipx_node[3],
|
||||
sipx.sipx_node[4], sipx.sipx_node[5],
|
||||
htons(sipx.sipx_port));
|
||||
printf("\tGot \"%s\"\n", msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
struct rip_data {
|
||||
unsigned long rip_net;
|
||||
unsigned short rip_hops __attribute__ ((packed));
|
||||
unsigned short rip_ticks __attribute__ ((packed));
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
int result;
|
||||
int s;
|
||||
char msg[1024];
|
||||
int len;
|
||||
char *bptr;
|
||||
struct rip_data *rp;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
sipx.sipx_family = AF_IPX;
|
||||
sipx.sipx_network = 0;
|
||||
sipx.sipx_port = htons(0x453);
|
||||
sipx.sipx_type = 17;
|
||||
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
|
||||
if (result < 0) {
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
len = sizeof(sipx);
|
||||
result = recvfrom(s, msg, sizeof(msg), 0,
|
||||
(struct sockaddr *)&sipx, &len);
|
||||
if (result < 0) {
|
||||
perror("IPX: recvfrom");
|
||||
exit(-1);
|
||||
}
|
||||
bptr = msg;
|
||||
result -= 2;
|
||||
printf("RIP packet from: %08lX:%02X%02X%02X%02X%02X%02X\n",
|
||||
htonl(sipx.sipx_network),
|
||||
sipx.sipx_node[0], sipx.sipx_node[1],
|
||||
sipx.sipx_node[2], sipx.sipx_node[3],
|
||||
sipx.sipx_node[4], sipx.sipx_node[5]);
|
||||
bptr += 2;
|
||||
rp = (struct rip_data *) bptr;
|
||||
while (result >= sizeof(struct rip_data)) {
|
||||
printf("\tNET: %08lX HOPS: %d\n", ntohl(rp->rip_net),
|
||||
ntohs(rp->rip_hops));
|
||||
result -= sizeof(struct rip_data);
|
||||
rp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
struct sap_data {
|
||||
unsigned short sap_type __attribute__ ((packed));
|
||||
char sap_name[48] __attribute__ ((packed));
|
||||
unsigned long sap_net __attribute__ ((packed));
|
||||
unsigned char sap_node[6] __attribute__ ((packed));
|
||||
unsigned short sap_sock __attribute__ ((packed));
|
||||
unsigned short sap_hops __attribute__ ((packed));
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int s;
|
||||
int result;
|
||||
struct sockaddr_ipx sipx;
|
||||
char msg[1024];
|
||||
long val = 0;
|
||||
int len;
|
||||
char *bptr;
|
||||
struct sap_data *sp;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result = setsockopt(s, SOL_SOCKET, SO_DEBUG, &val, 4);
|
||||
if (result < 0) {
|
||||
perror("IPX: setsockopt: ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sipx.sipx_family = PF_IPX;
|
||||
sipx.sipx_network = 0L;
|
||||
sipx.sipx_port = htons(0x452);
|
||||
sipx.sipx_type = 17;
|
||||
|
||||
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
|
||||
if (result < 0) {
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
len = 1024;
|
||||
result = recvfrom(s, msg, sizeof(msg), 0,
|
||||
(struct sockaddr *)&sipx, &len);
|
||||
if (result < 0) {
|
||||
perror("IPX: recvfrom: ");
|
||||
exit(-1);
|
||||
}
|
||||
bptr = msg;
|
||||
result -= 2;
|
||||
printf("SAP: OP is %x %x\n", bptr[0], bptr[1]);
|
||||
printf("Length is %d\n", result);
|
||||
if (bptr[1] != 2)
|
||||
continue;
|
||||
|
||||
bptr += 2;
|
||||
sp = (struct sap_data *) bptr;
|
||||
while (result >= sizeof(struct sap_data)) {
|
||||
int i;
|
||||
|
||||
sp->sap_name[32] = '\0';
|
||||
for (i = 31; (i > 0) && (sp->sap_name[i] == '_'); i--);
|
||||
i++;
|
||||
sp->sap_name[i] = '\0';
|
||||
printf("NAME: %s TYPE: %x HOPS: %x\n", sp->sap_name,
|
||||
ntohs(sp->sap_type), ntohs(sp->sap_hops));
|
||||
printf("%lx:%x %x %x %x %x %x: %x\n",
|
||||
ntohl(sp->sap_net),
|
||||
sp->sap_node[0],
|
||||
sp->sap_node[1],
|
||||
sp->sap_node[2],
|
||||
sp->sap_node[3],
|
||||
sp->sap_node[4],
|
||||
sp->sap_node[5],
|
||||
ntohs(sp->sap_sock));
|
||||
result -= sizeof(struct sap_data);
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
19
ipx-1.0/Makefile
Normal file
19
ipx-1.0/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
CFLAGS = -O2 -Wall -I../include
|
||||
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
|
||||
|
||||
all: $(UTILS)
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
mrproper: clean
|
||||
rm -f .depend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install $$i $(BINDIR); \
|
||||
done
|
||||
@@ -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
|
||||
49
ipx-1.0/Samples/ipxrcv.c
Normal file
49
ipx-1.0/Samples/ipxrcv.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
int s;
|
||||
int result;
|
||||
char msg[100];
|
||||
int len;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0)
|
||||
{
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
sipx.sipx_family = AF_IPX;
|
||||
sipx.sipx_network = 0;
|
||||
sipx.sipx_port = htons(0x5000);
|
||||
sipx.sipx_type = 17;
|
||||
len = sizeof(sipx);
|
||||
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
msg[0] = '\0';
|
||||
result = recvfrom(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx,
|
||||
&len);
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: recvfrom: ");
|
||||
}
|
||||
printf("From %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
|
||||
htonl(sipx.sipx_network),
|
||||
sipx.sipx_node[0], sipx.sipx_node[1],
|
||||
sipx.sipx_node[2], sipx.sipx_node[3],
|
||||
sipx.sipx_node[4], sipx.sipx_node[5],
|
||||
htons(sipx.sipx_port));
|
||||
printf("\tGot \"%s\"\n", msg);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
@@ -8,14 +12,15 @@
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
int s;
|
||||
int result;
|
||||
char msg[100] = "Hi Mom";
|
||||
int len = sizeof(sipx);
|
||||
struct sockaddr_ipx sipx;
|
||||
int s;
|
||||
int result;
|
||||
char msg[100] = "Hi Mom";
|
||||
int len = sizeof(sipx);
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
if (s < 0)
|
||||
{
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
@@ -24,23 +29,20 @@ main(int argc, char **argv)
|
||||
sipx.sipx_port = 0;
|
||||
sipx.sipx_type = 17;
|
||||
|
||||
result = bind(s, (struct sockaddr *)&sipx, sizeof(sipx));
|
||||
if (result < 0) {
|
||||
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result = getsockname(s, (struct sockaddr *)&sipx, &len);
|
||||
result = getsockname(s, (struct sockaddr *) &sipx, &len);
|
||||
sipx.sipx_port = htons(0x5000);
|
||||
result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *)&sipx,
|
||||
result = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &sipx,
|
||||
sizeof(sipx));
|
||||
if (result < 0) {
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: send: ");
|
||||
exit(-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
73
ipx-1.0/Samples/rip.c
Normal file
73
ipx-1.0/Samples/rip.c
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
struct rip_data
|
||||
{
|
||||
unsigned long rip_net;
|
||||
unsigned short rip_hops __attribute__((packed));
|
||||
unsigned short rip_ticks __attribute__((packed));
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx sipx;
|
||||
int result;
|
||||
int s;
|
||||
char msg[1024];
|
||||
int len;
|
||||
char *bptr;
|
||||
struct rip_data *rp;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0)
|
||||
{
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
sipx.sipx_family = AF_IPX;
|
||||
sipx.sipx_network = 0;
|
||||
sipx.sipx_port = htons(0x453);
|
||||
sipx.sipx_type = 17;
|
||||
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
len = sizeof(sipx);
|
||||
result = recvfrom(s, msg, sizeof(msg), 0,
|
||||
(struct sockaddr *) &sipx, &len);
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: recvfrom");
|
||||
exit(-1);
|
||||
}
|
||||
bptr = msg;
|
||||
result -= 2;
|
||||
printf("RIP packet from: %08lX:%02X%02X%02X%02X%02X%02X\n",
|
||||
htonl(sipx.sipx_network),
|
||||
sipx.sipx_node[0], sipx.sipx_node[1],
|
||||
sipx.sipx_node[2], sipx.sipx_node[3],
|
||||
sipx.sipx_node[6], sipx.sipx_node[5]);
|
||||
bptr += 2;
|
||||
rp = (struct rip_data *) bptr;
|
||||
while (result >= sizeof(struct rip_data))
|
||||
{
|
||||
printf("\tNET: %08lX HOPS: %d\n", ntohl(rp->rip_net),
|
||||
ntohs(rp->rip_hops));
|
||||
result -= sizeof(struct rip_data);
|
||||
rp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
100
ipx-1.0/Samples/sap.c
Normal file
100
ipx-1.0/Samples/sap.c
Normal file
@@ -0,0 +1,100 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
struct sap_data
|
||||
{
|
||||
unsigned short sap_type __attribute__((packed));
|
||||
char sap_name[48] __attribute__((packed));
|
||||
unsigned long sap_net __attribute__((packed));
|
||||
unsigned char sap_node[6] __attribute__((packed));
|
||||
unsigned short sap_sock __attribute__((packed));
|
||||
unsigned short sap_hops __attribute__((packed));
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int s;
|
||||
int result;
|
||||
struct sockaddr_ipx sipx;
|
||||
char msg[1024];
|
||||
long val = 0;
|
||||
int len;
|
||||
char *bptr;
|
||||
struct sap_data *sp;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0)
|
||||
{
|
||||
perror("IPX: socket: ");
|
||||
exit(-1);
|
||||
}
|
||||
result = setsockopt(s, SOL_SOCKET, SO_DEBUG, &val, 4);
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: setsockopt: ");
|
||||
exit(-1);
|
||||
}
|
||||
sipx.sipx_family = PF_IPX;
|
||||
sipx.sipx_network = 0L;
|
||||
sipx.sipx_port = htons(0x452);
|
||||
sipx.sipx_type = 17;
|
||||
|
||||
result = bind(s, (struct sockaddr *) &sipx, sizeof(sipx));
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: bind: ");
|
||||
exit(-1);
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
len = 1024;
|
||||
result = recvfrom(s, msg, sizeof(msg), 0,
|
||||
(struct sockaddr *) &sipx, &len);
|
||||
if (result < 0)
|
||||
{
|
||||
perror("IPX: recvfrom: ");
|
||||
exit(-1);
|
||||
}
|
||||
bptr = msg;
|
||||
result -= 2;
|
||||
printf("SAP: OP is %x %x\n", bptr[0], bptr[1]);
|
||||
printf("Length is %d\n", result);
|
||||
if (bptr[1] != 2)
|
||||
continue;
|
||||
|
||||
bptr += 2;
|
||||
sp = (struct sap_data *) bptr;
|
||||
while (result >= sizeof(struct sap_data))
|
||||
{
|
||||
int i;
|
||||
|
||||
sp->sap_name[32] = '\0';
|
||||
for (i = 31; (i > 0) && (sp->sap_name[i] == '_'); i--);
|
||||
i++;
|
||||
sp->sap_name[i] = '\0';
|
||||
printf("NAME: %s TYPE: %x HOPS: %x\n", sp->sap_name,
|
||||
ntohs(sp->sap_type), ntohs(sp->sap_hops));
|
||||
printf("%lx:%x %x %x %x %x %x: %x\n",
|
||||
ntohl(sp->sap_net),
|
||||
sp->sap_node[0],
|
||||
sp->sap_node[1],
|
||||
sp->sap_node[2],
|
||||
sp->sap_node[3],
|
||||
sp->sap_node[4],
|
||||
sp->sap_node[5],
|
||||
ntohs(sp->sap_sock));
|
||||
result -= sizeof(struct sap_data);
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
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,27 +1,34 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <strings.h>
|
||||
#include <linux/ipx.h>
|
||||
#include "kernel/ipx.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
struct option options[] = {
|
||||
{ "auto_primary", required_argument, NULL, 1 },
|
||||
{ "auto_interface", required_argument, NULL, 2 },
|
||||
{ "help", no_argument, NULL, 3},
|
||||
{ NULL, 0, NULL, 0 }
|
||||
struct option options[] =
|
||||
{
|
||||
{"auto_primary", required_argument, NULL, 1},
|
||||
{"auto_interface", required_argument, NULL, 2},
|
||||
{"help", no_argument, NULL, 3},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
char *progname;
|
||||
char *progname;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s --auto_primary=[on|off]\n\
|
||||
fprintf(stderr,
|
||||
"Usage: %s --auto_primary=[on|off]\n\
|
||||
Usage: %s --auto_interface=[on|off]\n\
|
||||
Usage: %s --help\n\
|
||||
Usage: %s\n", progname, progname, progname, progname);
|
||||
@@ -31,75 +38,86 @@ int
|
||||
map_string_to_bool(char *optarg)
|
||||
{
|
||||
if ((strcasecmp(optarg, "ON") == 0) ||
|
||||
(strcasecmp(optarg, "TRUE") == 0) ||
|
||||
(strcasecmp(optarg, "SET") == 0) ||
|
||||
(strcasecmp(optarg, "YES") == 0)) {
|
||||
(strcasecmp(optarg, "TRUE") == 0) ||
|
||||
(strcasecmp(optarg, "SET") == 0) ||
|
||||
(strcasecmp(optarg, "YES") == 0))
|
||||
{
|
||||
return 1;
|
||||
} else if ((strcasecmp(optarg, "OFF") == 0) ||
|
||||
(strcasecmp(optarg, "FALSE") == 0) ||
|
||||
(strcasecmp(optarg, "CLEAR") == 0) ||
|
||||
(strcasecmp(optarg, "NO") == 0)) {
|
||||
(strcasecmp(optarg, "FALSE") == 0) ||
|
||||
(strcasecmp(optarg, "CLEAR") == 0) ||
|
||||
(strcasecmp(optarg, "NO") == 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
char val;
|
||||
int option_index = 0;
|
||||
int got_auto_pri = 0;
|
||||
int got_auto_itf = 0;
|
||||
ipx_config_data data;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
char val;
|
||||
int option_index = 0;
|
||||
int got_auto_pri = 0;
|
||||
int got_auto_itf = 0;
|
||||
ipx_config_data data;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
if (s < 0)
|
||||
{
|
||||
int old_errno = errno;
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
if (old_errno == -EINVAL)
|
||||
{
|
||||
fprintf(stderr, "Probably you have no IPX support in "
|
||||
"your kernel\n");
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
while ((result = getopt_long(argc, argv, "", options,
|
||||
&option_index)) != -1) {
|
||||
switch (result) {
|
||||
case 1:
|
||||
while ((result = getopt_long(argc, argv, "", options,
|
||||
&option_index)) != -1)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case 1:
|
||||
if (got_auto_pri)
|
||||
break;
|
||||
got_auto_pri++;
|
||||
|
||||
|
||||
val = map_string_to_bool(optarg);
|
||||
if (val < 0) {
|
||||
if (val < 0)
|
||||
{
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result = ioctl(s, SIOCAIPXPRISLT, &val);
|
||||
if (result < 0) {
|
||||
if (result < 0)
|
||||
{
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (got_auto_itf)
|
||||
if (got_auto_itf)
|
||||
break;
|
||||
got_auto_itf++;
|
||||
|
||||
val = map_string_to_bool(optarg);
|
||||
if (val < 0) {
|
||||
if (val < 0)
|
||||
{
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result = ioctl(s, SIOCAIPXITFCRT, &val);
|
||||
if (result < 0) {
|
||||
if (result < 0)
|
||||
{
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
@@ -110,16 +128,17 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
result = ioctl(s, SIOCIPXCFGDATA, &data);
|
||||
if (result < 0) {
|
||||
if (result < 0)
|
||||
{
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
if (argc == 1) {
|
||||
if (argc == 1)
|
||||
{
|
||||
fprintf(stdout, "Auto Primary Select is %s\n\
|
||||
Auto Interface Create is %s\n",
|
||||
Auto Interface Create is %s\n",
|
||||
(data.ipxcfg_auto_select_primary) ? "ON" : "OFF",
|
||||
(data.ipxcfg_auto_create_interfaces) ? "ON" : "OFF");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
439
ipx-1.0/ipx_interface.c
Normal file
439
ipx-1.0/ipx_interface.c
Normal file
@@ -0,0 +1,439 @@
|
||||
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <netinet/in.h>
|
||||
#include "kernel/ipx.h"
|
||||
#include "kernel/if.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static struct ifreq id;
|
||||
static char *progname;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s add [-p] device frame_type [net_number]\n\
|
||||
Usage: %s del device frame_type\n\
|
||||
Usage: %s delall\n\
|
||||
Usage: %s check device frame_type\n", progname, progname, progname, progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
struct frame_type
|
||||
{
|
||||
char *ft_name;
|
||||
unsigned char ft_val;
|
||||
}
|
||||
frame_types[] =
|
||||
{
|
||||
{
|
||||
"802.2", IPX_FRAME_8022
|
||||
}
|
||||
,
|
||||
#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
|
||||
}
|
||||
};
|
||||
|
||||
#define NFTYPES (sizeof(frame_types)/sizeof(struct frame_type))
|
||||
|
||||
int
|
||||
lookup_frame_type(char *frame)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; (j < NFTYPES) &&
|
||||
(strcasecmp(frame_types[j].ft_name, frame));
|
||||
j++)
|
||||
;
|
||||
|
||||
if (j != NFTYPES)
|
||||
return j;
|
||||
|
||||
fprintf(stderr, "%s: Frame type must be", progname);
|
||||
for (j = 0; j < NFTYPES; j++)
|
||||
{
|
||||
fprintf(stderr, "%s%s",
|
||||
(j == NFTYPES - 1) ? " or " : " ",
|
||||
frame_types[j].ft_name);
|
||||
}
|
||||
fprintf(stderr, ".\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
ipx_add_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
int i, fti = 0;
|
||||
char c;
|
||||
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_type = IPX_FRAME_NONE;
|
||||
while ((c = getopt(argc, argv, "p")) > 0)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'p':
|
||||
sipx->sipx_special = IPX_PRIMARY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (((i = (argc - optind)) < 2) || (i > 3))
|
||||
{
|
||||
usage();
|
||||
}
|
||||
for (i = optind; i < argc; i++)
|
||||
{
|
||||
switch (i - optind)
|
||||
{
|
||||
case 0: /* Physical Device - Required */
|
||||
strcpy(id.ifr_name, argv[i]);
|
||||
break;
|
||||
case 1: /* Frame Type - Required */
|
||||
fti = lookup_frame_type(argv[i]);
|
||||
if (fti < 0)
|
||||
exit(-1);
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
break;
|
||||
|
||||
case 2: /* Network Number - Optional */
|
||||
netnum = strtoul(argv[i], (char **) NULL, 16);
|
||||
if (netnum == 0xffffffffL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Inappropriate network number %08lX\n",
|
||||
progname, netnum);
|
||||
exit(-1);
|
||||
}
|
||||
sipx->sipx_network = htonl(netnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
i = 0;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_CRTITF;
|
||||
do
|
||||
{
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
i++;
|
||||
}
|
||||
while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
|
||||
if (result == 0)
|
||||
exit(0);
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case EEXIST:
|
||||
fprintf(stderr, "%s: Primary network already selected.\n",
|
||||
progname);
|
||||
break;
|
||||
case EADDRINUSE:
|
||||
fprintf(stderr, "%s: Network number (%08X) already in use.\n",
|
||||
progname, (u_int32_t)htonl(sipx->sipx_network));
|
||||
break;
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_types[fti].ft_name);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case ENETDOWN:
|
||||
fprintf(stderr, "%s: Requested device (%s) is down.\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "%s: Invalid device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EAGAIN:
|
||||
fprintf(stderr,
|
||||
"%s: Insufficient memory to create interface.\n",
|
||||
progname);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
int fti;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
strcpy(id.ifr_name, argv[1]);
|
||||
fti = lookup_frame_type(argv[2]);
|
||||
if (fti < 0)
|
||||
exit(-1);
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0)
|
||||
{
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
if (result == 0)
|
||||
exit(0);
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_types[fti].ft_name);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "%s: No such IPX interface %s %s.\n", progname,
|
||||
id.ifr_name, frame_types[fti].ft_name);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_check_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
int fti;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
sipx->sipx_network = 0L;
|
||||
strcpy(id.ifr_name, argv[1]);
|
||||
fti = lookup_frame_type(argv[2]);
|
||||
if (fti < 0)
|
||||
exit(-1);
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0)
|
||||
{
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
sipx->sipx_family = AF_IPX;
|
||||
result = ioctl(s, SIOCGIFADDR, &id);
|
||||
if (result == 0)
|
||||
{
|
||||
printf(
|
||||
"IPX Address for (%s, %s) is %08X:%02X%02X%02X%02X%02X%02X.\n",
|
||||
argv[1], frame_types[fti].ft_name,
|
||||
(u_int32_t)htonl(sipx->sipx_network), sipx->sipx_node[0],
|
||||
sipx->sipx_node[1], sipx->sipx_node[2],
|
||||
sipx->sipx_node[3], sipx->sipx_node[4],
|
||||
sipx->sipx_node[5]);
|
||||
exit(0);
|
||||
}
|
||||
switch (errno)
|
||||
{
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_types[fti].ft_name);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n", progname,
|
||||
id.ifr_name);
|
||||
break;
|
||||
case EADDRNOTAVAIL:
|
||||
fprintf(stderr, "%s: No such IPX interface %s %s.\n", progname,
|
||||
id.ifr_name, frame_types[fti].ft_name);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
progname = argv[0];
|
||||
if (argc < 2)
|
||||
{
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
if (strncasecmp(argv[1], "add", 3) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_add_interface(argc - 1, argv);
|
||||
} else if (strncasecmp(argv[1], "delall", 6) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_delall_interface(argc - 1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_del_interface(argc - 1, argv);
|
||||
} else if (strncasecmp(argv[1], "check", 5) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_check_interface(argc - 1, argv);
|
||||
}
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,17 +1,22 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <linux/if.h>
|
||||
#include "kernel/ipx.h"
|
||||
#include "kernel/if.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
static struct ifreq id;
|
||||
static char *progname;
|
||||
static struct ifreq id;
|
||||
static char *progname;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
@@ -24,12 +29,15 @@ Usage: %s del\n", progname, progname);
|
||||
int
|
||||
map_char_to_val(char dig)
|
||||
{
|
||||
char digit = tolower(dig);
|
||||
if ((digit >= '0') && (digit <= '9')) {
|
||||
char digit = tolower(dig);
|
||||
if ((digit >= '0') && (digit <= '9'))
|
||||
{
|
||||
return digit - '0';
|
||||
} else if ((digit >= 'a') && (digit <= 'f')) {
|
||||
} else if ((digit >= 'a') && (digit <= 'f'))
|
||||
{
|
||||
return (10 + (digit - 'a'));
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -37,90 +45,95 @@ map_char_to_val(char dig)
|
||||
int
|
||||
ipx_add_internal_net(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
int nodelen;
|
||||
char *node;
|
||||
char tmpnode[13];
|
||||
unsigned char *tout;
|
||||
char *tin;
|
||||
int i;
|
||||
|
||||
if (argc != 3) {
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
int nodelen;
|
||||
char *node;
|
||||
char tmpnode[13];
|
||||
unsigned char *tout;
|
||||
char *tin;
|
||||
int i;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
netnum = strtoul(argv[1], (char **)NULL, 16);
|
||||
if ((netnum == 0L) || (netnum == 0xffffffffL)) {
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
|
||||
netnum = strtoul(argv[1], (char **) NULL, 16);
|
||||
if ((netnum == 0L) || (netnum == 0xffffffffL))
|
||||
{
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
|
||||
progname, netnum);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
node = argv[2];
|
||||
nodelen = strlen(node);
|
||||
if (nodelen > 12) {
|
||||
if (nodelen > 12)
|
||||
{
|
||||
fprintf(stderr, "%s: Node length is too long (> 12).\n", progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
|
||||
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
|
||||
;
|
||||
|
||||
if (i < nodelen) {
|
||||
if (i < nodelen)
|
||||
{
|
||||
fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n",
|
||||
progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
strcpy(tmpnode, "000000000000");
|
||||
memcpy(&(tmpnode[12-nodelen]), node, nodelen);
|
||||
for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++) {
|
||||
memcpy(&(tmpnode[12 - nodelen]), node, nodelen);
|
||||
for (tin = tmpnode, tout = sipx->sipx_node; *tin != '\0'; tin += 2, tout++)
|
||||
{
|
||||
*tout = (unsigned char) map_char_to_val(*tin);
|
||||
*tout <<= 4;
|
||||
*tout |= (unsigned char) map_char_to_val(*(tin+1));
|
||||
*tout |= (unsigned char) map_char_to_val(*(tin + 1));
|
||||
}
|
||||
|
||||
if ((memcmp(sipx->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
|
||||
(memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)){
|
||||
(memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0))
|
||||
{
|
||||
fprintf(stderr, "%s: Node is invalid.\n", progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sipx->sipx_network = htonl(netnum);
|
||||
sipx->sipx_type = IPX_FRAME_NONE;
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
if (s < 0)
|
||||
{
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_CRTITF;
|
||||
i = 0;
|
||||
do {
|
||||
do
|
||||
{
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
i++;
|
||||
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
}
|
||||
while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
|
||||
if (result == 0) exit(0);
|
||||
|
||||
switch (errno) {
|
||||
if (result == 0)
|
||||
exit(0);
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case EEXIST:
|
||||
fprintf(stderr, "%s: Primary network already selected.\n",
|
||||
progname);
|
||||
break;
|
||||
case EADDRINUSE:
|
||||
fprintf(stderr, "%s: Network number (%08lX) already in use.\n",
|
||||
progname, htonl(sipx->sipx_network));
|
||||
fprintf(stderr, "%s: Network number (%08X) already in use.\n",
|
||||
progname, (u_int32_t)htonl(sipx->sipx_network));
|
||||
break;
|
||||
case EAGAIN:
|
||||
fprintf(stderr,
|
||||
fprintf(stderr,
|
||||
"%s: Insufficient memory to create internal net.\n",
|
||||
progname);
|
||||
break;
|
||||
@@ -135,19 +148,20 @@ ipx_add_internal_net(int argc, char **argv)
|
||||
int
|
||||
ipx_del_internal_net(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
|
||||
if (argc != 1) {
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
if (s < 0)
|
||||
{
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
@@ -155,9 +169,11 @@ ipx_del_internal_net(int argc, char **argv)
|
||||
sipx->sipx_family = AF_IPX;
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
if (result == 0) exit(0);
|
||||
if (result == 0)
|
||||
exit(0);
|
||||
|
||||
switch (errno) {
|
||||
switch (errno)
|
||||
{
|
||||
case ENOENT:
|
||||
fprintf(stderr, "%s: No internal network configured.\n", progname);
|
||||
break;
|
||||
@@ -172,24 +188,25 @@ ipx_del_internal_net(int argc, char **argv)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
progname = argv[0];
|
||||
if (argc < 2) {
|
||||
if (argc < 2)
|
||||
{
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (strncasecmp(argv[1], "add", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_add_internal_net(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_del_internal_net(argc-1, argv);
|
||||
if (strncasecmp(argv[1], "add", 3) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_add_internal_net(argc - 1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_del_internal_net(argc - 1, argv);
|
||||
}
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@@ -5,24 +11,27 @@
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/ipx.h>
|
||||
#include "kernel/ipx.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/route.h>
|
||||
#include "kernel/route.h"
|
||||
|
||||
static struct rtentry rd;
|
||||
static char *progname;
|
||||
static struct rtentry rd;
|
||||
static char *progname;
|
||||
|
||||
int
|
||||
map_char_to_val(char dig)
|
||||
{
|
||||
char digit = tolower(dig);
|
||||
if ((digit >= '0') && (digit <= '9')) {
|
||||
char digit = tolower(dig);
|
||||
if ((digit >= '0') && (digit <= '9'))
|
||||
{
|
||||
return digit - '0';
|
||||
} else if ((digit >= 'a') && (digit <= 'f')) {
|
||||
} else if ((digit >= 'a') && (digit <= 'f'))
|
||||
{
|
||||
return (10 + (digit - 'a'));
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -30,8 +39,8 @@ map_char_to_val(char dig)
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s add network(hex) router_network(hex) router_node(hex)\n\
|
||||
fprintf(stderr,
|
||||
"Usage: %s add network(hex) router_network(hex) router_node(hex)\n\
|
||||
Usage: %s del network(hex)\n", progname, progname);
|
||||
exit(-1);
|
||||
}
|
||||
@@ -40,27 +49,28 @@ int
|
||||
ipx_add_route(int argc, char **argv)
|
||||
{
|
||||
/* Router */
|
||||
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway;
|
||||
struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway;
|
||||
/* Target */
|
||||
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
|
||||
int s;
|
||||
int result;
|
||||
int nodelen;
|
||||
int i;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
char *node;
|
||||
char *tin;
|
||||
char tmpnode[13];
|
||||
unsigned char *tout;
|
||||
|
||||
struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rd.rt_dst;
|
||||
int s;
|
||||
int result;
|
||||
int nodelen;
|
||||
int i;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
char *node;
|
||||
char *tin;
|
||||
char tmpnode[13];
|
||||
unsigned char *tout;
|
||||
|
||||
if (argc != 4)
|
||||
usage();
|
||||
|
||||
/* Network Number */
|
||||
netnum = strtoul(argv[1], (char **)NULL, 16);
|
||||
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
|
||||
netnum = strtoul(argv[1], (char **) NULL, 16);
|
||||
if ((netnum == 0xffffffffL) || (netnum == 0L))
|
||||
{
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
|
||||
progname, netnum);
|
||||
exit(-1);
|
||||
}
|
||||
@@ -68,66 +78,72 @@ ipx_add_route(int argc, char **argv)
|
||||
st->sipx_network = htonl(netnum);
|
||||
|
||||
/* Router Network Number */
|
||||
netnum = strtoul(argv[2], (char **)NULL, 16);
|
||||
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
|
||||
netnum = strtoul(argv[2], (char **) NULL, 16);
|
||||
if ((netnum == 0xffffffffL) || (netnum == 0L))
|
||||
{
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX\n",
|
||||
progname, netnum);
|
||||
exit(-1);
|
||||
}
|
||||
sr->sipx_network = htonl(netnum);
|
||||
|
||||
|
||||
/* Router Node */
|
||||
node = argv[3];
|
||||
nodelen = strlen(node);
|
||||
if (nodelen > 12) {
|
||||
fprintf(stderr, "%s: Node length is too long (> 12).\n",
|
||||
if (nodelen > 12)
|
||||
{
|
||||
fprintf(stderr, "%s: Node length is too long (> 12).\n",
|
||||
progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
|
||||
for (i = 0; (i < nodelen) && isxdigit(node[i]); i++)
|
||||
;
|
||||
|
||||
if (i < nodelen) {
|
||||
if (i < nodelen)
|
||||
{
|
||||
fprintf(stderr, "%s: Invalid value in node, must be hex digits.\n",
|
||||
progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
strcpy(tmpnode, "000000000000");
|
||||
memcpy(&(tmpnode[12-nodelen]), node, nodelen);
|
||||
for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++) {
|
||||
memcpy(&(tmpnode[12 - nodelen]), node, nodelen);
|
||||
for (tin = tmpnode, tout = sr->sipx_node; *tin != '\0'; tin += 2, tout++)
|
||||
{
|
||||
*tout = (unsigned char) map_char_to_val(*tin);
|
||||
*tout <<= 4;
|
||||
*tout |= (unsigned char) map_char_to_val(*(tin+1));
|
||||
*tout |= (unsigned char) map_char_to_val(*(tin + 1));
|
||||
}
|
||||
|
||||
if ((memcmp(sr->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
|
||||
(memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0)){
|
||||
(memcmp(sr->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0))
|
||||
{
|
||||
fprintf(stderr, "%s: Node (%s) is invalid.\n", progname, tmpnode);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
if (s < 0)
|
||||
{
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sr->sipx_family = st->sipx_family = AF_IPX;
|
||||
i = 0;
|
||||
do {
|
||||
do
|
||||
{
|
||||
result = ioctl(s, SIOCADDRT, &rd);
|
||||
i++;
|
||||
} while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
}
|
||||
while ((i < 5) && (result < 0) && (errno == EAGAIN));
|
||||
|
||||
if (result == 0) exit(0);
|
||||
if (result == 0)
|
||||
exit(0);
|
||||
|
||||
switch (errno) {
|
||||
switch (errno)
|
||||
{
|
||||
case ENETUNREACH:
|
||||
fprintf(stderr, "%s: Router network (%08lX) not reachable.\n",
|
||||
progname, htonl(sr->sipx_network));
|
||||
fprintf(stderr, "%s: Router network (%08X) not reachable.\n",
|
||||
progname, (u_int32_t)htonl(sr->sipx_network));
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
@@ -141,23 +157,24 @@ int
|
||||
ipx_del_route(int argc, char **argv)
|
||||
{
|
||||
/* Router */
|
||||
struct sockaddr_ipx *sr = (struct sockaddr_ipx *)&rd.rt_gateway;
|
||||
struct sockaddr_ipx *sr = (struct sockaddr_ipx *) &rd.rt_gateway;
|
||||
/* Target */
|
||||
struct sockaddr_ipx *st = (struct sockaddr_ipx *)&rd.rt_dst;
|
||||
int s;
|
||||
int result;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
|
||||
if (argc != 2) {
|
||||
struct sockaddr_ipx *st = (struct sockaddr_ipx *) &rd.rt_dst;
|
||||
int s;
|
||||
int result;
|
||||
unsigned long netnum;
|
||||
char errmsg[80];
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
rd.rt_flags = RTF_GATEWAY;
|
||||
/* Network Number */
|
||||
netnum = strtoul(argv[1], (char **)NULL, 16);
|
||||
if ((netnum == 0xffffffffL) || (netnum == 0L)) {
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX.\n",
|
||||
netnum = strtoul(argv[1], (char **) NULL, 16);
|
||||
if ((netnum == 0xffffffffL) || (netnum == 0L))
|
||||
{
|
||||
fprintf(stderr, "%s: Inappropriate network number %08lX.\n",
|
||||
progname, netnum);
|
||||
exit(-1);
|
||||
}
|
||||
@@ -165,15 +182,18 @@ ipx_del_route(int argc, char **argv)
|
||||
|
||||
st->sipx_family = sr->sipx_family = AF_IPX;
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
if (s < 0)
|
||||
{
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
result = ioctl(s, SIOCDELRT, &rd);
|
||||
if (result == 0) exit(0);
|
||||
if (result == 0)
|
||||
exit(0);
|
||||
|
||||
switch (errno) {
|
||||
switch (errno)
|
||||
{
|
||||
case ENOENT:
|
||||
fprintf(stderr, "%s: Route not found for network %08lX.\n",
|
||||
progname, netnum);
|
||||
@@ -193,22 +213,24 @@ ipx_del_route(int argc, char **argv)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
progname = argv[0];
|
||||
if (argc < 2) {
|
||||
if (argc < 2)
|
||||
{
|
||||
usage();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (strncasecmp(argv[1], "add", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_add_route(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_del_route(argc-1, argv);
|
||||
if (strncasecmp(argv[1], "add", 3) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_add_route(argc - 1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0)
|
||||
{
|
||||
for (i = 1; i < (argc - 1); i++)
|
||||
argv[i] = argv[i + 1];
|
||||
ipx_del_route(argc - 1, argv);
|
||||
}
|
||||
usage();
|
||||
return 0;
|
||||
35
ipxdump/Makefile
Normal file
35
ipxdump/Makefile
Normal file
@@ -0,0 +1,35 @@
|
||||
EXEC= ipxdump ipxparse
|
||||
|
||||
CFLAGS= -Wall -O2 -I../include
|
||||
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>
|
||||
237
ipxdump/ipxdump.c
Normal file
237
ipxdump/ipxdump.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/* 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 <netinet/if_ether.h>
|
||||
#include <strings.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <signal.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.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 (htons(packet_type))
|
||||
{
|
||||
case ETH_P_IPX:
|
||||
handle_ipx("EtherII", &(buf[sizeof(struct ethhdr)]));
|
||||
break;
|
||||
default:
|
||||
handle_other(buf, length, saddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
1108
ipxdump/ipxparse.c
Normal file
1108
ipxdump/ipxparse.c
Normal file
File diff suppressed because it is too large
Load Diff
134
ipxdump/ipxutil.c
Normal file
134
ipxdump/ipxutil.c
Normal file
@@ -0,0 +1,134 @@
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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 "kernel/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,298 +0,0 @@
|
||||
/*
|
||||
* ncp_fs.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_NCP_H
|
||||
#define _LINUX_NCP_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ipx.h>
|
||||
|
||||
#define NCP_PTYPE (0x11)
|
||||
#define NCP_PORT (0x0451)
|
||||
|
||||
#define NCP_ALLOC_SLOT_REQUEST (0x1111)
|
||||
#define NCP_REQUEST (0x2222)
|
||||
#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
|
||||
|
||||
struct ncp_request_header {
|
||||
__u16 type __attribute__ ((packed));
|
||||
__u8 sequence __attribute__ ((packed));
|
||||
__u8 conn_low __attribute__ ((packed));
|
||||
__u8 task __attribute__ ((packed));
|
||||
__u8 conn_high __attribute__ ((packed));
|
||||
__u8 function __attribute__ ((packed));
|
||||
__u8 data[0] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define NCP_REPLY (0x3333)
|
||||
#define NCP_POSITIVE_ACK (0x9999)
|
||||
|
||||
struct ncp_reply_header {
|
||||
__u16 type __attribute__ ((packed));
|
||||
__u8 sequence __attribute__ ((packed));
|
||||
__u8 conn_low __attribute__ ((packed));
|
||||
__u8 task __attribute__ ((packed));
|
||||
__u8 conn_high __attribute__ ((packed));
|
||||
__u8 completion_code __attribute__ ((packed));
|
||||
__u8 connection_state __attribute__ ((packed));
|
||||
__u8 data[0] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
|
||||
#define NCP_BINDERY_USER (0x0001)
|
||||
#define NCP_BINDERY_UGROUP (0x0002)
|
||||
#define NCP_BINDERY_PQUEUE (0x0003)
|
||||
#define NCP_BINDERY_FSERVER (0x0004)
|
||||
#define NCP_BINDERY_NAME_LEN (48)
|
||||
struct ncp_bindery_object {
|
||||
__u32 object_id;
|
||||
__u16 object_type;
|
||||
__u8 object_name[NCP_BINDERY_NAME_LEN];
|
||||
__u8 object_flags;
|
||||
__u8 object_security;
|
||||
__u8 object_has_prop;
|
||||
};
|
||||
|
||||
struct nw_property {
|
||||
__u8 value[128];
|
||||
__u8 more_flag;
|
||||
__u8 property_flag;
|
||||
};
|
||||
|
||||
struct prop_net_address {
|
||||
__u32 network __attribute__ ((packed));
|
||||
__u8 node[IPX_NODE_LEN] __attribute__ ((packed));
|
||||
__u16 port __attribute__ ((packed));
|
||||
};
|
||||
|
||||
#define NCP_VOLNAME_LEN (16)
|
||||
#define NCP_NUMBER_OF_VOLUMES (64)
|
||||
struct ncp_volume_info {
|
||||
__u32 total_blocks;
|
||||
__u32 free_blocks;
|
||||
__u32 purgeable_blocks;
|
||||
__u32 not_yet_purgeable_blocks;
|
||||
__u32 total_dir_entries;
|
||||
__u32 available_dir_entries;
|
||||
__u8 sectors_per_block;
|
||||
char volume_name[NCP_VOLNAME_LEN+1];
|
||||
};
|
||||
|
||||
struct ncp_filesearch_info {
|
||||
__u8 volume_number;
|
||||
__u16 directory_id;
|
||||
__u16 sequence_no;
|
||||
__u8 access_rights;
|
||||
};
|
||||
|
||||
#define NCP_MAX_FILENAME 14
|
||||
|
||||
/* these define the attribute byte as seen by NCP */
|
||||
#define aRONLY (1L<<0)
|
||||
#define aHIDDEN (1L<<1)
|
||||
#define aSYSTEM (1L<<2)
|
||||
#define aEXECUTE (1L<<3)
|
||||
#define aDIR (1L<<4)
|
||||
#define aARCH (1L<<5)
|
||||
|
||||
#define AR_READ (0x01)
|
||||
#define AR_WRITE (0x02)
|
||||
#define AR_EXCLUSIVE (0x20)
|
||||
|
||||
#define NCP_FILE_ID_LEN 6
|
||||
struct ncp_file_info {
|
||||
__u8 file_id[NCP_FILE_ID_LEN];
|
||||
char file_name[NCP_MAX_FILENAME+1];
|
||||
__u8 file_attributes;
|
||||
__u8 file_mode;
|
||||
__u32 file_length;
|
||||
__u16 creation_date;
|
||||
__u16 access_date;
|
||||
__u16 update_date;
|
||||
__u16 update_time;
|
||||
};
|
||||
|
||||
|
||||
/* Defines for ReturnInformationMask */
|
||||
#define RIM_NAME (0x0001L)
|
||||
#define RIM_SPACE_ALLOCATED (0x0002L)
|
||||
#define RIM_ATTRIBUTES (0x0004L)
|
||||
#define RIM_DATA_SIZE (0x0008L)
|
||||
#define RIM_TOTAL_SIZE (0x0010L)
|
||||
#define RIM_EXT_ATTR_INFO (0x0020L)
|
||||
#define RIM_ARCHIVE (0x0040L)
|
||||
#define RIM_MODIFY (0x0080L)
|
||||
#define RIM_CREATION (0x0100L)
|
||||
#define RIM_OWNING_NAMESPACE (0x0200L)
|
||||
#define RIM_DIRECTORY (0x0400L)
|
||||
#define RIM_RIGHTS (0x0800L)
|
||||
#define RIM_ALL (0x0FFFL)
|
||||
#define RIM_COMPRESSED_INFO (0x80000000L)
|
||||
|
||||
/* open/create modes */
|
||||
#define OC_MODE_OPEN 0x01
|
||||
#define OC_MODE_TRUNCATE 0x02
|
||||
#define OC_MODE_REPLACE 0x02
|
||||
#define OC_MODE_CREATE 0x08
|
||||
|
||||
/* open/create results */
|
||||
#define OC_ACTION_NONE 0x00
|
||||
#define OC_ACTION_OPEN 0x01
|
||||
#define OC_ACTION_CREATE 0x02
|
||||
#define OC_ACTION_TRUNCATE 0x04
|
||||
#define OC_ACTION_REPLACE 0x04
|
||||
|
||||
/* access rights attributes */
|
||||
#ifndef AR_READ_ONLY
|
||||
#define AR_READ_ONLY 0x0001
|
||||
#define AR_WRITE_ONLY 0x0002
|
||||
#define AR_DENY_READ 0x0004
|
||||
#define AR_DENY_WRITE 0x0008
|
||||
#define AR_COMPATIBILITY 0x0010
|
||||
#define AR_WRITE_THROUGH 0x0040
|
||||
#define AR_OPEN_COMPRESSED 0x0100
|
||||
#endif
|
||||
|
||||
struct nw_info_struct
|
||||
{
|
||||
__u32 spaceAlloc __attribute__ ((packed));
|
||||
__u32 attributes __attribute__ ((packed));
|
||||
__u16 flags __attribute__ ((packed));
|
||||
__u32 dataStreamSize __attribute__ ((packed));
|
||||
__u32 totalStreamSize __attribute__ ((packed));
|
||||
__u16 numberOfStreams __attribute__ ((packed));
|
||||
__u16 creationTime __attribute__ ((packed));
|
||||
__u16 creationDate __attribute__ ((packed));
|
||||
__u32 creatorID __attribute__ ((packed));
|
||||
__u16 modifyTime __attribute__ ((packed));
|
||||
__u16 modifyDate __attribute__ ((packed));
|
||||
__u32 modifierID __attribute__ ((packed));
|
||||
__u16 lastAccessDate __attribute__ ((packed));
|
||||
__u16 archiveTime __attribute__ ((packed));
|
||||
__u16 archiveDate __attribute__ ((packed));
|
||||
__u32 archiverID __attribute__ ((packed));
|
||||
__u16 inheritedRightsMask __attribute__ ((packed));
|
||||
__u32 dirEntNum __attribute__ ((packed));
|
||||
__u32 DosDirNum __attribute__ ((packed));
|
||||
__u32 volNumber __attribute__ ((packed));
|
||||
__u32 EADataSize __attribute__ ((packed));
|
||||
__u32 EAKeyCount __attribute__ ((packed));
|
||||
__u32 EAKeySize __attribute__ ((packed));
|
||||
__u32 NSCreator __attribute__ ((packed));
|
||||
__u8 nameLen __attribute__ ((packed));
|
||||
__u8 entryName[256] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
/* modify mask - use with MODIFY_DOS_INFO structure */
|
||||
#define DM_ATTRIBUTES (0x0002L)
|
||||
#define DM_CREATE_DATE (0x0004L)
|
||||
#define DM_CREATE_TIME (0x0008L)
|
||||
#define DM_CREATOR_ID (0x0010L)
|
||||
#define DM_ARCHIVE_DATE (0x0020L)
|
||||
#define DM_ARCHIVE_TIME (0x0040L)
|
||||
#define DM_ARCHIVER_ID (0x0080L)
|
||||
#define DM_MODIFY_DATE (0x0100L)
|
||||
#define DM_MODIFY_TIME (0x0200L)
|
||||
#define DM_MODIFIER_ID (0x0400L)
|
||||
#define DM_LAST_ACCESS_DATE (0x0800L)
|
||||
#define DM_INHERITED_RIGHTS_MASK (0x1000L)
|
||||
#define DM_MAXIMUM_SPACE (0x2000L)
|
||||
|
||||
struct nw_modify_dos_info
|
||||
{
|
||||
__u32 attributes __attribute__ ((packed));
|
||||
__u16 creationDate __attribute__ ((packed));
|
||||
__u16 creationTime __attribute__ ((packed));
|
||||
__u32 creatorID __attribute__ ((packed));
|
||||
__u16 modifyDate __attribute__ ((packed));
|
||||
__u16 modifyTime __attribute__ ((packed));
|
||||
__u32 modifierID __attribute__ ((packed));
|
||||
__u16 archiveDate __attribute__ ((packed));
|
||||
__u16 archiveTime __attribute__ ((packed));
|
||||
__u32 archiverID __attribute__ ((packed));
|
||||
__u16 lastAccessDate __attribute__ ((packed));
|
||||
__u16 inheritanceGrantMask __attribute__ ((packed));
|
||||
__u16 inheritanceRevokeMask __attribute__ ((packed));
|
||||
__u32 maximumSpace __attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct nw_file_info {
|
||||
struct nw_info_struct i;
|
||||
int opened;
|
||||
int access;
|
||||
__u32 server_file_handle __attribute__ ((packed));
|
||||
__u8 open_create_action __attribute__ ((packed));
|
||||
__u8 file_handle[6] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct nw_search_sequence {
|
||||
__u8 volNumber __attribute__ ((packed));
|
||||
__u32 dirBase __attribute__ ((packed));
|
||||
__u32 sequence __attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct nw_queue_job_entry {
|
||||
__u16 InUse __attribute__ ((packed));
|
||||
__u32 prev __attribute__ ((packed));
|
||||
__u32 next __attribute__ ((packed));
|
||||
__u32 ClientStation __attribute__ ((packed));
|
||||
__u32 ClientTask __attribute__ ((packed));
|
||||
__u32 ClientObjectID __attribute__ ((packed));
|
||||
__u32 TargetServerID __attribute__ ((packed));
|
||||
__u8 TargetExecTime[6] __attribute__ ((packed));
|
||||
__u8 JobEntryTime[6] __attribute__ ((packed));
|
||||
__u32 JobNumber __attribute__ ((packed));
|
||||
__u16 JobType __attribute__ ((packed));
|
||||
__u16 JobPosition __attribute__ ((packed));
|
||||
__u16 JobControlFlags __attribute__ ((packed));
|
||||
__u8 FileNameLen __attribute__ ((packed));
|
||||
char JobFileName[13] __attribute__ ((packed));
|
||||
__u32 JobFileHandle __attribute__ ((packed));
|
||||
__u32 ServerStation __attribute__ ((packed));
|
||||
__u32 ServerTaskNumber __attribute__ ((packed));
|
||||
__u32 ServerObjectID __attribute__ ((packed));
|
||||
char JobTextDescription[50] __attribute__ ((packed));
|
||||
char ClientRecordArea[152] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
struct queue_job {
|
||||
struct nw_queue_job_entry j;
|
||||
__u8 file_handle[6];
|
||||
};
|
||||
|
||||
#define QJE_OPER_HOLD 0x80
|
||||
#define QJE_USER_HOLD 0x40
|
||||
#define QJE_ENTRYOPEN 0x20
|
||||
#define QJE_SERV_RESTART 0x10
|
||||
#define QJE_SERV_AUTO 0x08
|
||||
|
||||
/* ClientRecordArea for print jobs */
|
||||
|
||||
#define KEEP_ON 0x0400
|
||||
#define NO_FORM_FEED 0x0800
|
||||
#define NOTIFICATION 0x1000
|
||||
#define DELETE_FILE 0x2000
|
||||
#define EXPAND_TABS 0x4000
|
||||
#define PRINT_BANNER 0x8000
|
||||
|
||||
struct print_job_record {
|
||||
__u8 Version __attribute__ ((packed));
|
||||
__u8 TabSize __attribute__ ((packed));
|
||||
__u16 Copies __attribute__ ((packed));
|
||||
__u16 CtrlFlags __attribute__ ((packed));
|
||||
__u16 Lines __attribute__ ((packed));
|
||||
__u16 Rows __attribute__ ((packed));
|
||||
char FormName[16] __attribute__ ((packed));
|
||||
__u8 Reserved[6] __attribute__ ((packed));
|
||||
char BannerName[13] __attribute__ ((packed));
|
||||
char FnameBanner[13] __attribute__ ((packed));
|
||||
char FnameHeader[14] __attribute__ ((packed));
|
||||
char Path[80] __attribute__ ((packed));
|
||||
};
|
||||
|
||||
|
||||
#endif /* _LINUX_NCP_H */
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
* ncp_fs.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_NCP_FS_H
|
||||
#define _LINUX_NCP_FS_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/ncp_mount.h>
|
||||
#include <linux/ncp_fs_sb.h>
|
||||
#include <linux/ncp_fs_i.h>
|
||||
|
||||
/*
|
||||
* ioctl commands
|
||||
*/
|
||||
|
||||
struct ncp_ioctl_request {
|
||||
unsigned int function;
|
||||
unsigned int size;
|
||||
char *data;
|
||||
};
|
||||
|
||||
struct ncp_fs_info {
|
||||
int version;
|
||||
struct sockaddr_ipx addr;
|
||||
uid_t mounted_uid;
|
||||
int connection; /* Connection number the server assigned us */
|
||||
int buffer_size; /* The negotiated buffer size, to be
|
||||
used for read/write requests! */
|
||||
|
||||
/* 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_GET_FS_INFO_VERSION (1)
|
||||
#define NCP_IOC_GET_FS_INFO _IOWR('i', 1, unsigned char *)
|
||||
|
||||
/*
|
||||
* The packet size to allocate. One page should be enough.
|
||||
*/
|
||||
#define NCP_PACKET_SIZE 4070
|
||||
|
||||
#define NCP_MAXPATHLEN 255
|
||||
#define NCP_MAXNAMELEN 14
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* The readdir cache size controls how many directory entries are
|
||||
* cached.
|
||||
*/
|
||||
#define NCP_READDIR_CACHE_SIZE 64
|
||||
|
||||
|
||||
#define NCP_MAX_RPC_TIMEOUT (60) /* 6 seconds */
|
||||
|
||||
/* Guess, what 0x564c is :-) */
|
||||
#define NCP_SUPER_MAGIC 0x564c
|
||||
|
||||
|
||||
#define NCP_SBP(sb) ((struct ncp_server *)((sb)->u.generic_sbp))
|
||||
#define NCP_INOP(inode) ((struct ncp_inode_info *)((inode)->u.generic_ip))
|
||||
|
||||
#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb)
|
||||
#define NCP_FINFO(inode) (&(NCP_INOP(inode)->finfo))
|
||||
#define NCP_ISTRUCT(inode) (&(NCP_FINFO(inode)->i))
|
||||
|
||||
#ifdef DEBUG_NCP_MALLOC
|
||||
|
||||
#include <linux/malloc.h>
|
||||
|
||||
extern int ncp_malloced;
|
||||
extern int ncp_current_malloced;
|
||||
|
||||
static inline void *
|
||||
ncp_kmalloc(unsigned int size, int priority)
|
||||
{
|
||||
ncp_malloced += 1;
|
||||
ncp_current_malloced += 1;
|
||||
return kmalloc(size, priority);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ncp_kfree_s(void *obj, int size)
|
||||
{
|
||||
ncp_current_malloced -= 1;
|
||||
kfree_s(obj, size);
|
||||
}
|
||||
|
||||
#else /* DEBUG_NCP_MALLOC */
|
||||
|
||||
#define ncp_kmalloc(s,p) kmalloc(s,p)
|
||||
#define ncp_kfree_s(o,s) kfree_s(o,s)
|
||||
|
||||
#endif /* DEBUG_NCP_MALLOC */
|
||||
|
||||
#if DEBUG_NCP > 0
|
||||
#define DPRINTK(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define DPRINTK(format, args...)
|
||||
#endif
|
||||
|
||||
#if DEBUG_NCP > 1
|
||||
#define DDPRINTK(format, args...) printk(format , ## args)
|
||||
#else
|
||||
#define DDPRINTK(format, args...)
|
||||
#endif
|
||||
|
||||
|
||||
/* linux/fs/ncpfs/file.c */
|
||||
extern struct inode_operations ncp_file_inode_operations;
|
||||
int ncp_make_open(struct inode *i, int right);
|
||||
|
||||
/* linux/fs/ncpfs/dir.c */
|
||||
extern struct inode_operations ncp_dir_inode_operations;
|
||||
void ncp_free_inode_info(struct ncp_inode_info *i);
|
||||
void ncp_free_all_inodes(struct ncp_server *server);
|
||||
void ncp_init_root(struct ncp_server *server);
|
||||
int ncp_stat_root(struct ncp_server *server);
|
||||
void ncp_init_dir_cache(void);
|
||||
void ncp_invalid_dir_cache(unsigned long ino);
|
||||
void ncp_invalidate_all_inodes(struct ncp_server *server);
|
||||
void ncp_free_dir_cache(void);
|
||||
int ncp_date_dos2unix(__u16 time, __u16 date);
|
||||
void ncp_date_unix2dos(int unix_date, __u16 *time, __u16 *date);
|
||||
|
||||
|
||||
/* linux/fs/ncpfs/ioctl.c */
|
||||
int ncp_ioctl (struct inode * inode, struct file * filp,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* linux/fs/ncpfs/inode.c */
|
||||
struct super_block *ncp_read_super(struct super_block *sb,
|
||||
void *raw_data, int silent);
|
||||
void ncp_invalidate_connection(struct ncp_server *server);
|
||||
int ncp_conn_is_valid(struct ncp_server *server);
|
||||
|
||||
/* linux/fs/ncpfs/sock.c */
|
||||
int ncp_request(struct ncp_server *server, int function);
|
||||
int ncp_connect(struct ncp_server *server);
|
||||
int ncp_disconnect(struct ncp_server *server);
|
||||
int ncp_catch_watchdog(struct ncp_server *server);
|
||||
int ncp_dont_catch_watchdog(struct ncp_server *server);
|
||||
void ncp_lock_server(struct ncp_server *server);
|
||||
void ncp_unlock_server(struct ncp_server *server);
|
||||
|
||||
/* linux/fs/ncpfs/mmap.c */
|
||||
int ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_NCP_FS_H */
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* ncp_fs_i.h
|
||||
*
|
||||
* Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_NCP_FS_I
|
||||
#define _LINUX_NCP_FS_I
|
||||
|
||||
#include <linux/ncp.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
enum ncp_inode_state {
|
||||
NCP_INODE_VALID = 19, /* Inode currently in use */
|
||||
NCP_INODE_LOOKED_UP, /* directly before iget */
|
||||
NCP_INODE_CACHED, /* in a path to an inode which is in use */
|
||||
NCP_INODE_INVALID
|
||||
};
|
||||
|
||||
/*
|
||||
* ncp fs inode data (in memory only)
|
||||
*/
|
||||
struct ncp_inode_info {
|
||||
enum ncp_inode_state state;
|
||||
int nused; /* for directories:
|
||||
number of references in memory */
|
||||
struct ncp_inode_info *dir;
|
||||
struct ncp_inode_info *next, *prev;
|
||||
struct nw_file_info finfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* ncp_fs_sb.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NCP_FS_SB
|
||||
#define _NCP_FS_SB
|
||||
|
||||
#include <linux/ncp_mount.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#define NCP_DEFAULT_BUFSIZE 1024
|
||||
|
||||
struct ncp_server {
|
||||
|
||||
struct ncp_mount_data m; /* Nearly all of the mount data is of
|
||||
interest for us later, so we store
|
||||
it completely. */
|
||||
|
||||
struct file *ncp_filp; /* File pointer to ncp socket */
|
||||
|
||||
struct file *wdog_filp; /* File pointer to wdog socket */
|
||||
void *data_ready; /* The wdog socket gets a new
|
||||
data_ready callback. We store the
|
||||
old one for checking purposes and
|
||||
to reset it on unmounting. */
|
||||
|
||||
u8 sequence;
|
||||
u8 task;
|
||||
u16 connection; /* Remote connection number */
|
||||
|
||||
u8 completion; /* Status message from server */
|
||||
u8 conn_status; /* Bit 4 = 1 ==> Server going down, no
|
||||
requests allowed anymore */
|
||||
|
||||
int buffer_size; /* Negotiated bufsize */
|
||||
|
||||
int reply_size; /* Size of last reply */
|
||||
|
||||
int packet_size;
|
||||
unsigned char *packet; /* Here we prepare requests and
|
||||
receive replies */
|
||||
|
||||
int lock; /* To prevent mismatch in protocols. */
|
||||
struct wait_queue *wait;
|
||||
|
||||
int current_size; /* for packet preparation */
|
||||
int has_subfunction;
|
||||
int ncp_reply_size;
|
||||
|
||||
struct ncp_inode_info root;
|
||||
char root_path; /* '\0' */
|
||||
};
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* ncp_mount.h
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_NCP_MOUNT_H
|
||||
#define _LINUX_NCP_MOUNT_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ipx.h>
|
||||
#include <linux/ncp.h>
|
||||
#include <linux/ncp_fs_i.h>
|
||||
|
||||
#define NCP_MOUNT_VERSION 1
|
||||
|
||||
#define NCP_USERNAME_LEN (NCP_BINDERY_NAME_LEN)
|
||||
#define NCP_PASSWORD_LEN 20
|
||||
|
||||
/* Values for flags */
|
||||
#define NCP_MOUNT_SOFT 0x0001
|
||||
#define NCP_MOUNT_INTR 0x0002
|
||||
|
||||
struct ncp_mount_data {
|
||||
int version;
|
||||
unsigned int ncp_fd; /* The socket to the ncp port */
|
||||
unsigned int wdog_fd; /* Watchdog packets come here */
|
||||
unsigned int message_fd; /* Not used yet, maybe for messages */
|
||||
uid_t mounted_uid; /* Who may umount() this filesystem? */
|
||||
|
||||
struct sockaddr_ipx serv_addr;
|
||||
unsigned char server_name[49];
|
||||
|
||||
unsigned char username[NCP_USERNAME_LEN+1];
|
||||
unsigned char password[NCP_PASSWORD_LEN+1];
|
||||
|
||||
unsigned int time_out; /* How long should I wait after
|
||||
sending a NCP request? */
|
||||
unsigned int retry_count; /* And how often should I retry? */
|
||||
unsigned int flags;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t file_mode;
|
||||
mode_t dir_mode;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
#
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
CFLAGS = -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer \
|
||||
$(INCLUDES) \
|
||||
# -DDEBUG_NCP=1 -DDEBUG_NCP_MALLOC
|
||||
# -DDEBUG_NCP_MALLOC
|
||||
|
||||
CC = gcc -D__KERNEL__ -I.
|
||||
AS = as
|
||||
ARCH = i386
|
||||
|
||||
.c.s:
|
||||
$(CC) $(CFLAGS) -S $<
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
.s.o:
|
||||
$(AS) -o $*.o $<
|
||||
|
||||
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib_kernel.o mmap.o
|
||||
|
||||
all: $(INTERM_BINDIR)/ncpfs.o
|
||||
|
||||
$(INTERM_BINDIR)/ncpfs.o: $(OBJS)
|
||||
$(LD) -r -o $@ $(OBJS)
|
||||
|
||||
ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h
|
||||
$(CC) $(CFLAGS) -finline-functions -c $<
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f *.o *~
|
||||
|
||||
realclean: clean
|
||||
rm -f ncpmount ncptest .depend $(DISTFILE) *.out
|
||||
|
||||
modules: ncpfs.o
|
||||
|
||||
SRCPATH=$(shell pwd)
|
||||
SRCDIR=$(shell basename $(SRCPATH))
|
||||
DISTFILE=$(SRCDIR).tgz
|
||||
BACKUPFILE=ncpfs01.tgz
|
||||
HOME=/home/me
|
||||
|
||||
backup:
|
||||
(rm -f $(DISTFILE); cd ..; tar cvf - $(SRCDIR) | gzip -1 \
|
||||
> $(HOME)/tarz/backup/$(BACKUPFILE))
|
||||
(cd $(HOME)/tarz/backup; ls -l $(BACKUPFILE); mcopy $(BACKUPFILE) a:)
|
||||
|
||||
dist: realclean
|
||||
rm -fr mnt
|
||||
(cd ..; \
|
||||
tar cvf - $(SRCDIR) | \
|
||||
gzip -9 > $(DISTFILE); \
|
||||
mv $(DISTFILE) $(SRCDIR))
|
||||
|
||||
#
|
||||
# include a dependency file if one exists
|
||||
#
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
1061
kernel-1.2/src/dir.c
1061
kernel-1.2/src/dir.c
File diff suppressed because it is too large
Load Diff
@@ -1,277 +0,0 @@
|
||||
/*
|
||||
* file.c
|
||||
*
|
||||
* Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#ifdef MODULE
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include "ncplib_kernel.h"
|
||||
#include <linux/malloc.h>
|
||||
|
||||
static inline int min(int a, int b)
|
||||
{
|
||||
return a<b ? a : b;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_fsync(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_make_open(struct inode *i, int right)
|
||||
{
|
||||
struct nw_file_info *finfo;
|
||||
|
||||
if (i == NULL)
|
||||
{
|
||||
printk("ncp_make_open: got NULL inode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
finfo = NCP_FINFO(i);
|
||||
|
||||
DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
|
||||
|
||||
if (finfo->opened == 0)
|
||||
{
|
||||
/* tries max. rights */
|
||||
if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
|
||||
NULL, NULL,
|
||||
OC_MODE_OPEN, 0,
|
||||
AR_READ | AR_WRITE,
|
||||
finfo) == 0)
|
||||
{
|
||||
finfo->access = O_RDWR;
|
||||
}
|
||||
else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
|
||||
NULL, NULL,
|
||||
OC_MODE_OPEN, 0,
|
||||
AR_READ,
|
||||
finfo) == 0)
|
||||
{
|
||||
finfo->access = O_RDONLY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ((right == O_RDONLY) && ( (finfo->access == O_RDONLY)
|
||||
|| (finfo->access == O_RDWR)))
|
||||
|| ((right == O_WRONLY) && ( (finfo->access == O_WRONLY)
|
||||
|| (finfo->access == O_RDWR)))
|
||||
|| ((right == O_RDWR) && (finfo->access == O_RDWR)))
|
||||
return 0;
|
||||
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
|
||||
{
|
||||
int bufsize, already_read;
|
||||
off_t pos;
|
||||
int errno;
|
||||
|
||||
DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName);
|
||||
|
||||
if (inode == NULL)
|
||||
{
|
||||
DPRINTK("ncp_file_read: inode = NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
{
|
||||
DPRINTK("ncp_file_read: read from non-file, mode %07o\n",
|
||||
inode->i_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pos = file->f_pos;
|
||||
|
||||
if (pos + count > inode->i_size)
|
||||
{
|
||||
count = inode->i_size - pos;
|
||||
}
|
||||
|
||||
if (count <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((errno = ncp_make_open(inode, O_RDONLY)) != 0)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
bufsize = NCP_SERVER(inode)->buffer_size;
|
||||
|
||||
already_read = 0;
|
||||
|
||||
/* First read in as much as possible for each bufsize. */
|
||||
while (already_read < count)
|
||||
{
|
||||
int read_this_time;
|
||||
int to_read = min(bufsize - (pos % bufsize),
|
||||
count - already_read);
|
||||
|
||||
if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
|
||||
pos, to_read, buf, &read_this_time) != 0)
|
||||
{
|
||||
return -EIO; /* This is not exact, i know.. */
|
||||
}
|
||||
|
||||
pos += read_this_time;
|
||||
buf += read_this_time;
|
||||
already_read += read_this_time;
|
||||
|
||||
if (read_this_time < to_read)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
file->f_pos = pos;
|
||||
|
||||
if (!IS_RDONLY(inode))
|
||||
{
|
||||
inode->i_atime = CURRENT_TIME;
|
||||
}
|
||||
|
||||
inode->i_dirt = 1;
|
||||
|
||||
DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName);
|
||||
|
||||
return already_read;
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_file_write(struct inode *inode, struct file *file, char *buf,
|
||||
int count)
|
||||
{
|
||||
int bufsize, already_written;
|
||||
off_t pos;
|
||||
int errno;
|
||||
|
||||
if (inode == NULL)
|
||||
{
|
||||
DPRINTK("ncp_file_write: inode = NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
{
|
||||
DPRINTK("ncp_file_write: write to non-file, mode %07o\n",
|
||||
inode->i_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
|
||||
|
||||
if (count <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((errno = ncp_make_open(inode, O_RDWR)) != 0)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
pos = file->f_pos;
|
||||
|
||||
if (file->f_flags & O_APPEND)
|
||||
{
|
||||
pos = inode->i_size;
|
||||
}
|
||||
|
||||
bufsize = NCP_SERVER(inode)->buffer_size;
|
||||
|
||||
already_written = 0;
|
||||
|
||||
while (already_written < count)
|
||||
{
|
||||
int written_this_time;
|
||||
int to_write = min(bufsize - (pos % bufsize),
|
||||
count - already_written);
|
||||
|
||||
if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
|
||||
pos, to_write, buf, &written_this_time) != 0)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
pos += written_this_time;
|
||||
buf += written_this_time;
|
||||
already_written += written_this_time;
|
||||
|
||||
if (written_this_time < to_write)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
inode->i_dirt = 1;
|
||||
|
||||
file->f_pos = pos;
|
||||
|
||||
if (pos > inode->i_size)
|
||||
{
|
||||
inode->i_size = pos;
|
||||
}
|
||||
|
||||
DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
|
||||
|
||||
return already_written;
|
||||
}
|
||||
|
||||
static struct file_operations ncp_file_operations = {
|
||||
NULL, /* lseek - default */
|
||||
ncp_file_read, /* read */
|
||||
ncp_file_write, /* write */
|
||||
NULL, /* readdir - bad */
|
||||
NULL, /* select - default */
|
||||
ncp_ioctl, /* ioctl */
|
||||
ncp_mmap, /* mmap */
|
||||
NULL, /* open */
|
||||
NULL, /* release */
|
||||
ncp_fsync, /* fsync */
|
||||
};
|
||||
|
||||
struct inode_operations ncp_file_inode_operations = {
|
||||
&ncp_file_operations, /* default file operations */
|
||||
NULL, /* create */
|
||||
NULL, /* lookup */
|
||||
NULL, /* link */
|
||||
NULL, /* unlink */
|
||||
NULL, /* symlink */
|
||||
NULL, /* mkdir */
|
||||
NULL, /* rmdir */
|
||||
NULL, /* mknod */
|
||||
NULL, /* rename */
|
||||
NULL, /* readlink */
|
||||
NULL, /* follow_link */
|
||||
NULL, /* bmap */
|
||||
NULL /* truncate */
|
||||
};
|
||||
@@ -1,528 +0,0 @@
|
||||
/*
|
||||
* inode.c
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#ifdef MODULE
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#else
|
||||
#define MOD_INC_USE_COUNT
|
||||
#define MOD_DEC_USE_COUNT
|
||||
#endif
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/segment.h>
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/locks.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/malloc.h>
|
||||
#include "ncplib_kernel.h"
|
||||
|
||||
extern int close_fp(struct file *filp);
|
||||
|
||||
static void ncp_put_inode(struct inode *);
|
||||
static void ncp_read_inode(struct inode *);
|
||||
static void ncp_put_super(struct super_block *);
|
||||
static void ncp_statfs(struct super_block *sb, struct statfs *stat);
|
||||
static int ncp_notify_change(struct inode *inode, struct iattr *attr);
|
||||
|
||||
static struct super_operations ncp_sops = {
|
||||
ncp_read_inode, /* read inode */
|
||||
ncp_notify_change, /* notify change */
|
||||
NULL, /* write inode */
|
||||
ncp_put_inode, /* put inode */
|
||||
ncp_put_super, /* put superblock */
|
||||
NULL, /* write superblock */
|
||||
ncp_statfs, /* stat filesystem */
|
||||
NULL
|
||||
};
|
||||
|
||||
/* ncp_read_inode: Called from iget, it only traverses the allocated
|
||||
ncp_inode_info's and initializes the inode from the data found
|
||||
there. It does not allocate or deallocate anything. */
|
||||
|
||||
static void
|
||||
ncp_read_inode(struct inode *inode)
|
||||
{
|
||||
/* Our task should be extremely simple here. We only have to
|
||||
look up the infomation somebody else (ncp_iget) put into
|
||||
the inode tree. The address of this information is the
|
||||
inode->i_ino. Just to make sure everything went well, we
|
||||
check it's there. */
|
||||
|
||||
struct ncp_inode_info *inode_info
|
||||
= (struct ncp_inode_info *)(inode->i_ino);
|
||||
|
||||
#if 1
|
||||
struct ncp_inode_info *root = &(NCP_SERVER(inode)->root);
|
||||
struct ncp_inode_info *check_info = root;
|
||||
|
||||
do
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
if (NCP_ISTRUCT(inode)->attributes & aDIR)
|
||||
{
|
||||
inode->i_mode = NCP_SERVER(inode)->m.dir_mode;
|
||||
/* for directories in dataStreamSize seems to be some
|
||||
Object ID ??? */
|
||||
inode->i_size = 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
inode->i_mode = NCP_SERVER(inode)->m.file_mode;
|
||||
inode->i_size = NCP_ISTRUCT(inode)->dataStreamSize;
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
|
||||
|
||||
inode->i_nlink = 1;
|
||||
inode->i_uid = NCP_SERVER(inode)->m.uid;
|
||||
inode->i_gid = NCP_SERVER(inode)->m.gid;
|
||||
inode->i_blksize = 1024;
|
||||
inode->i_rdev = 0;
|
||||
|
||||
if ((inode->i_blksize != 0) && (inode->i_size != 0))
|
||||
{
|
||||
inode->i_blocks =
|
||||
(inode->i_size - 1) / inode->i_blksize + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
inode->i_blocks = 0;
|
||||
}
|
||||
|
||||
inode->i_mtime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->modifyTime,
|
||||
NCP_ISTRUCT(inode)->modifyDate);
|
||||
inode->i_ctime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->creationTime,
|
||||
NCP_ISTRUCT(inode)->creationDate);
|
||||
inode->i_atime = ncp_date_dos2unix(0,
|
||||
NCP_ISTRUCT(inode)->lastAccessDate);
|
||||
|
||||
if (S_ISREG(inode->i_mode))
|
||||
{
|
||||
inode->i_op = &ncp_file_inode_operations;
|
||||
}
|
||||
else if (S_ISDIR(inode->i_mode))
|
||||
{
|
||||
inode->i_op = &ncp_dir_inode_operations;
|
||||
}
|
||||
else
|
||||
{
|
||||
inode->i_op = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_put_inode(struct inode *inode)
|
||||
{
|
||||
struct nw_file_info *finfo = NCP_FINFO(inode);
|
||||
|
||||
if (finfo->opened != 0)
|
||||
{
|
||||
if (ncp_close_file(NCP_SERVER(inode), finfo->file_handle)!=0)
|
||||
{
|
||||
/* We can't do anything but complain. */
|
||||
printk("ncp_put_inode: could not close\n");
|
||||
}
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_put_inode: put %s\n",
|
||||
finfo->i.entryName);
|
||||
|
||||
ncp_free_inode_info(NCP_INOP(inode));
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
{
|
||||
DDPRINTK("ncp_put_inode: put directory %ld\n",
|
||||
inode->i_ino);
|
||||
ncp_invalid_dir_cache(inode->i_ino);
|
||||
}
|
||||
|
||||
clear_inode(inode);
|
||||
}
|
||||
|
||||
struct super_block *
|
||||
ncp_read_super(struct super_block *sb, void *raw_data, int silent)
|
||||
{
|
||||
struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
|
||||
struct ncp_server *server;
|
||||
struct file *ncp_filp;
|
||||
struct file *wdog_filp;
|
||||
dev_t dev = sb->s_dev;
|
||||
int error;
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
printk("ncp_read_super: missing data argument\n");
|
||||
sb->s_dev = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (data->version != NCP_MOUNT_VERSION)
|
||||
{
|
||||
printk("ncp warning: mount version %s than kernel\n",
|
||||
(data->version < NCP_MOUNT_VERSION) ?
|
||||
"older" : "newer");
|
||||
}
|
||||
|
||||
if ( (data->ncp_fd >= NR_OPEN)
|
||||
|| ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL)
|
||||
|| (!S_ISSOCK(ncp_filp->f_inode->i_mode)))
|
||||
{
|
||||
printk("ncp_read_super: invalid ncp socket\n");
|
||||
sb->s_dev = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( (data->wdog_fd >= NR_OPEN)
|
||||
|| ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL)
|
||||
|| (!S_ISSOCK(wdog_filp->f_inode->i_mode)))
|
||||
{
|
||||
printk("ncp_read_super: invalid wdog socket\n");
|
||||
sb->s_dev = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We must malloc our own super-block info */
|
||||
server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (server == NULL)
|
||||
{
|
||||
printk("ncp_read_super: could not alloc ncp_server\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ncp_filp->f_count += 1;
|
||||
wdog_filp->f_count += 1;
|
||||
|
||||
lock_super(sb);
|
||||
|
||||
NCP_SBP(sb) = server;
|
||||
|
||||
sb->s_blocksize = 1024; /* Eh... Is this correct? */
|
||||
sb->s_blocksize_bits = 10;
|
||||
sb->s_magic = NCP_SUPER_MAGIC;
|
||||
sb->s_dev = dev;
|
||||
sb->s_op = &ncp_sops;
|
||||
|
||||
server->ncp_filp = ncp_filp;
|
||||
server->wdog_filp = wdog_filp;
|
||||
server->lock = 0;
|
||||
server->wait = NULL;
|
||||
server->packet = NULL;
|
||||
server->buffer_size = 0;
|
||||
|
||||
server->m = *data;
|
||||
server->m.file_mode = (server->m.file_mode &
|
||||
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
|
||||
server->m.dir_mode = (server->m.dir_mode &
|
||||
(S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
|
||||
|
||||
server->packet_size = NCP_PACKET_SIZE;
|
||||
server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
|
||||
|
||||
if (server->packet == NULL)
|
||||
{
|
||||
printk("ncpfs: could not alloc packet\n");
|
||||
error = -ENOMEM;
|
||||
unlock_super(sb);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ncp_init_root(server);
|
||||
|
||||
/*
|
||||
* Make the connection to the server
|
||||
*/
|
||||
|
||||
if (ncp_catch_watchdog(server) != 0)
|
||||
{
|
||||
printk("ncp_read_super: Could not catch watchdog\n");
|
||||
error = -EINVAL;
|
||||
unlock_super(sb);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ncp_lock_server(server);
|
||||
error = ncp_connect(server);
|
||||
ncp_unlock_server(server);
|
||||
unlock_super(sb);
|
||||
|
||||
if (error < 0)
|
||||
{
|
||||
sb->s_dev = 0;
|
||||
printk("ncp_read_super: Failed connection, bailing out "
|
||||
"(error = %d).\n", -error);
|
||||
ncp_kfree_s(server->packet, server->packet_size);
|
||||
ncp_dont_catch_watchdog(server);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));
|
||||
|
||||
if (!(sb->s_mounted = iget(sb, (int)&(server->root))))
|
||||
{
|
||||
sb->s_dev = 0;
|
||||
printk("ncp_read_super: get root inode failed\n");
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
|
||||
&(server->buffer_size)) != 0)
|
||||
{
|
||||
sb->s_dev = 0;
|
||||
printk("ncp_read_super: could not get bufsize\n");
|
||||
goto disconnect;
|
||||
}
|
||||
|
||||
DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
|
||||
|
||||
MOD_INC_USE_COUNT;
|
||||
return sb;
|
||||
|
||||
disconnect:
|
||||
ncp_lock_server(server);
|
||||
ncp_disconnect(server);
|
||||
ncp_unlock_server(server);
|
||||
ncp_kfree_s(server->packet, server->packet_size);
|
||||
ncp_dont_catch_watchdog(server);
|
||||
fail:
|
||||
ncp_filp->f_count -= 1;
|
||||
wdog_filp->f_count -= 1;
|
||||
ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_put_super(struct super_block *sb)
|
||||
{
|
||||
struct ncp_server *server = NCP_SBP(sb);
|
||||
|
||||
lock_super(sb);
|
||||
|
||||
ncp_lock_server(server);
|
||||
ncp_disconnect(server);
|
||||
ncp_unlock_server(server);
|
||||
|
||||
close_fp(server->ncp_filp);
|
||||
|
||||
ncp_dont_catch_watchdog(server);
|
||||
close_fp(server->wdog_filp);
|
||||
|
||||
ncp_free_all_inodes(server);
|
||||
|
||||
ncp_kfree_s(server->packet, server->packet_size);
|
||||
|
||||
sb->s_dev = 0;
|
||||
ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
|
||||
NCP_SBP(sb) = NULL;
|
||||
|
||||
unlock_super(sb);
|
||||
|
||||
MOD_DEC_USE_COUNT;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_statfs(struct super_block *sb, struct statfs *stat)
|
||||
{
|
||||
struct statfs tmp;
|
||||
|
||||
/* We cannot say how much disk space is left on a mounted
|
||||
NetWare Server, because free space is distributed over
|
||||
volumes, and the current user might have disk quotas. So
|
||||
free space is not that simple to determine. Our decision
|
||||
here is to err conservatively. */
|
||||
|
||||
tmp.f_type = NCP_SUPER_MAGIC;
|
||||
tmp.f_bsize = 512;
|
||||
tmp.f_blocks = 0;
|
||||
tmp.f_bfree = 0;
|
||||
tmp.f_bavail = 0;
|
||||
tmp.f_files = -1;
|
||||
tmp.f_ffree = -1;
|
||||
tmp.f_namelen = 12;
|
||||
memcpy_tofs(stat, &tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_notify_change(struct inode *inode, struct iattr *attr)
|
||||
{
|
||||
int result = 0;
|
||||
int info_mask;
|
||||
struct nw_modify_dos_info info;
|
||||
|
||||
if ((result = inode_change_ok(inode, attr)) < 0)
|
||||
return result;
|
||||
|
||||
if (((attr->ia_valid & ATTR_UID) &&
|
||||
(attr->ia_uid != NCP_SERVER(inode)->m.uid)))
|
||||
return -EPERM;
|
||||
|
||||
if (((attr->ia_valid & ATTR_GID) &&
|
||||
(attr->ia_uid != NCP_SERVER(inode)->m.gid)))
|
||||
return -EPERM;
|
||||
|
||||
if (((attr->ia_valid & ATTR_MODE) &&
|
||||
(attr->ia_mode &
|
||||
~(S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO))))
|
||||
return -EPERM;
|
||||
|
||||
info_mask = 0;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if ((attr->ia_valid & ATTR_CTIME) != 0)
|
||||
{
|
||||
info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
|
||||
ncp_date_unix2dos(attr->ia_ctime,
|
||||
&(info.creationTime), &(info.creationDate));
|
||||
}
|
||||
|
||||
if ((attr->ia_valid & ATTR_MTIME) != 0)
|
||||
{
|
||||
info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
|
||||
ncp_date_unix2dos(attr->ia_mtime,
|
||||
&(info.modifyTime), &(info.modifyDate));
|
||||
}
|
||||
|
||||
if ((attr->ia_valid & ATTR_ATIME) != 0)
|
||||
{
|
||||
__u16 dummy;
|
||||
info_mask |= (DM_LAST_ACCESS_DATE);
|
||||
ncp_date_unix2dos(attr->ia_ctime,
|
||||
&(dummy), &(info.lastAccessDate));
|
||||
}
|
||||
|
||||
if (info_mask != 0)
|
||||
{
|
||||
if ((result =
|
||||
ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
|
||||
NCP_ISTRUCT(inode),
|
||||
info_mask,
|
||||
&info)) != 0)
|
||||
{
|
||||
result = -EACCES;
|
||||
|
||||
if (info_mask == (DM_CREATE_TIME|DM_CREATE_DATE))
|
||||
{
|
||||
/* NetWare seems not to allow this. I
|
||||
do not know why. So, just tell the
|
||||
user everything went fine. This is
|
||||
a terrible hack, but I do not know
|
||||
how to do this correctly. */
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((attr->ia_valid & ATTR_SIZE) != 0)
|
||||
{
|
||||
int written;
|
||||
|
||||
DPRINTK("ncpfs: trying to change size of %s to %ld\n",
|
||||
NCP_ISTRUCT(inode)->entryName, attr->ia_size);
|
||||
|
||||
if ((result = ncp_make_open(inode, O_RDWR)) < 0)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
|
||||
attr->ia_size, 0, "", &written);
|
||||
|
||||
/* According to ndir, the changes only take effect after
|
||||
closing the file */
|
||||
ncp_close_file(NCP_SERVER(inode),
|
||||
NCP_FINFO(inode)->file_handle);
|
||||
NCP_FINFO(inode)->opened = 0;
|
||||
|
||||
result = 0;
|
||||
}
|
||||
|
||||
ncp_invalid_dir_cache((unsigned long)(NCP_INOP(inode)->dir));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NCP_MALLOC
|
||||
int ncp_malloced;
|
||||
int ncp_current_malloced;
|
||||
#endif
|
||||
|
||||
#ifdef MODULE
|
||||
|
||||
char kernel_version[] = UTS_RELEASE;
|
||||
|
||||
static struct file_system_type ncp_fs_type = {
|
||||
ncp_read_super, "ncpfs", 0, NULL
|
||||
};
|
||||
|
||||
int
|
||||
init_module( void)
|
||||
{
|
||||
DPRINTK("ncpfs: init_module called\n");
|
||||
|
||||
#ifdef DEBUG_NCP_MALLOC
|
||||
ncp_malloced = 0;
|
||||
ncp_current_malloced = 0;
|
||||
#endif
|
||||
|
||||
ncp_init_dir_cache();
|
||||
register_filesystem(&ncp_fs_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cleanup_module(void)
|
||||
{
|
||||
DPRINTK("ncpfs: cleanup_module called\n");
|
||||
ncp_free_dir_cache();
|
||||
unregister_filesystem(&ncp_fs_type);
|
||||
#ifdef DEBUG_NCP_MALLOC
|
||||
printk("ncp_malloced: %d\n", ncp_malloced);
|
||||
printk("ncp_current_malloced: %d\n", ncp_current_malloced);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* ioctl.c
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#ifdef MODULE
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#include <asm/segment.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ncp.h>
|
||||
|
||||
int
|
||||
ncp_ioctl (struct inode * inode, struct file * filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int result;
|
||||
struct ncp_ioctl_request request;
|
||||
struct ncp_fs_info info;
|
||||
struct ncp_server *server = NCP_SERVER(inode);
|
||||
|
||||
switch(cmd) {
|
||||
case NCP_IOC_NCPREQUEST:
|
||||
|
||||
if ( (permission(inode, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if ((result = verify_area(VERIFY_READ, (char *)arg,
|
||||
sizeof(request))) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy_fromfs(&request, (struct ncp_ioctl_request *)arg,
|
||||
sizeof(request));
|
||||
|
||||
if ( (request.function > 255)
|
||||
|| (request.size >
|
||||
NCP_PACKET_SIZE - sizeof(struct ncp_request_header)))
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((result = verify_area(VERIFY_WRITE, (char *)request.data,
|
||||
NCP_PACKET_SIZE)) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_lock_server(server);
|
||||
|
||||
/* FIXME: We hack around in the server's structures
|
||||
here to be able to use ncp_request */
|
||||
|
||||
server->has_subfunction = 0;
|
||||
server->current_size = request.size;
|
||||
memcpy_fromfs(server->packet, request.data, request.size);
|
||||
|
||||
ncp_request(server, request.function);
|
||||
|
||||
DPRINTK("ncp_ioctl: copy %d bytes\n",
|
||||
server->reply_size);
|
||||
memcpy_tofs(request.data, server->packet, server->reply_size);
|
||||
|
||||
ncp_unlock_server(server);
|
||||
|
||||
return server->reply_size;
|
||||
|
||||
case NCP_IOC_GET_FS_INFO:
|
||||
|
||||
if ( (permission(inode, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if ((result = verify_area(VERIFY_WRITE, (char *)arg,
|
||||
sizeof(info))) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy_fromfs(&info, (struct ncp_fs_info *)arg,
|
||||
sizeof(info));
|
||||
|
||||
if (info.version != NCP_GET_FS_INFO_VERSION)
|
||||
{
|
||||
DPRINTK("info.version invalid: %d\n", info.version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info.addr = server->m.serv_addr;
|
||||
info.mounted_uid = server->m.mounted_uid;
|
||||
info.connection = server->connection;
|
||||
info.buffer_size = server->buffer_size;
|
||||
|
||||
memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
|
||||
return 0;
|
||||
|
||||
case NCP_IOC_GETMOUNTUID:
|
||||
|
||||
if ( (permission(inode, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if ((result = verify_area(VERIFY_WRITE, (uid_t*) arg,
|
||||
sizeof(uid_t))) != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
put_fs_word(server->m.mounted_uid, (uid_t*) arg);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* mmap.c
|
||||
*
|
||||
* Copyright (C) 1995 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#ifdef MODULE
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#include <linux/stat.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/shm.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/malloc.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
|
||||
#include "ncplib_kernel.h"
|
||||
#include <asm/segment.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static inline int min(int a, int b)
|
||||
{
|
||||
return a<b ? a : b;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the supplied page for mmap
|
||||
*/
|
||||
static unsigned long
|
||||
ncp_file_mmap_nopage(struct vm_area_struct * area,
|
||||
unsigned long address, unsigned long page, int no_share)
|
||||
{
|
||||
struct inode * inode = area->vm_inode;
|
||||
unsigned int clear;
|
||||
unsigned long tmp;
|
||||
int bufsize;
|
||||
int pos;
|
||||
unsigned short fs;
|
||||
|
||||
address &= PAGE_MASK;
|
||||
pos = address - area->vm_start + area->vm_offset;
|
||||
|
||||
clear = 0;
|
||||
if (address + PAGE_SIZE > area->vm_end)
|
||||
{
|
||||
clear = address + PAGE_SIZE - area->vm_end;
|
||||
}
|
||||
|
||||
/* what we can read in one go */
|
||||
bufsize = NCP_SERVER(inode)->buffer_size;
|
||||
|
||||
fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
|
||||
if (ncp_make_open(inode, O_RDONLY) < 0)
|
||||
{
|
||||
clear = PAGE_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int already_read = 0;
|
||||
int count = PAGE_SIZE - clear;
|
||||
int to_read;
|
||||
|
||||
while (already_read < count)
|
||||
{
|
||||
int read_this_time;
|
||||
|
||||
if ((pos % bufsize) != 0)
|
||||
{
|
||||
to_read = bufsize - (pos % bufsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
to_read = bufsize;
|
||||
}
|
||||
|
||||
to_read = min(to_read, count - already_read);
|
||||
|
||||
if (ncp_read(NCP_SERVER(inode),
|
||||
NCP_FINFO(inode)->file_handle,
|
||||
pos, to_read,
|
||||
(char *)(page + already_read),
|
||||
&read_this_time) != 0)
|
||||
{
|
||||
read_this_time = 0;
|
||||
}
|
||||
|
||||
pos += read_this_time;
|
||||
already_read += read_this_time;
|
||||
|
||||
if (read_this_time < to_read)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set_fs(fs);
|
||||
|
||||
tmp = page + PAGE_SIZE;
|
||||
while (clear--) {
|
||||
*(char *)--tmp = 0;
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
struct vm_operations_struct ncp_file_mmap = {
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
NULL, /* unmap */
|
||||
NULL, /* protect */
|
||||
NULL, /* sync */
|
||||
NULL, /* advise */
|
||||
ncp_file_mmap_nopage, /* nopage */
|
||||
NULL, /* wppage */
|
||||
NULL, /* swapout */
|
||||
NULL, /* swapin */
|
||||
};
|
||||
|
||||
|
||||
/* This is used for a general mmap of a ncp file */
|
||||
int
|
||||
ncp_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
|
||||
{
|
||||
DPRINTK("ncp_mmap: called\n");
|
||||
|
||||
/* only PAGE_COW or read-only supported now */
|
||||
if (vma->vm_flags & VM_SHARED)
|
||||
return -EINVAL;
|
||||
if (!inode->i_sb || !S_ISREG(inode->i_mode))
|
||||
return -EACCES;
|
||||
if (!IS_RDONLY(inode)) {
|
||||
inode->i_atime = CURRENT_TIME;
|
||||
inode->i_dirt = 1;
|
||||
}
|
||||
|
||||
vma->vm_inode = inode;
|
||||
inode->i_count++;
|
||||
vma->vm_ops = &ncp_file_mmap;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,617 +0,0 @@
|
||||
#include <linux/config.h>
|
||||
#ifdef MODULE
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#include "ncplib_kernel.h"
|
||||
|
||||
typedef __u8 byte;
|
||||
typedef __u16 word;
|
||||
typedef __u32 dword;
|
||||
|
||||
static inline int min(int a, int b)
|
||||
{
|
||||
return a<b ? a : b;
|
||||
}
|
||||
|
||||
static void
|
||||
assert_server_locked(struct ncp_server *server)
|
||||
{
|
||||
if (server->lock == 0)
|
||||
{
|
||||
DPRINTK("ncpfs: server not locked!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_byte(struct ncp_server *server, byte x)
|
||||
{
|
||||
assert_server_locked(server);
|
||||
*(byte *)(&(server->packet[server->current_size])) = x;
|
||||
server->current_size += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_word(struct ncp_server *server, word x)
|
||||
{
|
||||
assert_server_locked(server);
|
||||
*(word *)(&(server->packet[server->current_size])) = x;
|
||||
server->current_size += 2;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_dword(struct ncp_server *server, dword x)
|
||||
{
|
||||
assert_server_locked(server);
|
||||
*(dword *)(&(server->packet[server->current_size])) = x;
|
||||
server->current_size += 4;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_mem(struct ncp_server *server, const void *source, int size)
|
||||
{
|
||||
assert_server_locked(server);
|
||||
memcpy(&(server->packet[server->current_size]), source, size);
|
||||
server->current_size += size;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_mem_fromfs(struct ncp_server *server, const char *source, int size)
|
||||
{
|
||||
assert_server_locked(server);
|
||||
memcpy_fromfs(&(server->packet[server->current_size]), source, size);
|
||||
server->current_size += size;
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_pstring(struct ncp_server *server, const char *s)
|
||||
{
|
||||
int len = strlen(s);
|
||||
assert_server_locked(server);
|
||||
if (len > 255)
|
||||
{
|
||||
DPRINTK("ncpfs: string too long: %s\n", s);
|
||||
len = 255;
|
||||
}
|
||||
ncp_add_byte(server, len);
|
||||
ncp_add_mem(server, s, len);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_init_request(struct ncp_server *server)
|
||||
{
|
||||
ncp_lock_server(server);
|
||||
|
||||
server->current_size = sizeof(struct ncp_request_header);
|
||||
server->has_subfunction = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_init_request_s(struct ncp_server *server, int subfunction)
|
||||
{
|
||||
ncp_init_request(server);
|
||||
ncp_add_word(server, 0); /* preliminary size */
|
||||
|
||||
ncp_add_byte(server, subfunction);
|
||||
|
||||
server->has_subfunction = 1;
|
||||
}
|
||||
|
||||
static char *
|
||||
ncp_reply_data(struct ncp_server *server, int offset)
|
||||
{
|
||||
return &(server->packet[sizeof(struct ncp_reply_header) + offset]);
|
||||
}
|
||||
|
||||
static byte
|
||||
ncp_reply_byte(struct ncp_server *server, int offset)
|
||||
{
|
||||
return *(byte *)(ncp_reply_data(server, offset));
|
||||
}
|
||||
|
||||
static word
|
||||
ncp_reply_word(struct ncp_server *server, int offset)
|
||||
{
|
||||
return *(word *)(ncp_reply_data(server, offset));
|
||||
}
|
||||
|
||||
static dword
|
||||
ncp_reply_dword(struct ncp_server *server, int offset)
|
||||
{
|
||||
return *(dword *)(ncp_reply_data(server, offset));
|
||||
}
|
||||
|
||||
int
|
||||
ncp_negotiate_buffersize(struct ncp_server *server,
|
||||
int size, int *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_word(server, htons(size));
|
||||
|
||||
if ((result = ncp_request(server, 33)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
*target =min(ntohs(ncp_reply_word(server, 0)), size);
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_volume_info_with_number(struct ncp_server *server, int n,
|
||||
struct ncp_volume_info *target)
|
||||
{
|
||||
int result;
|
||||
int len;
|
||||
|
||||
ncp_init_request_s(server, 44);
|
||||
ncp_add_byte(server, n);
|
||||
|
||||
if ((result = ncp_request(server, 22)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
target->total_blocks = ncp_reply_dword(server, 0);
|
||||
target->free_blocks = ncp_reply_dword(server, 4);
|
||||
target->purgeable_blocks = ncp_reply_dword(server, 8);
|
||||
target->not_yet_purgeable_blocks = ncp_reply_dword(server, 12);
|
||||
target->total_dir_entries = ncp_reply_dword(server, 16);
|
||||
target->available_dir_entries = ncp_reply_dword(server, 20);
|
||||
target->sectors_per_block = ncp_reply_byte(server, 28);
|
||||
|
||||
memset(&(target->volume_name), 0, sizeof(target->volume_name));
|
||||
|
||||
len = ncp_reply_byte(server, 29);
|
||||
if (len > NCP_VOLNAME_LEN)
|
||||
{
|
||||
DPRINTK("ncpfs: volume name too long: %d\n", len);
|
||||
ncp_unlock_server(server);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(server, 5);
|
||||
ncp_add_pstring(server, name);
|
||||
|
||||
if ((result = ncp_request(server, 22)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
*target = ncp_reply_byte(server, 0);
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_close_file(struct ncp_server *server, const char *file_id)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 0);
|
||||
ncp_add_mem(server, file_id, 6);
|
||||
|
||||
if ((result = ncp_request(server, 66)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_add_handle_path(struct ncp_server *server,
|
||||
__u8 vol_num,
|
||||
__u32 dir_base, int have_dir_base,
|
||||
char *path)
|
||||
{
|
||||
ncp_add_byte(server, vol_num);
|
||||
ncp_add_dword(server, dir_base);
|
||||
if (have_dir_base != 0)
|
||||
{
|
||||
ncp_add_byte(server, 1); /* dir_base */
|
||||
}
|
||||
else
|
||||
{
|
||||
ncp_add_byte(server, 0xff); /* no handle */
|
||||
}
|
||||
if (path != NULL)
|
||||
{
|
||||
ncp_add_byte(server, 1); /* 1 component */
|
||||
ncp_add_pstring(server, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
ncp_add_byte(server, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_extract_file_info(void *structure, struct nw_info_struct *target)
|
||||
{
|
||||
__u8 *name_len;
|
||||
const int info_struct_size = sizeof(struct nw_info_struct) - 257;
|
||||
|
||||
memcpy(target, structure, info_struct_size);
|
||||
name_len = structure + info_struct_size;
|
||||
target->nameLen = *name_len;
|
||||
strncpy(target->entryName, name_len+1, *name_len);
|
||||
target->entryName[*name_len] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_do_lookup(struct ncp_server *server,
|
||||
struct nw_info_struct *dir,
|
||||
char *path, /* may only be one 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_word(server, 0xff); /* get all */
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
ncp_add_handle_path(server, vol_num, dir_base, 1,
|
||||
path);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_extract_file_info(ncp_reply_data(server, 0), target);
|
||||
|
||||
if (volname != NULL)
|
||||
{
|
||||
target->nameLen = strlen(volname);
|
||||
strcpy(target->entryName, volname);
|
||||
}
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
|
||||
struct nw_info_struct *file,
|
||||
__u32 info_mask,
|
||||
struct nw_modify_dos_info *info)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 7); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
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);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_del_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_info_struct *dir, char *name)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 8); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
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);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
|
||||
{
|
||||
__u16 *dest = (__u16 *) ret;
|
||||
memcpy(&(dest[1]), &sfd, 4);
|
||||
dest[0] = dest[1] + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If both dir and name are NULL, then in target there's already a
|
||||
looked-up entry that wants to be opened. */
|
||||
int
|
||||
ncp_open_create_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_info_struct *dir, char *name,
|
||||
int open_create_mode,
|
||||
__u32 create_attributes,
|
||||
int desired_acc_rights,
|
||||
struct nw_file_info *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 1); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, open_create_mode);
|
||||
ncp_add_word(server, 0x8006);
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
ncp_add_dword(server, create_attributes);
|
||||
/* The desired acc rights seem to be the inherited rights mask
|
||||
for directories */
|
||||
ncp_add_word(server, desired_acc_rights);
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
ncp_add_handle_path(server, dir->volNumber,
|
||||
dir->DosDirNum, 1, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ncp_add_handle_path(server,
|
||||
target->i.volNumber, target->i.DosDirNum,
|
||||
1, NULL);
|
||||
}
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
target->opened = 1;
|
||||
target->server_file_handle = ncp_reply_dword(server, 0);
|
||||
target->open_create_action = ncp_reply_byte(server, 4);
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
/* in target there's a new finfo to fill */
|
||||
ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
|
||||
}
|
||||
|
||||
ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_initialize_search(struct ncp_server *server,
|
||||
struct nw_info_struct *dir,
|
||||
struct nw_search_sequence *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 2); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, 0); /* reserved */
|
||||
ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search for everything */
|
||||
int
|
||||
ncp_search_for_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_search_sequence *seq,
|
||||
struct nw_info_struct *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 3); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, 0); /* data stream (???) */
|
||||
ncp_add_word(server, 0xffff); /* Search attribs */
|
||||
ncp_add_dword(server, RIM_ALL); /* return info mask */
|
||||
ncp_add_mem(server, seq, 9);
|
||||
ncp_add_byte(server, 2); /* 2 byte pattern */
|
||||
ncp_add_byte(server, 0xff); /* following is a wildcard */
|
||||
ncp_add_byte(server, '*');
|
||||
|
||||
if ((result = ncp_request(server, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
|
||||
ncp_extract_file_info(ncp_reply_data(server, 10), target);
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_info_struct *old_dir, char *old_name,
|
||||
struct nw_info_struct *new_dir, char *new_name)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ( (old_dir == NULL) || (old_name == NULL)
|
||||
|| (new_dir == NULL) || (new_name == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 4); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
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_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_byte(server, 1);
|
||||
ncp_add_byte(server, 1); /* 1 destination component */
|
||||
|
||||
/* source path string */
|
||||
ncp_add_pstring(server, old_name);
|
||||
/* dest path string */
|
||||
ncp_add_pstring(server, new_name);
|
||||
|
||||
result = ncp_request(server, 87);
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* We have to transfer to/from user space */
|
||||
int
|
||||
ncp_read(struct ncp_server *server, const char *file_id,
|
||||
__u32 offset, __u16 to_read,
|
||||
char *target, int *bytes_read)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 0);
|
||||
ncp_add_mem(server, file_id, 6);
|
||||
ncp_add_dword(server, htonl(offset));
|
||||
ncp_add_word(server, htons(to_read));
|
||||
|
||||
if ((result = ncp_request(server, 72)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
*bytes_read = ntohs(ncp_reply_word(server, 0));
|
||||
|
||||
memcpy_tofs(target, ncp_reply_data(server, 2), *bytes_read);
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_write(struct ncp_server *server, const char *file_id,
|
||||
__u32 offset, __u16 to_write,
|
||||
const char *source, int *bytes_written)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 0);
|
||||
ncp_add_mem(server, file_id, 6);
|
||||
ncp_add_dword(server, htonl(offset));
|
||||
ncp_add_word(server, htons(to_write));
|
||||
ncp_add_mem_fromfs(server, source, to_write);
|
||||
|
||||
if ((result = ncp_request(server, 73)) != 0)
|
||||
{
|
||||
ncp_unlock_server(server);
|
||||
return result;
|
||||
}
|
||||
|
||||
*bytes_written = to_write;
|
||||
|
||||
ncp_unlock_server(server);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
#ifndef _NCPLIB_H
|
||||
#define _NCPLIB_H
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/ncp.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/ncp_fs_sb.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/malloc.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/string.h>
|
||||
|
||||
#include <linux/ncp.h>
|
||||
|
||||
int
|
||||
ncp_negotiate_buffersize(struct ncp_server *server, int size,
|
||||
int *target);
|
||||
int
|
||||
ncp_get_encryption_key(struct ncp_server *server,
|
||||
char *target);
|
||||
int
|
||||
ncp_get_bindery_object_id(struct ncp_server *server,
|
||||
int object_type, char *object_name,
|
||||
struct ncp_bindery_object *target);
|
||||
int
|
||||
ncp_login_encrypted(struct ncp_server *server,
|
||||
struct ncp_bindery_object *object,
|
||||
unsigned char *key,
|
||||
unsigned char *passwd);
|
||||
int
|
||||
ncp_login_user(struct ncp_server *server,
|
||||
unsigned char *username,
|
||||
unsigned char *password);
|
||||
int
|
||||
ncp_get_volume_info_with_number(struct ncp_server *server, int n,
|
||||
struct ncp_volume_info *target);
|
||||
|
||||
int
|
||||
ncp_get_volume_number(struct ncp_server *server, const char *name,
|
||||
int *target);
|
||||
|
||||
int
|
||||
ncp_file_search_init(struct ncp_server *server,
|
||||
int dir_handle, const char *path,
|
||||
struct ncp_filesearch_info *target);
|
||||
|
||||
int
|
||||
ncp_file_search_continue(struct ncp_server *server,
|
||||
struct ncp_filesearch_info *fsinfo,
|
||||
int attributes, const char *path,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
int
|
||||
ncp_get_finfo(struct ncp_server *server,
|
||||
int dir_handle, const char *path, const char *name,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
int
|
||||
ncp_open_file(struct ncp_server *server,
|
||||
int dir_handle, const char *path,
|
||||
int attr, int access,
|
||||
struct ncp_file_info *target);
|
||||
int
|
||||
ncp_close_file(struct ncp_server *server, const char *file_id);
|
||||
|
||||
int
|
||||
ncp_create_newfile(struct ncp_server *server,
|
||||
int dir_handle, const char *path,
|
||||
int attr,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
int
|
||||
ncp_create_file(struct ncp_server *server,
|
||||
int dir_handle, const char *path,
|
||||
int attr,
|
||||
struct ncp_file_info *target);
|
||||
|
||||
int
|
||||
ncp_erase_file(struct ncp_server *server,
|
||||
int dir_handle, const char *path,
|
||||
int attr);
|
||||
|
||||
int
|
||||
ncp_rename_file(struct ncp_server *server,
|
||||
int old_handle, const char *old_path,
|
||||
int attr,
|
||||
int new_handle, const char *new_path);
|
||||
|
||||
int
|
||||
ncp_create_directory(struct ncp_server *server,
|
||||
int dir_handle, const char *path,
|
||||
int inherit_mask);
|
||||
|
||||
int
|
||||
ncp_delete_directory(struct ncp_server *server,
|
||||
int dir_handle, const char *path);
|
||||
|
||||
int
|
||||
ncp_rename_directory(struct ncp_server *server,
|
||||
int dir_handle,
|
||||
const char *old_path, const char *new_path);
|
||||
|
||||
int
|
||||
ncp_read(struct ncp_server *server, const char *file_id,
|
||||
__u32 offset, __u16 to_read,
|
||||
char *target, int *bytes_read);
|
||||
|
||||
int
|
||||
ncp_write(struct ncp_server *server, const char *file_id,
|
||||
__u32 offset, __u16 to_write,
|
||||
const char *source, int *bytes_written);
|
||||
|
||||
int
|
||||
ncp_do_lookup(struct ncp_server *server,
|
||||
struct nw_info_struct *dir,
|
||||
char *path, /* may only be one component */
|
||||
struct nw_info_struct *target);
|
||||
|
||||
int
|
||||
ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
|
||||
struct nw_info_struct *file,
|
||||
__u32 info_mask,
|
||||
struct nw_modify_dos_info *info);
|
||||
|
||||
int
|
||||
ncp_del_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_info_struct *dir, char *name);
|
||||
|
||||
int
|
||||
ncp_open_create_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_info_struct *dir, char *name,
|
||||
int open_create_mode,
|
||||
__u32 create_attributes,
|
||||
int desired_acc_rights,
|
||||
struct nw_file_info *target);
|
||||
|
||||
int
|
||||
ncp_initialize_search(struct ncp_server *server,
|
||||
struct nw_info_struct *dir,
|
||||
struct nw_search_sequence *target);
|
||||
|
||||
int
|
||||
ncp_search_for_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_search_sequence *seq,
|
||||
struct nw_info_struct *target);
|
||||
|
||||
int
|
||||
ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_info_struct *old_dir, char *old_name,
|
||||
struct nw_info_struct *new_dir, char *new_name);
|
||||
|
||||
|
||||
#endif /* _NCPLIB_H */
|
||||
@@ -1,569 +0,0 @@
|
||||
/*
|
||||
* linux/fs/ncp/sock.c
|
||||
*
|
||||
* Copyright (C) 1992, 1993 Rick Sladkey
|
||||
*
|
||||
* Modified 1995 by Volker Lendecke to be usable for ncp
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#ifdef MODULE
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
#include <asm/segment.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/ipx.h>
|
||||
|
||||
#include <linux/ncp.h>
|
||||
#include <linux/ncp_fs.h>
|
||||
#include <linux/ncp_fs_sb.h>
|
||||
#include "/usr/src/linux/net/inet/sock.h"
|
||||
|
||||
|
||||
#define _S(nr) (1<<((nr)-1))
|
||||
static void
|
||||
ncp_wdog_data_ready(struct sock *sk, int len)
|
||||
{
|
||||
struct socket *sock = sk->socket;
|
||||
|
||||
if (!sk->dead)
|
||||
{
|
||||
unsigned char packet_buf[2];
|
||||
struct sockaddr_ipx sender;
|
||||
int addr_len = sizeof(struct sockaddr_ipx);
|
||||
int result;
|
||||
unsigned short fs;
|
||||
|
||||
fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
|
||||
result = sock->ops->recvfrom(sock, (void *)packet_buf, 2, 1, 0,
|
||||
(struct sockaddr *)&sender,
|
||||
&addr_len);
|
||||
|
||||
if ( (result != 2)
|
||||
|| (packet_buf[1] != '?')
|
||||
/* How to check connection number here? */
|
||||
)
|
||||
{
|
||||
/* Error, throw away the complete packet */
|
||||
sock->ops->recvfrom(sock, (void *)packet_buf, 2, 1, 0,
|
||||
(struct sockaddr *)&sender,
|
||||
&addr_len);
|
||||
|
||||
printk("ncpfs: got strange packet on watchdog "
|
||||
"socket\n");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int result;
|
||||
DDPRINTK("ncpfs: got watchdog from:\n");
|
||||
DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X,"
|
||||
" conn:%02X,type:%c\n",
|
||||
htonl(sender.sipx_network),
|
||||
sender.sipx_node[0], sender.sipx_node[1],
|
||||
sender.sipx_node[2], sender.sipx_node[3],
|
||||
sender.sipx_node[4], sender.sipx_node[5],
|
||||
ntohs(sender.sipx_port),
|
||||
packet_buf[0], packet_buf[1]);
|
||||
|
||||
packet_buf[1] = 'Y';
|
||||
result = sock->ops->sendto(sock, (void *)packet_buf,
|
||||
2, 1, 0,
|
||||
(struct sockaddr *)&sender,
|
||||
sizeof(sender));
|
||||
DDPRINTK("send result: %d\n", result);
|
||||
}
|
||||
set_fs(fs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_catch_watchdog(struct ncp_server *server)
|
||||
{
|
||||
struct file *file;
|
||||
struct inode *inode;
|
||||
struct socket *sock;
|
||||
struct sock *sk;
|
||||
|
||||
if ( (server == NULL)
|
||||
|| ((file = server->wdog_filp) == NULL)
|
||||
|| ((inode = file->f_inode) == NULL)
|
||||
|| (!S_ISSOCK(inode->i_mode)))
|
||||
{
|
||||
printk("ncp_catch_watchdog: did not get valid server!\n");
|
||||
server->data_ready = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sock = &(inode->u.socket_i);
|
||||
|
||||
if (sock->type != SOCK_DGRAM)
|
||||
{
|
||||
printk("ncp_catch_watchdog: did not get SOCK_STREAM\n");
|
||||
server->data_ready = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sk = (struct sock *)(sock->data);
|
||||
|
||||
if (sk == NULL)
|
||||
{
|
||||
printk("ncp_catch_watchdog: sk == NULL");
|
||||
server->data_ready = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_catch_watchdog.: sk->d_r = %x, server->d_r = %x\n",
|
||||
(unsigned int)(sk->data_ready),
|
||||
(unsigned int)(server->data_ready));
|
||||
|
||||
if (sk->data_ready == ncp_wdog_data_ready)
|
||||
{
|
||||
printk("ncp_catch_watchdog: already done\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
server->data_ready = sk->data_ready;
|
||||
sk->data_ready = ncp_wdog_data_ready;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_dont_catch_watchdog(struct ncp_server *server)
|
||||
{
|
||||
struct file *file;
|
||||
struct inode *inode;
|
||||
struct socket *sock;
|
||||
struct sock *sk;
|
||||
|
||||
if ( (server == NULL)
|
||||
|| ((file = server->wdog_filp) == NULL)
|
||||
|| ((inode = file->f_inode) == NULL)
|
||||
|| (!S_ISSOCK(inode->i_mode)))
|
||||
{
|
||||
printk("ncp_dont_catch_watchdog: "
|
||||
"did not get valid server!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sock = &(inode->u.socket_i);
|
||||
|
||||
if (sock->type != SOCK_DGRAM)
|
||||
{
|
||||
printk("ncp_dont_catch_watchdog: did not get SOCK_STREAM\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sk = (struct sock *)(sock->data);
|
||||
|
||||
if (sk == NULL)
|
||||
{
|
||||
printk("ncp_dont_catch_watchdog: sk == NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (server->data_ready == NULL)
|
||||
{
|
||||
printk("ncp_dont_catch_watchdog: "
|
||||
"server->data_ready == NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sk->data_ready != ncp_wdog_data_ready)
|
||||
{
|
||||
printk("ncp_dont_catch_watchdog: "
|
||||
"sk->data_callback != ncp_data_callback\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DDPRINTK("ncp_dont_catch_watchdog: sk->d_r = %x, server->d_r = %x\n",
|
||||
(unsigned int)(sk->data_ready),
|
||||
(unsigned int)(server->data_ready));
|
||||
|
||||
sk->data_ready = server->data_ready;
|
||||
server->data_ready = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define NCP_SLACK_SPACE 1024
|
||||
|
||||
#define _S(nr) (1<<((nr)-1))
|
||||
|
||||
static int
|
||||
do_ncp_rpc_call(struct ncp_server *server, int size)
|
||||
{
|
||||
struct file *file;
|
||||
struct inode *inode;
|
||||
struct socket *sock;
|
||||
unsigned short fs;
|
||||
int result;
|
||||
char *start = server->packet;
|
||||
select_table wait_table;
|
||||
struct select_table_entry entry;
|
||||
int (*select) (struct inode *, struct file *, int, select_table *);
|
||||
int init_timeout, max_timeout;
|
||||
int timeout;
|
||||
int retrans;
|
||||
int major_timeout_seen;
|
||||
int n;
|
||||
int addrlen;
|
||||
unsigned long old_mask;
|
||||
|
||||
/* We have to check the result, so store the complete header */
|
||||
struct ncp_request_header request =
|
||||
*((struct ncp_request_header *)(server->packet));
|
||||
|
||||
struct ncp_reply_header reply;
|
||||
|
||||
|
||||
file = server->ncp_filp;
|
||||
inode = file->f_inode;
|
||||
select = file->f_op->select;
|
||||
sock = &inode->u.socket_i;
|
||||
if (!sock)
|
||||
{
|
||||
printk("ncp_rpc_call: socki_lookup failed\n");
|
||||
return -EBADF;
|
||||
}
|
||||
init_timeout = server->m.time_out;
|
||||
max_timeout = NCP_MAX_RPC_TIMEOUT*HZ/10;
|
||||
retrans = server->m.retry_count;
|
||||
major_timeout_seen = 0;
|
||||
old_mask = current->blocked;
|
||||
current->blocked |= ~(_S(SIGKILL)
|
||||
#if 0
|
||||
| _S(SIGSTOP)
|
||||
#endif
|
||||
| ((server->m.flags & NCP_MOUNT_INTR)
|
||||
? ((current->sigaction[SIGINT - 1].sa_handler == SIG_DFL
|
||||
? _S(SIGINT) : 0)
|
||||
| (current->sigaction[SIGQUIT - 1].sa_handler == SIG_DFL
|
||||
? _S(SIGQUIT) : 0))
|
||||
: 0));
|
||||
fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1)
|
||||
{
|
||||
DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
|
||||
htonl(server->m.serv_addr.sipx_network),
|
||||
server->m.serv_addr.sipx_node[0],
|
||||
server->m.serv_addr.sipx_node[1],
|
||||
server->m.serv_addr.sipx_node[2],
|
||||
server->m.serv_addr.sipx_node[3],
|
||||
server->m.serv_addr.sipx_node[4],
|
||||
server->m.serv_addr.sipx_node[5],
|
||||
ntohs(server->m.serv_addr.sipx_port));
|
||||
DDPRINTK("ncpfs: req.typ: %04X, con: %d, "
|
||||
"seq: %d",
|
||||
request.type,
|
||||
(request.conn_high << 8) + request.conn_low,
|
||||
request.sequence);
|
||||
DDPRINTK(" func: %d\n",
|
||||
request.function);
|
||||
|
||||
result = sock->ops->sendto(sock, (void *) start, size, 0, 0,
|
||||
(struct sockaddr *)
|
||||
&(server->m.serv_addr),
|
||||
sizeof(server->m.serv_addr));
|
||||
if (result < 0)
|
||||
{
|
||||
printk("ncp_rpc_call: send error = %d\n", result);
|
||||
break;
|
||||
}
|
||||
re_select:
|
||||
wait_table.nr = 0;
|
||||
wait_table.entry = &entry;
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
if ( !select(inode, file, SEL_IN, &wait_table)
|
||||
&& !select(inode, file, SEL_IN, NULL))
|
||||
{
|
||||
if (timeout > max_timeout)
|
||||
{
|
||||
/* JEJB/JSP 2/7/94
|
||||
* This is useful to see if the system is
|
||||
* hanging */
|
||||
printk("NCP max timeout reached\n");
|
||||
timeout = max_timeout;
|
||||
}
|
||||
current->timeout = jiffies + timeout;
|
||||
schedule();
|
||||
remove_wait_queue(entry.wait_address, &entry.wait);
|
||||
current->state = TASK_RUNNING;
|
||||
if (current->signal & ~current->blocked)
|
||||
{
|
||||
current->timeout = 0;
|
||||
result = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
if (!current->timeout)
|
||||
{
|
||||
if (n < retrans)
|
||||
continue;
|
||||
if (server->m.flags & NCP_MOUNT_SOFT)
|
||||
{
|
||||
printk("NCP server not responding\n");
|
||||
result = -EIO;
|
||||
break;
|
||||
}
|
||||
n = 0;
|
||||
timeout = init_timeout;
|
||||
init_timeout <<= 1;
|
||||
if (!major_timeout_seen)
|
||||
{
|
||||
printk("NCP server not responding\n");
|
||||
}
|
||||
major_timeout_seen = 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
current->timeout = 0;
|
||||
}
|
||||
else if (wait_table.nr)
|
||||
remove_wait_queue(entry.wait_address, &entry.wait);
|
||||
current->state = TASK_RUNNING;
|
||||
addrlen = 0;
|
||||
|
||||
/* Get the header from the next packet using a peek, so keep it
|
||||
* on the recv queue. If it is wrong, it will be some reply
|
||||
* we don't now need, so discard it */
|
||||
result = sock->ops->recvfrom(sock, (void *)&reply,
|
||||
sizeof(reply), 1, MSG_PEEK,
|
||||
NULL, &addrlen);
|
||||
if (result < 0)
|
||||
{
|
||||
if (result == -EAGAIN)
|
||||
{
|
||||
DPRINTK("ncp_rpc_call: bad select ready\n");
|
||||
goto re_select;
|
||||
}
|
||||
if (result == -ECONNREFUSED)
|
||||
{
|
||||
DPRINTK("ncp_rpc_call: server playing coy\n");
|
||||
goto re_select;
|
||||
}
|
||||
if (result != -ERESTARTSYS)
|
||||
{
|
||||
printk("ncp_rpc_call: recv error = %d\n",
|
||||
-result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( (result == sizeof(reply))
|
||||
&& (reply.type == NCP_POSITIVE_ACK))
|
||||
{
|
||||
/* Throw away the packet */
|
||||
DPRINTK("ncp_rpc_call: got positive acknowledge\n");
|
||||
sock->ops->recvfrom(sock, (void *)&reply,
|
||||
sizeof(reply), 1, 0,
|
||||
NULL, &addrlen);
|
||||
goto re_select;
|
||||
}
|
||||
|
||||
DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d,"
|
||||
"seq: %d\n",
|
||||
reply.type,
|
||||
(reply.conn_high << 8) + reply.conn_low,
|
||||
reply.task,
|
||||
reply.sequence);
|
||||
|
||||
if ( (result >= sizeof(reply))
|
||||
&& (reply.type == NCP_REPLY)
|
||||
&& ( (request.type == NCP_ALLOC_SLOT_REQUEST)
|
||||
|| ( (reply.sequence == request.sequence)
|
||||
&& (reply.conn_low == request.conn_low)
|
||||
/* seem to get wrong task from NW311 && (reply.task == request.task)*/
|
||||
&& (reply.conn_high == request.conn_high))))
|
||||
{
|
||||
if (major_timeout_seen)
|
||||
printk("NCP server OK\n");
|
||||
break;
|
||||
}
|
||||
/* JEJB/JSP 2/7/94
|
||||
* we have xid mismatch, so discard the packet and start
|
||||
* again. What a hack! but I can't call recvfrom with
|
||||
* a null buffer yet. */
|
||||
sock->ops->recvfrom(sock, (void *)&reply, sizeof(reply), 1, 0,
|
||||
NULL, &addrlen);
|
||||
#if 1
|
||||
printk("ncp_rpc_call: reply mismatch\n");
|
||||
#endif
|
||||
goto re_select;
|
||||
}
|
||||
/*
|
||||
* we have the correct reply, so read into the correct place and
|
||||
* return it
|
||||
*/
|
||||
result = sock->ops->recvfrom(sock, (void *)start, server->packet_size,
|
||||
1, 0, NULL, &addrlen);
|
||||
if (result < 0)
|
||||
{
|
||||
printk("NCP: notice message: result=%d\n", result);
|
||||
}
|
||||
else if (result < sizeof(struct ncp_reply_header))
|
||||
{
|
||||
printk("NCP: just caught a too small read memory size..., "
|
||||
"email to NET channel\n");
|
||||
printk("NCP: result=%d,addrlen=%d\n", result, addrlen);
|
||||
result = -EIO;
|
||||
}
|
||||
|
||||
current->blocked = old_mask;
|
||||
set_fs(fs);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We need the server to be locked here, so check!
|
||||
*/
|
||||
|
||||
static int
|
||||
ncp_do_request(struct ncp_server *server, int size)
|
||||
{
|
||||
if (server->lock == 0)
|
||||
{
|
||||
printk("ncpfs: Server not locked!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return do_ncp_rpc_call(server, size);
|
||||
}
|
||||
|
||||
/* ncp_do_request assures that at least a complete reply header is
|
||||
* received. It assumes that server->current_size contains the ncp
|
||||
* request size */
|
||||
int
|
||||
ncp_request(struct ncp_server *server, int function)
|
||||
{
|
||||
struct ncp_request_header *h
|
||||
= (struct ncp_request_header *)(server->packet);
|
||||
struct ncp_reply_header *reply
|
||||
= (struct ncp_reply_header *)(server->packet);
|
||||
|
||||
int request_size = server->current_size
|
||||
- sizeof(struct ncp_request_header);
|
||||
|
||||
int result;
|
||||
|
||||
if (server->has_subfunction != 0)
|
||||
{
|
||||
*(__u16 *)&(h->data[0]) = request_size - 2;
|
||||
}
|
||||
|
||||
h->type = NCP_REQUEST;
|
||||
|
||||
server->sequence += 1;
|
||||
h->sequence = server->sequence;
|
||||
h->conn_low = (server->connection) & 0xff;
|
||||
h->conn_high = ((server->connection) & 0xff00) >> 8;
|
||||
h->task = (current->pid) & 0xff;
|
||||
h->function = function;
|
||||
|
||||
if ((result = ncp_do_request(server, request_size + sizeof(*h))) < 0)
|
||||
{
|
||||
DPRINTK("ncp_request_error: %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
server->completion = reply->completion_code;
|
||||
server->conn_status = reply->connection_state;
|
||||
server->reply_size = result;
|
||||
server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
|
||||
|
||||
result = reply->completion_code;
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
DPRINTK("ncp_completion_code: %d\n", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_connect(struct ncp_server *server)
|
||||
{
|
||||
struct ncp_request_header *h
|
||||
= (struct ncp_request_header *)(server->packet);
|
||||
int result;
|
||||
|
||||
h->type = NCP_ALLOC_SLOT_REQUEST;
|
||||
|
||||
server->sequence = 0;
|
||||
h->sequence = server->sequence;
|
||||
h->conn_low = 0xff;
|
||||
h->conn_high = 0xff;
|
||||
h->task = (current->pid) & 0xff;
|
||||
h->function = 0;
|
||||
|
||||
if ((result = ncp_do_request(server, sizeof(*h))) < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
server->sequence = 0;
|
||||
server->connection = h->conn_low + (h->conn_high * 256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_disconnect(struct ncp_server *server)
|
||||
{
|
||||
struct ncp_request_header *h
|
||||
= (struct ncp_request_header *)(server->packet);
|
||||
|
||||
h->type = NCP_DEALLOC_SLOT_REQUEST;
|
||||
|
||||
server->sequence += 1;
|
||||
h->sequence = server->sequence;
|
||||
h->conn_low = (server->connection) & 0xff;
|
||||
h->conn_high = ((server->connection) & 0xff00) >> 8;
|
||||
h->task = (current->pid) & 0xff;
|
||||
h->function = 0;
|
||||
|
||||
return ncp_do_request(server, sizeof(*h));
|
||||
}
|
||||
|
||||
void
|
||||
ncp_lock_server(struct ncp_server *server)
|
||||
{
|
||||
#if 0
|
||||
/* For testing, only 1 process */
|
||||
if (server->lock != 0)
|
||||
{
|
||||
DPRINTK("ncpfs: server locked!!!\n");
|
||||
}
|
||||
#endif
|
||||
while (server->lock)
|
||||
sleep_on(&server->wait);
|
||||
server->lock = 1;
|
||||
}
|
||||
|
||||
void
|
||||
ncp_unlock_server(struct ncp_server *server)
|
||||
{
|
||||
if (server->lock != 1)
|
||||
{
|
||||
printk("ncp_unlock_server: was not locked!\n");
|
||||
}
|
||||
|
||||
server->lock = 0;
|
||||
wake_up(&server->wait);
|
||||
}
|
||||
|
||||
95
lib/Makefile
Normal file
95
lib/Makefile
Normal file
@@ -0,0 +1,95 @@
|
||||
#
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
CC = gcc
|
||||
|
||||
ifeq ($(HAVE_ELF),yes)
|
||||
PIC_FLAG = -fPIC
|
||||
NCP_LIB = libncp.so.1.0
|
||||
LIB_LINK_COMMAND = gcc -shared -Wl,-soname,libncp.so.1 -o $(NCP_LIB)
|
||||
INSTALL_LIB = install $(NCP_LIB) -m 755 /lib; \
|
||||
ln -sf $(NCP_LIB) /lib/libncp.so.1; \
|
||||
ldconfig
|
||||
export PIC_FLAG
|
||||
else
|
||||
NCP_LIB = libncp.a
|
||||
LIB_LINK_COMMAND = ar r libncp.a
|
||||
endif
|
||||
|
||||
CFLAGS += $(PIC_FLAG)
|
||||
|
||||
ifdef NDS_SUPPORT
|
||||
CFLAGS += -DNDS_SUPPORT
|
||||
NDS_OBJ = ndslib.o mpilib.o ndscrypt.o
|
||||
endif
|
||||
ifdef SIGNATURES
|
||||
CFLAGS += -DSIGNATURES
|
||||
SIGN_OBJ = ncpsign.o
|
||||
endif
|
||||
|
||||
default:
|
||||
make -C ..
|
||||
|
||||
all: libcom_err.a ncplib_err.o $(NCP_LIB)
|
||||
|
||||
install:
|
||||
$(INSTALL_LIB)
|
||||
|
||||
mpilib.o: mpilib.c
|
||||
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c mpilib.c
|
||||
ndscrypt.o: ndscrypt.c
|
||||
$(CC) $(CFLAGS) -c ndscrypt.c
|
||||
ndslib.o: ndslib.c
|
||||
$(CC) $(CFLAGS) -DPORTABLE -DSMITH -DUNIT32 -DMUNIT16 -c ndslib.c
|
||||
|
||||
ncpsign.o: ncpsign.c
|
||||
$(CC) $(CFLAGS) -c ncpsign.c
|
||||
ncplib.o: ncplib.c ncplib_err.h
|
||||
$(CC) $(CFLAGS) -c ncplib.c
|
||||
|
||||
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
|
||||
com_err/init_et.c
|
||||
COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.o \
|
||||
com_err/init_et.o
|
||||
|
||||
libcom_err.a: $(COM_ERR_CFILES)
|
||||
make -C com_err
|
||||
|
||||
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a $(SIGN_OBJ) $(NDS_OBJ)
|
||||
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(SIGN_OBJ) \
|
||||
$(COM_ERR_OFILES) $(NDS_OBJ)
|
||||
ln -sf libncp.so.1.0 libncp.so.1
|
||||
ln -sf libncp.so.1 libncp.so
|
||||
export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH
|
||||
|
||||
ncplib_err.o: ncplib_err.h ncplib_err.c
|
||||
$(CC) $(CFLAGS) -c ncplib_err.c
|
||||
|
||||
ncplib_err.h: ncplib_err.et
|
||||
com_err/compile_et ncplib_err
|
||||
ln -sf ../lib/ncplib_err.h ../include/ncplib_err.h
|
||||
|
||||
ncplib_err.c: ncplib_err.et
|
||||
com_err/compile_et ncplib_err
|
||||
|
||||
dep: ncplib_err.h
|
||||
make -C com_err dep
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
make -C com_err clean
|
||||
rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h
|
||||
rm -f libncp.*
|
||||
|
||||
mrproper: clean
|
||||
make -C com_err mrproper
|
||||
rm -f $(UTILS) .depend $(DISTFILE)
|
||||
|
||||
#
|
||||
# include a dependency file if one exists
|
||||
#
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
|
||||
49
lib/com_err/ChangeLog
Normal file
49
lib/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.
|
||||
28
lib/com_err/Makefile
Normal file
28
lib/com_err/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# 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: ../libcom_err.a
|
||||
|
||||
../libcom_err.a: $(OBJECTS)
|
||||
ar r ../libcom_err.a $(OBJECTS)
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f *.o ../libcom_err.a
|
||||
|
||||
mrproper: clean
|
||||
rm -f .depend
|
||||
|
||||
#
|
||||
# include a dependency file if one exists
|
||||
#
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
|
||||
96
lib/com_err/com_err.3
Normal file
96
lib/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".
|
||||
124
lib/com_err/com_err.c
Normal file
124
lib/com_err/com_err.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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
lib/com_err/com_err.h
Normal file
40
lib/com_err/com_err.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Header file for common error description library.
|
||||
*
|
||||
* Copyright 1988, Student Information Processing Board of the
|
||||
* Massachusetts Institute of Technology.
|
||||
*
|
||||
* For copyright and distribution info, see the documentation supplied
|
||||
* with this package.
|
||||
*/
|
||||
|
||||
#ifndef __COM_ERR_H
|
||||
|
||||
typedef long errcode_t;
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
|
||||
/* ANSI C -- use prototypes etc */
|
||||
void com_err(const char *, long, const char *,...);
|
||||
void com_err_va(const char *whoami, errcode_t code, const char *fmt,
|
||||
va_list args);
|
||||
char const *error_message(long);
|
||||
extern void (*com_err_hook) (const char *, long, const char *, va_list);
|
||||
void (*set_com_err_hook(void (*)(const char *, long, const char *, va_list)))
|
||||
(const char *, long, const char *, va_list);
|
||||
void (*reset_com_err_hook(void)) (const char *, long, const char *, va_list);
|
||||
int init_error_table(const char *const *msgs, int base, int count);
|
||||
#else
|
||||
/* no prototypes */
|
||||
void com_err();
|
||||
void com_err_va();
|
||||
char *error_message();
|
||||
extern void (*com_err_hook) ();
|
||||
void (*set_com_err_hook()) ();
|
||||
void (*reset_com_err_hook()) ();
|
||||
int init_error_table();
|
||||
#endif
|
||||
|
||||
#define __COM_ERR_H
|
||||
#endif /* ! defined(__COM_ERR_H) */
|
||||
554
lib/com_err/com_err.texinfo
Normal file
554
lib/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
lib/com_err/compile_et
Executable file
11
lib/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
lib/com_err/compile_et.1
Normal file
79
lib/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".
|
||||
90
lib/com_err/error_message.c
Normal file
90
lib/com_err/error_message.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* $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);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user