Compare commits

..

5 Commits
v0.10 ... v0.15

Author SHA1 Message Date
ncpfs archive import
b8ce93c8bd Import ncpfs 0.15 2026-04-28 20:39:57 +02:00
ncpfs archive import
7bef99df0f Import ncpfs 0.14 2026-04-28 20:39:57 +02:00
ncpfs archive import
d31ec2ab61 Import ncpfs 0.13 2026-04-28 20:39:57 +02:00
ncpfs archive import
1ee60bade6 Import ncpfs 0.12 2026-04-28 20:39:57 +02:00
ncpfs archive import
20589ca203 Import ncpfs 0.11 2026-04-28 20:39:57 +02:00
36 changed files with 1832 additions and 453 deletions

BIN
.downloads/ncpfs-0.11.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-0.12.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-0.13.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-0.14.tgz Normal file

Binary file not shown.

BIN
.downloads/ncpfs-0.15.tgz Normal file

Binary file not shown.

17
BUGS
View File

@@ -3,6 +3,8 @@ them to be bugs.
But there are really problems that might be fixed in the future.
-------------------------------------------------------------------------------
'df' returns 0:
Free disk space is distributed among the volumes in NetWare. df is
only able to report one number per mounted filesystem. As connections
@@ -10,10 +12,19 @@ are quite expensive for NetWare (with lwared that might change ...), I
rejected the alternative to mount only a single volume for a unix
mount point. So I simply return 0.
-------------------------------------------------------------------------------
In your kernel log, there will appear messages like
If you use Linux 1.2.x, In your kernel log there will appear messages
like
Nov 25 16:09:08 lx01 kernel: alloc_skb called nonatomically from interrupt 0000002e
These are a bit annoying, but completely harmless. Maybe this will be
fixed in the future.
These are a bit annoying, but completely harmless.
-------------------------------------------------------------------------------
ncpfs has a problem with NetWare 4.1, when files are created. I think
NW4.1 does not like some of the creation mode bits. If somebody with
access to a NW4.1 server could compile the kernel module for 1.2 with
-DDEBUG_NCP=2, and send me the syslog output gzipped/uuencoded, I
might find out more about that problem.

24
Changes Normal file
View File

@@ -0,0 +1,24 @@
I only began this file with ncpfs-0.12. If you're interested in older
versions, you can find them on linux01.gwdg.de:/pub/ncpfs/old.
ncpfs-0.14 -> ncpfs-0.15
- A bug fixed that made normal mounting impossible. It was too late
yesterday. Sorry
- Manpage for pserver.c
ncpfs-0.13 -> ncpfs-0.14
- Improvements of manual pages by B. Galliart <bgallia@luc.edu> and
Terry Dawson <terry@perf.no.itg.telecom.com.au>
- fsinfo
- pserver.c. Please see this as ALPHA software. There is no
documentation, and it is not tested enough. But it might be useful for
you.
ncpfs-0.12 -> ncpfs-0.13
- support for automatic loading of ncpfs.o by kerneld.
Thanks to Steven N. Hirsch <hirsch@emba.uvm.edu>.
- A subtle problem in the read routines has been removed by Uwe Bonnes
<bon@elektron.ikp.physik.th-darmstadt.de>. Thanks a lot.

View File

@@ -6,8 +6,9 @@
TOPDIR = $(shell pwd)
BINDIR = $(TOPDIR)/bin
SUBDIRS = util ipx-0.75
BINDIR = /usr/local/bin
INTERM_BINDIR = $(TOPDIR)/bin
SUBDIRS = util ipx-0.75 man
#
# The following 2 lines are for those who use Kernel version 1.2.x.
@@ -15,10 +16,14 @@ SUBDIRS = util ipx-0.75
# the following lines. You have to recompile your kernel
# and say 'y' when 'make config' asks you for IPX and ncpfs.
#
SUBDIRS += kernel-1.2/src
INCLUDES = -I$(TOPDIR)/kernel-1.2
#SUBDIRS += kernel-1.2/src
#INCLUDES = -I$(TOPDIR)/kernel-1.2
export INCLUDES BINDIR
# If you are using kerneld to autoload ncp support,
# uncomment this (kerneld is in linux since about 1.3.57):
# KERNELD = -DHAVE_KERNELD
export INCLUDES BINDIR INTERM_BINDIR KERNELD
all:
for i in $(SUBDIRS); do make -C $$i; done
@@ -26,6 +31,9 @@ all:
dep:
for i in $(SUBDIRS); do make -C $$i dep; done
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`
@@ -34,7 +42,7 @@ clean:
for i in $(SUBDIRS); do make -C $$i clean; done
realclean: clean
rm -fr $(BINDIR)/* ncpfs.tgz
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
make -C util realclean
modules: ncpfs.o

58
README
View File

@@ -1,30 +1,18 @@
This is version 0.10 of ncpfs, a free NetWare client filesystem for
Linux.
The main change for this release is that the directory kernel-1.3 is
removed. Guess why? ncpfs is in the standard kernel since 1.3.53. But
please note that ncpfs does NOT work with 1.3.53. I sent a fix to
Linus, so it should work fine with 1.3.54, or 1.3.55.
I would like to invite you to write documentation. As those whose
native tongue is English might have noticed, my C is better than my
English. So I doubt that everything in the man/ subdirectory is
written very well. Please feel free to send me any comments about
that.
This is ncpfs, a free NetWare client filesystem for Linux. Besides
some little utilities it also contains nprint, which enables you to
print on NetWare print queues.
INSTALLATION
The installation of ncpfs depends on the kernel version you are
using. For kernel 1.2, you should simply type 'make' and look at
what's in the bin/ directory after that. Please be sure that your
kernel resides in /usr/src/linux, because the file kernel-1.2/sock.c
has to refer directly to it.
kernel resides in /usr/src/linux, because the file
kernel-1.2/src/sock.c has to refer directly to it.
If you use Kernel 1.3, please be sure that you use at least 1.3.54 (or
1.3.55, if 1.3.54 makes ncp connections hang). ncpfs does NOT work
with any earlier 1.3.x kernel, especially not with 1.3.53, although it
has a fs/ncpfs/ subdirectory.
If you use Kernel 1.3, please be sure that you use at least
1.3.54. ncpfs does NOT work with any earlier 1.3.x kernel, especially
not with 1.3.53, although this one has a fs/ncpfs/ subdirectory.
If you use Kernel 1.3.54 or later, you might have to recompile your
kernel. With these kernels, the kernel part of ncpfs is already
@@ -54,8 +42,8 @@ hand, note that there has to be a route to the internal network of
your server. Please see the file util/start_ipx for an example.
I use tools written by Greg Page, Caldera. I hope I did not do too
much harm to their business. For your convenience I included the file
ipx.tar made available by Caldera.
much harm to their business. For your convenience I included the
contents of the file ipx.tar made available by Caldera.
My main source of information is a book written in german by Manfred
Hill and Ralf Zessin, "Netzwerkprogrammierung in C", IWT Verlag GmbH,
@@ -75,6 +63,21 @@ free NetWare API for Linux! I would be happy to receive your comments
on this.
THANKS
I do not want to leave those unmentioned, who have helped me with
ncpfs.
The most enthusiastic user and tester is certainly Uwe Bonnes
<bon@elektron.ikp.physik.th-darmstadt.de>. So far he's the only one
who has contributed something, namely manpages and corretions to
existing manpages.
Ales Dyrak has written lwared, which was the initial start for ncpfs.
Alan Cox has found some bugs I would probably never have found.
LIMITATIONS (compare these with smbfs :-)
The limitations ncpfs has are the natural limitations of the NCP
@@ -96,3 +99,14 @@ different. You can never know when the client will access the file-id
you offered, so you would have to cache the inode numbers
indefinitely long. I think this should not be done in kernel mode, as
it would require an unlimited amount of RAM.
Those who looked at the kernel code a bit closer will have found out
that the last section is a little white lie. As I found out after the
first version of ncpfs, NetWare does indeed offer something like inode
numbers, although are only unique per volume. So one way to make ncpfs
re-exportable by nfs is to allocate a superblock per volume and show
the inode numbers to the user. I was just too lazy to do this
yet. Maybe once we will force Novell to make NetWare NFS
affordable... ;-)
Have fun with ncpfs!

View File

@@ -1,21 +1,20 @@
CFLAGS = -O2 -Wall
BINDIR = ../bin
UTILS = $(BINDIR)/ipx_configure $(BINDIR)/ipx_interface \
$(BINDIR)/ipx_internal_net $(BINDIR)/ipx_route
UTILS = $(INTERM_BINDIR)/ipx_configure $(INTERM_BINDIR)/ipx_interface \
$(INTERM_BINDIR)/ipx_internal_net $(INTERM_BINDIR)/ipx_route
all: $(UTILS)
$(BINDIR)/ipx_configure: ipx_configure.o
$(CC) -o $(BINDIR)/ipx_configure ipx_configure.o
$(INTERM_BINDIR)/ipx_configure: ipx_configure.o
$(CC) -s -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
$(BINDIR)/ipx_interface: ipx_interface.o
$(CC) -o $(BINDIR)/ipx_interface ipx_interface.o
$(INTERM_BINDIR)/ipx_interface: ipx_interface.o
$(CC) -s -o $(INTERM_BINDIR)/ipx_interface ipx_interface.o
$(BINDIR)/ipx_internal_net: ipx_internal_net.o
$(CC) -o $(BINDIR)/ipx_internal_net ipx_internal_net.o
$(INTERM_BINDIR)/ipx_internal_net: ipx_internal_net.o
$(CC) -s -o $(INTERM_BINDIR)/ipx_internal_net ipx_internal_net.o
$(BINDIR)/ipx_route: ipx_route.o
$(CC) -o $(BINDIR)/ipx_route ipx_route.o
$(INTERM_BINDIR)/ipx_route: ipx_route.o
$(CC) -s -o $(INTERM_BINDIR)/ipx_route ipx_route.o
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
@@ -26,7 +25,6 @@ clean:
install: $(UTILS)
for i in $(UTILS); \
do \
install --strip $$i /sbin; \
install $$i.8 /usr/man/man8; \
install --strip $$i $(BINDIR); \
done

View File

@@ -20,9 +20,9 @@ ARCH = i386
OBJS= dir.o inode.o file.o sock.o ioctl.o ncplib_kernel.o mmap.o
all: $(BINDIR)/ncpfs.o
all: $(INTERM_BINDIR)/ncpfs.o
$(BINDIR)/ncpfs.o: $(OBJS)
$(INTERM_BINDIR)/ncpfs.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
ncplib_kernel.o: ncplib_kernel.c ncplib_kernel.h

View File

@@ -567,6 +567,7 @@ ncp_init_root(struct ncp_server *server)
root->finfo.opened = 0;
i->attributes = aDIR;
i->dataStreamSize = 1024;
i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */
ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate));
@@ -624,6 +625,7 @@ ncp_find_inode(struct inode *dir, const char *name)
do
{
if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
&& (result->dir->finfo.i.volNumber == dir_info->volNumber)
&& (strcmp(result->finfo.i.entryName, name) == 0))
{
return result;
@@ -645,6 +647,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
struct ncp_inode_info *result_info;
int found_in_cache;
char name[len+1];
*result = NULL;
if (!dir || !S_ISDIR(dir->i_mode))
@@ -687,7 +691,10 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
}
}
result_info = ncp_find_inode(dir, __name);
memcpy(name, __name, len);
name[len] = 0;
result_info = ncp_find_inode(dir, name);
if (result_info != 0)
{
@@ -726,7 +733,7 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",
i, c_entry[i].i.entryName);
if (strcmp(c_entry[i].i.entryName, __name) == 0)
if (strcmp(c_entry[i].i.entryName, name) == 0)
{
DPRINTK("ncp_lookup: found in cache!\n");
finfo.i = c_entry[i].i;
@@ -740,20 +747,15 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
if (found_in_cache == 0)
{
char this_name[len+1];
memcpy(this_name, __name, len);
this_name[len] = 0;
str_upper(this_name);
str_upper(name);
DDPRINTK("ncp_lookup: do_lookup on %s/%s\n",
NCP_ISTRUCT(dir)->entryName, this_name);
NCP_ISTRUCT(dir)->entryName, name);
if (ncp_do_lookup(server,
dir->i_ino == (int)&(NCP_SERVER(dir)->root)
? NULL : NCP_ISTRUCT(dir),
this_name,
&(finfo.i)) != 0)
name, &(finfo.i)) != 0)
{
iput(dir);
return -ENOENT;

View File

@@ -583,7 +583,7 @@ ncp_read(struct ncp_server *server, const char *file_id,
*bytes_read = ntohs(ncp_reply_word(server, 0));
memcpy_tofs(target, ncp_reply_data(server, 2), *bytes_read);
memcpy_tofs(target, ncp_reply_data(server, 2+(offset&1)), *bytes_read);
ncp_unlock_server(server);
return 0;

16
man/Makefile Normal file
View File

@@ -0,0 +1,16 @@
MAN1= slist nprint pqlist
MAN5= nwclient
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net ipx_route
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
clean:

View File

@@ -1,6 +1,6 @@
.TH IPX_CONFIGURE 8 "IPX Utilities" "Caldera, Inc."
.SH NAME
ipx_configure \- query/configure IPX behavior
ipx_configure \- display/configure IPX behavior
.SH SYNOPSIS
.B ipx_configure
[\-\-help]
@@ -8,7 +8,7 @@ ipx_configure \- query/configure IPX behavior
[\-\-auto_primary=[on|off]]
.SH DESCRIPTION
.B ipx_configure
queries or configures IPX behavior with respect to automatic IPX
displays or configures IPX behavior with respect to automatic IPX
interface detection. IPX can be configured to automatically create
interfaces as they are detected. It can also be configured to
automatically select a primary interface when none is explicitly
@@ -23,15 +23,20 @@ arguments is described in the section
.SS OPTIONS
.TP
.I "\-\-auto_interface=[on|off]"
This argument either turns on or off the behavior of automatically creating
interfaces.
This argument enables or disables the feature that will automatically detect
whether IPX is use on a network interface. If
.B on
and IPX packets are seen on an interface that interface will be automatically
flagged as an IPX interface. The default setting is
.B off.
.TP
.I "\-\-auto_primary=[on|off]"
This argument either turns on or off the behavior of automatically selecting
a primary interface.
This argument enables or disables the feature that will automatically select
which IPX interface will be the primary IPX interface. The default setting is
.B off.
.TP
.I "\-\-help"
Print out information about utility.
Displays summarised usage instructions.
.SH FILES
.I /proc/net/ipx_interface
.SH BUGS

View File

@@ -1,6 +1,6 @@
.TH IPX_INTERFACE 8 "IPX Utilities" "Caldera, Inc."
.SH NAME
ipx_interface \- add, delete, or display an IPX interface
ipx_interface \- add, delete, or display IPX interface configuration.
.SH SYNOPSIS
.B ipx_interface
add [-p] device frame_type [network number]
@@ -15,11 +15,11 @@ check device frame_type
help
.SH DESCRIPTION
.B ipx_interface
adds, deletes, or displays IPX interfaces depending on the option selected.
adds, deletes, or displays the configuration of the specified IPX interface.
.P
An IPX interface is the item to which IPX sockets are bound.
An IPX interface corresponds to an IPX Network Number which corresponds
to a physical device and frame type. A sample IPX Interface would be:
An IPX interface has an associated IPX Network Number, a physical device
and frame type. A sample IPX Interface might look like:
.LP
Network Number: 0x00ABCDEF
.LP
@@ -35,22 +35,21 @@ or default interface.
.I add
This option is used to create an IPX interface. If the
.B -p
flag is used, the interface is made
.B
PRIMARY.
The network number can be optionally assigned. If it is not assigned, it
is set to 0 which indicates it should be detected from the traffic on the
network.
flag is used, the interface is flagged as the
.B PRIMARY
interface. The IPX network number may optionally be specified. If it is not
specified it is set to 0 which indicates it should be automatically detected
by analysis of the existing IPX traffic on the network.
.TP
.I del
This option is used to delete an IPX interface.
.TP
.I check
This option is used to display the device, frame type, and network number
of an IPX interface.
This option is used to display the network number associated with a specified
device and frame type combination.
.TP
.I help
This option displays information about the utility.
This option displays summarised usage instructions.
.SH FILES
.I /proc/net/ipx_interface /proc/net/ipx_route
.SH BUGS

View File

@@ -1,6 +1,6 @@
.TH IPX_ROUTE 8 "IPX Utilities" "Caldera, Inc."
.SH NAME
ipx_route \- add or delete IPX route
ipx_route \- add or delete an IPX route.
.SH SYNOPSIS
.B ipx_route
add target_network router_network router_node
@@ -10,11 +10,11 @@ del target_network
.SH DESCRIPTION
.B ipx_route
adds or deletes an IPX route.
The kernel IPX stores only one route per target network at a time.
The kernel IPX software stores only one route to any target network.
.SS OPTIONS
.TP
.I add
This option is used to set up the route to a target network.
This option is used to configure a route to a target network.
.TP
.I del
This option is used to delete the route to a target network.

View File

@@ -1,30 +1,27 @@
.TH NCPMOUNT 8 12/27/1995 ncpmount ncpmount
.SH NAME
ncpmount \- mount program for ncpfs
ncpmount \- mount all volumes of a specified Novell fileserver.
.SH SYNOPSIS
.B ncpmount
[
.B -h
] [
.B -S
.I server
] [
.B -h
] [
.B -n
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -s
.I server name
] [
.B -c
.I client name
] [
.B -U
.I user name
] [
.B -u
.I uid
] [
@@ -40,10 +37,11 @@ ncpmount \- mount program for ncpfs
mount-point
.SH DESCRIPTION
This program is an interface to the NCP filesystem.
This program is used to mount all volumes of the specified NetWare Fileserver
under the specified mount point.
.B ncpfs
is a filesystem which understands the NCP protocol. This is the
is a linux filesystem which understands the NCP protocol. This is the
protocol Novell NetWare clients use to talk to NetWare servers. ncpfs
was inspired by
.B lwared,
@@ -51,18 +49,23 @@ a free NetWare emulator for Linux written by Ales Dryak. See
ftp://klokan.sh.cvut.cz/pub/linux for this very intersting program.
.B ncpmount
looks up the file
when invoked with all appropriate arguments attaches, logs in and
mounts all of the volumes associated with the specified fileserver that are
readable by the user id under the specified mount point.
.B ncpmount
when invoked without any arguments specifying the fileserver, user id and
password checks the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please not that the access
permissions of .nwclient MUST be 600, for security reasons.
to find a file server, a user name and possibly a password to use for the
specified mount point. See nwclient(5) for more information. Please note
that the access permissions of .nwclient MUST be 600, for security reasons.
.SH OPTIONS
.B mount-point
.RS 3
.B mount-point
is the directory you want to mount the filesystem over. It's the same
as in the normal mount command.
is the directory you want to mount the filesystem over. Its function is the
the same as for a normal mount command.
If the real uid of the caller is not root,
.B ncpmount
@@ -90,42 +93,40 @@ is used to print out a short help text.
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
By default passwords are converted to uppercase before they are sent
to the server because most servers require this. This option disables this
feature ensuring that passwords are sent without any case conversion.
.RE
.B -n
.RS 3
.B -n
should be given to mount shares which do not require a password to log in.
must be specified for logins that do not have a password configured.
.RE
.B -P
.I password
.RS 3
You may want to give the password required by the server on the
command line. You should be careful to use passwords in scripts.
specifies the password to use for the Netware user id.
If neither
.B -n
nor
nor the
.B -P
are given, ncpmount prompts for a password. This makes it difficult to
use in scripts such as /etc/rc. But that's not ncpmount's fault, but a
general problem with the fact that you need a password on every
login. If anybody has a satisfying solution to this problem, please
tell me.
arguments are specified ncpmount will prompt for a password. This
makes it difficult to use in scripts such as /etc/rc. If you want to
have ncpmount work automatically from a script you must include the
appropriate option and be very careful to ensure that appopriate file
permissions are set for the script that includes your password to
ensure that others can not read it.
.RE
.B -U
.I user name
.RS 3
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about you NetWare user name.
Specifies the Netware user id to use when logging in to the fileserver. If
this option is not specified then ncpmount will attempt to login to the
fileserver using the Linux login id of the user invoking ncpmount.
.RE
.B -u
@@ -133,18 +134,37 @@ to tell the server about you NetWare user name.
.B -g
.I gid
.RS 3
Currently I did not implement a mapping from NetWare users/groups to
unix users/groups. Unix requires that each file has an owner
and a group it belongs to. With
ncpmount does not yet implement a scheme for mapping NetWare users/groups
to Linux users/groups. Linux requires that each file has an owner and group id.
With
.B -u
and
.B -g
you can tell ncpmount which id's it should assign to the files in the
mounted direcory.
mounted directory.
The defaults for these values are the current uid and gid.
.RE
.B -c
.I user name
.RS 3
.B -c
names the user who is the
.I owner
of the connection, where owner does not refer to file ownership (that
"owner" is set by the -u argument), but the owner of the mount, ie: who
is allowed to call ncpumount on this mount. The default owner of the
connection and the mount is the user who called ncpmount. This option
allows you to specify that some other user should be set as the owner.
In this this way it is possible to mount a public read-only directory,
but to allow the lp daemon to print on NetWare queues. This is
possible because only users who have write permissions on a directory
may issue ncp requests over a connection. The exception to this rule
is the 'mount owner', who is also granted 'request permission'.
.RE
.B -f
.I file mode,
.B -d
@@ -154,14 +174,11 @@ Like
.B -u
and
.B -g,
these options are also used to cover deficiencies in the
implementation of ncpfs. I did not implement a scheme to map NetWare
permissions to unix permissions. So ncpmount has to be told which
permissions it should assign to the mounted files and direcories. The
values have to be given as octal numbers. The default values are taken
from the current umask, where the file mode is the current umask, and
the dir mode adds execute permissions where the file mode gives read
permissions.
these options are used to determine what permissions should be assigned
files and directories of the mounted volumes. The values must be specified
as octal numbers. The default values are taken from the current umask, where
the file mode is the current umask, and the dir mode adds execute permissions
where the file mode gives read permissions.
Note that these permissions can differ from the rights the server
gives to us. If you do not have write permissions on the server, you
@@ -170,7 +187,9 @@ certainly cannot override the restrictions imposed by the server.
.RE
.SH NOTES
If you have difficulties in mounting, please make sure that you have configured your ipx subsystem correctly. It is especially important that there is a route to the internal network of your server.
You must configure the IPX subsystem before ncpmount will work.
It is especially important that there is a route to the internal network
of your server.
.SH ENVIRONMENT VARIABLES
.B USER / LOGNAME

View File

@@ -1,13 +1,14 @@
.TH NCPUMOUNT 8 12/27/1995 ncpumount ncpumount
.SH NAME
ncpumount \- umount for normal users
ncpumount \- unmount a NetWare filesystem mounted with ncpmount.
.SH SYNOPSIS
.B ncpumount
.B mount-point
.SH DESCRIPTION
With this program, normal users can unmount ncp-filesystems, provided
that it is suid root.
This utility unmounts a NetWare filesystem that was previously mounted
with the ncpmount utility. If the this utility is made suid root then
non-root users will also be able to make use of it.
.B ncpumount
has been written to give normal linux-users more control over their

View File

@@ -1,4 +1,4 @@
.TH NPRINT 8 12/27/1995 nprint nprint
.TH NPRINT 1 12/27/1995 nprint nprint
.SH NAME
nprint \- NetWare print client
.SH SYNOPSIS
@@ -9,24 +9,16 @@ nprint \- NetWare print client
] [
.B -h
] [
.B -n
] [
.B -P
.I password
] [
.B -C
] [
.B -S
.I server name
] [
.B -U
.I user name
] [
.B -P
.I password
] [
|
.B -n
] [
.B -C
] [
.B -q
.I queue name
] [
@@ -61,7 +53,7 @@ nprint \- NetWare print client
.B -F
.I form number
]
file
.B file
.SH DESCRIPTION
With
@@ -71,9 +63,12 @@ you can print files on print queues of a NetWare file server.
There are a lot of options, so you should probably wrap some default
configurations into some shell scripts.
As you will see, this manpage is not yet complete, but most of the
options should be self-explaining when you look at Novell's nprint
documentation. I promise to fix this with the next release :-).
.B nprint
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of .nwclient MUST be 600, for security reasons.
.SH OPTIONS
.B file
@@ -83,6 +78,12 @@ is the name of the file you want to print. If file is '-', or no
filename is given, standard input is used.
.RE
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
@@ -90,6 +91,56 @@ filename is given, standard input is used.
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 the print request at the server.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for the print request at the server. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, nprint
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if no password is required for the print request.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.B -q
.I queue name
.RS 3
.B queue name
is the name of the print queue to use at the print server. At
present, you must specify it in upper case characters.
.RE
.B -d
.I job description
.RS 3
.B job description
is the string that appears in pconsole when you list the jobs for the
print queue. It is also printed somewhere on the top of the banner
page.
.RE
.B -p
.I pathname
.RS 3
@@ -115,4 +166,57 @@ part of the banner page. Default: the name of the file that is
printed, or 'stdin'.
.RE
.B -l
.I lines
.RS 3
.B lines
is the number of lines to put on one page. Default: 66
.RE
.B -r
.I rows
.RS 3
.B rows
is the number of rows to put on one page. Default: 80
.RE
.B -c
.I copies
.RS 3
.B copies
tells the print server to the specified number of copies. Default: 1
.RE
.B -t
.I tabs
.RS 3
.B tabs
is the number of spaces to print for a Tab-Character. Default: 8
.RE
.B -T
.RS 3
tells the print server to expand Tab-Character and use 8 spaces
.RE
.B -N
.RS 3
tells the print server
.B not
to use Form Feeds
.RE
.B -F
.I form number
.RS 3
.B form number
is the the number of the form to be put into the printer. If it's
different from the one currently in the printer, your job is only
printed if a printer operator has put in the correct form.
.RE
.SH SEE ALSO
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
nprint was written by Volker Lendecke (lendecke@namu01.gwdg.de)

View File

@@ -13,8 +13,8 @@ connection. Lines beginning with # and empty lines are ignored as
comments.
Because you can store passwords in .nwclient, the user programs will
only scan .nwclient if ONLY the file owner has any access rights to
the file.
only scan .nwclient when only the file owner has access rights to
the file. The file must be have permissions 0600.
To specify a NWClient connection, the name of the file server, the
user name to be used and a password is necessary. The server name and
@@ -40,3 +40,16 @@ the the file server FS311 with user name ME on /mnt after asking the
user for a password.
\'nwmount -S cd-serv /cd' will silently mount the server cd-serv on /cd.
.B nprint
,
.B pqlist
and other user programs that require a valid login also look up
.I $HOME/.nwclient
to find a file server, a user name and possibly a password.
Please note that the access permissions of .nwclient MUST be 600, for
security reasons.
.SH SEE ALSO
.B ncpmount(8), ncpumount(8), slist(1), pqlist(1), nprint(1)

105
man/pqlist.1 Normal file
View File

@@ -0,0 +1,105 @@
.TH PQLIST 1 01/10/1996 pqlist pqlist
.SH NAME
pqlist \- List available NetWare print queues
.SH SYNOPSIS
.B pqlist
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.I pattern
]
.SH DESCRIPTION
.B pqlist
lists all the NetWare print queues available to you on some server.
If you are already connected to some server, this one is used.
If pqlist does not print to a tty, the decorative header line is
not printed, so that you can count the printing queue available
on your server by doing
pqlist -S server | wc -l
.B pqlist
looks up the file
.I $HOME/.nwclient
to find a file server, a user name and possibly a password. See
nwclient(5) for more information. Please note that the access
permissions of .nwclient MUST be 600, for security reasons.
.SH OPTIONS
.B pattern
.RS 3
.B pattern
is used to list only selected queues. You can use wildcards in the
pattern, but you have to be careful to prevent shell interpretation of
wildcards like '*'.
.RE
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user name
.RS 3
If the user name your NetWare administrator gave to you differs
from your unix user-id, you should use
.B -U
to tell the server about you NetWare user name.
.RE
.B -P
.I password
.RS 3
You may want to give the password required by the server on the
command line. You should be careful to use passwords in scripts.
.RE
.B -n
.RS 3
.B -n
should be given to mount shares which do not require a password to log in.
If neither
.B -n
nor
.B -P
are given, pqlist prompts for a password.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.SH SEE ALSO
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
pqlist was written by Volker Lendecke (lendecke@namu01.gwdg.de)

142
man/pserver.1 Normal file
View File

@@ -0,0 +1,142 @@
.TH PSERVER 1 02/10/1996 pserver pserver
.SH NAME
pserver \- NetWare print server
.SH SYNOPSIS
.B pserver
[
.B -S
.I server
] [
.B -h
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
] [
.B -q
.I queue name
] [
.B -c
.I command
] [
.B -j
.I job type
] [
.B -t
.I timeout
] [
.B -d
]
.SH DESCRIPTION
.B pserver
is a program that connects to print queues on NetWare servers and
feeds incoming print jobs to the Linux printing system.
.SH OPTIONS
.B -h
.RS 3
.B -h
is used to print out a short help text.
.RE
.B -S
.I server
.RS 3
.B server
is the name of the server you want to use.
.RE
.B -U
.I user
.RS 3
.B user
is the print server name at the server.
.RE
.B -P
.I password
.RS 3
.B password
is the password to use for the print server at the server. If neither
.B -n
nor
.B -P
are given, and the user has no open connection to the server, pserver
prompts for a password.
.RE
.B -n
.RS 3
.B -n
should be given if the print server does not require a password.
.RE
.B -C
.RS 3
By default, passwords are converted to uppercase before they are sent
to the server, because most servers require this. You can turn off
this conversion by
.B -C.
.RE
.B -q
.I queue name
.RS 3
.B queue name
is the name of the print queue you want to service.
.RE
.B -c
.I command
.RS 3
When a job is received from the print queue, pserver forks off a new
process, and feeds the job file to stdin.
.I command
is the printing command that is executed for each job. The default
command is 'lpr'.
.RE
.B -j
.I job type
.RS 3
Each job in a NetWare print queue has a job type. For print jobs, this
corresponds to the number of the form the job should be printed
on. You can tell pserver that it should only receive jobs for one
specific form from the queue. The default is -1, which means that
everything is received.
.RE
.B -t
.I timeout
.RS 3
Pserver is not informed by NetWare servers when new jobs arrive. So a
polling scheme has to be used. When there are no jobs to service,
.I timeout
tells pserver how long to wait between two requests. The default is 30
seconds. When a job is finished, pserver asks the NetWare server
immediately for a new job, and does not wait
.I timeout
seconds.
.RE
.B -d
.RS 3
Normally, pserver daemonizes itself.
.B -d
tells it not to do so. This is useful if you want to see the
diagnostic messages that are printed when a error occurs.
.RE
.SH SEE ALSO
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
pserver was written by Volker Lendecke (lendecke@namu01.gwdg.de)

43
man/slist.1 Normal file
View File

@@ -0,0 +1,43 @@
.TH SLIST 1 01/07/1996 slist slist
.SH NAME
slist \- Lists available NetWare Servers
.SH SYNOPSIS
.B slist
[
.I pattern
]
.SH DESCRIPTION
.B slist
lists all NetWare Servers available in your network.
If slist does not print to a tty, the decorative header line is not
printed, so that you can count the servers on your network by doing
slist | wc -l
.SH OPTIONS
.B pattern
.RS 3
.B pattern
is used to list only servers whose names match the specified pattern. For a
server to be listed, the pattern must match the full server name. You can use
wildcards for the pattern, but you must protect these wildcards from any
command line expansion by quoting. Case doesn't matter.
.RE
.SH EXAMPLE
.TP
slist "I*"
.TP
or
.TP
slist "i*"
List all available Netware servers on your Network, that begin with an "I".
.SH SEE ALSO
.B ncpmount(8), ncpumount(8), pqlist(1), nprint(1)
.SH CREDITS
slist was written by Volker Lendecke (lendecke@namu01.gwdg.de)

View File

@@ -1,15 +1,17 @@
Begin3
Title: ncpfs
Version: 0.10
Entered-date: 03. January 1996
Version: 0.15
Entered-date: 10. February 1996
Description: With ncpfs you can mount volumes of your novell
server under Linux.
server under Linux. You need kernel 1.2.x or
1.3.54 and above. ncpfs does NOT work with any 1.3.x
kernel below 1.3.54.
Keywords: filesystem kernel ncp novell netware
Author: lendecke@namu01.gwdg.de (Volker Lendecke)
Maintained-by: lendecke@namu01.gwdg.de (Volker Lendecke)
Primary-site: linux01.gwdg.de:/pub/ncpfs
Alternate-site: sunsite.unc.edu:/pub/system/Filesystems/
~63k ncpfs-0.10.tgz
~ 1k ncpfs-0.10.lsm
~70k ncpfs-0.15.tgz
~ 1k ncpfs-0.15.lsm
Copying-policy: GPL
End

View File

@@ -2,14 +2,21 @@
# Makefile for the linux ncp-filesystem routines.
#
UTIL_EXECS = ncpmount ncpumount nprint slist
UTILS = $(addprefix $(BINDIR)/,$(UTIL_EXECS))
UTIL_EXECS = ncpmount ncpumount nprint slist pqlist fsinfo pserver
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
UIDUTILS = ncpmount ncpumount
CFLAGS = -Wall $(INCLUDES) -O2
#CFLAGS = -Wall $(INCLUDES) $(KERNELD) -g
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -O2
CC = gcc
all: $(UTILS) ncptest
install: all
for i in $(UTIL_EXECS); \
do install --strip $(INTERM_BINDIR)/$$i -m 755 $(BINDIR); done
for i in $(UIDUTILS); do chmod 4755 $(BINDIR)/$$i; done
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) ncplib.o
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) ncplib.o
@@ -37,3 +44,4 @@ realclean: clean
ifeq (.depend,$(wildcard .depend))
include .depend
endif

78
util/fsinfo.c Normal file
View File

@@ -0,0 +1,78 @@
/*
* fsinfo.c
*
* Print the info strings of a server, maybe sometime more.
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include <stdio.h>
#include <unistd.h>
#include "ncplib.h"
int
main(int argc, char **argv)
{
struct ncp_conn conn;
int opt;
if (ncp_initialize(&conn, &argc, argv, 0) != 0)
{
perror("Could not open connection");
return 1;
}
while ((opt = getopt(argc, argv, "dt")) != EOF)
{
switch(opt)
{
case 'd':
{
char strings[512];
char *s;
if (ncp_get_file_server_description_strings(&conn,
strings)
!= 0)
{
perror("could not get strings");
ncp_close(&conn);
return 1;
}
s = strings;
while (s < strings+512)
{
if (strlen(s) == 0)
{
break;
}
puts(s);
s += strlen(s)+1;
}
break;
}
case 't':
{
time_t t;
if (ncp_get_file_server_time(&conn, &t) != 0)
{
perror("could not get server time");
ncp_close(&conn);
return 1;
}
fputs(ctime(&t), stdout);
break;
}
default:
printf("unknown option: %c\n", opt);
break;
}
}
ncp_close(&conn);
return 0;
}

View File

@@ -1,7 +1,7 @@
/*
* ncplib.c
*
* Copyright (C) 1995 by Volker Lendecke
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
@@ -34,8 +34,13 @@ extern pid_t wait(int *);
static int
ncp_negotiate_buffersize(struct ncp_conn *conn,
int size, int *target);
static int
ncp_login_object(struct ncp_conn *conn,
const unsigned char *username,
int login_type,
const unsigned char *password);
static void
void
str_upper(char *name)
{
while (*name) {
@@ -208,7 +213,7 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result,
goto finished;
}
memset(&addr, 0, sizeof(addr));
memzero(addr);
addr.sipx_family = AF_IPX;
addr.sipx_network = htonl(0x0);
addr.sipx_port = htons(0x0);
@@ -222,7 +227,7 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result,
*(unsigned short *)data = htons(IPX_SAP_NEAREST_QUERY);
*(unsigned short *)&(data[2]) = htons(server_type);
memset(&addr, 0, sizeof(addr));
memzero(addr);
addr.sipx_family = AF_IPX;
addr.sipx_port = htons(IPX_SAP_PORT);
addr.sipx_type = IPX_SAP_PTYPE;
@@ -289,7 +294,7 @@ ipx_make_reachable(IPXNet network)
return -1;
}
memset(&rip, 0, sizeof(rip));
memzero(rip);
sock = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
@@ -305,7 +310,7 @@ ipx_make_reachable(IPXNet network)
goto finished;
}
memset(&addr, 0, sizeof(addr));
memzero(addr);
addr.sipx_family = AF_IPX;
addr.sipx_network = htonl(0x0);
addr.sipx_port = htons(0x0);
@@ -710,13 +715,19 @@ ncp_connect_any(struct ncp_conn *conn, int wdog_needed)
{
struct sockaddr_ipx addr;
char name[NCP_BINDERY_NAME_LEN];
int result;
if (ipx_sap_find_nearest(IPX_SAP_FILE_SERVER, &addr, name) != 0)
{
return -1;
}
return ncp_connect_addr(conn, &addr, wdog_needed);
if ((result = ncp_connect_addr(conn, &addr, wdog_needed)) != 0)
{
return result;
}
strcpy(conn->server, name);
return 0;
}
static int
@@ -827,19 +838,130 @@ ncp_open_temporary(struct ncp_conn *conn,
return result;
}
strcpy(conn->server, spec->server);
if (strlen(spec->user) != 0)
{
if (ncp_login_user(conn, spec->user, spec->password) != 0)
if (ncp_login_object(conn, spec->user, spec->login_type,
spec->password) != 0)
{
ncp_close(conn);
errno = EACCES;
return -1;
}
strcpy(conn->user, spec->user);
}
return 0;
}
static int
ncp_open_permanent(struct ncp_conn *conn,
const struct ncp_conn_spec *spec)
{
FILE *mtab;
struct ncp_conn_ent *conn_ent;
if (conn == NULL)
{
errno = EINVAL;
return -1;
}
if (conn->is_connected != NOT_CONNECTED)
{
errno = EBUSY;
return -1;
}
if ((mtab = fopen(MOUNTED, "r")) == NULL)
{
return -1;
}
while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL)
{
if (spec != NULL)
{
if ( (conn_ent->uid != spec->uid)
|| ( (strlen(spec->server) != 0)
&& (strcasecmp(conn_ent->server,
spec->server) != 0))
|| ( (strlen(spec->user) != 0)
&& (strcasecmp(conn_ent->user,
spec->user) != 0)))
{
continue;
}
if (strlen(conn_ent->mount_point)
>= sizeof(conn->mount_point))
{
continue;
}
}
conn->mount_fid = open(conn_ent->mount_point, O_RDONLY, 0);
if (conn->mount_fid < 0)
{
continue;
}
conn->i.version = NCP_GET_FS_INFO_VERSION;
if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &(conn->i))<0)
{
close(conn->mount_fid);
continue;
}
strncpy(conn->server, conn_ent->server,
sizeof(conn->server));
strncpy(conn->user, conn_ent->user,
sizeof(conn->user));
strcpy(conn->mount_point, conn_ent->mount_point);
conn->is_connected = CONN_PERMANENT;
fclose(mtab);
return 0;
}
fclose(mtab);
return -1;
}
int
ncp_open(struct ncp_conn *conn, const struct ncp_conn_spec *spec)
{
if (ncp_open_permanent(conn, spec) != 0)
{
return ncp_open_temporary(conn, spec);
}
return 0;
}
int
ncp_open_mount(struct ncp_conn *conn,
const char *mount_point)
{
conn->is_connected = NOT_CONNECTED;
if (strlen(mount_point) >= sizeof(conn->mount_point))
{
errno = ENAMETOOLONG;
return -1;
}
conn->mount_fid = open(mount_point, O_RDONLY, 0);
if (conn->mount_fid < 0)
{
errno = ENODEV;
return -1;
}
strcpy(conn->mount_point, mount_point);
conn->is_connected = CONN_PERMANENT;
return 0;
}
struct ncp_conn_ent *
ncp_get_conn_ent(FILE *filep)
{
@@ -849,8 +971,8 @@ ncp_get_conn_ent(FILE *filep)
struct mntent *mnt_ent;
int fid;
memset(&server, 0, sizeof(server));
memset(&entry, 0, sizeof(entry));
memzero(server);
memzero(entry);
while ((mnt_ent = getmntent(filep)) != NULL)
{
@@ -913,7 +1035,7 @@ ncp_get_nwc_ent(FILE *nwc)
char *user;
char *password;
memset(&spec, 0, sizeof(spec));
memzero(spec);
spec.uid = getuid();
while (fgets(line, sizeof(line), nwc) != NULL)
@@ -1032,10 +1154,12 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
{
static struct ncp_conn_spec spec;
struct ncp_conn conn;
FILE *nwc;
struct ncp_conn_spec *nwc_ent;
memset(&spec, 0, sizeof(spec));
memzero(spec);
spec.uid = getuid();
if (server != NULL)
@@ -1064,7 +1188,6 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
}
strcpy(spec.server, nwc_ent->server);
strcpy(spec.user, nwc_ent->user);
strcpy(spec.password, nwc_ent->password);
}
if (user != NULL)
@@ -1076,6 +1199,16 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
strcpy(spec.user, user);
}
str_upper(spec.server);
str_upper(spec.user);
spec.login_type = NCP_BINDERY_USER;
if (ncp_open_permanent(&conn, &spec) == 0)
{
ncp_close(&conn);
return &spec;
}
if (password != NULL)
{
if (strlen(password) >= sizeof(spec.password))
@@ -1141,102 +1274,112 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
str_upper(spec.password);
return &spec;
}
int
ncp_open(struct ncp_conn *conn,
const struct ncp_conn_spec *spec)
ncp_initialize_as(struct ncp_conn *conn,
int *argc, char **argv,
int login_necessary, int login_type)
{
FILE *mtab;
struct ncp_conn_ent *conn_ent;
char *server = NULL;
char *user = NULL;
char *password = NULL;
struct ncp_conn_spec *spec;
int i = 1;
if (conn == NULL)
int get_argument(int arg_no, char **target)
{
errno = EINVAL;
return -1;
}
if (conn->is_connected != NOT_CONNECTED)
{
errno = EBUSY;
return -1;
}
int count = 1;
if ((mtab = fopen(MOUNTED, "r")) == NULL)
{
return -1;
}
while ((conn_ent = ncp_get_conn_ent(mtab)) != NULL)
{
if (spec != NULL)
if (target != NULL)
{
if ( (conn_ent->uid != spec->uid)
|| ( (strlen(spec->server) != 0)
&& (strcasecmp(conn_ent->server,
spec->server) != 0))
|| ( (strlen(spec->user) != 0)
&& (strcasecmp(conn_ent->user,
spec->user) != 0)))
if (arg_no+1 >= *argc)
{
continue;
}
if (strlen(conn_ent->mount_point)
>= sizeof(conn->mount_point))
{
continue;
/* No argument to switch */
return -1;
}
*target = argv[arg_no+1];
count = 2;
}
conn->mount_fid = open(conn_ent->mount_point, O_RDONLY, 0);
if (conn->mount_fid < 0)
/* Delete the consumed switch from the argument list
and decrement the argument count */
while (count+arg_no < *argc)
{
continue;
argv[arg_no] = argv[arg_no+count];
arg_no += 1;
}
conn->i.version = NCP_GET_FS_INFO_VERSION;
if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &(conn->i))<0)
{
close(conn->mount_fid);
continue;
}
strncpy(conn->server, conn_ent->server,
sizeof(conn->server));
strncpy(conn->user, conn_ent->user,
sizeof(conn->user));
strcpy(conn->mount_point, conn_ent->mount_point);
conn->is_connected = CONN_PERMANENT;
fclose(mtab);
*argc -= count;
return 0;
}
fclose(mtab);
errno = EINVAL;
memzero(*conn);
return ncp_open_temporary(conn, spec);
while (i < *argc)
{
if ( (argv[i][0] != '-')
|| (strlen(argv[i]) != 2))
{
i += 1;
continue;
}
switch (argv[i][1])
{
case 'S':
if (get_argument(i, &server) != 0)
{
return -1;
}
continue;
case 'U':
if (get_argument(i, &user) != 0)
{
return -1;
}
continue;
case 'P':
if (get_argument(i, &password) != 0)
{
return -1;
}
continue;
case 'n':
if (get_argument(i, 0) != 0)
{
return -1;
}
continue;
}
i += 1;
}
if (login_necessary == 0)
{
errno = 0;
return ncp_open(conn, NULL);
}
if ((spec = ncp_find_conn_spec(server, user, password,
getuid())) == NULL)
{
return -1;
}
errno = 0;
spec->login_type = login_type;
return ncp_open(conn, spec);
}
int
ncp_open_mount(struct ncp_conn *conn,
const char *mount_point)
ncp_initialize(struct ncp_conn *conn,
int *argc, char **argv,
int login_necessary)
{
conn->is_connected = NOT_CONNECTED;
if (strlen(mount_point) >= sizeof(conn->mount_point))
{
errno = ENAMETOOLONG;
return -1;
}
conn->mount_fid = open(mount_point, O_RDONLY, 0);
if (conn->mount_fid < 0)
{
errno = ENODEV;
return -1;
}
strcpy(conn->mount_point, mount_point);
conn->is_connected = CONN_PERMANENT;
return 0;
return ncp_initialize_as(conn, argc, argv, login_necessary,
NCP_BINDERY_USER);
}
static int
@@ -1252,12 +1395,49 @@ ncp_request(struct ncp_conn *conn, int function)
return -ENOTCONN;
}
/****************************************************************************/
/* */
/* Helper functions */
/* */
/****************************************************************************/
static inline int
min(int a, int b)
{
return (a<b) ? a : b;
}
struct nw_time_buffer {
__u8 year __attribute__ ((packed));
__u8 month __attribute__ ((packed));
__u8 day __attribute__ ((packed));
__u8 hour __attribute__ ((packed));
__u8 minute __attribute__ ((packed));
__u8 second __attribute__ ((packed));
__u8 wday __attribute__ ((packed));
};
static time_t
nw_to_ctime(struct nw_time_buffer *source)
{
struct tm u_time;
memzero(u_time);
u_time.tm_sec = source->second;
u_time.tm_min = source->minute;
u_time.tm_hour = source->hour;
u_time.tm_mday = source->day;
u_time.tm_mon = source->month - 1;
u_time.tm_year = source->year;
if (u_time.tm_year < 80)
{
u_time.tm_year += 100;
}
return mktime(&u_time);
}
static void
assert_conn_locked(struct ncp_conn *conn)
{
@@ -1384,6 +1564,69 @@ ncp_negotiate_buffersize(struct ncp_conn *conn,
}
int
ncp_get_file_server_description_strings(struct ncp_conn *conn,
char target[512])
{
int result;
ncp_init_request_s(conn, 201);
if ((result = ncp_request(conn, 23)) != 0)
{
ncp_unlock_conn(conn);
return result;
}
memcpy(target, ncp_reply_data(conn, 0), 512);
ncp_unlock_conn(conn);
return 0;
}
int
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target)
{
int result;
ncp_init_request(conn);
if ((result = ncp_request(conn, 20)) != 0)
{
ncp_unlock_conn(conn);
return result;
}
*target= nw_to_ctime((struct nw_time_buffer *)ncp_reply_data(conn, 0));
ncp_unlock_conn(conn);
return 0;
}
int
ncp_get_connlist(struct ncp_conn *conn, __u32 last_id,
__u16 object_type, const char *object_name,
int *returned_no, __u16 conn_numbers[256])
{
int result;
ncp_init_request_s(conn, 27);
ncp_add_dword(conn, htonl(last_id));
ncp_add_word(conn, htons(object_type));
ncp_add_pstring(conn, object_name);
if ((result = ncp_request(conn, 23)) != 0)
{
ncp_unlock_conn(conn);
return result;
}
*returned_no = ncp_reply_byte(conn, 0);
memcpy(conn_numbers, ncp_reply_data(conn, 1),
sizeof(__u16) * (*returned_no));
return 0;
}
/*
* result is a 8-byte buffer
*/
@@ -1528,6 +1771,15 @@ int
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password)
{
return ncp_login_object(conn, username, NCP_BINDERY_USER, password);
}
static int
ncp_login_object(struct ncp_conn *conn,
const unsigned char *username,
int login_type,
const unsigned char *password)
{
int result;
unsigned char ncp_key[8];
@@ -1537,7 +1789,7 @@ ncp_login_user(struct ncp_conn *conn,
return result;
}
if ((result = ncp_get_bindery_object_id(conn, NCP_BINDERY_USER,
if ((result = ncp_get_bindery_object_id(conn, login_type,
username, &user)) != 0) {
return result;
}
@@ -1574,7 +1826,7 @@ ncp_get_volume_info_with_number(struct ncp_conn *conn, int n,
target->available_dir_entries = ncp_reply_dword(conn, 20);
target->sectors_per_block = ncp_reply_byte(conn, 28);
memset(&(target->volume_name), 0, sizeof(target->volume_name));
memzero(target->volume_name);
len = ncp_reply_byte(conn, 29);
if (len > NCP_VOLNAME_LEN) {
@@ -1656,7 +1908,7 @@ ncp_file_search_continue(struct ncp_conn *conn,
fsinfo->sequence_no = ntohs(ncp_reply_word(conn, 0));
memset(&(target->file_name), 0, sizeof(target->file_name));
memzero(target->file_name);
memcpy(&(target->file_name), ncp_reply_data(conn, 4),
NCP_MAX_FILENAME);
@@ -1721,7 +1973,7 @@ ncp_open_file(struct ncp_conn *conn,
memcpy(&(target->file_id), ncp_reply_data(conn, 0),
NCP_FILE_ID_LEN);
memset(&(target->file_name), 0, sizeof(target->file_name));
memzero(target->file_name);
memcpy(&(target->file_name), ncp_reply_data(conn, 8),
NCP_MAX_FILENAME);
@@ -1777,7 +2029,7 @@ ncp_do_create(struct ncp_conn *conn,
memcpy(&(target->file_id), ncp_reply_data(conn, 0),
NCP_FILE_ID_LEN);
memset(&(target->file_name), 0, sizeof(target->file_name));
memzero(target->file_name);
memcpy(&(target->file_name), ncp_reply_data(conn, 8),
NCP_MAX_FILENAME);
@@ -2129,14 +2381,22 @@ ncp_open_create_file_or_subdir(struct ncp_conn *conn,
int
ncp_initialize_search(struct ncp_conn *conn,
struct nw_info_struct *dir,
struct nw_search_sequence *target)
const struct nw_info_struct *dir,
int namespace,
struct ncp_search_seq *target)
{
int result;
if ((namespace < 0) || (namespace > 255))
{
return EINVAL;
}
memzero(*target);
ncp_init_request(conn);
ncp_add_byte(conn, 2); /* subfunction */
ncp_add_byte(conn, 0); /* dos name space */
ncp_add_byte(conn, namespace);
ncp_add_byte(conn, 0); /* reserved */
ncp_add_handle_path(conn, dir->volNumber,
dir->DosDirNum, 1, NULL);
@@ -2146,7 +2406,8 @@ ncp_initialize_search(struct ncp_conn *conn,
return result;
}
memcpy(target, ncp_reply_data(conn, 0), sizeof(*target));
memcpy(&(target->s), ncp_reply_data(conn, 0), sizeof(target->s));
target->namespace = namespace;
ncp_unlock_conn(conn);
return 0;
@@ -2155,18 +2416,18 @@ ncp_initialize_search(struct ncp_conn *conn,
/* Search for everything */
int
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
struct nw_search_sequence *seq,
struct ncp_search_seq *seq,
struct nw_info_struct *target)
{
int result;
ncp_init_request(conn);
ncp_add_byte(conn, 3); /* subfunction */
ncp_add_byte(conn, 0); /* dos name space */
ncp_add_byte(conn, seq->namespace);
ncp_add_byte(conn, 0); /* data stream (???) */
ncp_add_word(conn, 0xffff); /* Search attribs */
ncp_add_dword(conn, RIM_ALL); /* return info mask */
ncp_add_mem(conn, seq, 9);
ncp_add_mem(conn, &(seq->s), 9);
ncp_add_byte(conn, 2); /* 2 byte pattern */
ncp_add_byte(conn, 0xff); /* following is a wildcard */
ncp_add_byte(conn, '*');
@@ -2241,7 +2502,6 @@ ncp_create_queue_job_and_file(struct ncp_conn *conn,
}
memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
ConvertToNWfromDWORD(job->j.JobFileHandle, job->file_handle);
ncp_unlock_conn(conn);
@@ -2266,7 +2526,106 @@ ncp_close_file_and_start_job(struct ncp_conn *conn,
ncp_unlock_conn(conn);
return 0;
}
}
int
ncp_attach_to_queue(struct ncp_conn *conn,
__u32 queue_id)
{
int result;
ncp_init_request_s(conn, 111);
ncp_add_dword(conn, htonl(queue_id));
if ((result = ncp_request(conn, 23)) != 0) {
ncp_unlock_conn(conn);
return result;
}
ncp_unlock_conn(conn);
return 0;
}
int
ncp_detach_from_queue(struct ncp_conn *conn,
__u32 queue_id)
{
int result;
ncp_init_request_s(conn, 112);
ncp_add_dword(conn, htonl(queue_id));
if ((result = ncp_request(conn, 23)) != 0) {
ncp_unlock_conn(conn);
return result;
}
ncp_unlock_conn(conn);
return 0;
}
int
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
struct queue_job *job)
{
int result;
ncp_init_request_s(conn, 124);
ncp_add_dword(conn, htonl(queue_id));
ncp_add_word(conn, htons(job_type));
if ((result = ncp_request(conn, 23)) != 0) {
ncp_unlock_conn(conn);
return result;
}
memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
ConvertToNWfromDWORD(job->j.JobFileHandle, job->file_handle);
ncp_unlock_conn(conn);
return 0;
}
int
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number, __u32 charge_info)
{
int result;
ncp_init_request_s(conn, 131);
ncp_add_dword(conn, htonl(queue_id));
ncp_add_dword(conn, job_number);
ncp_add_dword(conn, htonl(charge_info));
if ((result = ncp_request(conn, 23)) != 0) {
ncp_unlock_conn(conn);
return result;
}
ncp_unlock_conn(conn);
return 0;
}
int
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number)
{
int result;
ncp_init_request_s(conn, 132);
ncp_add_dword(conn, htonl(queue_id));
ncp_add_dword(conn, job_number);
if ((result = ncp_request(conn, 23)) != 0) {
ncp_unlock_conn(conn);
return result;
}
ncp_unlock_conn(conn);
return 0;
}
static int
ncp_do_read(struct ncp_conn *conn, const char *file_id,

View File

@@ -1,7 +1,7 @@
/*
* ncplib.h
*
* Copyright (C) 1995 by Volker Lendecke
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
@@ -14,9 +14,18 @@
#include <linux/ipx.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>
#include "ipxlib.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,
@@ -60,9 +69,33 @@ 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;
};
/* 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. */
int
ncp_initialize(struct ncp_conn *conn,
int *argc, char **argv,
int login_necessary);
/* You can login as another object by this procedure. As a first use
pserver comes to mind. */
int
ncp_initialize_as(struct ncp_conn *conn,
int *argc, char **argv,
int login_necessary, int login_type);
/* Open an existing permanent connection */
int
ncp_open(struct ncp_conn *conn,
@@ -109,6 +142,18 @@ struct ncp_conn_spec *
ncp_find_conn_spec(const char *server, const char *user, const char *password,
uid_t uid);
int
ncp_get_file_server_description_strings(struct ncp_conn *conn,
char target[512]);
int
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target);
int
ncp_get_connlist(struct ncp_conn *conn, __u32 last_id,
__u16 object_type, const char *object_name,
int *returned_no, __u16 conn_numbers[256]);
int
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
@@ -239,12 +284,13 @@ ncp_open_create_file_or_subdir(struct ncp_conn *conn,
int
ncp_initialize_search(struct ncp_conn *conn,
struct nw_info_struct *dir,
struct nw_search_sequence *target);
const struct nw_info_struct *dir,
int namespace,
struct ncp_search_seq *target);
int
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
struct nw_search_sequence *seq,
struct ncp_search_seq *seq,
struct nw_info_struct *target);
int
@@ -262,4 +308,24 @@ ncp_close_file_and_start_job(struct ncp_conn *conn,
__u32 queue_id,
struct queue_job *job);
int
ncp_attach_to_queue(struct ncp_conn *conn,
__u32 queue_id);
int
ncp_detach_from_queue(struct ncp_conn *conn,
__u32 queue_id);
int
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
struct queue_job *job);
int
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number, __u32 charge_info);
int
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number);
#endif /* _NCPLIB_H */

View File

@@ -3,6 +3,16 @@
*
* 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 insmod causes it to bypass a
* path search. This may lead to ncpfs.o not being found on
* some systems.
*/
#include <stdio.h>
@@ -37,18 +47,18 @@ extern pid_t waitpid(pid_t, int *, int);
#include "ncplib.h"
static char *progname;
static void str_upper(char *name);
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 *fver, *ffs;
FILE *ffs;
char s[1024];
char modname[1024];
char *p, *p1;
pid_t pid;
int status;
@@ -81,33 +91,6 @@ load_ncpfs(void)
{
return 0;
}
fver = fopen("/proc/version", "r");
if (fver == NULL)
{
perror("Error: \"/proc/version\" could not be read:");
return -1;
}
fgets(s, 1024, fver);
fclose(fver);
p = strstr(s, "version ");
if (p == NULL)
{
version_error:
fprintf(stderr, "Error: Unable to determine the Linux version"
"from \"/proc/version\n");
return -1;
}
p = strchr(p, ' ') + 1;
p1 = strchr(p, ' ');
if (p1 == NULL)
{
goto version_error;
}
strcpy(modname, "/lib/modules/");
strncat(modname, p, p1 - p);
strcat(modname, "/ncpfs.o");
/* system() function without signal handling, from Stevens */
@@ -118,7 +101,7 @@ load_ncpfs(void)
else if (pid == 0)
{
/* child */
execl("/sbin/insmod", "insmod", modname, NULL);
execl("/sbin/insmod", "insmod", "ncpfs", NULL);
_exit(127); /* execl error */
}
else
@@ -136,6 +119,8 @@ load_ncpfs(void)
return status;
}
#endif /* HAVE_KERNELD */
/* Check whether user is allowed to mount on the specified mount point */
static int
mount_ok(struct stat *st)
@@ -192,15 +177,14 @@ main(int argc, char *argv[])
progname = argv[0];
memzero(data); memzero(spec); memzero(conn);
if (geteuid() != 0)
{
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
memset(&data, 0, sizeof(data));
memset(&spec, 0, sizeof(spec));
data.uid = getuid();
data.gid = getgid();
um = umask(0);
@@ -346,6 +330,7 @@ main(int argc, char *argv[])
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)
@@ -353,6 +338,7 @@ main(int argc, char *argv[])
fprintf(stderr, "Error: Unable to load ncpfs, exiting...\n");
exit(1);
}
#endif
data.version = NCP_MOUNT_VERSION;
data.mounted_uid = conn_uid;
@@ -405,7 +391,7 @@ main(int argc, char *argv[])
exit(1);
}
memset(&addr, 0, sizeof(addr));
memzero(addr);
addr.sipx_type = NCP_PTYPE;
if (bind(data.ncp_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
@@ -505,15 +491,6 @@ main(int argc, char *argv[])
return 0;
}
static void
str_upper(char *name)
{
while (*name) {
*name = toupper(*name);
name = name + 1;
}
}
static void
usage(void)
{

View File

@@ -96,24 +96,69 @@ test_print(struct ncp_conn *conn)
}
void
main(void)
test_ls(struct ncp_conn *server)
{
struct nw_info_struct sys;
struct nw_info_struct public;
struct ncp_search_seq seq;
struct nw_info_struct found;
int res;
if (ncp_do_lookup(server, NULL, "SYS", &sys) != 0)
{
printf("lookup error\n");
return;
}
if (ncp_do_lookup(server, &sys, "PUBLIC", &public) != 0)
{
printf("lookup public error\n");
return;
}
if (ncp_initialize_search(server, &public, 4, &seq) != 0)
{
printf("init error\n");
return;
}
while ((res=ncp_search_for_file_or_subdir(server,&seq,&found)) == 0)
{
printf("found %s: %s\n",
(found.attributes & aDIR) ? "dir " : "file",
found.entryName);
}
if (res == 0xfe)
{
printf("result: no more files\n");
}
else
{
printf("other error: %x\n", res);
}
return;
}
void
test_connlist(struct ncp_conn *conn)
{
__u16 conn_list[256];
int no;
ncp_get_connlist(conn, 0, NCP_BINDERY_USER, "*", &no, conn_list);
return;
}
int
main(int argc, char *argv[])
{
struct ncp_conn conn;
struct ncp_conn_spec *spec;
if ((spec = ncp_find_conn_spec("NW311", "me", "", 0)) == NULL)
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
{
perror("could not find spec");
exit(1);
perror("ncp_initialize");
return 1;
}
if (ncp_open(&conn, NULL) != 0)
{
perror("ncp_open");
exit(1);
}
test_print(&conn);
test_connlist(&conn);
ncp_close(&conn);
return 0;
}

View File

@@ -1,57 +1,34 @@
/*
* nwprint.c
*
* Send data to a NetWare print queue.
*
* 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/time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.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 <linux/ipx.h>
#include <ctype.h>
#include <linux/fs.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ncplib.h"
static char *progname;
static void
usage(void);
static void help(void);
void
main(int argc, char *argv[])
{
struct ncp_conn conn;
char *server = NULL;
char *user = NULL;
char *password = NULL;
struct ncp_conn_spec *spec;
char *queue = "*";
char default_queue[] = "*";
char *queue = default_queue;
int opt;
@@ -68,8 +45,20 @@ main(int argc, char *argv[])
progname = argv[0];
memset(&spec, 0, sizeof(spec));
memset(&j, 0, sizeof(j));
memzero(j); memzero(pj); memzero(q); memzero(conn);
if ( (argc == 2)
&& (strcmp(argv[1], "-h") == 0))
{
help();
exit(0);
}
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
{
perror("Could not open connection");
exit(1);
}
/*
* Fill in default values for print job
@@ -78,9 +67,7 @@ main(int argc, char *argv[])
/* at once */
memset(&(j.j.TargetExecTime), 0xff, sizeof(j.j.TargetExecTime));
j.j.JobType = htons(0);
strcpy(j.j.JobTextDescription, "Test Job");
memset(&pj, 0, sizeof(pj));
strcpy(j.j.JobTextDescription, "No Description");
pj.Version = 0;
pj.TabSize = 8;
@@ -90,10 +77,13 @@ main(int argc, char *argv[])
pj.Rows = htons(80);
strcpy(pj.FnameHeader, "stdin");
while ((opt = getopt(argc, argv,
"S:U:P:nq:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
while ((opt = getopt(argc, argv, "hq:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
{
switch (opt) {
case 'h':
help();
ncp_close(&conn);
exit(1);
case 'p':
/* Path */
pj.CtrlFlags |= PRINT_BANNER;
@@ -195,39 +185,6 @@ main(int argc, char *argv[])
}
j.j.JobType = htons(atoi(optarg));
break;
case 'S':
/* File Server */
if (strlen(optarg) >= sizeof(spec->server))
{
fprintf(stderr, "Servername too long:%s\n",
optarg);
exit(1);
}
server = optarg;
break;
case 'U':
/* User to use */
if (strlen(optarg) >= sizeof(spec->user))
{
fprintf(stderr, "Username too long: %s\n",
optarg);
exit(1);
}
user = optarg;
break;
case 'P':
/* Password */
if (strlen(optarg) >= sizeof(spec->password))
{
printf("password too long\n");
exit(1);
}
password = optarg;
break;
case 'n':
/* use no password */
password = "";
break;
case 'q':
/* Queue name to print on, default: '*' */
if (strlen(optarg) >= NCP_BINDERY_NAME_LEN)
@@ -305,17 +262,7 @@ main(int argc, char *argv[])
memcpy(j.j.ClientRecordArea, &pj, sizeof(pj));
if ((spec = ncp_find_conn_spec(server, user, password, 0)) == NULL)
{
perror("could not find connection");
exit(1);
}
if (ncp_open(&conn, spec) != 0)
{
perror("could not open connection");
exit(1);
}
str_upper(queue);
if (ncp_scan_bindery_object(&conn, 0xffffffff, NCP_BINDERY_PQUEUE,
queue, &q) != 0)
@@ -346,7 +293,7 @@ main(int argc, char *argv[])
}
written += read_this_time;
} while (read_this_time == sizeof(buf));
} while (read_this_time > 0);
close(file);
@@ -364,3 +311,29 @@ usage(void)
fprintf(stderr, "usage: %s [options] file\n", progname);
exit(1);
}
static void
help(void)
{
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");
}

View File

@@ -1,46 +0,0 @@
/*
* nwlsconn.c
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include "ncplib.h"
void
main(void)
{
struct ncp_ioctl_conn conn;
struct passwd *pwd;
conn.connection = NCP_NO_CONNECTION;
if (isatty(1))
{
printf("\n%-30s %-30s %s\n"
"-----------------------------------------------"
"---------------------------\n",
"Server Name",
"NetWare Login Name",
"Conn. Owner");
}
while (ncp_list_conn(&conn) == 0)
{
pwd = getpwuid(conn.uid);
printf("%-30s %-30s %s\n", conn.server, conn.user,
pwd == NULL ? "<unknown>" : pwd->pw_name);
}
}

75
util/pqlist.c Normal file
View File

@@ -0,0 +1,75 @@
/*
* pqlist.c
*
* List all print queues on a server
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include "ncplib.h"
int
main(int argc, char **argv)
{
struct ncp_conn conn;
struct ncp_bindery_object q;
int found = 0;
char default_pattern[] = "*";
char *pattern = default_pattern;
char *p;
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
{
perror("Could not open connection");
return 1;
}
if (argc > 2)
{
fprintf(stderr, "usage: %s [options] [pattern]\n", argv[0]);
return 1;
}
if (argc == 2)
{
pattern = argv[1];
}
for (p = pattern; *p != '\0'; p++)
{
*p = toupper(*p);
}
if (isatty(1))
{
printf("\nServer: %s\n", conn.server);
printf("%-52s%-10s\n"
"-----------------------------------------------"
"-------------\n",
"Print queue name",
"Queue ID");
}
q.object_id = 0xffffffff;
while (ncp_scan_bindery_object(&conn, q.object_id,
NCP_BINDERY_PQUEUE, "*", &q) == 0)
{
found = 1;
printf("%-52s", q.object_name);
printf("%08x\n", q.object_id);
}
if ((found == 0) && (isatty(1)))
{
printf("No queues found\n");
}
ncp_close(&conn);
return 0;
}

338
util/pserver.c Normal file
View File

@@ -0,0 +1,338 @@
/*
* pserver.c
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include "ncplib.h"
struct nw_queue {
struct ncp_conn *conn;
char queue_name[NCP_BINDERY_NAME_LEN];
__u32 queue_id;
__u16 job_type;
char *command;
};
static struct nw_queue q;
static int term_request;
static char *progname;
static int
init_queue(struct ncp_conn *conn, char *queue_name,
char *command, struct nw_queue *q);
static int
poll_queue(struct nw_queue *q);
static void
usage(void)
{
fprintf(stderr, "usage: %s [options] file\n", progname);
exit(1);
}
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-S server Server name to be used\n"
"-U username Print Server name 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"
"-c command Name of print command, default: 'lpr'\n"
"-j job type Type of job (Form number) to service\n"
"-t timeout Polling interval, default: 30 sec\n"
"-d Debug: don't daemonize\n"
"-h print this help text\n"
"\n");
}
#ifndef NCP_BINDERY_PSERVER
#define NCP_BINDERY_PSERVER (0x0007)
#endif
static void
terminate_handler()
{
signal(SIGTERM,terminate_handler);
signal(SIGINT, terminate_handler);
term_request=1;
}
static void
daemonize()
{
int fd,c;
if ((c = fork()) > 0) exit(0);
if (c < 0)
{
fprintf(stderr, "ipxripd: can't fork: %s\n",strerror(errno));
exit(1);
}
close(0);
close(1);
close(2);
if ((fd = open("/dev/tty", O_RDWR)) >= 0)
{
ioctl(fd, TIOCNOTTY, NULL);
close(fd);
}
}
int
main(int argc, char *argv[])
{
struct ncp_conn conn;
int poll_timeout = 30;
int opt;
int job_type = 0xffff;
int debug = 0;
int i;
char *queue_name = NULL;
char default_command[] = "lpr";
char *command = default_command;
progname = argv[0];
for (i = 1; i < argc; i += 1)
{
if ( (strcmp(argv[i], "-h") == 0)
|| (strcmp(argv[i], "-?") == 0))
{
help();
exit(0);
}
}
for (i = 1; i < argc; i += 1)
{
if (strcmp(argv[i], "-d") == 0)
{
debug = 1;
break;
}
}
if (debug == 0)
{
daemonize();
}
if (ncp_initialize_as(&conn, &argc, argv, 1, NCP_BINDERY_PSERVER) != 0)
{
perror("Could not open connection");
return 1;
}
while ((opt = getopt(argc, argv, "q:c:j:t:dh")) != EOF)
{
switch (opt)
{
case 'q':
queue_name = optarg;
break;
case 'c':
command = optarg;
break;
case 'j':
job_type = atoi(optarg);
break;
case 't':
poll_timeout = atoi(optarg);
break;
case 'd':
debug = 1;
break;
case 'h':
break;
default:
usage();
return -1;
}
}
if (argc != optind)
{
usage();
return -1;
}
memzero(q);
if (queue_name == NULL)
{
fprintf(stderr, "You must specify a queue\n");
return 1;
}
if (init_queue(&conn, queue_name, command, &q) != 0)
{
perror("Could not init queue");
ncp_close(&conn);
return 1;
}
q.job_type = job_type;
term_request = 0;
signal(SIGTERM,terminate_handler);
signal(SIGINT, terminate_handler);
while (1)
{
if ( (poll_queue(&q) != 0)
&& (term_request == 0))
{
continue;
}
if (term_request != 0)
{
break;
}
sleep(poll_timeout);
}
ncp_detach_from_queue(&conn, q.queue_id);
ncp_close(&conn);
return 0;
}
static int
init_queue(struct ncp_conn *conn, char *queue_name, char *command,
struct nw_queue *q)
{
struct ncp_bindery_object obj;
str_upper(queue_name);
q->conn = conn;
q->command = command;
if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE,
queue_name, &obj) != 0)
{
fprintf(stderr, "Queue %s not found\n", queue_name);
return -1;
}
q->queue_id = obj.object_id;
memcpy(q->queue_name, obj.object_name, sizeof(q->queue_name));
if (ncp_attach_to_queue(conn, q->queue_id) != 0)
{
fprintf(stderr, "Could not attach to queue %s\n",
queue_name);
return -1;
}
return 0;
}
static int
poll_queue(struct nw_queue *q)
{
struct queue_job job;
int fd[2];
int pid;
if (ncp_service_queue_job(q->conn, q->queue_id, q->job_type,
&job) != 0)
{
/* No job for us */
return 0;
}
if (pipe(fd) < 0)
{
perror("pipe");
goto fail;
}
if ((pid = fork()) < 0)
{
perror("fork");
goto fail;
}
if (pid > 0)
{
/* parent */
char buf[1024];
size_t result;
off_t offset = 0;
close(fd[0]); /* close read end */
while ((result = ncp_read(q->conn, job.file_handle, offset,
sizeof(buf), buf)) > 0)
{
offset += result;
if (write(fd[1], buf, result) != result)
{
goto fail;
}
}
close(fd[1]); /* and close write end */
if (waitpid(pid, NULL, 0) < 0)
{
perror("waitpid");
}
}
else
{
/* child */
close(fd[1]); /* close write end */
if (fd[0] != STDIN_FILENO)
{
if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
{
perror("dup2");
close(fd[0]);
exit(1);
}
close(fd[0]);
}
execl("/bin/sh", "sh", "-c", q->command, NULL);
perror("exec");
close(fd[0]);
exit(1);
}
ncp_finish_servicing_job(q->conn, q->queue_id, job.j.JobNumber,0);
return 1;
fail:
ncp_abort_servicing_job(q->conn, q->queue_id, job.j.JobNumber);
/* We tell that we did not have a job to avoid overloading
when something's wrong */
return 0;
}

View File

@@ -1,6 +1,8 @@
/*
* slist.c
*
* List all file server that are known in the IPX network.
*
* Copyright (C) 1995 by Volker Lendecke
*
*/
@@ -18,7 +20,7 @@ main(int argc, char *argv[])
struct ncp_conn conn;
struct ncp_bindery_object obj;
int found = 0;
char default_pattern[2] = "*";
char default_pattern[] = "*";
char *pattern = default_pattern;
char *p;
@@ -38,9 +40,7 @@ main(int argc, char *argv[])
*p = toupper(*p);
}
memset(&conn, 0, sizeof(conn));
if (ncp_open(&conn, NULL) != 0)
if (ncp_initialize(&conn, &argc, argv, 0) != 0)
{
perror("ncp_connect");
exit(1);