Compare commits

..

8 Commits

Author SHA1 Message Date
ncpfs archive import
f88460b2e6 Import ncpfs 2.0.9 2026-04-28 20:39:58 +02:00
ncpfs archive import
fff159f2db Import ncpfs 2.0.8 2026-04-28 20:39:58 +02:00
ncpfs archive import
c4d2144d0d Import ncpfs 2.0.7 2026-04-28 20:39:58 +02:00
ncpfs archive import
134b5d6ebf Import ncpfs 2.0.6 2026-04-28 20:39:58 +02:00
ncpfs archive import
ab78307868 Import ncpfs 2.0.5 2026-04-28 20:39:58 +02:00
ncpfs archive import
3019bba627 Import ncpfs 2.0.4 2026-04-28 20:39:58 +02:00
ncpfs archive import
011a5107c5 Import ncpfs 2.0.3 2026-04-28 20:39:58 +02:00
ncpfs archive import
7179281575 Import ncpfs 2.0.2 2026-04-28 20:39:58 +02:00
116 changed files with 9748 additions and 3549 deletions

BIN
.downloads/ncpfs-2.0.2.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.3.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.4.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.5.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.6.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.7.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.8.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-2.0.9.tgz Normal file

Binary file not shown.

14
BUGS
View File

@@ -5,6 +5,20 @@ But there are really problems that might be fixed in the future.
-------------------------------------------------------------------------------
You might experience lockups of ncpfs volumes. It happens especially
under high network traffic, not necessarily only IPX traffic. I am not
able to reproduce this problem on my machine, so I'm sorry I can not
do anything about that. When such a lockup happens, you have to shut
down the complete ipx subsystem by deleting all ipx interfaces,
unmounting all ncpfs volumes (in this order!) and restarting all
again.
For the kernel hackers who want to look at the problem: The routine
ipx_sendmsg in net/ipx/af_ipx.c sometimes locks forever if called with
nonblock=0. I DO NOT KNOW WHY!!! HELP ME, PLEASE!
-------------------------------------------------------------------------------
'df' returns 0: Free disk space is distributed among the volumes in
NetWare. df is only able to report one number per mounted
filesystem. As connections are quite expensive for NetWare (with

73
Changes
View File

@@ -1,6 +1,77 @@
I only began this file with ncpfs-0.12. If you're interested in older
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
ncpfs-2.0.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
@@ -126,4 +197,4 @@ ncpfs-0.12 -> ncpfs-0.13
- support for automatic loading of ncpfs.o by kerneld.
Thanks to Steven N. Hirsch <hirsch@emba.uvm.edu>.
- A subtle problem in the read routines has been removed by Uwe Bonnes
<bon@elektron.ikp.physik.th-darmstadt.de>. Thanks a lot.
<bon@elektron.ikp.physik.th-darmstadt.de>. Thanks a lot.

9
FAQ
View File

@@ -1,5 +1,5 @@
There is certainly not enough material to call this an FAQ, but some
questions reach me regularly. Probably the documenation is not clear
questions reach me regularly. Probably the documentation is not clear
enough.
-------------------------------------------------------------------------------
@@ -37,13 +37,6 @@ packet signatures on the 4.1 server, as ncpfs does not support them.
-------------------------------------------------------------------------------
Q: Does ncpfs support long file names, using the OS/2 namespace?
No. Not yet. I still have to sort out how that really works. But it should
certainly be possible.
-------------------------------------------------------------------------------
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?

View File

@@ -2,29 +2,51 @@
# Makefile for the linux ncp-filesystem routines.
#
VERSION = 2.0.1
VERSION = 2.0.9
# If you are using kerneld to autoload ncp support,
# uncomment this (kerneld is in linux since about 1.3.57):
#KERNELD = -DHAVE_KERNELD
KERNELD = -DHAVE_KERNELD
# If your system is ELF, either also do a 'make install', or append the util/
# directory where the dynamic library resides to the environment
# variable LD_LIBRARY_PATH
HAVE_ELF=$(shell file `whereis gcc|cut -d ' ' -f 2`| \
grep ELF >/dev/null && echo -n yes )
TOPDIR = $(shell pwd)
BINDIR = /usr/local/bin
BINDIR = /usr/bin
SBINDIR = /sbin
INTERM_BINDIR = $(TOPDIR)/bin
SUBDIRS = util ipx-1.0 man
SUBDIRS = lib sutil util ipx-1.0 man
KVERSION=$(shell uname -r | cut -b1-3)
INCLUDES=-I$(TOPDIR)/include
ifeq ($(KVERSION),1.2)
SUBDIRS += kernel-1.2/src
INCLUDES = -I$(TOPDIR)/kernel-1.2
INCLUDES += -I$(TOPDIR)/kernel-1.2
endif
export INCLUDES BINDIR INTERM_BINDIR SBINDIR KERNELD VERSION
COPT = -O2
COPT += -g
CFLAGS = $(COPT) -Wall $(INCLUDES) $(KERNELD) -DNCPFS_VERSION=\"$(VERSION)\"
export INCLUDES BINDIR SBINDIR KERNELD VERSION HAVE_ELF CFLAGS
all:
for i in $(SUBDIRS); do make -C $$i all; done
@if [ "$(HAVE_ELF)" = yes ] ;\
then \
echo ; echo ; echo ;\
echo Please add \'`pwd`/lib\' to the environment ; \
echo variable LD_LIBRARY_PATH by executing ; \
echo ;\
echo export LD_LIBRARY_PATH=\"\$$LD_LIBRARY_PATH:`pwd`/lib\" ; \
echo ;\
echo or do a \'make install\'. ;\
echo ;\
fi
dep:
for i in $(SUBDIRS); do make -C $$i dep; done
@@ -32,17 +54,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
mrproper: clean
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
make -C util mrproper
(cd daemon; make clean)
mrproper: clean_me
for i in $(SUBDIRS) ipxdump; do make -C $$i mrproper; done
modules: ncpfs.o
@@ -51,12 +72,10 @@ SRCDIR=$(shell basename $(SRCPATH))
DISTFILE=$(SRCDIR).tgz
dist: mrproper
mv daemon ..
(cd ..; \
tar cvf - $(SRCDIR) | \
gzip -9 > $(DISTFILE); \
mv $(DISTFILE) $(SRCDIR))
mv ../daemon .
make dep
make all

29
README
View File

@@ -3,11 +3,24 @@ some little utilities it also contains nprint, which enables you to
print on NetWare print queues. The opposite side, pserver, is also
provided.
I'm planning major changes in the structure of ncpfs for Linux 2.1.x
which will break the binary compatibility. So I changed the numbering
scheme for ncpfs. ncpfs-2.0.x will be the version to be used with
Linux 2.0.0 and older kernels, and ncpfs-2.1.x will be the version for
the development kernels.
ncpfs works with NetWare versions 3.x and following. It does NOT work
with NetWare version 2.x. Some of the NetWare look-alikes, such as
CD-ROM servers WinNT 3.51 Server are also NOT supported. This
restriction comes from the fact that ncpfs relies heavily on the name
space facilities NetWare supports since version 3. When you want to
mount volumes that have been exported by mars_nwe, you have to
activate the name space calls in mars_nwe's config.h file, although
probably it's more clever to use nfs between two Linux machines.
The user-space utilities such as nprint and the bindery utils should
work with all versions of NetWare.
ncpfs does NOT support access to the NDS, so if you want to mount
volumes exported by a NetWare 4.x server, you will have to install the
bindery emulation on that server. If you need access to the NDS, ask
Caldera for their CND. See http://www.caldera.com for more
information.
INSTALLATION
@@ -39,6 +52,12 @@ ncpfs.
If you are running kerneld, please uncomment the corresponding line in
the Makefile to reflect this.
If your system is ELF, please enable the use of the shared ncp-library
in the Makefile. This will save at least 1MB of disk space.
After you adapted your Makefile, type 'make' and, as root, 'make install'.
HELP
In the meantime my mail volume has grown considerably, so the response

17
TODO
View File

@@ -1,17 +0,0 @@
Here's a list of things I want to do. Feel free to send suggestions,
or even help me ;-).
- Add flags to pserver's command line, so that the print command can
find out the name of user who printed the job.
- do rtt estimation, like tcp does.
- Do better connection management. I imagine to create a ncpd.
- When ncp is done, one can think about mounting several volumes over
a single NCP connection. This should make the trade-off mentioned in
ncpmount.8 unnecessary.
- long file names
- Do some kind of mapping of NCP uid's to unix uid's

24
bin/nwbpsecurity Executable file
View 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

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

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

57
contrib/tknwmsg/tknwmsg Executable file
View File

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

BIN
contrib/tknwmsg/tknwmsg.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

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

View File

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

40
include/com_err.h Normal file
View 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) */

98
include/ipxlib.h Normal file
View File

@@ -0,0 +1,98 @@
/*
* ipxlib.h
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#ifndef _IPXLIB_H
#define _IPXLIB_H
#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include <stdio.h>
typedef unsigned long IPXNet;
typedef unsigned short IPXPort;
typedef unsigned char IPXNode[IPX_NODE_LEN];
#define IPX_USER_PTYPE (0x00)
#define IPX_RIP_PTYPE (0x01)
#define IPX_SAP_PTYPE (0x04)
#define IPX_AUTO_PORT (0x0000)
#define IPX_SAP_PORT (0x0452)
#define IPX_RIP_PORT (0x0453)
#define IPX_SAP_GENERAL_QUERY (0x0001)
#define IPX_SAP_GENERAL_RESPONSE (0x0002)
#define IPX_SAP_NEAREST_QUERY (0x0003)
#define IPX_SAP_NEAREST_RESPONSE (0x0004)
#define IPX_SAP_FILE_SERVER (0x0004)
struct sap_query
{
unsigned short query_type; /* net order */
unsigned short server_type; /* net order */
};
struct sap_server_ident
{
unsigned short server_type __attribute__((packed));
char server_name[48] __attribute__((packed));
IPXNet server_network __attribute__((packed));
IPXNode server_node __attribute__((packed));
IPXPort server_port __attribute__((packed));
unsigned short intermediate_network __attribute__((packed));
};
#define IPX_RIP_REQUEST (0x1)
#define IPX_RIP_RESPONSE (0x2)
struct ipx_rip_packet
{
__u16 operation __attribute__((packed));
struct ipx_rt_def
{
__u32 network __attribute__((packed));
__u16 hops __attribute__((packed));
__u16 ticks __attribute__((packed));
}
rt[1] __attribute__((packed));
};
#define IPX_BROADCAST_NODE ("\xff\xff\xff\xff\xff\xff")
#define IPX_THIS_NODE ("\0\0\0\0\0\0")
#define IPX_THIS_NET (0)
#ifndef IPX_NODE_LEN
#define IPX_NODE_LEN (6)
#endif
void
ipx_print_node(IPXNode node);
void
ipx_print_network(IPXNet net);
void
ipx_print_port(IPXPort port);
void
ipx_print_saddr(struct sockaddr_ipx *sipx);
void
ipx_fprint_node(FILE * file, IPXNode node);
void
ipx_fprint_network(FILE * file, IPXNet net);
void
ipx_fprint_port(FILE * file, IPXPort port);
void
ipx_fprint_saddr(FILE * file, struct sockaddr_ipx *sipx);
int
ipx_sscanf_node(char *buf, unsigned char node[IPX_NODE_LEN]);
void
ipx_assign_node(IPXNode dest, IPXNode src);
int
ipx_node_equal(IPXNode n1, IPXNode n2);
#endif /* _IPXLIB_H */

671
include/ncplib.h Normal file
View File

@@ -0,0 +1,671 @@
/*
* ncplib.h
*
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#include "ipxlib.h"
#include "com_err.h"
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];
};
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_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 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_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_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);
#endif /* _NCPLIB_H */

View File

@@ -1,24 +0,0 @@
CFLAGS = -O2 -Wall
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
all: $(UTILS)
clean:
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
install: $(UTILS)
for i in $(UTILS); \
do \
install --strip $$i /sbin; \
install $$i.8 /usr/man/man8; \
done
install init.ipx /etc/rc.d/init.d/ipx
install -m 0644 config.ipx /etc/sysconfig/ipx
rm -f /etc/rc.d/rc2.d/S15ipx
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc2.d/S15ipx
rm -f /etc/rc.d/rc3.d/S15ipx
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc3.d/S15ipx
rm -f /etc/rc.d/rc5.d/S15ipx
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc5.d/S15ipx
rm -f /etc/rc.d/rc6.d/K55ipx
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc6.d/K55ipx

View File

@@ -1,30 +1,19 @@
CFLAGS = -O2 -Wall
UTILS = $(INTERM_BINDIR)/ipx_configure $(INTERM_BINDIR)/ipx_interface \
$(INTERM_BINDIR)/ipx_internal_net $(INTERM_BINDIR)/ipx_route
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
all: $(UTILS)
$(INTERM_BINDIR)/ipx_configure: ipx_configure.o
$(CC) -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
$(INTERM_BINDIR)/ipx_interface: ipx_interface.o
$(CC) -o $(INTERM_BINDIR)/ipx_interface ipx_interface.o
$(INTERM_BINDIR)/ipx_internal_net: ipx_internal_net.o
$(CC) -o $(INTERM_BINDIR)/ipx_internal_net ipx_internal_net.o
$(INTERM_BINDIR)/ipx_route: ipx_route.o
$(CC) -o $(INTERM_BINDIR)/ipx_route ipx_route.o
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
mrproper: clean
rm -f .depend
install: $(UTILS)
for i in $(UTILS); \
do \
install $$i $(BINDIR); \
done

View File

@@ -89,10 +89,31 @@ struct ncp_reply_header {
__u8 data[0] __attribute__ ((packed));
};
#define NCP_BURST_PACKET (0x7777)
struct ncp_burst_header {
__u16 type __attribute__ ((packed));
__u8 system_flags __attribute__ ((packed));
__u8 stream_type __attribute__ ((packed));
__u32 source_conn __attribute__ ((packed));
__u32 dest_conn __attribute__ ((packed));
__u32 packet_sequence __attribute__ ((packed));
__u32 send_delay __attribute__ ((packed));
__u16 burst_sequence __attribute__ ((packed));
__u16 ack_sequence __attribute__ ((packed));
__u32 burst_length __attribute__ ((packed));
__u32 data_offset __attribute__ ((packed));
__u16 data_bytes __attribute__ ((packed));
__u16 missing_frags __attribute__ ((packed));
};
void handle_ipx (unsigned char *buf, int length, char *frame, int no);
void handle_ncp (struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no);
int handle_burst(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no);
#define SAP_MAX_SERVER_NAME_LENGTH 48 /* in network packets */
#define SAP_MAX_SAPS_PER_PACKET 7
@@ -165,6 +186,12 @@ handle_ipx (unsigned char *buf, int length, char *frame, int no)
ipx_print_saddr(&d_addr);
printf("\n");
if (handle_burst(&s_addr, &d_addr, buf + sizeof(struct ipx_packet),
length - sizeof(struct ipx_packet), no) != 0)
{
return;
}
if ( (ntohs(s_addr.sipx_port) == 0x451)
|| (ntohs(d_addr.sipx_port) == 0x451))
{
@@ -253,9 +280,59 @@ handle_ipx (unsigned char *buf, int length, char *frame, int no)
}
void handle_ncp (struct sockaddr_ipx *source,
int handle_burst(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no)
{
struct ncp_burst_header *rq = (struct ncp_burst_header *)buf;
if (rq->type != NCP_BURST_PACKET)
{
return 0;
}
printf("Burst Packet\n");
printf("Stream Type: %02X, System Flags: %02X\n",
rq->stream_type, rq->system_flags);
printf("Source Conn: %08X, Dest Conn: %08X, Packet Seq: %08X\n",
rq->source_conn, rq->dest_conn,
(unsigned int)ntohl(rq->packet_sequence));
printf("Send Delay: %08X, Burst Seq: %04X, Ack Seq: %04X\n",
(unsigned int)ntohl(rq->send_delay), ntohs(rq->burst_sequence),
ntohs(rq->ack_sequence));
printf("Burst Length: %08X\n", (unsigned int)ntohl(rq->burst_length));
printf("Data Offset: %08X, Data Bytes: %04X, Missing Frags: %04X\n",
(unsigned int)ntohl(rq->data_offset), ntohs(rq->data_bytes),
ntohs(rq->missing_frags));
if (ntohs(rq->data_bytes) == 24)
{
struct ncp_burst_request
{
struct ncp_burst_header h __attribute__ ((packed));
__u32 function __attribute__ ((packed));
__u32 file_handle __attribute__ ((packed));
__u8 reserved[8] __attribute__ ((packed));
__u32 file_offset __attribute__ ((packed));
__u32 number_of_bytes __attribute__ ((packed));
} *brq = (struct ncp_burst_request *)rq;
printf("Assuming Burst Request:\n");
printf("%s: Handle %08X, Offset %08X, Bytes %08X\n",
brq->function == 1 ? "Read " : "Write",
brq->file_handle,
(unsigned int)ntohl(brq->file_offset),
(unsigned int)ntohl(brq->number_of_bytes));
}
printf("\n");
return 1;
}
void
handle_ncp(struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no)
{
struct ncp_request_header *rq = (struct ncp_request_header *)buf;
struct ncp_reply_header *rs = (struct ncp_reply_header *)buf;
@@ -263,6 +340,10 @@ void handle_ncp (struct sockaddr_ipx *source,
int data_length = 0;
int i;
static struct sockaddr_ipx request_source;
static struct ncp_request_header request_header;
static char request_data[5];
if (ntohs(rq->type) == NCP_REQUEST)
{
/* Request */
@@ -270,11 +351,19 @@ void handle_ncp (struct sockaddr_ipx *source,
rq->conn_low + 256 * rq->conn_high,
rq->sequence, rq->task);
memcpy(&request_source, source, sizeof(request_source));
memcpy(&request_header, rq, sizeof(request_header));
memcpy(request_data, rq+1, sizeof(request_data));
data = buf + sizeof(struct ncp_request_header);
data_length = length - sizeof(struct ncp_request_header);
switch(rq->function)
{
case 18:
printf("fn: %-3d\n", rq->function);
printf("Get Volume Info with Number\n");
break;
case 20:
printf("fn: %-3d\n", rq->function);
printf("Get File Server Date and Time\n");
@@ -305,12 +394,21 @@ void handle_ncp (struct sockaddr_ipx *source,
case 01:
printf("Get Directory Path\n");
break;
case 02:
printf("Scan Directory Information\n");
break;
case 03:
printf("Get Effective Directory Rights\n");
break;
case 05:
printf("Get Volume Number\n");
break;
case 06:
printf("Get Volume Name\n");
break;
case 10:
printf("Create directory\n");
break;
case 18:
printf("Allocate Permanent Dir Handle\n");
break;
@@ -320,6 +418,9 @@ void handle_ncp (struct sockaddr_ipx *source,
case 21:
printf("Get Volume Info with handle\n");
break;
case 39:
printf("Add ext. Trustee to Dir or File\n");
break;
case 48:
printf("Get Name Space Directory Entry\n");
break;
@@ -347,21 +448,54 @@ void handle_ncp (struct sockaddr_ipx *source,
case 28:
printf("Get Connection Information\n");
break;
case 50:
printf("Create Bindery Object\n");
break;
case 53:
printf("Get Bindery Object ID\n");
break;
case 54:
printf("Get Bindery Object Name\n");
break;
case 55:
printf("Scan Bindery Object\n");
break;
case 57:
printf("Create Property\n");
break;
case 59:
printf("Change Property Security\n");
break;
case 60:
printf("Scan Property\n");
break;
case 61:
printf("Read Property Value\n");
break;
case 62:
printf("Write Property Value\n");
break;
case 65:
printf("Add Bindery Object to Set\n");
break;
case 67:
printf("Is Bindery Object in Set\n");
break;
case 70:
printf("Get Bindery Access Level\n");
break;
case 72:
printf("Get Bindery Object Access Level\n");
break;
case 75:
printf("Keyed change password\n");
break;
case 113:
printf("Service Queue Job (old)\n");
break;
case 124:
printf("Service Queue Job \n");
break;
}
data += 3;
@@ -397,6 +531,10 @@ void handle_ncp (struct sockaddr_ipx *source,
printf("fn: %-3d\n", rq->function);
printf("Close File\n");
break;
case 67:
printf("fn: %-3d\n", rq->function);
printf("Create File\n");
break;
case 72:
printf("fn: %-3d\n", rq->function);
printf("Read from File\n");
@@ -409,6 +547,11 @@ void handle_ncp (struct sockaddr_ipx *source,
printf("fn: %-3d\n", rq->function);
printf("Set File Time Date Stamp\n");
break;
case 76:
printf("fn: %-3d\n", rq->function);
printf("Open File (old)\n");
break;
case 87:
printf("fn: %-3d, subfn: %-3d\n",
rq->function, data[0]);
@@ -449,13 +592,343 @@ void handle_ncp (struct sockaddr_ipx *source,
data_length -= 1;
break;
case 97:
{
struct INPUT
{
__u16 proposed_max_size;
__u8 security_flag;
} *i = (struct INPUT *)data;
printf("fn: %-3d\n", rq->function);
printf("Get Big Packet NCP Max Packet Size\n");
printf("proposed_max_size: %x\n",
ntohs(i->proposed_max_size));
printf("security_flag: %x\n",
i->security_flag);
break;
}
case 101:
{
struct INPUT
{
__u32 local_conn_id;
__u32 local_max_packet_size;
__u16 local_target_socket;
__u32 local_max_send_size;
__u32 local_max_recv_size;
} *i = (struct INPUT *)data;
printf("fn: %-3d\n", rq->function);
printf("Packet Burst Connection Request\n");
printf("local_conn_id: %lx\n",
ntohl(i->local_conn_id));
printf("local_max_packet_size: %lx\n",
ntohl(i->local_max_packet_size));
printf("local_target_socket: %lx\n",
ntohl(i->local_target_socket));
printf("local_max_send_size: %lx\n",
ntohl(i->local_max_send_size));
printf("local_max_recv_size: %lx\n",
ntohl(i->local_max_recv_size));
}
break;
case 104:
{
printf("fn: %-3d, subfn: %-3d, NDS call\n",
rq->function, data[0]);
/* I took this information from the (german!!)
book 'Einf"uhrung in die NetWare LAN
Analyse', Laura A. Chappell, Dan E. Hakes,
Novell Press, Markt & Technik, ISBN
3-8272-5084-6, and from the book mentioned
in the ncpfs README. I'm not sure it is
correct, because I do not have NW 4.x. If
you have the time, could you watch a NW4
workstation, and tell me whether anything
of this makes sense at all. */
switch(data[0])
{
case 1:
printf("Ping for NDS\n");
break;
case 2:
{
struct INPUT
{
__u8 subfunction_code;
__u32 fragger_handle;
__u32 max_fragment_size;
__u32 message_size;
__u32 fragment_flag;
__u32 verb;
} *i = (struct INPUT *)data;
printf("Send NDS Fragment Request/Reply\n");
printf("fragger_handle: %lx\n",
(unsigned long)i->fragger_handle);
printf("max_fragment_size: %lx\n",
(unsigned long)i->max_fragment_size);
printf("message_size: %lx\n",
(unsigned long)i->message_size);
printf("fragment_flag: %lx\n",
(unsigned long)i->fragment_flag);
printf("verb: %d\n", i->verb);
switch (i->verb)
{
case 1:
printf("Resolve Name\n");
break;
case 2:
printf("Read Entry Information\n");
break;
case 3:
printf("Read\n");
break;
case 4:
printf("Compare\n");
break;
case 5:
printf("List\n");
break;
case 6:
printf("Search Entries\n");
break;
case 7:
printf("Add Entry\n");
break;
case 8:
printf("Remove Entry\n");
break;
case 9:
printf("Modify Entry\n");
break;
case 10:
printf("Modify RDN\n");
break;
case 11:
printf("Create Attribute\n");
break;
case 12:
printf("Read Attribute Definition\n");
break;
case 13:
printf("Remove Attribute Definition\n");
break;
case 14:
printf("Define Class\n");
break;
case 15:
printf("Read Class Definition\n");
break;
case 16:
printf("Modify Class Definition\n");
break;
case 17:
printf("Remove Class Definition\n");
break;
case 18:
printf("List Containable Classes\n");
break;
case 19:
printf("Get Effective Rights\n");
break;
case 20:
printf("Add Partition\n");
break;
case 21:
printf("Remove Partition\n");
break;
case 22:
printf("List Partitions\n");
break;
case 23:
printf("Split Partition\n");
break;
case 24:
printf("Join Partitions\n");
break;
case 25:
printf("Add Replica\n");
break;
case 26:
printf("Remove Replica\n");
break;
case 27:
printf("Open Stream\n");
break;
case 28:
printf("Search Filter\n");
break;
case 29:
printf("Create Subordinate Reference\n");
break;
case 30:
printf("Link Replica\n");
break;
case 31:
printf("Change Replica Type\n");
break;
case 32:
printf("Start Update Schema\n");
break;
case 33:
printf("End Update Schema\n");
break;
case 34:
printf("Update Schema\n");
break;
case 35:
printf("Start Update Replica\n");
break;
case 36:
printf("End Update Replica\n");
break;
case 37:
printf("Update Replica\n");
break;
case 38:
printf("Synchronize Partition\n");
break;
case 39:
printf("Synchronize Schema\n");
break;
case 40:
printf("Read Syntaxes\n");
break;
case 41:
printf("Get Replica Root ID\n");
break;
case 42:
printf("Begin Move Entry\n");
break;
case 43:
printf("Finish Move Entry\n");
break;
case 44:
printf("Release Moved Entry\n");
break;
case 45:
printf("Backup Entry\n");
break;
case 46:
printf("Restore Entry\n");
break;
case 47:
printf("Save DIB\n");
break;
case 48:
case 49:
printf("Unused\n");
break;
case 50:
printf("Close Iteration\n");
break;
case 51:
printf("Unused\n");
break;
case 52:
printf("Audit Skulking\n");
break;
case 53:
printf("Get Server Address\n");
break;
case 54:
printf("Set Keys\n");
break;
case 55:
printf("Change Password\n");
break;
case 56:
printf("Verify Password\n");
break;
case 57:
printf("Begin Login\n");
break;
case 58:
printf("Finish Login\n");
break;
case 59:
printf("Begin Authentication\n");
break;
case 60:
printf("Finish Authentication\n");
break;
case 61:
printf("Logout\n");
break;
case 62:
printf("Repair Ring\n");
break;
case 63:
printf("Repair Timestamps\n");
break;
case 64:
printf("Create Back Link\n");
break;
case 65:
printf("Delete External Reference\n");
break;
case 66:
printf("Rename External Reference\n");
break;
case 67:
printf("Create Directory Entry\n");
break;
case 68:
printf("Remove Directory Entry\n");
break;
case 69:
printf("Designate New Master\n");
break;
case 70:
printf("Change Tree Name\n");
break;
case 71:
printf("Partition Entry Count\n");
break;
case 72:
printf("Check Login Restrictions\n");
break;
case 73:
printf("Start Join\n");
break;
case 74:
printf("Low Level Split\n");
break;
case 75:
printf("Low Level Join\n");
break;
case 76:
printf("Abort Low Level Join\n");
break;
case 77:
printf("Get All Servers\n");
break;
default:
printf("Unknown Verb: %d\n",
data[0]);
break;
}
break;
}
case 3:
printf("Close NDS Fragment\n");
break;
case 4:
printf("Return Bindery Context\n");
break;
case 5:
printf("Monitor NDS connection\n");
break;
case 200:
printf("NDS Auditing\n");
break;
default:
break;
}
}
default:
printf("fn: %-3d\n", rq->function);
}
@@ -471,6 +944,70 @@ void handle_ncp (struct sockaddr_ipx *source,
data = buf + sizeof(struct ncp_reply_header);
data_length = length - sizeof(struct ncp_reply_header);
if ( (memcmp(&request_source, target,
sizeof(request_source)) == 0)
&& (request_header.sequence == rs->sequence))
{
switch (request_header.function)
{
case 22:
switch (request_data[2])
{
case 18:
{
struct XDATA
{
__u8 new_directory_handle;
__u8 access_rights_mask;
} *x = (struct XDATA *)data;
printf("new_directory_handle: %x\n",
x->new_directory_handle);
printf("access_rights_mask: %x\n",
x->access_rights_mask);
}
break;
}
break;
case 72:
printf("Read data\n");
data_length = 0;
break;
case 97:
{
struct XDATA
{
__u16 accepted_max_size;
__u16 echo_socket;
__u8 security_flag;
} *x = (struct XDATA *)data;
printf("accepted_max_size: %x\n",
ntohs(x->accepted_max_size));
printf("echo_socket: %x\n",
ntohs(x->echo_socket));
printf("security_flag: %x\n",
(x->security_flag));
}
break;
case 101:
{
struct XDATA
{
__u8 completion_code;
__u32 remote_target_id;
__u32 remote_max_packet_size;
} *x = (struct XDATA *)data;
printf("completion_code: %x\n",
x->completion_code);
printf("remote_target_id: %lx\n",
ntohl(x->remote_target_id));
printf("remote_max_packet_size: %lx\n",
ntohl(x->remote_max_packet_size));
}
break;
}
}
}
if (data == NULL)

View File

@@ -116,6 +116,12 @@ struct ncp_file_info {
__u16 update_time;
};
/* Defines for Name Spaces */
#define NW_NS_DOS 0
#define NW_NS_MAC 1
#define NW_NS_NFS 2
#define NW_NS_FTAM 3
#define NW_NS_OS2 4
/* Defines for ReturnInformationMask */
#define RIM_NAME (0x0001L)

View File

@@ -21,6 +21,8 @@ struct ncp_server {
interest for us later, so we store
it completely. */
__u8 name_space[NCP_NUMBER_OF_VOLUMES];
struct file *ncp_filp; /* File pointer to ncp socket */
struct file *wdog_filp; /* File pointer to wdog socket */
void *data_ready; /* The wdog socket gets a new

View File

@@ -97,6 +97,20 @@ str_lower(char *name)
}
}
static inline int
ncp_namespace(struct inode *i)
{
struct ncp_server *server = NCP_SERVER(i);
struct nw_info_struct *info = NCP_ISTRUCT(i);
return server->name_space[info->volNumber];
}
static inline int
ncp_preserve_case(struct inode *i)
{
return (ncp_namespace(i) == NW_NS_OS2);
}
static struct file_operations ncp_dir_operations = {
NULL, /* lseek - default */
ncp_dir_read, /* read - bad */
@@ -133,7 +147,7 @@ struct inode_operations ncp_dir_inode_operations = {
/* Here we encapsulate the inode number handling that depends upon the
* mount mode: When we mount a complete server, the memory address of
* the npc_inode_info is used as an inode. When only a single volume
* is mounted, then the DosDirNum is used as the inode number. As this
* is mounted, then the dirEntNum is used as the inode number. As this
* is unique for the complete volume, this should enable the NFS
* exportability of a ncpfs-mounted volume.
*/
@@ -148,7 +162,7 @@ inline ino_t
ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info)
{
return ncp_single_volume(server)
? info->finfo.i.DosDirNum : (ino_t)info;
? info->finfo.i.dirEntNum : (ino_t)info;
}
static inline int
@@ -351,9 +365,12 @@ ncp_readdir(struct inode *inode, struct file *filp,
c_last_returned_index = 0;
index = 0;
for (i = 0; i < c_size; i++)
if (!ncp_preserve_case(inode))
{
str_lower(c_entry[i].i.entryName);
for (i = 0; i < c_size; i++)
{
str_lower(c_entry[i].i.entryName);
}
}
}
}
@@ -375,7 +392,7 @@ ncp_readdir(struct inode *inode, struct file *filp,
if (ncp_single_volume(server))
{
ino = (ino_t)(entry->i.DosDirNum);
ino = (ino_t)(entry->i.dirEntNum);
}
else
{
@@ -671,7 +688,7 @@ ncp_init_root(struct ncp_server *server)
root->finfo.opened = 0;
i->attributes = aDIR;
i->dataStreamSize = 1024;
i->DosDirNum = 0;
i->dirEntNum = i->DosDirNum = 0;
i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */
ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
@@ -748,7 +765,7 @@ ncp_find_dir_inode(struct inode *dir, const char *name)
do
{
if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum)
&& (result->dir->finfo.i.volNumber == dir_info->volNumber)
&& (strcmp(result->finfo.i.entryName, name) == 0)
/* The root dir is never looked up using this
@@ -776,7 +793,7 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
struct ncp_server *server;
struct ncp_inode_info *result_info;
int found_in_cache;
int down_case = 0;
char name[len+1];
*result = NULL;
@@ -887,20 +904,26 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
if (found_in_cache == 0)
{
int res;
str_upper(name);
DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
NCP_ISTRUCT(dir)->entryName, name);
if (ncp_is_server_root(dir))
{
str_upper(name);
down_case = 1;
res = ncp_lookup_volume(server, name, &(finfo.i));
}
else
{
if (!ncp_preserve_case(dir))
{
str_upper(name);
down_case = 1;
}
res = ncp_obtain_info(server,
NCP_ISTRUCT(dir)->volNumber,
NCP_ISTRUCT(dir)->DosDirNum,
NCP_ISTRUCT(dir)->dirEntNum,
name, &(finfo.i));
}
if (res != 0)
@@ -912,7 +935,11 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
}
finfo.opened = 0;
str_lower(finfo.i.entryName);
if (down_case != 0)
{
str_lower(finfo.i.entryName);
}
if (!(*result = ncp_iget(dir, &finfo)))
{
@@ -949,7 +976,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
strncpy(_name, name, len);
_name[len] = '\0';
str_upper(_name);
if (!ncp_preserve_case(dir))
{
str_upper(_name);
}
lock_super(dir->i_sb);
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
@@ -966,7 +997,11 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
ncp_invalid_dir_cache(dir);
str_lower(finfo.i.entryName);
if (!ncp_preserve_case(dir))
{
str_lower(finfo.i.entryName);
}
finfo.access = O_RDWR;
if (!(*result = ncp_iget(dir, &finfo)) < 0)
@@ -1000,7 +1035,11 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
strncpy(_name, name, len);
_name[len] = '\0';
str_upper(_name);
if (!ncp_preserve_case(dir))
{
str_upper(_name);
}
if (!dir || !S_ISDIR(dir->i_mode))
{
@@ -1058,7 +1097,11 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
strncpy(_name, name, len);
_name[len] = '\0';
str_upper(_name);
if (!ncp_preserve_case(dir))
{
str_upper(_name);
}
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir),
@@ -1101,7 +1144,11 @@ ncp_unlink(struct inode *dir, const char *name, int len)
{
strncpy(_name, name, len);
_name[len] = '\0';
str_upper(_name);
if (!ncp_preserve_case(dir))
{
str_upper(_name);
}
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir),
@@ -1155,11 +1202,19 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
strncpy(_old_name, old_name, old_len);
_old_name[old_len] = '\0';
str_upper(_old_name);
if (!ncp_preserve_case(old_dir))
{
str_upper(_old_name);
}
strncpy(_new_name, new_name, new_len);
_new_name[new_len] = '\0';
str_upper(_new_name);
if (!ncp_preserve_case(new_dir))
{
str_upper(_new_name);
}
res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
NCP_ISTRUCT(old_dir), _old_name,

View File

@@ -188,25 +188,6 @@ ncp_get_volume_info_with_number(struct ncp_server *server, int n,
return 0;
}
int
ncp_get_volume_number(struct ncp_server *server, const char *name, int *target)
{
int result;
ncp_init_request_s(server, 5);
ncp_add_pstring(server, name);
if ((result = ncp_request(server, 22)) != 0)
{
ncp_unlock_server(server);
return result;
}
*target = ncp_reply_byte(server, 0);
ncp_unlock_server(server);
return 0;
}
int
ncp_close_file(struct ncp_server *server, const char *file_id)
{
@@ -282,8 +263,8 @@ ncp_obtain_info(struct ncp_server *server,
ncp_init_request(server);
ncp_add_byte(server, 6); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, 0); /* dos name space as dest */
ncp_add_byte(server, server->name_space[vol_num]);
ncp_add_byte(server, server->name_space[vol_num]);
ncp_add_word(server, 0xff); /* get all */
ncp_add_dword(server, RIM_ALL);
ncp_add_handle_path(server, vol_num, dir_base, 1, path);
@@ -299,20 +280,57 @@ ncp_obtain_info(struct ncp_server *server,
return 0;
}
static inline int
ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
{
int result;
__u8 *namespace;
__u16 no_namespaces;
ncp_init_request(server);
ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */
ncp_add_word(server, 0);
ncp_add_byte(server, volume);
if ((result = ncp_request(server, 87)) != 0)
{
ncp_unlock_server(server);
return 0;
}
no_namespaces = ncp_reply_word(server, 0);
namespace = ncp_reply_data(server, 2);
while (no_namespaces > 0)
{
DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume);
if (*namespace == 4)
{
DPRINTK("get_namespaces: found OS2\n");
ncp_unlock_server(server);
return 1;
}
namespace += 1;
no_namespaces -= 1;
}
ncp_unlock_server(server);
return 0;
}
int
ncp_lookup_volume(struct ncp_server *server,
char *volname,
struct nw_info_struct *target)
{
int result;
__u8 vol_num;
__u32 dir_base;
int volnum;
DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
ncp_init_request(server);
ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */
ncp_add_byte(server, 0); /* DOS name space */
ncp_add_byte(server, 0); /* DOS namespace */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* reserved */
ncp_add_byte(server, 0); /* reserved */
@@ -329,20 +347,19 @@ ncp_lookup_volume(struct ncp_server *server,
return result;
}
dir_base = ncp_reply_dword(server, 4);
vol_num = ncp_reply_byte(server, 8);
memset(target, 0, sizeof(*target));
target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4);
target->volNumber = volnum = ncp_reply_byte(server, 8);
ncp_unlock_server(server);
if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL,
target)) != 0)
{
return result;
}
server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0;
DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes);
DPRINTK("lookup_vol: namespace[%d] = %d\n",
volnum, server->name_space[volnum]);
target->nameLen = strlen(volname);
strcpy(target->entryName, volname);
target->attributes = aDIR;
return 0;
}
@@ -356,14 +373,14 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
ncp_init_request(server);
ncp_add_byte(server, 7); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, server->name_space[file->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_word(server, 0x8006); /* search attribs: all */
ncp_add_dword(server, info_mask);
ncp_add_mem(server, info, sizeof(*info));
ncp_add_handle_path(server, file->volNumber,
file->DosDirNum, 1, NULL);
file->dirEntNum, 1, NULL);
if ((result = ncp_request(server, 87)) != 0)
{
@@ -383,11 +400,11 @@ ncp_del_file_or_subdir(struct ncp_server *server,
ncp_init_request(server);
ncp_add_byte(server, 8); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, server->name_space[dir->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_word(server, 0x8006); /* search attribs: all */
ncp_add_handle_path(server, dir->volNumber,
dir->DosDirNum, 1, name);
dir->dirEntNum, 1, name);
if ((result = ncp_request(server, 87)) != 0)
{
@@ -420,15 +437,16 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
{
int result;
__u16 search_attribs = 0x0006;
__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
if ((create_attributes & aDIR) != 0)
{
search_attribs |= 0x8000;
}
search_attribs |= 0x8000;
}
ncp_init_request(server);
ncp_add_byte(server, 1); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, server->name_space[volume]);
ncp_add_byte(server, open_create_mode);
ncp_add_word(server, search_attribs);
ncp_add_dword(server, RIM_ALL);
@@ -439,13 +457,11 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
if (dir != NULL)
{
ncp_add_handle_path(server, dir->volNumber,
dir->DosDirNum, 1, name);
ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
}
else
{
ncp_add_handle_path(server,
target->i.volNumber, target->i.DosDirNum,
ncp_add_handle_path(server, volume, target->i.dirEntNum,
1, NULL);
}
@@ -481,9 +497,9 @@ ncp_initialize_search(struct ncp_server *server,
ncp_init_request(server);
ncp_add_byte(server, 2); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, server->name_space[dir->volNumber]);
ncp_add_byte(server, 0); /* reserved */
ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL);
ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
if ((result = ncp_request(server, 87)) != 0)
{
@@ -507,7 +523,7 @@ ncp_search_for_file_or_subdir(struct ncp_server *server,
ncp_init_request(server);
ncp_add_byte(server, 3); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, server->name_space[seq->volNumber]);
ncp_add_byte(server, 0); /* data stream (???) */
ncp_add_word(server, 0xffff); /* Search attribs */
ncp_add_dword(server, RIM_ALL); /* return info mask */
@@ -542,19 +558,19 @@ ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
ncp_init_request(server);
ncp_add_byte(server, 4); /* subfunction */
ncp_add_byte(server, 0); /* dos name space */
ncp_add_byte(server, server->name_space[old_dir->volNumber]);
ncp_add_byte(server, 1); /* rename flag */
ncp_add_word(server, 0x8006); /* search attributes */
/* source Handle Path */
ncp_add_byte(server, old_dir->volNumber);
ncp_add_dword(server, old_dir->DosDirNum);
ncp_add_dword(server, old_dir->dirEntNum);
ncp_add_byte(server, 1);
ncp_add_byte(server, 1); /* 1 source component */
/* dest Handle Path */
ncp_add_byte(server, new_dir->volNumber);
ncp_add_dword(server, new_dir->DosDirNum);
ncp_add_dword(server, new_dir->dirEntNum);
ncp_add_byte(server, 1);
ncp_add_byte(server, 1); /* 1 destination component */

76
lib/Makefile Normal file
View File

@@ -0,0 +1,76 @@
#
# Makefile for the linux ncp-filesystem routines.
#
CC = gcc
ifeq ($(HAVE_ELF),yes)
PIC_FLAG = -fPIC
NCP_LIB = libncp.so.1.0
LIB_LINK_COMMAND = gcc -shared -Wl,-soname,libncp.so.1 -o $(NCP_LIB)
INSTALL_LIB = install $(NCP_LIB) -m 755 /lib; \
ln -sf $(NCP_LIB) /lib/libncp.so.1; \
ldconfig
export PIC_FLAG
else
NCP_LIB = libncp.a
LIB_LINK_COMMAND = ar r libncp.a
endif
CFLAGS += $(PIC_FLAG)
default:
make -C ..
all: libcom_err.a ncplib_err.o $(NCP_LIB)
install:
$(INSTALL_LIB)
ncplib.o: ncplib.c ncplib_err.h
$(CC) $(CFLAGS) -c ncplib.c
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
com_err/init_et.c
COM_ERR_OFILES = com_err/com_err.o com_err/error_message.o com_err/et_name.o \
com_err/init_et.o
libcom_err.a: $(COM_ERR_CFILES)
make -C com_err
$(NCP_LIB): ncplib.o ncplib_err.o libcom_err.a
$(LIB_LINK_COMMAND) ncplib.o ncplib_err.o $(COM_ERR_OFILES)
ln -sf libncp.so.1.0 libncp.so.1
ln -sf libncp.so.1 libncp.so
export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH
ncplib_err.o: ncplib_err.h ncplib_err.c
$(CC) $(CFLAGS) -c ncplib_err.c
ncplib_err.h: ncplib_err.et
com_err/compile_et ncplib_err
ln -sf ../lib/ncplib_err.h ../include/ncplib_err.h
ncplib_err.c: ncplib_err.et
com_err/compile_et ncplib_err
dep: ncplib_err.h
make -C com_err dep
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
make -C com_err clean
rm -f *.o *~ ncplib_err.[ch] ../include/ncplib_err.h
rm -f libncp.*
mrproper: clean
make -C com_err mrproper
rm -f $(UTILS) .depend $(DISTFILE)
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif

View File

@@ -3,15 +3,18 @@
#
OBJECTS = com_err.o error_message.o et_name.o init_et.o
CFLAGS = -Wall -O2
CFLAGS = -Wall -O2 $(PIC_FLAG)
all: $(OBJECTS)
all: ../libcom_err.a
../libcom_err.a: $(OBJECTS)
ar r ../libcom_err.a $(OBJECTS)
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f *.o
rm -f *.o ../libcom_err.a
mrproper: clean
rm -f .depend

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,9 @@ error_table NCPL
ec NCPL_ET_NO_SERVER,
"No server found"
ec NCPL_ET_NO_USER,
"No username found"
ec NCPL_ET_HOST_UNKNOWN,
"Server Unknown"
@@ -19,7 +22,7 @@ ec NCPL_ET_NO_SPEC,
"Could not find valid connection spec"
ec NCPL_ET_INVALID_MODE,
"$HOME/.nwclient has invalid mode"
"$HOME/.nwclient has invalid mode, must be 600"
ec NCPL_ET_LOGIN_DENIED,
"Login denied"
@@ -34,6 +37,9 @@ ec NCPL_ET_PWD_TOO_LONG,
"Password too long"
ec NCPL_ET_NO_IPX,
"Could not alloc IPX socket. Probably no IPX support in kernel."
"Could not alloc IPX socket. Probably no IPX support in kernel"
ec NCPL_ET_NO_NCPFS_FILE,
"The file is probably not on a ncpfs mounted directory"
end

View File

@@ -1,17 +1,17 @@
/*$*********************************************************
$*
$* This code has been taken from DDJ 11/93, from an
$* article by Pawel Szczerbina.
$*
$* Password encryption routines follow.
$* Converted to C from Barry Nance's Pascal
$* prog published in the March -93 issue of Byte.
$*
$* Adapted to be useable for ncpfs by
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
$* October 1995.
$*
$**********************************************************/
$*
$* This code has been taken from DDJ 11/93, from an
$* article by Pawel Szczerbina.
$*
$* Password encryption routines follow.
$* Converted to C from Barry Nance's Pascal
$* prog published in the March -93 issue of Byte.
$*
$* Adapted to be useable for ncpfs by
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
$* October 1995.
$*
$********************************************************* */
/****************************************************************************
@@ -91,28 +91,28 @@ typedef unsigned char buf8[8];
typedef unsigned char buf4[4];
static unsigned char encrypttable[256] =
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
{0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD};
static buf32 encryptkeys =
{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
static buf32 encryptkeys =
{0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0};
static void
@@ -128,15 +128,16 @@ shuffle1(buf32 temp, unsigned char *target)
{
for (s = 0; s <= 31; ++s)
{
b3 = (temp[s]+b4) ^ (temp[(s+b4)&31] - encryptkeys[s]);
b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]);
b4 = b4 + b3;
temp[s] = b3;
}
}
for (i = 0; i <= 15; ++i) {
target[i] = encrypttable[temp[ 2*i ]]
| (encrypttable[temp[ 2*i + 1]] << 4);
for (i = 0; i <= 15; ++i)
{
target[i] = encrypttable[temp[2 * i]]
| (encrypttable[temp[2 * i + 1]] << 4);
}
}
@@ -148,12 +149,14 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
int b2, d, s;
buf32 temp;
while ( (buflen > 0)
&& (buf[buflen - 1] == 0)) {
while ((buflen > 0)
&& (buf[buflen - 1] == 0))
{
buflen = buflen - 1;
}
for (s = 0; s < 32; s++) {
for (s = 0; s < 32; s++)
{
temp[s] = 0;
}
@@ -176,17 +179,17 @@ shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
{
b2 = d;
temp[s] = temp[s] ^ encryptkeys[s];
} else {
} else
{
temp[s] = temp[s] ^ buf[b2];
b2 = b2 + 1;
}
}
}
for (s = 0; s <= 31; ++s)
temp[s] = temp[s] ^ lon[s & 3];
shuffle1(temp,target);
shuffle1(temp, target);
}
@@ -198,7 +201,7 @@ nw_encrypt(const unsigned char *fra,
buf32 k;
int s;
shuffle(&(fra[0]), buf, 16, &(k[ 0]));
shuffle(&(fra[0]), buf, 16, &(k[0]));
shuffle(&(fra[4]), buf, 16, &(k[16]));
for (s = 0; s <= 15; ++s)
@@ -219,16 +222,17 @@ nw_encrypt(const unsigned char *fra,
/* server side (mars etc.) should:
* store the *encrypted* password internally (output from shuffle)
* verify if nw_encrypt(cryptkey from GetCryptKey, old stored password)
== cryptkey in EncryptedChangePassword request buffer (this means
old password was correct)
== cryptkey in EncryptedChangePassword request buffer (this means
old password was correct)
* decrypt new password in request buffer using (yet to write) inverse of
newpassencrypt with old stored password as parameter
newpassencrypt with old stored password as parameter
* compute the length of the unencrypted new password as len ^ (first byte of
old internal password) ^ (second byte of old internal password)
old internal password) ^ (second byte of old internal password)
*/
static char
newshuffle[256+16] = {
static char
newshuffle[256 + 16] =
{
0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
@@ -279,17 +283,17 @@ newshuffle[256+16] = {
* - Shuffle (aus nwcrypt.c) altes passwort nach old (16 bytes)
* - shuffle neues passwort nach new (16 bytes)
* - nwpassencrypt (diese Funktion) zweimal aufrufen fuer je 8 bytes:
* nwpassencrypt(old+0, new+0, out+0)
* nwpassencrypt(old+8, new+8, out+8)
* nwpassencrypt(old+0, new+0, out+0)
* nwpassencrypt(old+8, new+8, out+8)
* - NCP-Buffer aufbauen:
* 2 byte Laenge im Hi-Lo-Format
* 1 byte Funktion (0x4b)
* 8 byte (nwcrypt Ergebnis analog login/verify password)
* 2 byte Objecttype
* 1 byte Objectname-Laenge
* n byte Objectname
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
* 2 byte Laenge im Hi-Lo-Format
* 1 byte Funktion (0x4b)
* 8 byte (nwcrypt Ergebnis analog login/verify password)
* 2 byte Objecttype
* 1 byte Objectname-Laenge
* n byte Objectname
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
*/
/*
@@ -308,31 +312,31 @@ newpassencrypt(char *old, char *new, char *out)
memcpy(copy, new, 8);
for (i=0; i<16; i++)
for (i = 0; i < 16; i++)
{
for (di=0, ax=0, p=old; di<8; di++, ax+=0x20, p++)
for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++)
{
cl=newshuffle[(((copy[di]^*p)>>4)&0x0f)+ax+0x10]<<4;
dl=newshuffle[((copy[di]^*p)&0xf)+ax];
copy[di]=cl|dl;
cl = newshuffle[(((copy[di] ^ *p) >> 4) & 0x0f) + ax + 0x10] << 4;
dl = newshuffle[((copy[di] ^ *p) & 0xf) + ax];
copy[di] = cl | dl;
}
ch=old[7];
for (bx=old+7; bx>old; bx--)
ch = old[7];
for (bx = old + 7; bx > old; bx--)
{
*bx=((bx[-1]>>4)&0x0f)|((*bx)<<4);
*bx = ((bx[-1] >> 4) & 0x0f) | ((*bx) << 4);
}
*old=((ch>>4)&0x0f)|(*old)<<4;
*old = ((ch >> 4) & 0x0f) | (*old) << 4;
memset(out, '\0', 8);
for (di=0; di<16; di++)
for (di = 0; di < 16; di++)
{
if (newshuffle[di+0x100]&1)
ch=((copy[newshuffle[di+0x100]/2]>>4)&0x0f);
if (newshuffle[di + 0x100] & 1)
ch = ((copy[newshuffle[di + 0x100] / 2] >> 4) & 0x0f);
else
ch=copy[newshuffle[di+0x100]/2]&0x0f;
out[di/2]|=((di&1) ? ch<<4 : ch);
ch = copy[newshuffle[di + 0x100] / 2] & 0x0f;
out[di / 2] |= ((di & 1) ? ch << 4 : ch);
}
memcpy(copy, out, 8);
}

View File

@@ -1,20 +1,12 @@
MAN1= slist nprint pqlist nsend pserver ncopy npasswd
MAN1 += nwbols nwboprops nwbpvalues
MAN5= nwclient
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net \
ipx_route nwmsg
MAN8 += nwbocreate nwborm nwbpadd nwbpcreate nwbprm
MAN8 += nwgrant nwrevoke
all:
dep:
install:
for i in $(MAN1); do install $$i.1 -m 755 /usr/local/man/man1; done
for i in $(MAN5); do install $$i.5 -m 755 /usr/local/man/man5; done
for i in $(MAN8); do install $$i.8 -m 755 /usr/local/man/man8; done
for i in *.1; do install $$i -m 755 /usr/local/man/man1; done
for i in *.5; do install $$i -m 755 /usr/local/man/man5; done
for i in *.8; do install $$i -m 755 /usr/local/man/man8; done
clean:
rm -f *~

View File

@@ -90,7 +90,7 @@ option to
.B ncpmount(8), ncpumount(8)
.SH CREDITS
ncopy was written by Brian G. Reid (breid@tim.com) and
Tom C. Henderson (thenderson@tim.com).
Many thanks to Volker Lendecke (lendecke@namu01.gwdg.de) for the ncpfs
and ncplib which made ncopy possible.
ncopy was written by Brian G. Reid (breid@tim.com) and Tom
C. Henderson (thenderson@tim.com). Many thanks to Volker Lendecke
(lendecke@math.uni-goettingen.de) for the ncpfs and ncplib which made
ncopy possible.

View File

@@ -57,7 +57,7 @@ protocol Novell NetWare clients use to talk to NetWare servers. ncpfs
was inspired by
.B lwared,
a free NetWare emulator for Linux written by Ales Dryak. See
ftp://klokan.sh.cvut.cz/pub/linux for this very intersting program.
ftp://klokan.sh.cvut.cz/pub/linux for this very interesting program.
.B ncpmount
when invoked with all appropriate arguments attaches, logs in and
@@ -83,7 +83,7 @@ If the real uid of the caller is not root,
checks whether the user is allowed to mount a filesystem on the
mount-point. So it should be safe to make
.B ncpmount
setuid root. The filesystem stores the uid of the user who called
setuid root. The filesystem stores the uid of the user who called
ncpmount. So
.B ncpumount
can check whether the caller is allowed to unmount the filesystem.
@@ -271,7 +271,7 @@ of your server.
.B USER / LOGNAME
.RS 3
The variables USER or LOGNAME may contain the username of the person
using the client. USER is tried first. If it's emtpy, LOGNAME is
using the client. USER is tried first. If it's empty, LOGNAME is
tried.
.RE
@@ -291,5 +291,5 @@ The encryption code was taken from Dr. Dobbs's Journal 11/93. There
Pawel Szczerbina described it in an article on NCP.
The ncpfs code was initially hacked from smbfs by Volker Lendecke
(lendecke@namu01.gwdg.de). smbfs was put together by Paal-Kr. Engstad
(lendecke@math.uni-goettingen.de). smbfs was put together by Paal-Kr. Engstad
(pke@engstad.ingok.hitos.no) and later polished by Volker.

View File

@@ -219,4 +219,4 @@ printed if a printer operator has put in the correct form.
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
nprint was written by Volker Lendecke (lendecke@namu01.gwdg.de)
nprint was written by Volker Lendecke (lendecke@math.uni-goettingen.de)

View File

@@ -65,14 +65,14 @@ is the name of the server you want to use.
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about you NetWare user name.
to tell the server about your NetWare user name.
.RE
.B -P
.I password
.RS 3
You may want to give the password required by the server on the
command line. You should be careful to use passwords in scripts.
command line. You should be careful about using passwords in scripts.
.RE
.B -n

69
man/nwauth.1 Normal file
View File

@@ -0,0 +1,69 @@
.TH NWAUTH 1 10/27/1996 nwauth nwauth
.SH NAME
nwauth \- Verify username/password
.SH SYNOPSIS
.B nwauth
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
]
.SH DESCRIPTION
.B nwauth
does nothing but logging into a NetWare server. If the login was
successful, an error code of 0 is returned. If the login was not
successful, an error code of 1 is returned. It was designed for
use by other programs who want authenticate users via a NetWare
server.
nwauth
.B always
expects a password on stdin. If the stdin is a tty, then the user is
prompted for a password. Otherwise nwauth simply reads stdin for a
password.
.B nwauth
looks up the file
.I $HOME/.nwclient
to find a file server and a user name. See nwclient(5) for more
information. Please note that the access permissions of .nwclient MUST
be 600, for security reasons.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user name
.RS 3
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about your NetWare user name.
.RE
.SH SEE ALSO
.B nwclient(5)
.SH CREDITS
nwauth was written by Volker Lendecke (lendecke@math.uni-goettingen.de)

View File

@@ -22,9 +22,10 @@ nwbols \- List NetWare Bindery Objects
.B -t
.I type
] [
.B -v
.B -o
.I pattern
] [
.B pattern
.B -v
]
.SH DESCRIPTION
@@ -95,7 +96,8 @@ objects to be listed.
must be given as a decimal number.
.RE
.B pattern
.B -o
.I pattern
.RS 3
Specifying a pattern is another way to restrict the objects
listed. Please note that this pattern is evaluated by the NetWare

107
man/nwbpset.1 Normal file
View File

@@ -0,0 +1,107 @@
.TH NWBPSET 1 8/7/1996 nwbpset nwbpset
.SH NAME
nwbpset \- Create a bindery property or set its value
.SH SYNOPSIS
.B nwbpset
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
]
.SH DESCRIPTION
.B nwbpset
Reads a property specification from the standard input and creates and
sets the corresponding property. The format is determined by the
output of 'nwbpvalues -c'. nwbpset will hopefully become an important
part of the bindery management suite of ncpfs, together with
'nwbpvalues -c'. See util/nwbpsecurity for an example.
As another example, look at the following command line:
nwbpvalues -t 1 -o supervisor -p user_defaults -c |\\
sed '2s/.*/ME/'|\\
sed '3s/.*/LOGIN_CONTROL/'|\\
nwbpset
With this command, the property user_defaults of the user object
\'supervisor\' is copied into the property login_control of the user
object \'me\'.
nwbpvalues -t 1 -o me -p login_control -c |\\
sed '9s/.*/ff/'|\\
nwbpset
This command disables the user object me.
Feel free to contribute other examples!
.B nwbpset
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of $HOME/.nwclient MUST be 600 for security reasons.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the user name to use for login.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for login. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nwbpset
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the login.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.SH AUTHORS
nwbpset was written by Volker Lendecke. See the Changes file of ncpfs
for other contributors.

View File

@@ -29,6 +29,8 @@ nwbpvalues \- Print a NetWare Bindery Propery's contents
.I property
] [
.B -v
] [
.B -c
]
.SH DESCRIPTION
@@ -122,9 +124,10 @@ the object flags, its security byte and the properties flag is also
listed.
.RE
.SH BUGS
Only SET properties can be printed. This will hopefully be fixed in
the future. (Feel free to fix this and send me a patch ;-)).
.B -c
.RS 3
Use canonical output, to be used with nwbpset.
.RE
.SH AUTHORS
nwbpvalues was written by Volker Lendecke with the corresponding

View File

@@ -1,4 +1,4 @@
.TH NWCLIENT 5 12/27/1995 nwmount nwmount
.TH NWCLIENT 5 12/27/1995 nwclient nwclient
.SH NAME
nwclient \- configuration file for NWClient program suite
.SH DESCRIPTION
@@ -35,11 +35,11 @@ An example might be the following:
# And a passwordless account on another server
CD-SERV/GUEST -
With these lines in $HOME/.nwclient, calling 'nwmount /mnt' will mount
With these lines in $HOME/.nwclient, calling 'ncpmount /mnt' will mount
the the file server FS311 with user name ME on /mnt after asking the
user for a password.
\'nwmount -S cd-serv /cd' will silently mount the server cd-serv on /cd.
\'ncpmount -S cd-serv /cd' will silently mount the server cd-serv on /cd.
.B nprint
,

52
man/nwfsinfo.1 Normal file
View File

@@ -0,0 +1,52 @@
.TH NWFSINFO 1 07/22/1996 nwfsinfo nwfsinfo
.SH NAME
nwfsinfo \- Print some information about the file server
.SH SYNOPSIS
.B nwfsinfo
[
.B -h
] [
.B -S
.I server
] [
.B -t
] [
.B -i
] [
.B -d
]
.SH DESCRIPTION
.B nwfsinfo
prints some of the information the NetWare servers present without
logging in. The options control what is printed. You should try the
different options to find out what is printed when.
.SH OPTIONS
.B -h
.RS 3
With -h nwfsinfo prints a little help text.
.RE
.B -S
.I server
.RS 3
is the name of the server you want to know something about.
.RE
.B -t
.RS 3
Print what the file server believes to be the current time.
.RE
.B -d
.RS 3
Print the so-called file server description strings.
.RE
.B -i
.RS 3
Print the extended file server information such as NetWare version,
maximum connections an others.
.RE

85
man/nwfstime.1 Normal file
View File

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

View File

@@ -1,8 +1,8 @@
.TH NPASSWD 1 06/22/1996 npasswd npasswd
.TH NWPASSWD 1 01/16/1997 nwpasswd nwpasswd
.SH NAME
npasswd \- Change a user's password
nwpasswd \- Change a user's password
.SH SYNOPSIS
.B npasswd
.B nwpasswd
[
.B -h
] [
@@ -11,6 +11,9 @@ npasswd \- Change a user's password
] [
.B -U
.I user name
] [
.B -O
.I object name
]
.B -t
.I object type
@@ -18,9 +21,9 @@ npasswd \- Change a user's password
.SH DESCRIPTION
With
.B npasswd,
.B nwpasswd,
you can change your password on a NetWare server.
.B npasswd
.B nwpasswd
asks for the old password and twice for the new password. Then it
changes the password on the server.
@@ -28,7 +31,7 @@ changes the password on the server.
.B -h
.RS 3
With -h npasswd prints a little help text.
With -h nwpasswd prints a little help text.
.RE
.B -S
@@ -43,6 +46,16 @@ is the name of the server you want to use.
is the name of the bindery object whose password is to be changed.
.RE
.B -O
.I object name
.RS 3
If you have supervisor privileges, you can change other users'
passwords. With
.B -O
you can tell nwpasswd the name of the user whose password should be
changed.
.RE
.B -t
.I object type
.RS 3
@@ -51,5 +64,5 @@ changed.
.RE
.SH CREDITS
npasswd would not have been possible without the work of Guntram
nwpasswd would not have been possible without the work of Guntram
Blom. Look at nwcrypt.c for his work.

41
man/nwrights.1 Normal file
View File

@@ -0,0 +1,41 @@
.TH NWRIGHTS 1 8/1/1996 nwrights nwrights
.SH NAME
nwrights \- Show effective rights for file or directory
.SH SYNOPSIS
.B nwrights
[
.B -h
]
.B file/directory
.SH DESCRIPTION
.B nwrights
asks the NetWare server for the effective rights the user has for a
specific file or directory. The rights the server grants are the
definitive restriction for what you may do with files or
directories. The Linux permission bits are not really relevant, they
can only restrict the possibilities further.
.B nwrights
operates on the current directory or the file or directory that is
given as an argument. Certainly the file or directory you specify has
to reside on a ncpfs mounted directory for nwrights to work properly.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B file/directory
.RS 3
You can specify the file or directory you want information about. The
default is the current working directory.
.RE
.SH AUTHORS
nwrights was written by Volker Lendecke with the corresponding NetWare
utility in mind. See the Changes file of ncpfs for other contributors.

36
man/nwsfind.1 Normal file
View File

@@ -0,0 +1,36 @@
.TH NWSFIND 1 10/27/1996 nwsfind nwsfind
.SH NAME
nwsfind \- Find a NetWare Server
.SH SYNOPSIS
.B nwsfind
[
.B -t
.I type
] [
.I name
]
.SH DESCRIPTION
.B nwsfind
searches for a NetWare server and finds a route to this
server. nwsfind was written to be setuid root. It is called from
within the ncp library, so that it is possible that normal users use
the utilities.
.SH OPTIONS
.B name
.RS 3
If you look for a specific server, you should give nwsfind this
argument. If you omit it, nwsfind looks for the server nearest to you.
.RE
.B -t
.I type
.RS 3
By default nwsfind looks for file servers. In case you want to look up
another server type, you have to specify its numerical type as
.B type.
.RE
.SH CREDITS
nwsfind was written by Volker Lendecke (lendecke@math.uni-goettingen.de)

93
man/nwuserlist.1 Normal file
View File

@@ -0,0 +1,93 @@
.TH NWUSERLIST 1 7/22/1996 nwuserlist nwuserlist
.SH NAME
nwuserlist \- List Users logged in at a NetWare server
.SH SYNOPSIS
.B nwuserlist
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -a
]
.SH DESCRIPTION
.B nwuserlist
lists the users logged in at a NetWare server, together with their
connection number and their login time.
.B nwuserlist
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of $HOME/.nwclient MUST be 600 for security reasons.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the user name to use for login.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for login. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nwuserlist
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the login.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.B -a
.RS 3
With option -a the IPX address of the station the user is logged in
from is printed as well.
.RE
.SH AUTHORS
nwuserlist was written by Volker Lendecke. See the Changes file of ncpfs
for other contributors.

100
man/nwvolinfo.1 Normal file
View File

@@ -0,0 +1,100 @@
.TH NWVOLINFO 8 7/9/1996 nwvolinfo nwvolinfo
.SH NAME
nwvolinfo \- Diplay info on NetWare Volumes
.SH SYNOPSIS
.B nwvolinfo
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -v
.I volume
] [
.B -N
]
.SH DESCRIPTION
.B nwvolinfo
displays information on a NetWare Server Volume.
.B nwvolinfo
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of $HOME/.nwclient MUST be 600 for security reasons.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the user name to use for login.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for login. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nwvolinfo
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the login.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.B -v
.I volume
.RS 3
The volume name to be used. Defaults to 'SYS'.
.RE
.B -N
.RS 3
Display the information in numeric-only format for use in a pipe.
.RE
.SH AUTHORS
nwvolinfo was written by Jacek Stepniewski <cunio@gazeta.pl> based on
utilities by Volker Lendecke.

View File

@@ -68,14 +68,14 @@ is the name of the server you want to use.
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about you NetWare user name.
to tell the server about your NetWare user name.
.RE
.B -P
.I password
.RS 3
You may want to give the password required by the server on the
command line. You should be careful to use passwords in scripts.
command line. You should be careful about using passwords in scripts.
.RE
.B -n
@@ -102,4 +102,4 @@ this conversion by
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
pqlist was written by Volker Lendecke (lendecke@namu01.gwdg.de)
pqlist was written by Volker Lendecke (lendecke@math.uni-goettingen.de)

View File

@@ -1,4 +1,4 @@
.TH PSERVER 1 02/10/1996 pserver pserver
.TH PSERVER 1 10/22/1996 pserver pserver
.SH NAME
pserver \- NetWare print server
.SH SYNOPSIS
@@ -101,6 +101,13 @@ process, and feeds the job file to stdin.
.I command
is the printing command that is executed for each job. The default
command is 'lpr'.
You can insert several flags into the command, preceded by %. These
are replaced with values retrieved from the queue structure for the
print job.
%u: This field will be replaced by the name of the user who posted
this print job.
.RE
.B -j
@@ -139,4 +146,4 @@ diagnostic messages that are printed when a error occurs.
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
pserver was written by Volker Lendecke (lendecke@namu01.gwdg.de)
pserver was written by Volker Lendecke (lendecke@math.uni-goettingen.de)

View File

@@ -40,4 +40,4 @@ List all available Netware servers on your Network, that begin with an "I".
.B ncpmount(8), ncpumount(8), pqlist(1), nprint(1)
.SH CREDITS
slist was written by Volker Lendecke (lendecke@namu01.gwdg.de)
slist was written by Volker Lendecke (lendecke@math.uni-goettingen.de)

View File

@@ -1,7 +1,7 @@
Begin3
Title: ncpfs
Version: 2.0.1
Entered-date: 10. July 1996
Version: 2.0.9
Entered-date: 16. February 1997
Description: With ncpfs you can mount volumes of your netware
server under Linux. You can also print to netware
print queues and spool netware print queues to the
@@ -12,8 +12,8 @@ Keywords: filesystem ncp novell netware printing
Author: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
Alternate-site: sunsite.unc.edu:/pub/system/Filesystems/ncpfs
~124k ncpfs-2.0.1.tgz
~ 1k ncpfs-2.0.1.lsm
Alternate-site: sunsite.unc.edu:/pub/Linux/system/Filesystems/ncpfs
~156k ncpfs-2.0.9.tgz
~ 1k ncpfs-2.0.9.lsm
Copying-policy: GPL
End

13
patches/README Normal file
View File

@@ -0,0 +1,13 @@
To apply the patches, cd into the appropriate kernel source directory
and do:
patch -p1 < patch-file
lockup-2.0.28.diff:
An *extremely* dirty fix to the lockup bug mentioned in the BUGS
file. Please only apply it if you experience the problem. Should apply
to 2.0.28 and above in the 2.0.x series. NOT TESTED with 2.1.x.
linux-2.1.26.diff:
Little fix to make ncpfs work with 2.1.26. Sent to Linus.

35
patches/linux-2.1.26.diff Normal file
View File

@@ -0,0 +1,35 @@
--- 2.1.26/fs/ncpfs/sock.c Sun Jan 26 11:07:44 1997
+++ 2.1.26-patched/fs/ncpfs/sock.c Sun Feb 16 17:05:13 1997
@@ -24,6 +24,7 @@
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_fs_sb.h>
+#include <linux/poll.h>
#include <net/sock.h>
@@ -343,7 +344,6 @@
char *start = server->packet;
poll_table wait_table;
struct poll_table_entry entry;
- int (*select) (struct inode *, poll_table *);
int init_timeout, max_timeout;
int timeout;
int retrans;
@@ -362,7 +362,6 @@
file = server->ncp_filp;
inode = file->f_inode;
- select = file->f_op->poll;
sock = &inode->u.socket_i;
if (!sock)
{
@@ -418,7 +417,7 @@
wait_table.nr = 0;
wait_table.entry = &entry;
current->state = TASK_INTERRUPTIBLE;
- if (!select(inode, &wait_table))
+ if (!(file->f_op->poll(file, &wait_table) & POLLIN))
{
if (timeout > max_timeout)
{

View File

@@ -0,0 +1,44 @@
diff -urN 2.0.11/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c
--- 2.0.28/fs/ncpfs/sock.c Fri Jul 12 08:14:53 1996
+++ linux/fs/ncpfs/sock.c Thu Aug 8 19:27:26 1996
@@ -55,7 +55,8 @@
{
struct iovec iov;
struct msghdr msg;
-
+ int result;
+
iov.iov_base = (void *)buff;
iov.iov_len = len;
@@ -65,7 +66,29 @@
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);
+ result = sock->ops->sendmsg(sock, &msg, len, 1, flags);
+
+ if ((result != -EAGAIN) || (nonblock != 0))
+ {
+ return result;
+ }
+
+ /* The following is probably one of the worst sins you can do
+ to a multitasking kernel: active polling. But when you call
+ ipx_sendmsg with nonblock==0, then it will block forever
+ from time to time. I really do not know why. To work around
+ this, I try to send the packet with nonblock=1 and retry
+ it. */
+
+ do {
+ /* Before retrying, give others a chance */
+ current->state = TASK_INTERRUPTIBLE;
+ current->timeout = jiffies + HZ/10;
+ schedule();
+ result = sock->ops->sendmsg(sock, &msg, len, 1, flags);
+ } while (result == -EAGAIN);
+
+ return result;
}

42
sutil/Makefile Normal file
View File

@@ -0,0 +1,42 @@
#
# Makefile for the linux ncp-filesystem routines.
#
UTILS = ncpmount ncpumount nwsfind
CC = gcc
default:
make -C ..
all: $(UTILS)
install: all
for i in $(UTILS); \
do install $$i -m 4755 $(BINDIR); done
$(UTILS): %: %.o libncp.a
$(CC) -o $@ $(addsuffix .o,$@) -L. -lncp -L../lib -lcom_err
ncplib.o: ncplib.c ncplib.h
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
libncp.a: ncplib.o ../lib/ncplib_err.o
ar r libncp.a ncplib.o ../lib/ncplib_err.o
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f *.o *~ libncp.a $(UTILS)
mrproper: clean
rm -f .depend
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif

1871
sutil/ncplib.c Normal file

File diff suppressed because it is too large Load Diff

282
sutil/ncplib.h Normal file
View File

@@ -0,0 +1,282 @@
/*
* ncplib.h
*
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#include "ipxlib.h"
#include "com_err.h"
#ifndef memzero
#include <string.h>
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif
typedef __u8 byte;
typedef __u16 word;
typedef __u32 dword;
#define BVAL(buf,pos) (((__u8 *)(buf))[pos])
#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos))
#define BSET(buf,pos,val) (BVAL(buf,pos) = (val))
static inline word
WVAL_HL(__u8 *buf, int pos)
{
return PVAL(buf,pos)<<8 | PVAL(buf, pos+1);
}
static inline dword
DVAL_HL(__u8 *buf, int pos)
{
return WVAL_HL(buf, pos)<<16 | WVAL_HL(buf, pos+2);
}
static inline void
WSET_HL(__u8 *buf, int pos, word val)
{
BSET(buf,pos,val>>8);
BSET(buf,pos+1, val & 0xff);
}
static inline void
DSET_HL(__u8 *buf, int pos, dword val)
{
WSET_HL(buf, pos, val >>16);
WSET_HL(buf, pos+2, val & 0xffff);
}
/* we know that the 386 can handle misalignment and has the "right"
byteorder */
#if defined(__i386__)
static inline word
WVAL_LH(__u8 *buf, int pos)
{
return *((word *)(buf+pos));
}
static inline dword
DVAL_LH(__u8 *buf, int pos)
{
return *((dword *)(buf+pos));
}
static inline void
WSET_LH(__u8 *buf, int pos, word val)
{
*((word *)(buf+pos)) = val;
}
static inline void
DSET_LH(__u8 *buf, int pos, dword val)
{
*((dword *)(buf+pos)) = val;
}
#else
static inline word
WVAL_LH(__u8 *buf, int pos)
{
return PVAL(buf,pos) | PVAL(buf, pos+1)<<8;
}
static inline dword
DVAL_LH(__u8 *buf, int pos)
{
return WVAL_LH(buf, pos) | WVAL_LH(buf, pos+2) << 16;
}
static inline void
WSET_LH(__u8 *buf, int pos, word val)
{
BSET(buf,pos,val & 0xff);
BSET(buf,pos+1, val >> 8);
}
static inline void
DSET_LH(__u8 *buf, int pos, dword val)
{
WSET_LH(buf, pos, val & 0xffff);
WSET_LH(buf, pos+2, val >> 16);
}
#endif
void
str_upper(char *name);
enum connect_state {
NOT_CONNECTED = 0,
CONN_PERMANENT,
CONN_TEMPORARY
};
struct ncp_conn {
enum connect_state is_connected;
char server[NCP_BINDERY_NAME_LEN];
char user [NCP_BINDERY_NAME_LEN];
struct ncp_fs_info i;
/* Fields for use with permanent connections */
int mount_fid;
char mount_point[MAXPATHLEN];
/* Fields for use with temporary connections */
int ncp_sock;
int wdog_sock;
int wdog_pid;
__u8 sequence;
int completion;
int conn_status;
int reply_size;
/* Fields used to setup ncp requests */
int current_size;
int has_subfunction;
int verbose;
int ncp_reply_size;
int lock;
char packet[NCP_PACKET_SIZE];
};
struct ncp_conn_spec {
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
int login_type; /* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */
char password[NCP_BINDERY_NAME_LEN];
};
struct ncp_property_info {
__u8 property_name[16];
__u8 property_flags;
__u8 property_security;
__u32 search_instance;
__u8 value_available_flag;
__u8 more_properties_flag;
};
/* ncp_initialize is the main entry point for user programs which want
to connect to a NetWare Server. It looks for -S, -U, -P and -n in
the argument list, opens the connection and removes the arguments
from the list. It was designed after the X Windows init
functions. */
struct ncp_conn *
ncp_initialize(int *argc, char **argv,
int login_necessary, long *err);
/* You can login as another object by this procedure. As a first use
pserver comes to mind. */
struct ncp_conn *
ncp_initialize_as(int *argc, char **argv,
int login_necessary, int login_type, long *err);
/* Open a connection */
struct ncp_conn *
ncp_open(struct ncp_conn_spec *spec, long *err);
/* Open a connection on an existing mount point */
struct ncp_conn *
ncp_open_mount(const char *mount_point, long *err);
/* Find a permanent connection that fits the spec, return NULL if
* there is none. */
char *
ncp_find_permanent(const struct ncp_conn_spec *spec);
/* Find the address of a file server */
struct sockaddr_ipx *
ncp_find_fileserver(char *server_name, long *err);
/* Find the address of a server */
struct sockaddr_ipx *
ncp_find_server(char **server_name, int type, long *err);
/* Detach from a permanent connection or destroy a temporary
connection */
long
ncp_close(struct ncp_conn *conn);
/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable
connections */
struct ncp_conn_ent {
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
char mount_point[MAXPATHLEN];
};
struct ncp_conn_ent *
ncp_get_conn_ent(FILE *filep);
#define NWCLIENT (".nwclient")
#define NWC_NOPASSWORD ("-")
/* find an appropriate connection */
struct ncp_conn_spec *
ncp_find_conn_spec(const char *server, const char *user, const char *password,
int login_necessary, uid_t uid, long *err);
long
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
struct ncp_station_addr {
__u32 NetWork __attribute__ ((packed));
__u8 Node[6] __attribute__ ((packed));
__u16 Socket __attribute__ ((packed));
};
struct ncp_prop_login_control {
__u8 AccountExpireDate[3] __attribute__ ((packed));
__u8 Disabled __attribute__ ((packed));
__u8 PasswordExpireDate[3] __attribute__ ((packed));
__u8 GraceLogins __attribute__ ((packed));
__u16 PasswordExpireInterval __attribute__ ((packed));
__u8 MaxGraceLogins __attribute__ ((packed));
__u8 MinPasswordLength __attribute__ ((packed));
__u16 MaxConnections __attribute__ ((packed));
__u8 ConnectionTimeMask[42] __attribute__ ((packed));
__u8 LastLogin[6] __attribute__ ((packed));
__u8 RestrictionMask __attribute__ ((packed));
__u8 reserved __attribute__ ((packed));
__u32 MaxDiskUsage __attribute__ ((packed));
__u16 BadLoginCount __attribute__ ((packed));
__u32 BadLoginCountDown __attribute__ ((packed));
struct ncp_station_addr LastIntruder __attribute__ ((packed));
};
long
ncp_read_property_value(struct ncp_conn *conn,
int object_type, const char *object_name,
int segment, const char *prop_name,
struct nw_property *target);
#define NCP_GRACE_PERIOD (0xdf)
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
struct ncp_bindery_object *target);
long
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password);
#endif /* _NCPLIB_H */

576
sutil/ncpmount.c Normal file
View File

@@ -0,0 +1,576 @@
/*
* nwmount.c
*
* Copyright (C) 1995 by Volker Lendecke
*
* 1/20/96 - Steven N. Hirsch (hirsch@emba.uvm.edu)
*
* If the ncpfs support is not loaded and we are using kerneld to
* autoload modules, then we don't want to do it here. I added
* a conditional which leaves out the test and load code.
*
* Even if we _do_ want ncpmount to load the module, passing a
* fully-qualified pathname to modprobe causes it to bypass a
* path search. This may lead to ncpfs.o not being found on
* some systems.
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
/* #include <sys/wait.h> *//* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
#include <linux/ipx.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ncplib.h"
#include "com_err.h"
static char *progname;
static void usage(void);
static void help(void);
#ifndef HAVE_KERNELD
/* Returns 0 if the filesystem is in the kernel after this routine
completes */
static int
load_ncpfs(void)
{
FILE *ffs;
char s[1024];
char *p, *p1;
pid_t pid;
int status;
/* Check if ncpfs is in the kernel */
ffs = fopen("/proc/filesystems", "r");
if (ffs == NULL)
{
perror("Error: \"/proc/filesystems\" could not be read:");
return -1;
}
p = NULL;
while (!feof(ffs))
{
p1 = fgets(s, sizeof(s), ffs);
if (p1)
{
p = strstr(s, "ncpfs");
if (p)
{
break;
}
}
}
fclose(ffs);
if (p)
{
return 0;
}
/* system() function without signal handling, from Stevens */
if ((pid = fork()) < 0)
{
return 1;
} else if (pid == 0)
{
/* child */
execl("/sbin/modprobe", "modprobe", "ncpfs", NULL);
_exit(127); /* execl error */
} else
{
/* parent */
while (waitpid(pid, &status, 0) < 0)
{
if (errno != EINTR)
{
status = -1;
break;
}
}
}
return status;
}
#endif /* HAVE_KERNELD */
/* Check whether user is allowed to mount on the specified mount point */
static int
mount_ok(struct stat *st)
{
if (!S_ISDIR(st->st_mode))
{
errno = ENOTDIR;
return -1;
}
if ((getuid() != 0)
&& ((getuid() != st->st_uid)
|| ((st->st_mode & S_IRWXU) != S_IRWXU)))
{
errno = EPERM;
return -1;
}
return 0;
}
int
main(int argc, char *argv[])
{
struct ncp_mount_data data;
struct stat st;
char mount_name[256];
int fd, result;
struct sockaddr_ipx addr;
struct sockaddr_ipx *server_addr;
int addrlen;
int upcase_password;
long err;
int um;
unsigned int flags;
char mount_point[MAXPATHLEN];
struct mntent ment;
FILE *mtab;
char *tmp_mount;
char *server = NULL;
char *user = NULL;
char *password = NULL;
struct ncp_conn_spec *spec;
uid_t conn_uid = getuid();
struct ncp_conn *conn;
int opt;
progname = argv[0];
memzero(data);
memzero(spec);
if (geteuid() != 0)
{
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
data.uid = getuid();
data.gid = getgid();
um = umask(0);
umask(um);
data.file_mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~um;
data.dir_mode = 0;
data.flags |= NCP_MOUNT_SOFT;
data.time_out = 60;
data.retry_count = 5;
upcase_password = 1;
while ((opt = getopt(argc, argv, "CS:U:c:u:g:f:d:P:nh?vV:t:r:"))
!= EOF)
{
switch (opt)
{
case 'C':
upcase_password = 0;
break;
case 'S':
if (strlen(optarg) >= sizeof(spec->server))
{
fprintf(stderr, "Servername too long:%s\n",
optarg);
return 1;
}
server = optarg;
break;
case 'U':
if (strlen(optarg) >= sizeof(spec->user))
{
fprintf(stderr, "Username too long: %s\n",
optarg);
return 1;
}
user = optarg;
break;
case 'c':
if (isdigit(optarg[0]))
{
conn_uid = atoi(optarg);
} else
{
struct passwd *pwd = getpwnam(optarg);
if (pwd == NULL)
{
fprintf(stderr, "Unknown user: %s\n",
optarg);
return 1;
}
conn_uid = pwd->pw_uid;
}
break;
case 'u':
if (isdigit(optarg[0]))
{
data.uid = atoi(optarg);
} else
{
struct passwd *pwd = getpwnam(optarg);
if (pwd == NULL)
{
fprintf(stderr, "Unknown user: %s\n",
optarg);
return 1;
}
data.uid = pwd->pw_uid;
}
break;
case 'g':
if (isdigit(optarg[0]))
{
data.gid = atoi(optarg);
} else
{
struct group *grp = getgrnam(optarg);
if (grp == NULL)
{
fprintf(stderr, "Unknown group: %s\n",
optarg);
return 1;
}
data.gid = grp->gr_gid;
}
break;
case 'f':
data.file_mode = strtol(optarg, NULL, 8);
break;
case 'd':
data.dir_mode = strtol(optarg, NULL, 8);
break;
case 'P':
if (strlen(optarg) >= sizeof(spec->password))
{
printf("password too long\n");
exit(1);
}
password = optarg;
break;
case 'V':
if (strlen(optarg) >= sizeof(data.mounted_vol))
{
printf("Volume too long: %s\n", optarg);
exit(1);
}
strcpy(data.mounted_vol, optarg);
break;
case 'n':
password = "";
break;
case 't':
data.time_out = atoi(optarg);
break;
case 'r':
data.retry_count = atoi(optarg);
break;
case 'h':
case '?':
help();
exit(1);
case 'v':
fprintf(stderr, "ncpfs version %s\n", NCPFS_VERSION);
exit(1);
default:
usage();
return -1;
}
}
if ((spec = ncp_find_conn_spec(server, user, password, 1, data.uid, &err))
== NULL)
{
com_err(progname, err, "in find_conn_spec");
exit(1);
}
if (upcase_password != 0)
{
str_upper(spec->password);
}
if (optind != argc - 1)
{
usage();
return -1;
}
realpath(argv[optind], mount_point);
if (stat(mount_point, &st) == -1)
{
fprintf(stderr, "could not find mount point %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
if (mount_ok(&st) != 0)
{
fprintf(stderr, "cannot to mount on %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
#ifndef HAVE_KERNELD
/* Check if the ncpfs filesystem is in the kernel. If not, attempt
* to load the ncpfs module */
if (load_ncpfs() != 0)
{
fprintf(stderr, "Error: Unable to load ncpfs, exiting...\n");
exit(1);
}
#endif
data.version = NCP_MOUNT_VERSION;
data.mounted_uid = conn_uid;
memcpy(data.server_name, spec->server, sizeof(data.server_name));
if (data.dir_mode == 0)
{
data.dir_mode = data.file_mode;
if ((data.dir_mode & S_IRUSR) != 0)
data.dir_mode |= S_IXUSR;
if ((data.dir_mode & S_IRGRP) != 0)
data.dir_mode |= S_IXGRP;
if ((data.dir_mode & S_IROTH) != 0)
data.dir_mode |= S_IXOTH;
}
if ((tmp_mount = ncp_find_permanent(spec)) != NULL)
{
fprintf(stderr,
"You already have mounted server %s\nas user "
"%s\non mount point %s\n", spec->server, spec->user,
tmp_mount);
exit(1);
}
if ((server_addr = ncp_find_fileserver(spec->server, &err)) == NULL)
{
com_err("ncpmount", err, "when trying to find %s",
spec->server);
exit(1);
}
data.serv_addr = *server_addr;
data.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.ncp_fd == -1)
{
com_err("ncpmount", err, "opening ncp_socket");
exit(1);
}
data.wdog_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.wdog_fd == -1)
{
fprintf(stderr, "could not open wdog socket: %s\n",
strerror(errno));
exit(1);
}
memzero(addr);
addr.sipx_type = NCP_PTYPE;
if (bind(data.ncp_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
fprintf(stderr, "\nbind: %s\n",
strerror(errno));
fprintf(stderr,
"\nMaybe you want to use \n"
"ipx_configure --auto_interface=on --auto_primary=on\n"
"and try again after waiting a minute.\n\n");
exit(1);
}
addrlen = sizeof(addr);
if (getsockname(data.ncp_fd, (struct sockaddr *) &addr, &addrlen) == -1)
{
perror("getsockname ncp socket");
close(data.ncp_fd);
close(data.wdog_fd);
exit(1);
}
addr.sipx_port = htons(ntohs(addr.sipx_port) + 1);
if (bind(data.wdog_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
fprintf(stderr, "bind(wdog_sock, ): %s\n",
strerror(errno));
exit(1);
}
#if NCP_MOUNT_VERSION>1
data.message_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.message_fd == -1)
{
fprintf(stderr, "could not open message socket: %s\n",
strerror(errno));
exit(1);
}
addr.sipx_port = htons(ntohs(addr.sipx_port) + 1);
if (bind(data.message_fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
fprintf(stderr, "bind(message_sock, ): %s\n",
strerror(errno));
exit(1);
}
if (strlen(mount_point) < sizeof(data.mount_point))
{
strcpy(data.mount_point, mount_point);
}
#endif
flags = MS_MGC_VAL;
strcpy(mount_name, spec->server);
strcat(mount_name, "/");
strcat(mount_name, spec->user);
result = mount(mount_name, mount_point, "ncpfs", flags, (char *) &data);
if (result < 0)
{
printf("mount failed\n");
exit(1);
}
if ((conn = ncp_open_mount(mount_point, &err)) == NULL)
{
com_err("ncpmount", err, "attempt to open mount point");
umount(mount_point);
exit(1);
}
if ((err = ncp_login_user(conn, spec->user, spec->password)) != 0)
{
struct nw_property p;
struct ncp_prop_login_control *l
= (struct ncp_prop_login_control *) &p;
if (conn->completion != NCP_GRACE_PERIOD)
{
com_err("ncpmount", err, "in login");
fprintf(stderr, "Login denied\n");
ncp_close(conn);
umount(mount_point);
exit(1);
}
fprintf(stderr, "Your password has expired\n");
if ((err = ncp_read_property_value(conn, NCP_BINDERY_USER,
spec->user, 1,
"LOGIN_CONTROL", &p)) == 0)
{
fprintf(stderr, "You have %d login attempts left\n",
l->GraceLogins);
}
}
if ((err = ioctl(conn->mount_fid, NCP_IOC_CONN_LOGGED_IN, NULL)) != 0)
{
com_err("ncpmount", err, "in logged_indication");
ncp_close(conn);
umount(mount_point);
exit(1);
}
ncp_close(conn);
ment.mnt_fsname = mount_name;
ment.mnt_dir = mount_point;
ment.mnt_type = "ncpfs";
ment.mnt_opts = "rw";
ment.mnt_freq = 0;
ment.mnt_passno = 0;
if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1)
{
fprintf(stderr, "Can't get " MOUNTED "~ lock file");
exit(1);
}
close(fd);
if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED);
exit(1);
}
if (addmntent(mtab, &ment) == 1)
{
fprintf(stderr, "Can't write mount entry");
exit(1);
}
if (fchmod(fileno(mtab), 0644) == -1)
{
fprintf(stderr, "Can't set perms on " MOUNTED);
exit(1);
}
endmntent(mtab);
if (unlink(MOUNTED "~") == -1)
{
fprintf(stderr, "Can't remove " MOUNTED "~");
exit(1);
}
return 0;
}
static void
usage(void)
{
printf("usage: %s [options] mount-point\n", progname);
printf("Try `%s -h' for more information\n", progname);
}
static void
help(void)
{
printf("\n");
printf("usage: %s [options] mount-point\n", progname);
printf("\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-V volume Volume to mount, for NFS re-export\n"
"-u uid uid the mounted files get\n"
"-g gid gid the mounted files get\n"
"-f mode permission the files get (octal notation)\n"
"-d mode permission the dirs get (octal notation)\n"
"-c uid uid to identify the connection to mount on\n"
" Only makes sense for root\n"
"-t time_out Waiting time (in 1/100s) to wait for\n"
" an answer from the server. Default: 60\n"
"-r retry_count Number of retry attempts. Default: 5\n"
"-C Don't convert password to uppercase\n"
"-P password Use this password\n"
"-n Do not use any password\n"
" If neither -P nor -n are given, you are\n"
" asked for a password.\n"
"-h print this help text\n"
"-v print ncpfs version number\n"
"\n");
}

192
sutil/ncpumount.c Normal file
View File

@@ -0,0 +1,192 @@
/*
* nwumount.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
/* #include <sys/wait.h> *//* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_mount.h>
#include <linux/ncp_fs.h>
static char *progname;
static void
usage(void)
{
printf("usage: %s mount-point\n", progname);
}
static int
umount_ok(const char *mount_point)
{
int fid = open(mount_point, O_RDONLY, 0);
uid_t mount_uid;
if (fid == -1)
{
fprintf(stderr, "Could not open %s: %s\n",
mount_point, strerror(errno));
return -1;
}
if (ioctl(fid, NCP_IOC_GETMOUNTUID, &mount_uid) != 0)
{
fprintf(stderr, "%s probably not ncp-filesystem\n",
mount_point);
return -1;
}
if ((getuid() != 0)
&& (mount_uid != getuid()))
{
fprintf(stderr, "You are not allowed to umount %s\n",
mount_point);
return -1;
}
close(fid);
return 0;
}
/* Make a canonical pathname from PATH. Returns a freshly malloced string.
It is up the *caller* to ensure that the PATH is sensible. i.e.
canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse
we return unmodified. */
char *
canonicalize(const char *path)
{
char *canonical = malloc(PATH_MAX + 1);
if (path == NULL)
return NULL;
if (realpath(path, canonical))
return canonical;
if (strlen(path) > PATH_MAX)
{
return NULL;
}
strcpy(canonical, path);
return canonical;
}
int
main(int argc, char *argv[])
{
int fd;
char *mount_point;
struct mntent *mnt;
FILE *mtab;
FILE *new_mtab;
progname = argv[0];
if (geteuid() != 0)
{
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
if (argc != 2)
{
usage();
exit(1);
}
mount_point = canonicalize(argv[1]);
if (mount_point == NULL)
{
fprintf(stderr, "Invalid mount point: %s\n", argv[1]);
exit(1);
}
if (umount_ok(mount_point) != 0)
{
fprintf(stderr, "You are not allowed to umount %s\n",
mount_point);
exit(1);
}
if (umount(mount_point) != 0)
{
fprintf(stderr, "Could not umount %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
if ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1)
{
fprintf(stderr, "Can't get " MOUNTED "~ lock file");
return 1;
}
close(fd);
if ((mtab = setmntent(MOUNTED, "r")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED ": %s\n",
strerror(errno));
return 1;
}
#define MOUNTED_TMP MOUNTED".tmp"
if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
strerror(errno));
endmntent(mtab);
return 1;
}
while ((mnt = getmntent(mtab)) != NULL)
{
if (strcmp(mnt->mnt_dir, mount_point) != 0)
{
addmntent(new_mtab, mnt);
}
}
endmntent(mtab);
if (fchmod(fileno(new_mtab), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
{
fprintf(stderr, "Error changing mode of %s: %s\n",
MOUNTED_TMP, strerror(errno));
exit(1);
}
endmntent(new_mtab);
if (rename(MOUNTED_TMP, MOUNTED) < 0)
{
fprintf(stderr, "Cannot rename %s to %s: %s\n",
MOUNTED, MOUNTED_TMP, strerror(errno));
exit(1);
}
if (unlink(MOUNTED "~") == -1)
{
fprintf(stderr, "Can't remove " MOUNTED "~");
return 1;
}
return 0;
}

212
sutil/nwcrypt.c Normal file
View File

@@ -0,0 +1,212 @@
/*$*********************************************************
$*
$* This code has been taken from DDJ 11/93, from an
$* article by Pawel Szczerbina.
$*
$* Password encryption routines follow.
$* Converted to C from Barry Nance's Pascal
$* prog published in the March -93 issue of Byte.
$*
$* Adapted to be useable for ncpfs by
$* Volker Lendecke <lendecke@namu01.gwdg.de> in
$* October 1995.
$*
$********************************************************* */
/****************************************************************************
I read that Novell is not very open when it comes to technical details
of the Netware Core Protocol. This might be especially true for the
encryption stuff. I took the necessary code from Dr. Dobb's Journal
11/93, Undocumented Corner. I asked Jon Erickson <jon@ddj.com> about
the legal status of this piece of code:
---
Date: Thu, 12 Oct 1995 13:44:18 +0100
From: Volker Lendecke <lendecke>
To: jon@ddj.com
Subject: legal status of your source code?
Hello!
I hope that you're the right one to write to, you are the first on your WWW
server. If you are not, could you please forward this message to the right
person? Thanks.
I'm currently exploring the possibility to write a free (in the GNU GPL
sense) NCP filesystem, which would allow me to access a novell server
transparently. For that I would like to use the encryption functions you
published in DDJ 11/93, Undocumented Corner. I would make some cosmetic
changes, such as other indentations, minor code changes and so on. But I do
not know if that allows me to publish this code under GPL. One alternative
would be to publish a diff against your listing, but that would probably
contain much of your code as well, and it would be very inconvenient for
the average user.
I think that you have some kind of standard procedure for such a
case. Please tell me what I should do.
Many thanks in advance,
Volker
+=================================================================+
! Volker Lendecke Internet: lendecke@namu01.gwdg.de !
! D-37081 Goettingen, Germany !
+=================================================================+
--
I got the following answer:
---
From: Jon Erickson <jon@ddj.com>
X-Mailer: SCO System V Mail (version 3.2)
To: lendecke@namu01.gwdg.de
Subject: Re: legal status of your source code?
Date: Thu, 12 Oct 95 5:42:56 PDT
Volker,
Code from Dr. Dobb's Journal related articles is provided for
anyone to use. Clearly, the author of the article should be
given credit.
Jon Erickson
---
With this answer in mind, I took the code and made it a bit more
C-like. The original seemed to be translated by a mechanical pascal->c
translator. Jon's answer encouraged me to publish nwcrypt.c under the
GPL. If anybody who knows more about copyright and sees any problems
with this, please tell me.
****************************************************************************/
/******************* Data types ***************************/
typedef unsigned char buf32[32];
typedef unsigned char buf16[16];
typedef unsigned char buf8[8];
typedef unsigned char buf4[4];
static unsigned char encrypttable[256] =
{0x7, 0x8, 0x0, 0x8, 0x6, 0x4, 0xE, 0x4, 0x5, 0xC, 0x1, 0x7, 0xB, 0xF, 0xA, 0x8,
0xF, 0x8, 0xC, 0xC, 0x9, 0x4, 0x1, 0xE, 0x4, 0x6, 0x2, 0x4, 0x0, 0xA, 0xB, 0x9,
0x2, 0xF, 0xB, 0x1, 0xD, 0x2, 0x1, 0x9, 0x5, 0xE, 0x7, 0x0, 0x0, 0x2, 0x6, 0x6,
0x0, 0x7, 0x3, 0x8, 0x2, 0x9, 0x3, 0xF, 0x7, 0xF, 0xC, 0xF, 0x6, 0x4, 0xA, 0x0,
0x2, 0x3, 0xA, 0xB, 0xD, 0x8, 0x3, 0xA, 0x1, 0x7, 0xC, 0xF, 0x1, 0x8, 0x9, 0xD,
0x9, 0x1, 0x9, 0x4, 0xE, 0x4, 0xC, 0x5, 0x5, 0xC, 0x8, 0xB, 0x2, 0x3, 0x9, 0xE,
0x7, 0x7, 0x6, 0x9, 0xE, 0xF, 0xC, 0x8, 0xD, 0x1, 0xA, 0x6, 0xE, 0xD, 0x0, 0x7,
0x7, 0xA, 0x0, 0x1, 0xF, 0x5, 0x4, 0xB, 0x7, 0xB, 0xE, 0xC, 0x9, 0x5, 0xD, 0x1,
0xB, 0xD, 0x1, 0x3, 0x5, 0xD, 0xE, 0x6, 0x3, 0x0, 0xB, 0xB, 0xF, 0x3, 0x6, 0x4,
0x9, 0xD, 0xA, 0x3, 0x1, 0x4, 0x9, 0x4, 0x8, 0x3, 0xB, 0xE, 0x5, 0x0, 0x5, 0x2,
0xC, 0xB, 0xD, 0x5, 0xD, 0x5, 0xD, 0x2, 0xD, 0x9, 0xA, 0xC, 0xA, 0x0, 0xB, 0x3,
0x5, 0x3, 0x6, 0x9, 0x5, 0x1, 0xE, 0xE, 0x0, 0xE, 0x8, 0x2, 0xD, 0x2, 0x2, 0x0,
0x4, 0xF, 0x8, 0x5, 0x9, 0x6, 0x8, 0x6, 0xB, 0xA, 0xB, 0xF, 0x0, 0x7, 0x2, 0x8,
0xC, 0x7, 0x3, 0xA, 0x1, 0x4, 0x2, 0x5, 0xF, 0x7, 0xA, 0xC, 0xE, 0x5, 0x9, 0x3,
0xE, 0x7, 0x1, 0x2, 0xE, 0x1, 0xF, 0x4, 0xA, 0x6, 0xC, 0x6, 0xF, 0x4, 0x3, 0x0,
0xC, 0x0, 0x3, 0x6, 0xF, 0x8, 0x7, 0xB, 0x2, 0xD, 0xC, 0x6, 0xA, 0xA, 0x8, 0xD};
static buf32 encryptkeys =
{0x48, 0x93, 0x46, 0x67, 0x98, 0x3D, 0xE6, 0x8D,
0xB7, 0x10, 0x7A, 0x26, 0x5A, 0xB9, 0xB1, 0x35,
0x6B, 0x0F, 0xD5, 0x70, 0xAE, 0xFB, 0xAD, 0x11,
0xF4, 0x47, 0xDC, 0xA7, 0xEC, 0xCF, 0x50, 0xC0};
static void
shuffle1(buf32 temp, unsigned char *target)
{
short b4;
unsigned char b3;
int s, b2, i;
b4 = 0;
for (b2 = 0; b2 <= 1; ++b2)
{
for (s = 0; s <= 31; ++s)
{
b3 = (temp[s] + b4) ^ (temp[(s + b4) & 31] - encryptkeys[s]);
b4 = b4 + b3;
temp[s] = b3;
}
}
for (i = 0; i <= 15; ++i)
{
target[i] = encrypttable[temp[2 * i]]
| (encrypttable[temp[2 * i + 1]] << 4);
}
}
static void
shuffle(const unsigned char *lon, const unsigned char *buf, int buflen,
unsigned char *target)
{
int b2, d, s;
buf32 temp;
while ((buflen > 0)
&& (buf[buflen - 1] == 0))
{
buflen = buflen - 1;
}
for (s = 0; s < 32; s++)
{
temp[s] = 0;
}
d = 0;
while (buflen >= 32)
{
for (s = 0; s <= 31; ++s)
{
temp[s] = temp[s] ^ buf[d];
d = d + 1;
}
buflen = buflen - 32;
}
b2 = d;
if (buflen > 0)
{
for (s = 0; s <= 31; ++s)
{
if (d + buflen == b2)
{
b2 = d;
temp[s] = temp[s] ^ encryptkeys[s];
} else
{
temp[s] = temp[s] ^ buf[b2];
b2 = b2 + 1;
}
}
}
for (s = 0; s <= 31; ++s)
temp[s] = temp[s] ^ lon[s & 3];
shuffle1(temp, target);
}
static void
nw_encrypt(const unsigned char *fra,
const unsigned char *buf,
unsigned char *til)
{
buf32 k;
int s;
shuffle(&(fra[0]), buf, 16, &(k[0]));
shuffle(&(fra[4]), buf, 16, &(k[16]));
for (s = 0; s <= 15; ++s)
k[s] = k[s] ^ k[31 - s];
for (s = 0; s <= 7; ++s)
til[s] = k[s] ^ k[15 - s];
}

100
sutil/nwsfind.c Normal file
View File

@@ -0,0 +1,100 @@
/*
* nwsfind.c
*
* Find a NetWare server and open a route to it.
* This tool can safely be setuid root, if normal users should be able to
* access any NetWare server.
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include "ncplib.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
static char *progname;
static void
usage(void)
{
fprintf(stderr, "usage: %s [server]\n", progname);
}
static void
help(void)
{
printf("\n");
printf("usage: %s [server]\n", progname);
printf("\n"
"-t Server type, default: File server\n"
"-h Print this help text\n"
"\n");
}
static void
swallow_error(const char *name, long code, const char *format, va_list arg)
{
printf("%s ", error_message(code));
vfprintf(stdout, format, arg);
putchar('\n');
return;
}
int
main(int argc, char *argv[])
{
char *server = NULL;
int object_type = NCP_BINDERY_FSERVER;
struct sockaddr_ipx *result;
long err;
int opt;
progname = argv[0];
set_com_err_hook(swallow_error);
while ((opt = getopt(argc, argv, "t:")) != EOF)
{
switch (opt)
{
case 't':
object_type = atoi(optarg);
break;
case 'h':
case '?':
help();
exit(1);
default:
usage();
exit(1);
}
}
if (optind < argc - 1)
{
usage();
exit(1);
}
if (optind == argc - 1)
{
server = argv[optind];
if (strlen(server) >= NCP_BINDERY_NAME_LEN)
{
com_err(argv[0], ENAMETOOLONG, "server name too long");
exit(1);
}
}
result = ncp_find_server(&server, object_type, &err);
if (result == NULL)
{
com_err(argv[0], err, "when trying to find server");
exit(1);
}
ipx_print_saddr(result);
printf(" %s\n", server);
return 0;
}

View File

@@ -2,71 +2,46 @@
# Makefile for the linux ncp-filesystem routines.
#
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy npasswd
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy nwpasswd
USERUTILS += nwbols nwbocreate nwborm nwboprops
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd
USERUTILS += nwgrant nwrevoke
UIDUTILS = ncpmount ncpumount
USERUTILS += nwbpcreate nwbprm nwbpvalues nwbpadd nwbpset
USERUTILS += nwgrant nwrevoke nwuserlist nwrights nwauth
USERUTILS += nwfstime nwvolinfo
SBINUTILS = nwmsg
UTIL_EXECS = $(USERUTILS) $(UIDUTILS) $(SBINUTILS)
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
UTILS = $(USERUTILS) $(SBINUTILS) ncptest
#CFLAGS = -Wall $(INCLUDES) $(KERNELD) -g -DNCPFS_VERSION=\"$(VERSION)\"
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -O2 -DNCPFS_VERSION=\"$(VERSION)\"
CC = gcc
ifeq ($(HAVE_ELF),yes)
NCP_LIB = libncp.so.1.0
else
NCP_LIB = libncp.a
LIBDEP = ../lib/libncp.a
endif
default:
make -C ..
all: $(UTILS) ncptest
install: all
for i in $(UTIL_EXECS); \
do install $(INTERM_BINDIR)/$$i -m 755 $(BINDIR); done
for i in $(UIDUTILS); \
do install $(INTERM_BINDIR)/$$i -m 4755 $(BINDIR); done
for i in $(USERUTILS); \
do install $$i -m 755 $(BINDIR); done
for i in $(SBINUTILS); \
do install $(INTERM_BINDIR)/$$i -m 755 $(SBINDIR); done
do install $$i -m 755 $(SBINDIR); done
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) libncp.a
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) -L. -lncp
$(UTILS): %: %.o $(LIBDEP)
$(CC) -o $@ $(addsuffix .o,$@) -L../lib -lncp
ncplib.o: ncplib.c ncplib.h ncplib_err.h
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
com_err/init_et.c
libncp.a: ncplib.o ncplib_err.o $(COM_ERR_CFILES)
make -C com_err
ar r libncp.a ncplib.o ncplib_err.o \
com_err/com_err.o com_err/error_message.o com_err/et_name.o \
com_err/init_et.o
ncplib_err.h: ncplib_err.et
com_err/compile_et ncplib_err
ncplib_err.c: ncplib_err.et
com_err/compile_et ncplib_err
test: test.o ncplib.o
$(CC) -o test test.o ncplib.o
ncptest: ncptest.o libncp.a
$(CC) -o ncptest ncptest.o -L. -lncp
dep: ncplib_err.h
make -C com_err dep
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
make -C com_err clean
rm -f *.o *~ slist test ncptest ncplib_err.[ch] libncp.a
rm -f *.o *~ $(UTILS)
mrproper: clean
make -C com_err mrproper
rm -f $(UTILS) .depend $(DISTFILE)
rm -f .depend
#
# include a dependency file if one exists

View File

@@ -1 +0,0 @@
com_err/com_err.h

File diff suppressed because it is too large Load Diff

View File

@@ -1,481 +0,0 @@
/*
* ncplib.h
*
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
#ifndef _NCPLIB_H
#define _NCPLIB_H
#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#include "ipxlib.h"
#include "com_err.h"
#ifndef memzero
#include <string.h>
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif
void
str_upper(char *name);
enum connect_state {
NOT_CONNECTED = 0,
CONN_PERMANENT,
CONN_TEMPORARY
};
struct ncp_conn {
enum connect_state is_connected;
char server[NCP_BINDERY_NAME_LEN];
char user [NCP_BINDERY_NAME_LEN];
struct ncp_fs_info i;
/* Fields for use with permanent connections */
int mount_fid;
char mount_point[MAXPATHLEN];
/* Fields for use with temporary connections */
int ncp_sock;
int wdog_sock;
int wdog_pid;
__u8 sequence;
int completion;
int conn_status;
int reply_size;
/* Fields used to setup ncp requests */
int current_size;
int has_subfunction;
int verbose;
int ncp_reply_size;
int lock;
char packet[NCP_PACKET_SIZE];
};
struct ncp_conn_spec {
char server[NCP_BINDERY_NAME_LEN];
char user[NCP_BINDERY_NAME_LEN];
uid_t uid;
int login_type; /* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */
char password[NCP_BINDERY_NAME_LEN];
};
struct ncp_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);
/* 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_get_connlist(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
int *returned_no, __u8 conn_numbers[256]);
long
ncp_send_broadcast(struct ncp_conn *conn,
__u8 no_conn, const __u8 *connections,
const char *message);
long
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
struct ncp_bindery_object *target);
long
ncp_get_bindery_object_name(struct ncp_conn *conn,
__u32 object_id,
struct ncp_bindery_object *target);
long
ncp_scan_bindery_object(struct ncp_conn *conn,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target);
long
ncp_create_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 object_security,
__u8 object_status);
long
ncp_delete_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name);
long
ncp_change_object_security(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 security);
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));
__u8 LastIntruder[8] __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);
long
ncp_login_encrypted(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
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 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_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_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_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);
#endif /* _NCPLIB_H */

View File

@@ -1,603 +0,0 @@
/*
* nwmount.c
*
* Copyright (C) 1995 by Volker Lendecke
*
* 1/20/96 - Steven N. Hirsch (hirsch@emba.uvm.edu)
*
* If the ncpfs support is not loaded and we are using kerneld to
* autoload modules, then we don't want to do it here. I added
* a conditional which leaves out the test and load code.
*
* Even if we _do_ want ncpmount to load the module, passing a
* fully-qualified pathname to modprobe causes it to bypass a
* path search. This may lead to ncpfs.o not being found on
* some systems.
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
/* #include <sys/wait.h> */ /* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
#include <linux/ipx.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ncplib.h"
#include "com_err.h"
static char *progname;
static void usage(void);
static void help(void);
#ifndef HAVE_KERNELD
/* Returns 0 if the filesystem is in the kernel after this routine
completes */
static int
load_ncpfs(void)
{
FILE *ffs;
char s[1024];
char *p, *p1;
pid_t pid;
int status;
/* Check if ncpfs is in the kernel */
ffs = fopen("/proc/filesystems", "r");
if (ffs == NULL)
{
perror("Error: \"/proc/filesystems\" could not be read:");
return -1;
}
p = NULL;
while (! feof(ffs))
{
p1 = fgets(s, sizeof(s), ffs);
if (p1)
{
p = strstr(s, "ncpfs");
if (p)
{
break;
}
}
}
fclose(ffs);
if (p)
{
return 0;
}
/* system() function without signal handling, from Stevens */
if ((pid = fork()) < 0)
{
return 1;
}
else if (pid == 0)
{
/* child */
execl("/sbin/modprobe", "modprobe", "ncpfs", NULL);
_exit(127); /* execl error */
}
else
{
/* parent */
while (waitpid(pid, &status, 0) < 0)
{
if (errno != EINTR)
{
status = -1;
break;
}
}
}
return status;
}
#endif /* HAVE_KERNELD */
/* Check whether user is allowed to mount on the specified mount point */
static int
mount_ok(struct stat *st)
{
if (!S_ISDIR(st->st_mode))
{
errno = ENOTDIR;
return -1;
}
if ( (getuid() != 0)
&& ( (getuid() != st->st_uid)
|| ((st->st_mode & S_IRWXU) != S_IRWXU)))
{
errno = EPERM;
return -1;
}
return 0;
}
int
main(int argc, char *argv[])
{
struct ncp_mount_data data;
struct stat st;
char mount_name[256];
int fd, result;
struct sockaddr_ipx addr;
struct sockaddr_ipx *server_addr;
int addrlen;
int upcase_password;
long err;
int um;
unsigned int flags;
char mount_point[MAXPATHLEN];
struct mntent ment;
FILE *mtab;
char *tmp_mount;
char *server = NULL;
char *user = NULL;
char *password = NULL;
struct ncp_conn_spec *spec;
uid_t conn_uid = getuid();
struct ncp_conn *conn;
int opt;
progname = argv[0];
memzero(data); memzero(spec);
if (geteuid() != 0)
{
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
data.uid = getuid();
data.gid = getgid();
um = umask(0);
umask(um);
data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
data.dir_mode = 0;
data.flags |= NCP_MOUNT_SOFT;
data.time_out = 60;
data.retry_count = 5;
upcase_password = 1;
while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nhvV:t:r:"))
!= EOF)
{
switch (opt)
{
case 'C':
upcase_password = 0;
break;
case 'S':
if (strlen(optarg) >= sizeof(spec->server))
{
fprintf(stderr, "Servername too long:%s\n",
optarg);
return 1;
}
server = optarg;
break;
case 'U':
if (strlen(optarg) >= sizeof(spec->user))
{
fprintf(stderr, "Username too long: %s\n",
optarg);
return 1;
}
user = optarg;
break;
case 'c':
if (isdigit(optarg[0]))
{
conn_uid = atoi(optarg);
}
else
{
struct passwd *pwd = getpwnam(optarg);
if (pwd == NULL)
{
fprintf(stderr, "Unknown user: %s\n",
optarg);
return 1;
}
conn_uid = pwd->pw_uid;
}
break;
case 'u':
if (isdigit(optarg[0]))
{
data.uid = atoi(optarg);
}
else
{
struct passwd *pwd = getpwnam(optarg);
if (pwd == NULL)
{
fprintf(stderr, "Unknown user: %s\n",
optarg);
return 1;
}
data.uid = pwd->pw_uid;
}
break;
case 'g':
if (isdigit(optarg[0]))
{
data.gid = atoi(optarg);
}
else
{
struct group *grp = getgrnam(optarg);
if (grp == NULL)
{
fprintf(stderr, "Unknown group: %s\n",
optarg);
return 1;
}
data.gid = grp->gr_gid;
}
break;
case 'f':
data.file_mode = strtol(optarg, NULL, 8);
break;
case 'd':
data.dir_mode = strtol(optarg, NULL, 8);
break;
case 'P':
if (strlen(optarg) >= sizeof(spec->password))
{
printf("password too long\n");
exit(1);
}
password = optarg;
break;
case 'V':
if (strlen(optarg) >= sizeof(data.mounted_vol))
{
printf("Volume too long: %s\n", optarg);
exit(1);
}
strcpy(data.mounted_vol, optarg);
break;
case 'n':
password = "";
break;
case 't':
data.time_out = atoi(optarg);
break;
case 'r':
data.retry_count = atoi(optarg);
break;
case 'h':
help();
exit(1);
case 'v':
fprintf(stderr, "ncpfs version %s\n", NCPFS_VERSION);
exit(1);
default:
usage();
return -1;
}
}
if ((spec = ncp_find_conn_spec(server,user,password,1, data.uid, &err))
== NULL)
{
com_err(progname, err, "in find_conn_spec");
exit(1);
}
if (upcase_password != 0)
{
str_upper(spec->password);
}
if (optind != argc-1)
{
usage();
return -1;
}
realpath(argv[optind], mount_point);
if (stat(mount_point, &st) == -1)
{
fprintf(stderr, "could not find mount point %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
if (mount_ok(&st) != 0)
{
fprintf(stderr, "cannot to mount on %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
#ifndef HAVE_KERNELD
/* Check if the ncpfs filesystem is in the kernel. If not, attempt
* to load the ncpfs module */
if (load_ncpfs() != 0)
{
fprintf(stderr, "Error: Unable to load ncpfs, exiting...\n");
exit(1);
}
#endif
data.version = NCP_MOUNT_VERSION;
data.mounted_uid = conn_uid;
memcpy(data.server_name, spec->server, sizeof(data.server_name));
if (data.dir_mode == 0)
{
data.dir_mode = data.file_mode;
if ((data.dir_mode & S_IRUSR) != 0)
data.dir_mode |= S_IXUSR;
if ((data.dir_mode & S_IRGRP) != 0)
data.dir_mode |= S_IXGRP;
if ((data.dir_mode & S_IROTH) != 0)
data.dir_mode |= S_IXOTH;
}
if ((tmp_mount = ncp_find_permanent(spec)) != NULL)
{
fprintf(stderr,
"You already have mounted server %s\nas user "
"%s\non mount point %s\n", spec->server, spec->user,
tmp_mount);
exit(1);
}
if ((server_addr = ncp_find_fileserver(spec->server, &err)) == NULL)
{
com_err("ncpmount", err, "when trying to find %s",
spec->server);
exit(1);
}
data.serv_addr = *server_addr;
data.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.ncp_fd == -1)
{
com_err("ncpmount", err, "opening ncp_socket");
exit(1);
}
data.wdog_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.wdog_fd == -1)
{
fprintf(stderr, "could not open wdog socket: %s\n",
strerror(errno));
exit(1);
}
memzero(addr);
addr.sipx_type = NCP_PTYPE;
if (bind(data.ncp_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
fprintf(stderr, "\nbind: %s\n",
strerror(errno));
fprintf(stderr,
"\nMaybe you want to use \n"
"ipx_configure --auto_interface=on --auto_primary=on\n"
"and try again after waiting a minute.\n\n");
exit(1);
}
addrlen = sizeof(addr);
if (getsockname(data.ncp_fd, (struct sockaddr *)&addr, &addrlen)==-1)
{
perror("getsockname ncp socket");
close(data.ncp_fd); close(data.wdog_fd);
exit(1);
}
addr.sipx_port = htons(ntohs(addr.sipx_port) + 1);
if (bind(data.wdog_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
fprintf(stderr, "bind(wdog_sock, ): %s\n",
strerror(errno));
exit(1);
}
#if NCP_MOUNT_VERSION>1
data.message_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.message_fd == -1)
{
fprintf(stderr, "could not open message socket: %s\n",
strerror(errno));
exit(1);
}
addr.sipx_port = htons(ntohs(addr.sipx_port) + 1);
if (bind(data.message_fd, (struct sockaddr *)&addr,sizeof(addr)) == -1)
{
fprintf(stderr, "bind(message_sock, ): %s\n",
strerror(errno));
exit(1);
}
if (strlen(mount_point) < sizeof(data.mount_point))
{
strcpy(data.mount_point, mount_point);
}
#endif
flags = MS_MGC_VAL;
strcpy(mount_name, spec->server);
strcat(mount_name, "/");
strcat(mount_name, spec->user);
result = mount(mount_name, mount_point, "ncpfs", flags, (char *)&data);
if (result < 0)
{
printf("mount failed\n");
exit(1);
}
if ((conn = ncp_open_mount(mount_point, &err)) == NULL)
{
com_err("ncpmount", err, "attempt to open mount point");
umount(mount_point);
exit(1);
}
if ((err = ncp_login_user(conn, spec->user, spec->password)) != 0)
{
struct nw_property p;
struct ncp_prop_login_control *l
= (struct ncp_prop_login_control *)&p;
if (conn->completion != NCP_GRACE_PERIOD)
{
com_err("ncpmount", err, "in login");
fprintf(stderr, "Login denied\n");
ncp_close(conn);
umount(mount_point);
exit(1);
}
fprintf(stderr, "Your password has expired\n");
if ((err = ncp_read_property_value(conn, NCP_BINDERY_USER,
spec->user, 1,
"LOGIN_CONTROL", &p)) == 0)
{
fprintf(stderr, "You have %d login attempts left\n",
l->GraceLogins);
}
}
if ((err = ioctl(conn->mount_fid, NCP_IOC_CONN_LOGGED_IN, NULL)) != 0)
{
com_err("ncpmount", err, "in logged_indication");
ncp_close(conn);
umount(mount_point);
exit(1);
}
ncp_close(conn);
ment.mnt_fsname = mount_name;
ment.mnt_dir = mount_point;
ment.mnt_type = "ncpfs";
ment.mnt_opts = "rw";
ment.mnt_freq = 0;
ment.mnt_passno= 0;
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
{
fprintf(stderr, "Can't get "MOUNTED"~ lock file");
exit(1);
}
close(fd);
if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
{
fprintf(stderr, "Can't open " MOUNTED);
exit(1);
}
if (addmntent(mtab, &ment) == 1)
{
fprintf(stderr, "Can't write mount entry");
exit(1);
}
if (fchmod(fileno(mtab), 0644) == -1)
{
fprintf(stderr, "Can't set perms on "MOUNTED);
exit(1);
}
endmntent(mtab);
if (unlink(MOUNTED"~") == -1)
{
fprintf(stderr, "Can't remove "MOUNTED"~");
exit(1);
}
return 0;
}
static void
usage(void)
{
printf("usage: %s [options] mount-point\n", progname);
printf("Try `%s -h' for more information\n", progname);
}
static void
help(void)
{
printf("\n");
printf("usage: %s [options] mount-point\n", progname);
printf("\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-V volume Volume to mount, for NFS re-export\n"
"-u uid uid the mounted files get\n"
"-g gid gid the mounted files get\n"
"-f mode permission the files get (octal notation)\n"
"-d mode permission the dirs get (octal notation)\n"
"-c uid uid to identify the connection to mount on\n"
" Only makes sense for root\n"
"-t time_out Waiting time (in 1/100s) to wait for\n"
" an answer from the server. Default: 60\n"
"-r retry_count Number of retry attempts. Default: 5\n"
"-C Don't convert password to uppercase\n"
"-P password Use this password\n"
"-n Do not use any password\n"
" If neither -P nor -n are given, you are\n"
" asked for a password.\n"
"-h print this help text\n"
"-v print ncpfs version number\n"
"\n");
}

View File

@@ -19,7 +19,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
/* #include <sys/wait.h> */ /* generates a warning here */
/* #include <sys/wait.h> *//* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <unistd.h>
@@ -41,7 +41,8 @@ extern pid_t waitpid(pid_t, int *, int);
void
test_connlist(struct ncp_conn *conn)
{
__u8 conn_list[256] = {0,};
__u8 conn_list[256] =
{0,};
int no;
ncp_get_connlist(conn, NCP_BINDERY_USER, "SUPERVISOR", &no,
@@ -52,7 +53,8 @@ test_connlist(struct ncp_conn *conn)
void
test_send(struct ncp_conn *conn)
{
__u8 conn_list[256] = {0,};
__u8 conn_list[256] =
{0,};
int no;
if (ncp_get_connlist(conn, NCP_BINDERY_USER, "ME", &no,
@@ -60,7 +62,6 @@ test_send(struct ncp_conn *conn)
{
no = 0;
}
if (no > 0)
{
ncp_send_broadcast(conn, no, conn_list, "Hallo");
@@ -85,21 +86,18 @@ test_create(struct ncp_conn *conn)
printf("lookup public error\n");
return;
}
if (ncp_alloc_short_dir_handle(conn, &me, NCP_ALLOC_TEMPORARY,
&dir_handle) != 0)
{
printf("alloc_dir_handle error\n");
return;
}
if (ncp_create_file(conn, dir_handle, "BLUB.TXT", 0,
&new_file) != 0)
{
printf("create error\n");
return;
}
if (ncp_dealloc_dir_handle(conn, dir_handle) != 0)
{
printf("dealloc error\n");
@@ -114,15 +112,15 @@ test_change(struct ncp_conn *conn)
unsigned char ncp_key[8];
struct ncp_bindery_object user;
if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) {
if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0)
{
return result;
}
if ((result = ncp_get_bindery_object_id(conn, 1,
"ME", &user)) != 0) {
"ME", &user)) != 0)
{
return result;
}
if ((result = ncp_change_login_passwd(conn, &user, ncp_key,
"MEE", "ME")) != 0)
{
@@ -131,6 +129,92 @@ test_change(struct ncp_conn *conn)
return 0;
}
void
test_readdir(struct ncp_conn *conn)
{
struct nw_info_struct sys;
struct nw_info_struct blub;
struct ncp_search_seq seq;
struct nw_info_struct entry;
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0)
{
printf("lookup error\n");
return;
}
if (ncp_do_lookup(conn, &sys, "BLUB", &blub) != 0)
{
printf("lookup blub error\n");
return;
}
if (ncp_initialize_search(conn, &sys, 0, &seq) != 0)
{
printf("init error\n");
return;
}
while (ncp_search_for_file_or_subdir(conn, &seq, &entry) == 0)
{
struct nw_info_struct nfs;
printf("found: %s\n", entry.entryName);
if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_NFS,
0x8006, RIM_ALL,
entry.volNumber,
entry.DosDirNum,
NULL,
&nfs) == 0)
{
printf("nfs name: %s\n", nfs.entryName);
}
if (ncp_obtain_file_or_subdir_info(conn, NW_NS_DOS, NW_NS_OS2,
0x8006, RIM_ALL,
entry.volNumber,
entry.DosDirNum,
NULL,
&nfs) == 0)
{
printf("os2 name: %s\n", nfs.entryName);
}
}
}
void
test_rights(struct ncp_conn *conn)
{
struct nw_info_struct sys;
struct nw_info_struct me;
__u16 rights;
if (ncp_do_lookup(conn, NULL, "SYS", &sys) != 0)
{
printf("lookup error\n");
return;
}
if (ncp_do_lookup(conn, &sys, "ME", &me) != 0)
{
printf("lookup me error\n");
return;
}
if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006,
sys.volNumber, sys.DosDirNum, NULL,
&rights) != 0)
{
printf("get sys rights error\n");
return;
}
printf("sys right: %4.4x\n", rights);
if (ncp_get_eff_directory_rights(conn, 0, 0, 0x8006,
me.volNumber, me.DosDirNum, NULL,
&rights) != 0)
{
printf("get me rights error\n");
return;
}
printf("me right: %4.4x\n", rights);
return;
}
int
main(int argc, char *argv[])
{
@@ -142,8 +226,7 @@ main(int argc, char *argv[])
com_err(argv[0], err, "in ncp_initialize");
return 1;
}
test_change(conn);
test_rights(conn);
ncp_close(conn);
return 0;
}

View File

@@ -1,180 +0,0 @@
/*
* nwumount.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/types.h>
/* #include <sys/wait.h> */ /* generates a warning here */
extern pid_t waitpid(pid_t, int *, int);
#include <sys/errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_mount.h>
#include <linux/ncp_fs.h>
static char *progname;
static void
usage(void)
{
printf("usage: %s mount-point\n", progname);
}
static int
umount_ok(const char *mount_point)
{
int fid = open(mount_point, O_RDONLY, 0);
uid_t mount_uid;
if (fid == -1) {
fprintf(stderr, "Could not open %s: %s\n",
mount_point, strerror(errno));
return -1;
}
if (ioctl(fid, NCP_IOC_GETMOUNTUID, &mount_uid) != 0) {
fprintf(stderr, "%s probably not ncp-filesystem\n",
mount_point);
return -1;
}
if ( (getuid() != 0)
&& (mount_uid != getuid())) {
fprintf(stderr, "You are not allowed to umount %s\n",
mount_point);
return -1;
}
close(fid);
return 0;
}
/* Make a canonical pathname from PATH. Returns a freshly malloced string.
It is up the *caller* to ensure that the PATH is sensible. i.e.
canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse
we return unmodified. */
char *
canonicalize (const char *path)
{
char *canonical = malloc (PATH_MAX + 1);
if (path == NULL)
return NULL;
if (realpath (path, canonical))
return canonical;
strcpy (canonical, path);
return canonical;
}
int
main(int argc, char *argv[])
{
int fd;
char* mount_point;
struct mntent *mnt;
FILE* mtab;
FILE* new_mtab;
progname = argv[0];
if (geteuid() != 0) {
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
if (argc != 2) {
usage();
exit(1);
}
mount_point = canonicalize(argv[1]);
if (umount_ok(mount_point) != 0) {
exit(1);
}
if (umount(mount_point) != 0) {
fprintf(stderr, "Could not umount %s: %s\n",
mount_point, strerror(errno));
exit(1);
}
if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
{
fprintf(stderr, "Can't get "MOUNTED"~ lock file");
return 1;
}
close(fd);
if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
fprintf(stderr, "Can't open " MOUNTED ": %s\n",
strerror(errno));
return 1;
}
#define MOUNTED_TMP MOUNTED".tmp"
if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
strerror(errno));
endmntent(mtab);
return 1;
}
while ((mnt = getmntent(mtab)) != NULL) {
if (strcmp(mnt->mnt_dir, mount_point) != 0) {
addmntent(new_mtab, mnt);
}
}
endmntent(mtab);
if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
fprintf(stderr, "Error changing mode of %s: %s\n",
MOUNTED_TMP, strerror(errno));
exit(1);
}
endmntent(new_mtab);
if (rename(MOUNTED_TMP, MOUNTED) < 0) {
fprintf(stderr, "Cannot rename %s to %s: %s\n",
MOUNTED, MOUNTED_TMP, strerror(errno));
exit(1);
}
if (unlink(MOUNTED"~") == -1)
{
fprintf(stderr, "Can't remove "MOUNTED"~");
return 1;
}
return 0;
}

View File

@@ -19,7 +19,7 @@
static char *progname;
static void
usage(void);
usage(void);
static void help(void);
void
@@ -46,25 +46,25 @@ main(int argc, char *argv[])
progname = argv[0];
memzero(j); memzero(pj); memzero(q);
memzero(j);
memzero(pj);
memzero(q);
if ( (argc == 2)
if ((argc == 2)
&& (strcmp(argv[1], "-h") == 0))
{
help();
exit(0);
}
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing connection");
exit(1);
}
/*
* Fill in default values for print job
*/
j.j.TargetServerID = 0xffffffff; /* any server */
j.j.TargetServerID = 0xffffffff; /* any server */
/* at once */
memset(&(j.j.TargetExecTime), 0xff, sizeof(j.j.TargetExecTime));
j.j.JobType = htons(0);
@@ -78,10 +78,12 @@ main(int argc, char *argv[])
pj.Rows = htons(80);
strcpy(pj.FnameHeader, "stdin");
while ((opt = getopt(argc, argv, "hq:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
while ((opt = getopt(argc, argv, "h?q:d:p:b:f:l:r:c:t:F:TN")) != EOF)
{
switch (opt) {
switch (opt)
{
case 'h':
case '?':
help();
ncp_close(conn);
exit(1);
@@ -92,8 +94,7 @@ main(int argc, char *argv[])
{
strncpy(pj.Path, optarg,
sizeof(pj.Path));
}
else
} else
{
strcpy(pj.Path, optarg);
}
@@ -105,8 +106,7 @@ main(int argc, char *argv[])
{
strncpy(pj.BannerName, optarg,
sizeof(pj.BannerName));
}
else
} else
{
strcpy(pj.BannerName, optarg);
}
@@ -118,8 +118,7 @@ main(int argc, char *argv[])
{
strncpy(pj.FnameBanner, optarg,
sizeof(pj.FnameBanner));
}
else
} else
{
strcpy(pj.FnameBanner, optarg);
}
@@ -204,13 +203,12 @@ main(int argc, char *argv[])
{
strncpy(j.j.JobTextDescription, optarg,
sizeof(j.j.JobTextDescription));
}
else
} else
{
strcpy(j.j.JobTextDescription, optarg);
}
break;
default:
usage();
ncp_close(conn);
@@ -218,20 +216,18 @@ main(int argc, char *argv[])
}
}
if (optind != argc-1)
if (optind != argc - 1)
{
usage();
ncp_close(conn);
exit(1);
}
file_name = argv[optind];
if (strcmp(file_name, "-") == 0)
{
file = 0; /* stdin */
}
else
} else
{
file = open(file_name, O_RDONLY, 0);
if (file < 0)
@@ -240,13 +236,11 @@ main(int argc, char *argv[])
ncp_close(conn);
exit(1);
}
if (strlen(file_name) >= sizeof(pj.FnameHeader))
{
strncpy(pj.FnameHeader, file_name,
sizeof(pj.FnameHeader));
}
else
} else
{
strcpy(pj.FnameHeader, file_name);
}
@@ -257,8 +251,7 @@ main(int argc, char *argv[])
{
strncpy(pj.FnameBanner, file_name,
sizeof(pj.FnameBanner));
}
else
} else
{
strcpy(pj.FnameBanner, file_name);
}
@@ -276,40 +269,35 @@ main(int argc, char *argv[])
ncp_close(conn);
exit(1);
}
if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0)
{
printf("create error\n");
ncp_close(conn);
exit(1);
}
written = 0;
do
{
read_this_time = read(file, buf, sizeof(buf));
read_this_time = read(file, buf, sizeof(buf));
if (read_this_time < 0)
{
break;
}
if (ncp_write(conn, j.file_handle,
written, read_this_time, buf) < read_this_time)
{
break;
}
written += read_this_time;
} while (read_this_time > 0);
}
while (read_this_time > 0);
close(file);
if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) {
if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0)
{
printf("close error\n");
ncp_close(conn);
return;
}
ncp_close(conn);
return;
}
@@ -323,25 +311,25 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options] file\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options] file\n", progname);
printf("\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-q queue name Name of the printing queue to use\n"
"-d job desc Job description\n"
"-p path name Path name to appear on banner\n"
"-b bannername Banner name (up to 12 chars)\n"
"-f filename Filename to appear on banner\n"
"-l lines Number of lines per page\n"
"-r rows Number of rows per page\n"
"-t tab Number of spaces per tab\n"
"-T Print server tab expantion\n"
"-N Surpress print server form feeds\n"
"-F form # Form number to print on\n"
"-h print this help text\n"
"\n");
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-q queue name Name of the printing queue to use\n"
"-d job desc Job description\n"
"-p path name Path name to appear on banner\n"
"-b bannername Banner name (up to 12 chars)\n"
"-f filename Filename to appear on banner\n"
"-l lines Number of lines per page\n"
"-r rows Number of rows per page\n"
"-t tab Number of spaces per tab\n"
"-T Print server tab expantion\n"
"-N Surpress print server form feeds\n"
"-F form # Form number to print on\n"
"-h print this help text\n"
"\n");
}

View File

@@ -16,7 +16,8 @@ int
main(int argc, char **argv)
{
struct ncp_conn *conn;
__u8 conn_list[256] = {0,};
__u8 conn_list[256] =
{0,};
int no_conn;
char *message = NULL;
@@ -25,17 +26,15 @@ main(int argc, char **argv)
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
exit(1);
}
if (argc != 3)
{
fprintf(stderr, "usage: %s [options] user message\n", argv[0]);
ncp_close(conn);
exit(1);
}
user = argv[1];
message = argv[2];
@@ -46,14 +45,12 @@ main(int argc, char **argv)
ncp_close(conn);
exit(1);
}
if (no_conn == 0)
{
fprintf(stderr, "No connection found for %s\n", user);
ncp_close(conn);
exit(1);
}
if ((err = ncp_send_broadcast(conn, no_conn, conn_list, message)) != 0)
{
com_err(argv[0], err, "in send_broadcast");

124
util/nwauth.c Normal file
View File

@@ -0,0 +1,124 @@
/*
* nwauth.c
*
* Check a user/passwd against a NetWare server
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include "ncplib.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
static char *progname;
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-t type Object type (decimal value)\n"
"\n");
}
static void
swallow_error(const char *s, long x, const char *t, va_list arg)
{
return;
}
int
main(int argc, char *argv[])
{
struct ncp_conn_spec *spec;
struct ncp_conn *conn;
char *server = NULL;
char *object_name = NULL;
int object_type = NCP_BINDERY_USER;
long err;
char *str;
int opt;
progname = argv[0];
if (!isatty(0))
{
set_com_err_hook(swallow_error);
}
while ((opt = getopt(argc, argv, "h?S:U:t:")) != EOF)
{
switch (opt)
{
case 'S':
server = optarg;
break;
case 'U':
object_name = optarg;
break;
case 't':
object_type = atoi(optarg);
break;
case 'h':
case '?':
help();
exit(1);
default:
usage();
exit(1);
}
}
spec = ncp_find_conn_spec(server, object_name, "",
1, getuid(), &err);
if (spec == NULL)
{
com_err(argv[0], err, "when trying to find server");
exit(1);
}
if (ncp_find_fileserver(spec->server, &err) == NULL)
{
com_err(argv[0], err, "when trying to find server");
exit(1);
}
spec->login_type = object_type;
memset(spec->password, 0, sizeof(spec->password));
if (isatty(0))
{
str = getpass("Enter password: ");
if (strlen(str) >= sizeof(spec->password))
{
printf("Password too long\n");
exit(1);
}
strcpy(spec->password, str);
} else
{
fgets(spec->password, sizeof(spec->password), stdin);
}
str_upper(spec->password);
if ((conn = ncp_open(spec, &err)) == NULL)
{
com_err(argv[0], err, "when trying to open connection");
exit(1);
}
ncp_close(conn);
return 0;
}

View File

@@ -22,15 +22,15 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"\n"
"-o object_name Name of created object\n"
"-t type Object type (decimal value)\n"
@@ -63,8 +63,8 @@ parse_security(const char *security)
return 4;
}
return -1;
}
}
int
main(int argc, char *argv[])
{
@@ -76,20 +76,20 @@ main(int argc, char *argv[])
int read_sec = 1; /* logged read */
int write_sec = 3; /* supervisor write */
int result = 1;
int opt;
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "ho:t:r:w:")) != EOF)
while ((opt = getopt(argc, argv, "h?o:t:r:w:")) != EOF)
{
switch(opt) {
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -122,6 +122,7 @@ main(int argc, char *argv[])
}
break;
case 'h':
case '?':
help();
goto finished;
default:
@@ -136,25 +137,22 @@ main(int argc, char *argv[])
argv[0]);
goto finished;
}
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (ncp_create_bindery_object(conn, object_type, object_name,
(write_sec << 4) + read_sec, 0) != 0)
{
fprintf(stderr, "%s: Could not create the object\n", argv[0]);
}
else
} else
{
result = 0;
}
finished:
finished:
ncp_close(conn);
return result;
}

View File

@@ -25,17 +25,18 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"\n"
"-t type Object type to be listed (decimal)\n"
"-o object Object pattern\n"
"-v Verbose listing\n"
"\n");
}
@@ -59,19 +60,23 @@ main(int argc, char **argv)
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
return 1;
}
while ((opt = getopt(argc, argv, "hvt:")) != EOF)
while ((opt = getopt(argc, argv, "h?vt:o:")) != EOF)
{
switch(opt) {
switch (opt)
{
case 'h':
case '?':
help();
exit(1);
case 't':
type = atoi(optarg);
break;
case 'o':
pattern = optarg;
break;
case 'v':
verbose = 1;
break;
@@ -81,17 +86,11 @@ main(int argc, char **argv)
}
}
if (optind < argc-1)
if (optind < argc)
{
usage();
exit(1);
}
if (optind == argc-1)
{
pattern = argv[optind];
}
for (p = pattern; *p != '\0'; p++)
{
*p = toupper(*p);
@@ -106,17 +105,16 @@ main(int argc, char **argv)
if (verbose != 0)
{
printf("%s %08X %04X %d %02X %d\n",
o.object_name, (unsigned int)o.object_id,
(unsigned int)o.object_type,
o.object_name, (unsigned int) o.object_id,
(unsigned int) o.object_type,
o.object_flags, o.object_security,
o.object_has_prop);
}
else
} else
{
printf("%s %08X %04X\n",
o.object_name, (unsigned int)o.object_id,
(unsigned int)o.object_type);
}
o.object_name, (unsigned int) o.object_id,
(unsigned int) o.object_type);
}
}
ncp_close(conn);

View File

@@ -22,15 +22,15 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"\n"
"-o object_name Name of object inspected\n"
"-t type Object type (decimal value)\n"
@@ -47,7 +47,7 @@ main(int argc, char *argv[])
long err;
struct ncp_property_info info;
int result = 1;
int verbose = 0;
int opt;
@@ -56,13 +56,13 @@ main(int argc, char *argv[])
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "ho:t:v")) != EOF)
while ((opt = getopt(argc, argv, "h?o:t:v")) != EOF)
{
switch(opt) {
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -74,6 +74,7 @@ main(int argc, char *argv[])
verbose = 1;
break;
case 'h':
case '?':
help();
goto finished;
default:
@@ -88,14 +89,12 @@ main(int argc, char *argv[])
argv[0]);
goto finished;
}
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
info.search_instance = 0xffffffff;
while (ncp_scan_property(conn, object_type, object_name,
@@ -107,14 +106,13 @@ main(int argc, char *argv[])
info.property_name, info.property_flags,
info.property_security,
info.value_available_flag);
}
else
} else
{
printf("%s\n", info.property_name);
}
}
finished:
finished:
ncp_close(conn);
return result;
}

View File

@@ -22,15 +22,15 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"\n"
"-o object_name Name of object to be removed\n"
"-t type Object type (decimal value)\n"
@@ -46,20 +46,20 @@ main(int argc, char *argv[])
long err;
int result = 1;
int opt;
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "ho:t:")) != EOF)
while ((opt = getopt(argc, argv, "h?o:t:")) != EOF)
{
switch(opt) {
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -68,6 +68,7 @@ main(int argc, char *argv[])
object_type = atoi(optarg);
break;
case 'h':
case '?':
help();
goto finished;
default:
@@ -82,24 +83,21 @@ main(int argc, char *argv[])
argv[0]);
goto finished;
}
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (ncp_delete_bindery_object(conn, object_type, object_name) != 0)
{
fprintf(stderr, "%s: Could not delete the object\n", argv[0]);
}
else
} else
{
result = 0;
}
finished:
finished:
ncp_close(conn);
return result;
}

View File

@@ -22,15 +22,15 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options] [values]\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options] [values]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"\n"
"-o object_name Name of accessed object\n"
"-t type Object type (decimal value)\n"
@@ -63,13 +63,13 @@ main(int argc, char *argv[])
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "ho:t:p:v:")) != EOF)
while ((opt = getopt(argc, argv, "h?o:t:p:v:")) != EOF)
{
switch(opt) {
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -91,6 +91,7 @@ main(int argc, char *argv[])
value = optarg;
break;
case 'h':
case '?':
help();
goto finished;
default:
@@ -105,28 +106,24 @@ main(int argc, char *argv[])
argv[0]);
goto finished;
}
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (property_name == NULL)
{
fprintf(stderr, "%s: You must specify a property name\n",
argv[0]);
goto finished;
}
if (optind > argc-1)
if (optind > argc - 1)
{
fprintf(stderr, "%s: You must specify a property value\n",
argv[0]);
goto finished;
}
value = argv[optind];
optind += 1;
@@ -136,7 +133,6 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: Could not find property\n", argv[0]);
goto finished;
}
if ((info.property_flags & 2) != 0)
{
/* Property is of type SET */
@@ -149,7 +145,6 @@ main(int argc, char *argv[])
progname, property_name);
goto finished;
}
if (ncp_get_bindery_object_name(conn,
ntohl(strtol(value, NULL, 16)),
&o) != 0)
@@ -158,7 +153,6 @@ main(int argc, char *argv[])
progname, value);
goto finished;
}
if (ncp_add_object_to_set(conn, object_type, object_name,
property_name,
o.object_type, o.object_name) != 0)
@@ -166,12 +160,11 @@ main(int argc, char *argv[])
fprintf(stderr, "%s: could not add object %s\n",
progname, o.object_name);
goto finished;
}
}
else
}
} else
{
/* Property is of type ITEM */
char contents[255*128];
char contents[255 * 128];
int segno = 1;
int length;
@@ -188,8 +181,7 @@ main(int argc, char *argv[])
goto finished;
}
strcpy(contents, value);
}
else
} else
{
/* value is the byte count */
int i;
@@ -218,15 +210,15 @@ main(int argc, char *argv[])
for (segno = 1; segno <= 255; segno++)
{
struct nw_property segment;
int offset = (segno-1)*128;
int offset = (segno - 1) * 128;
if ( offset > length )
if (offset > length)
{
/* everything written */
break;
}
memcpy(segment.value, &(contents[offset]), 128);
segment.more_flag = segno*128 < length;
segment.more_flag = segno * 128 < length;
if (ncp_write_property_value(conn, object_type,
object_name,
property_name,
@@ -240,7 +232,7 @@ main(int argc, char *argv[])
}
result = 0;
finished:
finished:
ncp_close(conn);
return result;
}

View File

@@ -22,15 +22,15 @@ usage(void)
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"-U username Username sent to server\n"
"-P password Use this password\n"
"-n Do not use any password\n"
"-C Don't convert password to uppercase\n"
"\n"
"-o object_name Name of object\n"
"-t type Object type (decimal value)\n"
@@ -65,8 +65,8 @@ parse_security(const char *security)
return 4;
}
return -1;
}
}
int
main(int argc, char *argv[])
{
@@ -80,20 +80,20 @@ main(int argc, char *argv[])
int read_sec = 1; /* logged read */
int write_sec = 3; /* supervisor write */
int result = 1;
int opt;
progname = argv[0];
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "when initializing");
goto finished;
}
while ((opt = getopt(argc, argv, "ho:t:p:sr:w:")) != EOF)
while ((opt = getopt(argc, argv, "h?o:t:p:sr:w:")) != EOF)
{
switch(opt) {
switch (opt)
{
case 'o':
object_name = optarg;
str_upper(object_name);
@@ -139,6 +139,7 @@ main(int argc, char *argv[])
}
break;
case 'h':
case '?':
help();
goto finished;
default:
@@ -153,34 +154,30 @@ main(int argc, char *argv[])
argv[0]);
goto finished;
}
if (object_name == NULL)
{
fprintf(stderr, "%s: You must specify an object name\n",
argv[0]);
goto finished;
}
if (property_name == NULL)
{
fprintf(stderr, "%s: You must specify a property name\n",
argv[0]);
goto finished;
}
if (ncp_create_property(conn, object_type, object_name,
property_name,
property_is_set ? 2 : 0,
(write_sec << 4) + read_sec) != 0)
{
fprintf(stderr, "%s: Could not create the property\n",argv[0]);
}
else
fprintf(stderr, "%s: Could not create the property\n", argv[0]);
} else
{
result = 0;
}
finished:
finished:
ncp_close(conn);
return result;
}

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