Import ncpfs 0.11

This commit is contained in:
ncpfs archive import
2026-04-28 20:39:57 +02:00
parent 517e207709
commit 20589ca203
20 changed files with 678 additions and 287 deletions

BIN
.downloads/ncpfs-0.11.tgz Normal file

Binary file not shown.

View File

@@ -6,8 +6,9 @@
TOPDIR = $(shell pwd)
BINDIR = $(TOPDIR)/bin
SUBDIRS = util ipx-0.75
BINDIR = /usr/local/bin
INTERM_BINDIR = $(TOPDIR)/bin
SUBDIRS = util ipx-0.75 man
#
# The following 2 lines are for those who use Kernel version 1.2.x.
@@ -18,7 +19,7 @@ SUBDIRS = util ipx-0.75
SUBDIRS += kernel-1.2/src
INCLUDES = -I$(TOPDIR)/kernel-1.2
export INCLUDES BINDIR
export INCLUDES BINDIR INTERM_BINDIR
all:
for i in $(SUBDIRS); do make -C $$i; done
@@ -26,6 +27,9 @@ all:
dep:
for i in $(SUBDIRS); do make -C $$i dep; done
install:
for i in $(SUBDIRS); do make -C $$i install; done
clean:
rm -f `find . -type f -name '*.o' -print`
rm -f `find . -type f -name '*~' -print`
@@ -34,7 +38,7 @@ clean:
for i in $(SUBDIRS); do make -C $$i clean; done
realclean: clean
rm -fr $(BINDIR)/* ncpfs.tgz
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
make -C util realclean
modules: ncpfs.o

49
README
View File

@@ -1,30 +1,23 @@
This is version 0.10 of ncpfs, a free NetWare client filesystem for
This is version 0.11 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.
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 +47,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 +68,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>. Up to now 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 +104,14 @@ different. You can never know when the client will access the file-id
you offered, so you would have to cache the inode numbers
indefinitely long. I think this should not be done in kernel mode, as
it would require an unlimited amount of RAM.
Those who looked at the kernel code a bit closer will have found out
that the last section is a little white lie. As I found out after the
first version of ncpfs, NetWare does indeed offer something like inode
numbers, although are only unique per volume. So one way to make ncpfs
re-exportable by nfs is to allocate a superblock per volume and show
the inode numbers to the user. I was just too lazy to do this
yet. Maybe once we will force Novell to make NetWare NFS
affordable... ;-)
Have fun with ncpfs!

View File

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

View File

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

16
man/Makefile Normal file
View File

@@ -0,0 +1,16 @@
MAN1= slist nprint pqlist
MAN5= nwclient
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net ipx_route
all:
dep:
install:
for i in $(MAN1); do install $$i.1 -m 755 /usr/local/man/man1; done
for i in $(MAN5); do install $$i.5 -m 755 /usr/local/man/man5; done
for i in $(MAN8); do install $$i.8 -m 755 /usr/local/man/man8; done
clean:

View File

@@ -16,9 +16,6 @@ ncpmount \- mount program for ncpfs
] [
.B -C
] [
.B -s
.I server name
] [
.B -c
.I client name
] [
@@ -54,7 +51,7 @@ ftp://klokan.sh.cvut.cz/pub/linux for this very intersting program.
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 not that the access
nwclient(5) for more information. Please note that the access
permissions of .nwclient MUST be 600, for security reasons.
.SH OPTIONS
@@ -140,11 +137,29 @@ and a group it belongs to. With
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
This option is only makes sense if root mounts the directory. root can
mount directories on behalf of other users.
.B -c
names the user who is the
.I owner
of the connection, where owner is not meant in the unix sense (that
"owner" is set by -u), but as the one who has mounted the directory.
This way it could be possible to mount a public read-only directory,
but to allow the lp daemon to print on NetWare queues. This is
possible, because only users who have write permissions on a directory
may issue ncp requests over a connection. An exception is the owner
(in the sense mentioned above), who is also given 'request
permission'.
.RE
.B -f
.I file mode,
.B -d
@@ -157,7 +172,7 @@ and
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
permissions it should assign to the mounted files and directories. The
values have to be given as octal numbers. The default values are taken
from the current umask, where the file mode is the current umask, and
the dir mode adds execute permissions where the file mode gives read

View File

@@ -1,4 +1,4 @@
.TH NPRINT 8 12/27/1995 nprint nprint
.TH NPRINT 1 12/27/1995 nprint nprint
.SH NAME
nprint \- NetWare print client
.SH SYNOPSIS
@@ -11,14 +11,8 @@ nprint \- NetWare print client
] [
.B -n
] [
.B -P
.I password
] [
.B -C
] [
.B -S
.I server name
] [
.B -U
.I user name
] [
@@ -61,7 +55,7 @@ nprint \- NetWare print client
.B -F
.I form number
]
file
.B file
.SH DESCRIPTION
With
@@ -71,10 +65,6 @@ 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 :-).
.SH OPTIONS
.B file
.RS 3
@@ -90,6 +80,48 @@ 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 -q
.I queue name
.RS 3
.B queue name
is the name of the print queue to use at the print server. At
present, you must give it in upper case characters.
.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 +147,46 @@ 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 -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

39
man/pqlist.1 Normal file
View File

@@ -0,0 +1,39 @@
.TH PQLIST 1 01/10/1996 pqlist pqlist
.SH NAME
pqlist \- List available NetWare print queues
.SH SYNOPSIS
.B pqlist
[
.B -S
.I server
] [
.B -U
.I user name
] [
.B -n
] [
.B -P
.I password
] [
.I pattern
]
.SH DESCRIPTION
With
.B pqlist,
you can list the NetWare print queues available to you on some
server. If you are already connected to some server, this one is
used.
.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
See ncpmount(8) for an explanation of the other options. They are
necessary because you might have to login into a server before it
tells you where you may print.

36
man/slist.1 Normal file
View File

@@ -0,0 +1,36 @@
.TH SLIST 1 01/07/1996 slist slist
.SH NAME
slist \- List available NetWare Servers
.SH SYNOPSIS
.B slist
[
.I pattern
]
.SH DESCRIPTION
With
.B slist,
you can get a list of NetWare Servers available in your network. If
slist does not print to a tty, the decorative header line is not
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 selected servers. For a server to be listed, the
pattern must match the full server name. You can use wildcards for the
pattern, but you must protect these wildcards from any command line
expansion by quoting. Case doesn't matter.
.RE
.SH EXAMPLE
.TP
slist "I*"
.TP
or
.TP
slist "i*"
List all available Netware servers on your Network, that begin with an "I".

View File

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

View File

@@ -2,14 +2,20 @@
# 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
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
UIDUTILS = ncpmount ncpumount
CFLAGS = -Wall $(INCLUDES) -O2
CC = gcc
all: $(UTILS) ncptest
install: all
for i in $(UTIL_EXECS); \
do install --strip $(INTERM_BINDIR)/$$i -m 755 $(BINDIR); done
for i in $(UIDUTILS); do chmod 4755 $(BINDIR)/$$i; done
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) ncplib.o
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) ncplib.o
@@ -37,3 +43,4 @@ realclean: clean
ifeq (.depend,$(wildcard .depend))
include .depend
endif

46
util/fsinfo.c Normal file
View File

@@ -0,0 +1,46 @@
/*
* fsinfo.c
*
* Print the info strings of a server, maybe sometime more.
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include <stdio.h>
#include "ncplib.h"
int
main(int argc, char **argv)
{
struct ncp_conn conn;
char strings[512];
char *s;
if (ncp_initialize(&conn, &argc, argv, 0) != 0)
{
perror("Could not open connection");
return 1;
}
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;
}
ncp_close(&conn);
return 0;
}

View File

@@ -1,7 +1,7 @@
/*
* ncplib.c
*
* Copyright (C) 1995 by Volker Lendecke
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
@@ -208,7 +208,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 +222,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 +289,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 +305,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 +710,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,6 +833,8 @@ 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)
@@ -835,11 +843,119 @@ ncp_open_temporary(struct ncp_conn *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 +965,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 +1029,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 +1148,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 +1182,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 +1193,15 @@ 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);
if (ncp_open_permanent(&conn, &spec) == 0)
{
ncp_close(&conn);
return &spec;
}
if (password != NULL)
{
if (strlen(password) >= sizeof(spec.password))
@@ -1141,104 +1267,102 @@ 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(struct ncp_conn *conn,
int *argc, char **argv,
int login_necessary)
{
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;
return ncp_open_temporary(conn, spec);
}
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))
while (i < *argc)
{
if ( (argv[i][0] != '-')
|| (strlen(argv[i]) != 2))
{
i += 1;
continue;
}
switch (argv[i][1])
{
case 'S':
if (get_argument(i, &server) != 0)
{
return -1;
}
continue;
case 'U':
if (get_argument(i, &user) != 0)
{
return -1;
}
continue;
case 'P':
if (get_argument(i, &password) != 0)
{
return -1;
}
continue;
case 'n':
if (get_argument(i, 0) != 0)
{
return -1;
}
continue;
}
i += 1;
}
if (login_necessary == 0)
{
errno = 0;
return ncp_open(conn, NULL);
}
if ((spec = ncp_find_conn_spec(server, user, password,
getuid())) == NULL)
{
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;
}
errno = 0;
return ncp_open(conn, spec);
}
static int
ncp_request(struct ncp_conn *conn, int function)
{
@@ -1384,6 +1508,25 @@ 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;
}
/*
* result is a 8-byte buffer
*/
@@ -1574,7 +1717,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 +1799,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 +1864,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 +1920,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);

View File

@@ -1,7 +1,7 @@
/*
* ncplib.h
*
* Copyright (C) 1995 by Volker Lendecke
* Copyright (C) 1995, 1996 by Volker Lendecke
*
*/
@@ -17,6 +17,10 @@
#include "ipxlib.h"
#ifndef memzero
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif
enum connect_state {
NOT_CONNECTED = 0,
CONN_PERMANENT,
@@ -63,6 +67,16 @@ struct ncp_conn_spec {
char password[NCP_BINDERY_NAME_LEN];
};
/* 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);
/* Open an existing permanent connection */
int
ncp_open(struct ncp_conn *conn,
@@ -109,6 +123,10 @@ 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_encryption_key(struct ncp_conn *conn,
char *target);

View File

@@ -192,15 +192,14 @@ main(int argc, char *argv[])
progname = argv[0];
memzero(data); memzero(spec); memzero(conn);
if (geteuid() != 0)
{
fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
memset(&data, 0, sizeof(data));
memset(&spec, 0, sizeof(spec));
data.uid = getuid();
data.gid = getgid();
um = umask(0);
@@ -405,7 +404,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)

View File

@@ -1,57 +1,35 @@
/*
* 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
str_upper(char *name);
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 +46,13 @@ 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 (ncp_initialize(&conn, &argc, argv, 1) != 0)
{
perror("Could not open connection");
exit(1);
}
/*
* Fill in default values for print job
@@ -78,9 +61,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,8 +71,7 @@ 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, "q:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
{
switch (opt) {
case 'p':
@@ -195,39 +175,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 +252,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 +283,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 +301,12 @@ usage(void)
fprintf(stderr, "usage: %s [options] file\n", progname);
exit(1);
}
static void
str_upper(char *name)
{
while (*name) {
*name = toupper(*name);
name = name + 1;
}
}

View File

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

75
util/pqlist.c Normal file
View File

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

View File

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