diff --git a/.downloads/ncpfs-0.11.tgz b/.downloads/ncpfs-0.11.tgz new file mode 100644 index 0000000..4512242 Binary files /dev/null and b/.downloads/ncpfs-0.11.tgz differ diff --git a/Makefile b/Makefile index 3b59b8e..ee83bf3 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README b/README index 7883bdc..18bf944 100644 --- a/README +++ b/README @@ -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 +. 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! diff --git a/ipx-0.75/Makefile b/ipx-0.75/Makefile index 278ce08..f2a2a8a 100644 --- a/ipx-0.75/Makefile +++ b/ipx-0.75/Makefile @@ -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 diff --git a/kernel-1.2/src/Makefile b/kernel-1.2/src/Makefile index 39530ca..a12973b 100644 --- a/kernel-1.2/src/Makefile +++ b/kernel-1.2/src/Makefile @@ -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 diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 0000000..129ba0c --- /dev/null +++ b/man/Makefile @@ -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: diff --git a/man/ncpmount.8 b/man/ncpmount.8 index c4c95c9..3061872 100644 --- a/man/ncpmount.8 +++ b/man/ncpmount.8 @@ -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 diff --git a/man/nprint.1 b/man/nprint.1 index 1e1090e..04e6404 100644 --- a/man/nprint.1 +++ b/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 @@ -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 + diff --git a/man/pqlist.1 b/man/pqlist.1 new file mode 100644 index 0000000..8eca8b3 --- /dev/null +++ b/man/pqlist.1 @@ -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. diff --git a/man/slist.1 b/man/slist.1 new file mode 100644 index 0000000..1ed4b36 --- /dev/null +++ b/man/slist.1 @@ -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". diff --git a/ncpfs-0.10.lsm b/ncpfs-0.11.lsm similarity index 58% rename from ncpfs-0.10.lsm rename to ncpfs-0.11.lsm index bd4269b..acb2264 100644 --- a/ncpfs-0.10.lsm +++ b/ncpfs-0.11.lsm @@ -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 diff --git a/util/Makefile b/util/Makefile index f4455d6..cf5b50f 100644 --- a/util/Makefile +++ b/util/Makefile @@ -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 + diff --git a/util/fsinfo.c b/util/fsinfo.c new file mode 100644 index 0000000..fda3174 --- /dev/null +++ b/util/fsinfo.c @@ -0,0 +1,46 @@ +/* + * fsinfo.c + * + * Print the info strings of a server, maybe sometime more. + * + * Copyright (C) 1996 by Volker Lendecke + * + */ + +#include +#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; +} diff --git a/util/ncplib.c b/util/ncplib.c index 7ab262c..c35c9cc 100644 --- a/util/ncplib.c +++ b/util/ncplib.c @@ -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); diff --git a/util/ncplib.h b/util/ncplib.h index 38477e4..4bc2076 100644 --- a/util/ncplib.h +++ b/util/ncplib.h @@ -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); diff --git a/util/ncpmount.c b/util/ncpmount.c index e2161d7..5079390 100644 --- a/util/ncpmount.c +++ b/util/ncpmount.c @@ -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) diff --git a/util/nprint.c b/util/nprint.c index e0d659a..fd61b8d 100644 --- a/util/nprint.c +++ b/util/nprint.c @@ -1,57 +1,35 @@ /* * nwprint.c * + * Send data to a NetWare print queue. + * * Copyright (C) 1995 by Volker Lendecke * */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* #include */ /* generates a warning here */ -extern pid_t waitpid(pid_t, int *, int); -#include #include #include #include -#include #include -#include -#include -#include +#include -#include -#include -#include -#include #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; + } +} diff --git a/util/nwlsconn.c b/util/nwlsconn.c deleted file mode 100644 index d921a6a..0000000 --- a/util/nwlsconn.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * nwlsconn.c - * - * Copyright (C) 1995 by Volker Lendecke - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 ? "" : pwd->pw_name); - } -} diff --git a/util/pqlist.c b/util/pqlist.c new file mode 100644 index 0000000..3958f65 --- /dev/null +++ b/util/pqlist.c @@ -0,0 +1,75 @@ +/* + * pqlist.c + * + * List all print queues on a server + * + * Copyright (C) 1996 by Volker Lendecke + * + */ + +#include +#include +#include +#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; +} diff --git a/util/slist.c b/util/slist.c index e34f569..b0b4206 100644 --- a/util/slist.c +++ b/util/slist.c @@ -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);