Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5753870858 | ||
|
|
b8ce93c8bd | ||
|
|
7bef99df0f | ||
|
|
d31ec2ab61 | ||
|
|
1ee60bade6 | ||
|
|
20589ca203 |
BIN
.downloads/ncpfs-0.11.tgz
Normal file
BIN
.downloads/ncpfs-0.11.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.12.tgz
Normal file
BIN
.downloads/ncpfs-0.12.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.13.tgz
Normal file
BIN
.downloads/ncpfs-0.13.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.14.tgz
Normal file
BIN
.downloads/ncpfs-0.14.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.15.tgz
Normal file
BIN
.downloads/ncpfs-0.15.tgz
Normal file
Binary file not shown.
BIN
.downloads/ncpfs-0.16.tgz
Normal file
BIN
.downloads/ncpfs-0.16.tgz
Normal file
Binary file not shown.
21
BUGS
21
BUGS
@@ -3,17 +3,20 @@ them to be bugs.
|
||||
|
||||
But there are really problems that might be fixed in the future.
|
||||
|
||||
'df' returns 0:
|
||||
Free disk space is distributed among the volumes in NetWare. df is
|
||||
only able to report one number per mounted filesystem. As connections
|
||||
are quite expensive for NetWare (with lwared that might change ...), I
|
||||
rejected the alternative to mount only a single volume for a unix
|
||||
mount point. So I simply return 0.
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
'df' returns 0: Free disk space is distributed among the volumes in
|
||||
NetWare. df is only able to report one number per mounted
|
||||
filesystem. As connections are quite expensive for NetWare (with
|
||||
mars_nwe and lwared that might change ...), I rejected the alternative
|
||||
to mount only a single volume for a unix mount point. So I simply
|
||||
return 0.
|
||||
|
||||
In your kernel log, there will appear messages like
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
If you use Linux 1.2.x, In your kernel log there will appear messages
|
||||
like
|
||||
|
||||
Nov 25 16:09:08 lx01 kernel: alloc_skb called nonatomically from interrupt 0000002e
|
||||
|
||||
These are a bit annoying, but completely harmless. Maybe this will be
|
||||
fixed in the future.
|
||||
These are a bit annoying, but completely harmless.
|
||||
|
||||
35
Changes
Normal file
35
Changes
Normal file
@@ -0,0 +1,35 @@
|
||||
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.15 -> ncpfs-0.16
|
||||
|
||||
- Included ipx-1.0, made available by Greg Page <greg@caldera.com>,
|
||||
Caldera
|
||||
- Made -n work for password-less accounts. Thanks to Alexander Jolk
|
||||
<jolk@ap-pc513b.physik.uni-karlsruhe.de>.
|
||||
- Fixed the kerneld support.
|
||||
- Fixed the NetWare 4.1 problem. Many thanks to
|
||||
Chatchai JANTARAPRIM <chat@ratree.psu.ac.th> and
|
||||
hitesh.soneji@industry.net for their patience.
|
||||
|
||||
ncpfs-0.14 -> ncpfs-0.15
|
||||
|
||||
- A bug fixed that made normal mounting impossible. It was too late
|
||||
yesterday. Sorry
|
||||
- Manpage for pserver.c
|
||||
|
||||
ncpfs-0.13 -> ncpfs-0.14
|
||||
|
||||
- Improvements of manual pages by B. Galliart <bgallia@luc.edu> and
|
||||
Terry Dawson <terry@perf.no.itg.telecom.com.au>
|
||||
- fsinfo
|
||||
- pserver.c. Please see this as ALPHA software. There is no
|
||||
documentation, and it is not tested enough. But it might be useful for
|
||||
you.
|
||||
|
||||
ncpfs-0.12 -> ncpfs-0.13
|
||||
|
||||
- support for automatic loading of ncpfs.o by kerneld.
|
||||
Thanks to Steven N. Hirsch <hirsch@emba.uvm.edu>.
|
||||
- A subtle problem in the read routines has been removed by Uwe Bonnes
|
||||
<bon@elektron.ikp.physik.th-darmstadt.de>. Thanks a lot.
|
||||
27
Makefile
27
Makefile
@@ -2,12 +2,12 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
# KERNEL = 1.2
|
||||
|
||||
VERSION = 0.16
|
||||
TOPDIR = $(shell pwd)
|
||||
|
||||
BINDIR = $(TOPDIR)/bin
|
||||
SUBDIRS = util ipx-0.75
|
||||
BINDIR = /usr/local/bin
|
||||
INTERM_BINDIR = $(TOPDIR)/bin
|
||||
SUBDIRS = util ipx-1.0 man
|
||||
|
||||
#
|
||||
# The following 2 lines are for those who use Kernel version 1.2.x.
|
||||
@@ -15,10 +15,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 VERSION
|
||||
|
||||
all:
|
||||
for i in $(SUBDIRS); do make -C $$i; done
|
||||
@@ -26,6 +30,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`
|
||||
@@ -33,8 +40,8 @@ clean:
|
||||
rm -f `find . -type f -name '*.out' -print`
|
||||
for i in $(SUBDIRS); do make -C $$i clean; done
|
||||
|
||||
realclean: clean
|
||||
rm -fr $(BINDIR)/* ncpfs.tgz
|
||||
mrproper: clean
|
||||
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
|
||||
make -C util realclean
|
||||
|
||||
modules: ncpfs.o
|
||||
@@ -47,7 +54,7 @@ dist: tgz
|
||||
make dep
|
||||
make all
|
||||
|
||||
tgz: realclean
|
||||
tgz: mrproper
|
||||
(cd ..; \
|
||||
tar cvf - $(SRCDIR) | \
|
||||
gzip -9 > $(DISTFILE); \
|
||||
|
||||
59
README
59
README
@@ -1,30 +1,19 @@
|
||||
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. The opposite side, pserver, is also
|
||||
provided.
|
||||
|
||||
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 +43,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 +64,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 +100,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!
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
CFLAGS = -O2 -Wall
|
||||
BINDIR = ../bin
|
||||
UTILS = $(BINDIR)/ipx_configure $(BINDIR)/ipx_interface \
|
||||
$(BINDIR)/ipx_internal_net $(BINDIR)/ipx_route
|
||||
|
||||
all: $(UTILS)
|
||||
|
||||
$(BINDIR)/ipx_configure: ipx_configure.o
|
||||
$(CC) -o $(BINDIR)/ipx_configure ipx_configure.o
|
||||
|
||||
$(BINDIR)/ipx_interface: ipx_interface.o
|
||||
$(CC) -o $(BINDIR)/ipx_interface ipx_interface.o
|
||||
|
||||
$(BINDIR)/ipx_internal_net: ipx_internal_net.o
|
||||
$(CC) -o $(BINDIR)/ipx_internal_net ipx_internal_net.o
|
||||
|
||||
$(BINDIR)/ipx_route: ipx_route.o
|
||||
$(CC) -o $(BINDIR)/ipx_route ipx_route.o
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install --strip $$i /sbin; \
|
||||
install $$i.8 /usr/man/man8; \
|
||||
done
|
||||
|
||||
9
ipx-1.0/COPYING
Normal file
9
ipx-1.0/COPYING
Normal file
@@ -0,0 +1,9 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the original work is
|
||||
properly attributed to Greg Page and Caldera, Inc.
|
||||
Neither the name of Greg Page nor Caldera, Inc. may be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
This software is provided by Greg Page and Caldera, Inc. "AS IS"
|
||||
and without any express or implied warranties.
|
||||
|
||||
24
ipx-1.0/Gregs.Makefile
Normal file
24
ipx-1.0/Gregs.Makefile
Normal file
@@ -0,0 +1,24 @@
|
||||
CFLAGS = -O2 -Wall
|
||||
UTILS = ipx_configure ipx_interface ipx_internal_net ipx_route
|
||||
all: $(UTILS)
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install --strip $$i /sbin; \
|
||||
install $$i.8 /usr/man/man8; \
|
||||
done
|
||||
install init.ipx /etc/rc.d/init.d/ipx
|
||||
install -m 0644 config.ipx /etc/sysconfig/ipx
|
||||
rm -f /etc/rc.d/rc2.d/S15ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc2.d/S15ipx
|
||||
rm -f /etc/rc.d/rc3.d/S15ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc3.d/S15ipx
|
||||
rm -f /etc/rc.d/rc5.d/S15ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc5.d/S15ipx
|
||||
rm -f /etc/rc.d/rc6.d/K55ipx
|
||||
ln -sf /etc/rc.d/init.d/ipx /etc/rc.d/rc6.d/K55ipx
|
||||
|
||||
30
ipx-1.0/Makefile
Normal file
30
ipx-1.0/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
CFLAGS = -O2 -Wall
|
||||
UTILS = $(INTERM_BINDIR)/ipx_configure $(INTERM_BINDIR)/ipx_interface \
|
||||
$(INTERM_BINDIR)/ipx_internal_net $(INTERM_BINDIR)/ipx_route
|
||||
|
||||
all: $(UTILS)
|
||||
|
||||
$(INTERM_BINDIR)/ipx_configure: ipx_configure.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_configure ipx_configure.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_interface: ipx_interface.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_interface ipx_interface.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_internal_net: ipx_internal_net.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_internal_net ipx_internal_net.o
|
||||
|
||||
$(INTERM_BINDIR)/ipx_route: ipx_route.o
|
||||
$(CC) -o $(INTERM_BINDIR)/ipx_route ipx_route.o
|
||||
|
||||
dep:
|
||||
$(CPP) -M $(INCLUDES) *.c > .depend
|
||||
|
||||
clean:
|
||||
rm -f $(UTILS) *.o rip sap ipxrcv ipxsend
|
||||
|
||||
install: $(UTILS)
|
||||
for i in $(UTILS); \
|
||||
do \
|
||||
install $$i $(BINDIR); \
|
||||
done
|
||||
|
||||
@@ -47,7 +47,7 @@ This program is used to read/write two configuration parameters:
|
||||
|
||||
By default, these are both turned off.
|
||||
|
||||
The following are sample IPX programs:
|
||||
The following are sample IPX programs (found in directory Samples):
|
||||
|
||||
ipxrcv.c and ipxsend.c
|
||||
ipxsend will send a single packet to an instance of ipxrcv running on the
|
||||
@@ -51,7 +51,7 @@ main(int argc, char **argv)
|
||||
htonl(sipx.sipx_network),
|
||||
sipx.sipx_node[0], sipx.sipx_node[1],
|
||||
sipx.sipx_node[2], sipx.sipx_node[3],
|
||||
sipx.sipx_node[4], sipx.sipx_node[5]);
|
||||
sipx.sipx_node[6], sipx.sipx_node[5]);
|
||||
bptr += 2;
|
||||
rp = (struct rip_data *) bptr;
|
||||
while (result >= sizeof(struct rip_data)) {
|
||||
7
ipx-1.0/config.ipx
Normal file
7
ipx-1.0/config.ipx
Normal file
@@ -0,0 +1,7 @@
|
||||
IPX_AUTO_PRIMARY=on
|
||||
IPX_AUTO_INTERFACE=on
|
||||
IPX_CONFIGURED=no
|
||||
IPX_DEVICE=eth0
|
||||
IPX_FRAME=802.2
|
||||
IPX_INTERNAL_NET=no
|
||||
IPX_NETNUM=0
|
||||
41
ipx-1.0/init.ipx
Normal file
41
ipx-1.0/init.ipx
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# ipx Bring up/down IPX networking
|
||||
#
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
. /etc/sysconfig/network
|
||||
. /etc/sysconfig/ipx
|
||||
|
||||
# Check that networking is up.
|
||||
[ ${NETWORKING} = "no" ] && exit 0
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
if [ ${IPX_CONFIGURED} = "yes" ]; then
|
||||
if [ ${IPX_INTERNAL_NET} = "yes" ]; then
|
||||
/sbin/ipx_internal_net add ${IPX_NETNUM}
|
||||
else
|
||||
/sbin/ipx_interface add -p ${IPX_DEVICE} \
|
||||
${IPX_FRAME} ${IPX_NETNUM}
|
||||
fi
|
||||
fi
|
||||
ipx_configure \
|
||||
--auto_primary=${IPX_AUTO_PRIMARY} \
|
||||
--auto_interface=${IPX_AUTO_INTERFACE}
|
||||
touch /var/lock/subsys/ipx
|
||||
;;
|
||||
stop)
|
||||
ipx_configure --auto_primary=off --auto_interface=off
|
||||
ipx_interface delall
|
||||
rm -f /var/lock/subsys/ipx
|
||||
;;
|
||||
*)
|
||||
echo "Usage: network {start|stop}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@@ -19,7 +24,8 @@ usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s add [-p] device frame_type [net_number]\n\
|
||||
Usage: %s del device frame_type\n\
|
||||
Usage: %s check device frame_type\n", progname, progname, progname);
|
||||
Usage: %s delall\n\
|
||||
Usage: %s check device frame_type\n", progname, progname, progname, progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@@ -28,6 +34,9 @@ struct frame_type {
|
||||
unsigned char ft_val;
|
||||
} frame_types[] = {
|
||||
{"802.2", IPX_FRAME_8022},
|
||||
#ifdef IPX_FRAME_TR_8022
|
||||
{"802.2TR", IPX_FRAME_TR_8022},
|
||||
#endif
|
||||
{"802.3", IPX_FRAME_8023},
|
||||
{"SNAP", IPX_FRAME_SNAP},
|
||||
{"EtherII", IPX_FRAME_ETHERII}
|
||||
@@ -162,6 +171,76 @@ ipx_add_interface(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_delall_interface(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)&id.ifr_addr;
|
||||
int s;
|
||||
int result;
|
||||
char errmsg[80];
|
||||
char buffer[80];
|
||||
char device[20];
|
||||
char frame_type[20];
|
||||
int fti;
|
||||
FILE *fp;
|
||||
|
||||
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
if (s < 0) {
|
||||
sprintf(errmsg, "%s: socket", progname);
|
||||
perror(errmsg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fp = fopen("/proc/net/ipx_interface", "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: Unable to open \"/proc/net/ipx_interface.\"\n",
|
||||
progname);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fgets(buffer, 80, fp);
|
||||
while (fscanf(fp, "%s %s %s %s %s", buffer, buffer, buffer,
|
||||
device, frame_type) == 5) {
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
if (strcasecmp(device, "Internal") == 0) {
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
} else {
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
strcpy(id.ifr_name, device);
|
||||
fti = lookup_frame_type(frame_type);
|
||||
if (fti < 0) continue;
|
||||
sipx->sipx_type = frame_types[fti].ft_val;
|
||||
}
|
||||
|
||||
sipx->sipx_action = IPX_DLTITF;
|
||||
sipx->sipx_family = AF_IPX;
|
||||
result = ioctl(s, SIOCSIFADDR, &id);
|
||||
if (result == 0) continue;
|
||||
switch (errno) {
|
||||
case EPROTONOSUPPORT:
|
||||
fprintf(stderr, "%s: Invalid frame type (%s).\n",
|
||||
progname, frame_type);
|
||||
break;
|
||||
case ENODEV:
|
||||
fprintf(stderr, "%s: No such device (%s).\n",
|
||||
progname, device);
|
||||
break;
|
||||
case EINVAL:
|
||||
fprintf(stderr, "%s: No such IPX interface %s %s.\n",
|
||||
progname, device, frame_type);
|
||||
break;
|
||||
default:
|
||||
sprintf(errmsg, "%s: ioctl", progname);
|
||||
perror(errmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
ipx_del_interface(int argc, char **argv)
|
||||
{
|
||||
@@ -176,6 +255,7 @@ ipx_del_interface(int argc, char **argv)
|
||||
}
|
||||
|
||||
sipx->sipx_network = 0L;
|
||||
sipx->sipx_special = IPX_SPECIAL_NONE;
|
||||
strcpy(id.ifr_name, argv[1]);
|
||||
fti = lookup_frame_type(argv[2]);
|
||||
if (fti < 0)
|
||||
@@ -289,6 +369,10 @@ main(int argc, char **argv)
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_add_interface(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "delall", 6) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
ipx_delall_interface(argc-1, argv);
|
||||
} else if (strncasecmp(argv[1], "del", 3) == 0) {
|
||||
for (i = 1; i < (argc-1); i++)
|
||||
argv[i] = argv[i+1];
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Copyright (c) 1995-1996 Caldera, Inc. All Rights Reserved.
|
||||
*
|
||||
* See file COPYING for details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
CFLAGS = -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer \
|
||||
$(INCLUDES) \
|
||||
$(INCLUDES) -DNCPFS_VERSION=\"$(VERSION)\"\
|
||||
# -DDEBUG_NCP=1 -DDEBUG_NCP_MALLOC
|
||||
# -DDEBUG_NCP_MALLOC
|
||||
|
||||
@@ -20,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
|
||||
|
||||
@@ -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;
|
||||
@@ -795,7 +797,8 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
|
||||
|
||||
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
|
||||
NCP_ISTRUCT(dir), _name,
|
||||
OC_MODE_CREATE|OC_MODE_OPEN,
|
||||
OC_MODE_CREATE|OC_MODE_OPEN|
|
||||
OC_MODE_REPLACE,
|
||||
0, AR_READ|AR_WRITE,
|
||||
&finfo) != 0)
|
||||
{
|
||||
@@ -893,7 +896,7 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
|
||||
}
|
||||
else
|
||||
{
|
||||
error = -EINVAL;
|
||||
error = -EACCES;
|
||||
}
|
||||
}
|
||||
iput(dir);
|
||||
@@ -930,7 +933,7 @@ ncp_unlink(struct inode *dir, const char *name, int len)
|
||||
}
|
||||
else
|
||||
{
|
||||
error = -EINVAL;
|
||||
error = -EACCES;
|
||||
}
|
||||
}
|
||||
iput(dir);
|
||||
|
||||
@@ -510,6 +510,7 @@ init_module( void)
|
||||
|
||||
ncp_init_dir_cache();
|
||||
register_filesystem(&ncp_fs_type);
|
||||
printk("ncpfs version %s loaded\n", NCPFS_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -417,12 +417,18 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
|
||||
struct nw_file_info *target)
|
||||
{
|
||||
int result;
|
||||
__u16 search_attribs = 0x0006;
|
||||
|
||||
if ((create_attributes & aDIR) != 0)
|
||||
{
|
||||
search_attribs |= 0x8000;
|
||||
}
|
||||
|
||||
ncp_init_request(server);
|
||||
ncp_add_byte(server, 1); /* subfunction */
|
||||
ncp_add_byte(server, 0); /* dos name space */
|
||||
ncp_add_byte(server, open_create_mode);
|
||||
ncp_add_word(server, 0x8006);
|
||||
ncp_add_word(server, search_attribs);
|
||||
ncp_add_dword(server, RIM_ALL);
|
||||
ncp_add_dword(server, create_attributes);
|
||||
/* The desired acc rights seem to be the inherited rights mask
|
||||
@@ -583,7 +589,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
16
man/Makefile
Normal 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:
|
||||
@@ -9,6 +9,9 @@ add [-p] device frame_type [network number]
|
||||
del device frame_type
|
||||
.LP
|
||||
.B ipx_interface
|
||||
delall
|
||||
.LP
|
||||
.B ipx_interface
|
||||
check device frame_type
|
||||
.LP
|
||||
.B ipx_interface
|
||||
@@ -45,6 +48,9 @@ network.
|
||||
.I del
|
||||
This option is used to delete an IPX interface.
|
||||
.TP
|
||||
.I delall
|
||||
This option is used to delete all IPX interfaces.
|
||||
.TP
|
||||
.I check
|
||||
This option is used to display the device, frame type, and network number
|
||||
of an IPX interface.
|
||||
|
||||
124
man/ncpmount.8
124
man/ncpmount.8
@@ -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
|
||||
] [
|
||||
@@ -36,14 +33,17 @@ ncpmount \- mount program for ncpfs
|
||||
] [
|
||||
.B -d
|
||||
.I dir mode
|
||||
]
|
||||
] [
|
||||
.B -v
|
||||
]
|
||||
mount-point
|
||||
|
||||
.SH DESCRIPTION
|
||||
This program is an interface to the NCP filesystem.
|
||||
This program is used to mount all volumes of the specified NetWare Fileserver
|
||||
under the specified mount point.
|
||||
|
||||
.B ncpfs
|
||||
is a filesystem which understands the NCP protocol. This is the
|
||||
is a linux filesystem which understands the NCP protocol. This is the
|
||||
protocol Novell NetWare clients use to talk to NetWare servers. ncpfs
|
||||
was inspired by
|
||||
.B lwared,
|
||||
@@ -51,18 +51,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 +95,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 +136,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 +176,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
|
||||
@@ -169,8 +188,15 @@ can very well choose a file mode that tells that you have. This
|
||||
certainly cannot override the restrictions imposed by the server.
|
||||
.RE
|
||||
|
||||
.B -v
|
||||
.RS 3
|
||||
Print ncpfs version number
|
||||
.RE
|
||||
|
||||
.SH NOTES
|
||||
If you have difficulties in mounting, please make sure that you have configured your ipx subsystem correctly. It is especially important that there is a route to the internal network of your server.
|
||||
You must configure the IPX subsystem before ncpmount will work.
|
||||
It is especially important that there is a route to the internal network
|
||||
of your server.
|
||||
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
.B USER / LOGNAME
|
||||
|
||||
@@ -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
|
||||
|
||||
136
man/nprint.1
136
man/nprint.1
@@ -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)
|
||||
|
||||
@@ -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
105
man/pqlist.1
Normal 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
142
man/pserver.1
Normal file
@@ -0,0 +1,142 @@
|
||||
.TH PSERVER 1 02/10/1996 pserver pserver
|
||||
.SH NAME
|
||||
pserver \- NetWare print server
|
||||
.SH SYNOPSIS
|
||||
.B pserver
|
||||
[
|
||||
.B -S
|
||||
.I server
|
||||
] [
|
||||
.B -h
|
||||
] [
|
||||
.B -U
|
||||
.I user name
|
||||
] [
|
||||
.B -P
|
||||
.I password
|
||||
|
|
||||
.B -n
|
||||
] [
|
||||
.B -C
|
||||
] [
|
||||
.B -q
|
||||
.I queue name
|
||||
] [
|
||||
.B -c
|
||||
.I command
|
||||
] [
|
||||
.B -j
|
||||
.I job type
|
||||
] [
|
||||
.B -t
|
||||
.I timeout
|
||||
] [
|
||||
.B -d
|
||||
]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B pserver
|
||||
is a program that connects to print queues on NetWare servers and
|
||||
feeds incoming print jobs to the Linux printing system.
|
||||
|
||||
.SH OPTIONS
|
||||
.B -h
|
||||
.RS 3
|
||||
.B -h
|
||||
is used to print out a short help text.
|
||||
.RE
|
||||
|
||||
.B -S
|
||||
.I server
|
||||
.RS 3
|
||||
.B server
|
||||
is the name of the server you want to use.
|
||||
.RE
|
||||
|
||||
.B -U
|
||||
.I user
|
||||
.RS 3
|
||||
.B user
|
||||
is the print server name at the server.
|
||||
.RE
|
||||
|
||||
.B -P
|
||||
.I password
|
||||
.RS 3
|
||||
.B password
|
||||
is the password to use for the print server at the server. If neither
|
||||
.B -n
|
||||
nor
|
||||
.B -P
|
||||
are given, and the user has no open connection to the server, pserver
|
||||
prompts for a password.
|
||||
.RE
|
||||
|
||||
.B -n
|
||||
.RS 3
|
||||
.B -n
|
||||
should be given if the print server does not require a password.
|
||||
.RE
|
||||
|
||||
.B -C
|
||||
.RS 3
|
||||
By default, passwords are converted to uppercase before they are sent
|
||||
to the server, because most servers require this. You can turn off
|
||||
this conversion by
|
||||
.B -C.
|
||||
.RE
|
||||
|
||||
.B -q
|
||||
.I queue name
|
||||
.RS 3
|
||||
.B queue name
|
||||
is the name of the print queue you want to service.
|
||||
.RE
|
||||
|
||||
.B -c
|
||||
.I command
|
||||
.RS 3
|
||||
When a job is received from the print queue, pserver forks off a new
|
||||
process, and feeds the job file to stdin.
|
||||
.I command
|
||||
is the printing command that is executed for each job. The default
|
||||
command is 'lpr'.
|
||||
.RE
|
||||
|
||||
.B -j
|
||||
.I job type
|
||||
.RS 3
|
||||
Each job in a NetWare print queue has a job type. For print jobs, this
|
||||
corresponds to the number of the form the job should be printed
|
||||
on. You can tell pserver that it should only receive jobs for one
|
||||
specific form from the queue. The default is -1, which means that
|
||||
everything is received.
|
||||
.RE
|
||||
|
||||
.B -t
|
||||
.I timeout
|
||||
.RS 3
|
||||
Pserver is not informed by NetWare servers when new jobs arrive. So a
|
||||
polling scheme has to be used. When there are no jobs to service,
|
||||
.I timeout
|
||||
tells pserver how long to wait between two requests. The default is 30
|
||||
seconds. When a job is finished, pserver asks the NetWare server
|
||||
immediately for a new job, and does not wait
|
||||
.I timeout
|
||||
seconds.
|
||||
.RE
|
||||
|
||||
.B -d
|
||||
.RS 3
|
||||
Normally, pserver daemonizes itself.
|
||||
.B -d
|
||||
tells it not to do so. This is useful if you want to see the
|
||||
diagnostic messages that are printed when a error occurs.
|
||||
.RE
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
.B nwclient(5), slist(1), pqlist(1), ncpmount(8), ncpumount(8)
|
||||
|
||||
.SH CREDITS
|
||||
pserver was written by Volker Lendecke (lendecke@namu01.gwdg.de)
|
||||
43
man/slist.1
Normal file
43
man/slist.1
Normal 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)
|
||||
@@ -1,15 +0,0 @@
|
||||
Begin3
|
||||
Title: ncpfs
|
||||
Version: 0.10
|
||||
Entered-date: 03. January 1996
|
||||
Description: With ncpfs you can mount volumes of your novell
|
||||
server under Linux.
|
||||
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
|
||||
Copying-policy: GPL
|
||||
End
|
||||
19
ncpfs-0.16.lsm
Normal file
19
ncpfs-0.16.lsm
Normal file
@@ -0,0 +1,19 @@
|
||||
Begin3
|
||||
Title: ncpfs
|
||||
Version: 0.16
|
||||
Entered-date: 21. February 1996
|
||||
Description: With ncpfs you can mount volumes of your netware
|
||||
server under Linux. You can also print to netware
|
||||
print queues and spool netware print queues to the
|
||||
Linux printing system. You need kernel 1.2.x or
|
||||
1.3.54 and above. ncpfs does NOT work with any 1.3.x
|
||||
kernel below 1.3.54.
|
||||
Keywords: filesystem ncp novell netware printing
|
||||
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/
|
||||
~73k ncpfs-0.16.tgz
|
||||
~ 1k ncpfs-0.16.lsm
|
||||
Copying-policy: GPL
|
||||
End
|
||||
@@ -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 -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -O2 -DNCPFS_VERSION=\"$(VERSION)\"
|
||||
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
78
util/fsinfo.c
Normal 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;
|
||||
}
|
||||
678
util/ncplib.c
678
util/ncplib.c
@@ -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))
|
||||
@@ -1104,35 +1237,36 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
}
|
||||
fclose(nwc);
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(spec.user) == 0)
|
||||
|
||||
if (strlen(spec.user) == 0)
|
||||
{
|
||||
return &spec;
|
||||
}
|
||||
|
||||
if (strlen(spec.password) == 0)
|
||||
{
|
||||
char *password;
|
||||
if (!(isatty(0) && isatty(1)))
|
||||
{
|
||||
return &spec;
|
||||
return NULL;
|
||||
}
|
||||
printf("Logging into %s as %s\n",
|
||||
spec.server, spec.user);
|
||||
|
||||
if (strlen(spec.password) == 0)
|
||||
password = getpass("Password: ");
|
||||
if (strlen(password) > sizeof(spec.password))
|
||||
{
|
||||
char *password;
|
||||
if (!(isatty(0) && isatty(1)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
printf("Logging into %s as %s\n",
|
||||
spec.server, spec.user);
|
||||
|
||||
password = getpass("Password: ");
|
||||
if (strlen(password) > sizeof(spec.password))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
strcpy(spec.password, password);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
strcpy(spec.password, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(spec.password, NWC_NOPASSWORD) == 0)
|
||||
{
|
||||
if (strcmp(spec.password, NWC_NOPASSWORD) == 0)
|
||||
{
|
||||
*spec.password = '\0';
|
||||
}
|
||||
*spec.password = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1141,102 +1275,113 @@ 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;
|
||||
}
|
||||
password = NWC_NOPASSWORD;
|
||||
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 +1397,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 +1566,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 +1773,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 +1791,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 +1828,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 +1910,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 +1975,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 +2031,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 +2383,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 +2408,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 +2418,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 +2504,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 +2528,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,
|
||||
@@ -2380,3 +2741,68 @@ ncp_write(struct ncp_conn *conn, const char *file_id,
|
||||
}
|
||||
return already_written;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256])
|
||||
{
|
||||
int result;
|
||||
int length;
|
||||
|
||||
ncp_init_request_s(conn, 1);
|
||||
|
||||
if ((result = ncp_request(conn, 21)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
length = ncp_reply_byte(conn, 0);
|
||||
message[length] = 0;
|
||||
memcpy(message, ncp_reply_data(conn, 1), length);
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 20);
|
||||
ncp_add_byte(conn, dir_handle);
|
||||
|
||||
if ((result = ncp_request(conn, 22)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_alloc_short_dir_handle(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir,
|
||||
word alloc_mode,
|
||||
byte *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(conn);
|
||||
ncp_add_byte(conn, 12); /* subfunction */
|
||||
ncp_add_byte(conn, 0); /* dos name space */
|
||||
ncp_add_byte(conn, 0); /* reserved */
|
||||
ncp_add_word(conn, htons(alloc_mode));
|
||||
ncp_add_handle_path(conn, dir->volNumber, dir->DosDirNum,
|
||||
1, NULL);
|
||||
|
||||
if ((result = ncp_request(conn, 87)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
*target = ncp_reply_byte(conn, 0);
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -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,40 @@ 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);
|
||||
|
||||
int
|
||||
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
|
||||
|
||||
int
|
||||
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)
|
||||
|
||||
int
|
||||
ncp_alloc_short_dir_handle(struct ncp_conn *conn,
|
||||
struct nw_info_struct *dir,
|
||||
__u16 alloc_mode,
|
||||
__u8 *target);
|
||||
|
||||
#endif /* _NCPLIB_H */
|
||||
|
||||
@@ -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,25 +177,25 @@ 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);
|
||||
umask(um);
|
||||
data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
|
||||
data.dir_mode = 0;
|
||||
data.flags |= NCP_MOUNT_SOFT;
|
||||
|
||||
upcase_password = 1;
|
||||
|
||||
while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nh")) != EOF)
|
||||
while ((opt = getopt (argc, argv, "CS:U:c:u:g:f:d:P:nhv")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
@@ -306,6 +291,9 @@ main(int argc, char *argv[])
|
||||
case 'h':
|
||||
help();
|
||||
exit(1);
|
||||
case 'v':
|
||||
fprintf(stderr, "ncpfs version %s\n", NCPFS_VERSION);
|
||||
exit(1);
|
||||
default:
|
||||
usage();
|
||||
return -1;
|
||||
@@ -346,6 +334,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 +342,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 +395,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)
|
||||
@@ -437,6 +427,31 @@ main(int argc, char *argv[])
|
||||
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;
|
||||
|
||||
data.time_out = 20;
|
||||
@@ -505,15 +520,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)
|
||||
{
|
||||
@@ -541,5 +547,6 @@ help(void)
|
||||
" 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");
|
||||
}
|
||||
|
||||
112
util/ncptest.c
112
util/ncptest.c
@@ -96,24 +96,110 @@ 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;
|
||||
}
|
||||
|
||||
void
|
||||
test_create(struct ncp_conn *conn)
|
||||
{
|
||||
struct nw_info_struct sys;
|
||||
struct nw_info_struct me;
|
||||
__u8 dir_handle;
|
||||
struct ncp_file_info new_file;
|
||||
|
||||
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 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");
|
||||
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_create(&conn);
|
||||
ncp_close(&conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
135
util/nprint.c
135
util/nprint.c
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
75
util/pqlist.c
Normal 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
338
util/pserver.c
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user