Compare commits

..

1 Commits
v0.18 ... v0.19

Author SHA1 Message Date
ncpfs archive import
0520c1d2f7 Import ncpfs 0.19 2026-04-28 20:39:57 +02:00
45 changed files with 2872 additions and 759 deletions

BIN
.downloads/ncpfs-0.19.tgz Normal file

Binary file not shown.

10
Changes
View File

@@ -1,6 +1,16 @@
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.18 -> ncpfs-0.19
- hacked around in ncplib.[ch] quite heavily.
- SAP handling in ipxparse.c. Thanks to Jeff Buhrt <buhrt@iquest.net>
- Changed error handling to use the com_err library. This should
eventually provide better error messages, because it's now much
easier to define nice messages.
- If no server is active, report this correctly
- added nsend
ncpfs-0.17 -> ncpfs-0.18
- Another attempt at solving the problem that -n is not working.

View File

@@ -2,7 +2,7 @@
# Makefile for the linux ncp-filesystem routines.
#
VERSION = 0.18
VERSION = 0.19
TOPDIR = $(shell pwd)
BINDIR = /usr/local/bin
@@ -43,7 +43,7 @@ clean:
mrproper: clean
rm -fr $(INTERM_BINDIR)/* ncpfs.tgz
make -C util realclean
make -C util mrproper
modules: ncpfs.o

18
README
View File

@@ -30,13 +30,21 @@ problem.
HELP
To get more help you can subscribe to the LinWare mailing list:
control addr: listserv@sh.cvut.cz
posting addr: linware@sh.cvut.cz
In the meantime my mail volume has grown considerably, so the response
time might be better at the LinWare mailing list than at my personal
email address.
email address. You can mail to and/or subscribe to the LinWare mailing
list:
Topics for the list:
- discussing LinWare server, its features, installation problems and bugs
- using IPX protocol under Linux
- IPX routing and router daemons under Linux
- mars_nwe
- ncpfs
You can subscribe to the list by sending the command "add linware" in
the mail message body to address: "listserv@sh.cvut.cz". Your
postings should be sent to: "linware@sh.cvut.cz".
USING NCPFS

20
TODO Normal file
View File

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

View File

@@ -60,7 +60,7 @@ struct ipx_packet
void handle_frame (unsigned char *buf, int length, struct sockaddr *saddr);
void handle_ipx (unsigned char *buf);
void handle_ipx(char *frame, unsigned char *buf);
static int filter = 0;
static IPXNode filter_node;
@@ -147,7 +147,7 @@ main (int argc, char *argv[])
}
void
handle_ipx (unsigned char *buf)
handle_ipx (char *frame, unsigned char *buf)
{
int i;
struct ipx_packet *h = (struct ipx_packet *)buf;
@@ -179,6 +179,8 @@ handle_ipx (unsigned char *buf)
}
}
printf("%s ", frame);
for (i = 0; i < length; i++)
{
printf("%2.2X", buf[i]);
@@ -207,23 +209,20 @@ handle_other (unsigned char *buf, int length, struct sockaddr *saddr)
if (*(unsigned short *)p == 0xffff)
{
printf("802.3 ");
handle_ipx(p);
handle_ipx("802.3", p);
return;
}
if ( (*(unsigned short *)p == htons(0xe0e0))
&& (p[2] == 0x03))
{
printf("802.2 ");
handle_ipx(p+3);
handle_ipx("802.2", p+3);
return;
}
if (memcmp(p, "\252\252\003\000\000\000\201\067", 8) == 0)
{
printf("snap ");
handle_ipx(p+8);
handle_ipx("snap", p+8);
return;
}
}
@@ -237,8 +236,7 @@ handle_frame (unsigned char *buf, int length, struct sockaddr *saddr)
switch( packet_type )
{
case __constant_ntohs(ETH_P_IPX):
printf("EtherII ");
handle_ipx(&(buf[sizeof(struct ethhdr)]));
handle_ipx("EtherII ", &(buf[sizeof(struct ethhdr)]));
break;
default:
handle_other(buf, length, saddr);

View File

@@ -35,6 +35,8 @@
#include <ctype.h>
#include "ipxutil.h"
#define DUMPALLSAPS /* #define if you want to dump all SAP's */
struct ipx_address
{
unsigned long net;
@@ -92,12 +94,58 @@ void handle_ncp (struct sockaddr_ipx *source,
struct sockaddr_ipx *target,
unsigned char *buf, int length, int no);
#define SAP_MAX_SERVER_NAME_LENGTH 48 /* in network packets */
#define SAP_MAX_SAPS_PER_PACKET 7
#define SAP_SHUTDOWN 16 /* Magic "hops" value to stop SAP advertising */
/* SAP Query structure (returned in sap_packet as an array)
* NBO == Network Byte Order)
*/
typedef struct saps {
__u16 serverType __attribute__ ((packed)); /* NBO */
__u8 serverName[SAP_MAX_SERVER_NAME_LENGTH] __attribute__ ((packed));
struct ipx_address serverAddress __attribute__ ((packed));
__u16 serverHops __attribute__ ((packed)); /* NBO */
} SAPS;
/* General Service/Nearest Server Response SAP packet */
union sap_packet {
unsigned short sapOperation;
struct sap_query {
__u16 sapOperation __attribute__ ((packed));
__u16 serverType __attribute__ ((packed));
} query;
struct sap_response {
__u16 sapOperation __attribute__ ((packed));
/* each SAP can has a max of SAP_MAX_SAPS_PER_PACKET packets */
SAPS sap[SAP_MAX_SAPS_PER_PACKET] __attribute__ ((packed));
} response;
};
/* print out one SAP record */
static void
print_sap(FILE *file, SAPS *sapp)
{
fprintf(file, " Name:%s, serverType 0x%x, ",
sapp->serverName,
ntohs(sapp->serverType));
ipx_fprint_network(file, ntohl(sapp->serverAddress.net));
fprintf(file, ":");
ipx_fprint_node(file, sapp->serverAddress.node);
fprintf(file, ":");
ipx_fprint_port(file, ntohs(sapp->serverAddress.sock));
fprintf(file, " (Hops %d)\n", ntohs(sapp->serverHops));
}
void
handle_ipx (unsigned char *buf, int length, char *frame, int no)
{
struct ipx_packet *h = (struct ipx_packet *)buf;
struct sockaddr_ipx s_addr;
struct sockaddr_ipx d_addr;
union sap_packet *sappacket;
int hbo_dsock; /* Host Byte Order of Destination SOCKet */
int hbo_sapop; /* Host Byte Order of SAP OPeration */
memset(&s_addr, 0, sizeof(s_addr));
memset(&d_addr, 0, sizeof(d_addr));
@@ -123,6 +171,86 @@ handle_ipx (unsigned char *buf, int length, char *frame, int no)
handle_ncp(&s_addr, &d_addr, buf + sizeof(struct ipx_packet),
length - sizeof(struct ipx_packet), no);
}
else /* next 3 handle IPX by type vs by socket (one or other) */
/* Note: most things use either ipx_type OR socket, not both */
if (h->ipx_type == 0x01)
printf(" type 0x01 (RIP packet (router))\n");
else
if (h->ipx_type == 0x05)
printf(" type 0x05 (SPX sequenced packet)\n");
else
if (h->ipx_type == 0x14)
printf(" type 0x14 (propogated Client-NetBios)\n");
else
{
hbo_dsock = ntohs(d_addr.sipx_port);
if (hbo_dsock == 0x452) /* SAP */
{
sappacket = (union sap_packet *)
(buf + sizeof(struct ipx_packet));
hbo_sapop = ntohs(sappacket->sapOperation);
if ((hbo_sapop == 0x01) || (hbo_sapop == 0x03))
{
printf(" type 0x%x, SAP op:0x%x %s Query, "
"serverType 0x%x wanted\n",
h->ipx_type, hbo_sapop,
(hbo_sapop == 0x01)?"General Service" :
(hbo_sapop == 0x03)?"Nearest Server" :
"Error",
ntohs(sappacket->query.serverType));
}
else
{
int hops;
hops = ntohs(sappacket->
response.sap[0].serverHops);
printf(" type 0x%x, SAP op:0x%x %s %s\n",
h->ipx_type, hbo_sapop,
(hbo_sapop == 0x02)
? "General Service Response" :
(hbo_sapop == 0x04)
? "Nearest Server Response" :
"Unknown",
(hops >= SAP_SHUTDOWN)
? "[Shutdown]" : "");
/* Service ending */
if (hops >= SAP_SHUTDOWN)
{
print_sap(stdout,
sappacket->response.sap);
}
#ifdef DUMPALLSAPS
/* If you want to dump all SAP's */
else
{ int num_saps;
SAPS *sapp;
num_saps = (length
- sizeof(struct ipx_packet)
- 2) / sizeof(SAPS);
sapp = sappacket->response.sap;
for(; num_saps > 0; sapp++, num_saps--)
print_sap(stdout, sapp);
}
#endif /* DUMPALLSAPS */
}
}
else /* Other IPX types */
printf(" type 0x%x, Socket 0x%x (%s)\n", h->ipx_type,
hbo_dsock,
(hbo_dsock == 0x451) ? "NCP" :
/* (hbo_dsock == 0x452) ? "SAP" :*/
(hbo_dsock == 0x453) ? "RIP" :
(hbo_dsock == 0x455) ? "Client-NetBios" :
(hbo_dsock == 0x456) ? "Diags" :
(hbo_dsock == 0x002) ? "Xecho" :
(hbo_dsock == 0x8063) ? "NVT2" : "Other");
}
}
void handle_ncp (struct sockaddr_ipx *source,
@@ -183,6 +311,21 @@ void handle_ncp (struct sockaddr_ipx *source,
data += 1;
data_length -= 1;
break;
case 21:
printf("fn: %-3d, subfn: %-3d\n",
rq->function, data[2]);
switch(data[2])
{
case 0:
printf("Send Broadcast Message\n");
break;
case 1:
printf("Get Broadcast Message\n");
break;
}
data += 3;
data_length -= 3;
break;
case 22:
printf("fn: %-3d, subfn: %-3d\n",
rq->function, data[2]);
@@ -198,6 +341,19 @@ void handle_ncp (struct sockaddr_ipx *source,
case 23:
printf("fn: %-3d, subfn: %-3d\n", rq->function,
data[2]);
switch(data[2])
{
case 17:
printf("Get Fileserver Information\n");
break;
case 28:
printf("Get Connection Information\n");
break;
case 55:
printf("Scan Bindery Object\n");
break;
}
data += 3;
data_length -= 3;
break;
@@ -342,4 +498,3 @@ main (int argc, char *argv[])
exit (0);
}

View File

@@ -34,18 +34,16 @@ struct ncp_fs_info {
int buffer_size; /* The negotiated buffer size, to be
used for read/write requests! */
/* Not used yet, but here some day the namespace numbers will be
stored. */
int volume_number;
__u32 directory_id;
};
#define NCP_IOC_NCPREQUEST _IOR('n', 1, unsigned char *)
#define NCP_IOC_GETMOUNTUID _IOR('u', 1, uid_t)
#define NCP_IOC_CONN_LOGGED_IN _IO('l', 1)
#define NCP_IOC_NCPREQUEST _IOR('n', 1, struct ncp_ioctl_request)
#define NCP_IOC_GETMOUNTUID _IOW('n', 2, uid_t)
#define NCP_IOC_CONN_LOGGED_IN _IO('n', 3)
#define NCP_GET_FS_INFO_VERSION (1)
#define NCP_IOC_GET_FS_INFO _IOWR('i', 1, unsigned char *)
#define NCP_IOC_GET_FS_INFO _IOWR('n', 4, struct ncp_fs_info)
/*
* The packet size to allocate. One page should be enough.

View File

@@ -723,6 +723,11 @@ ncp_find_dir_inode(struct inode *dir, const char *name)
if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
&& (result->dir->finfo.i.volNumber == dir_info->volNumber)
&& (strcmp(result->finfo.i.entryName, name) == 0)
/* The root dir is never looked up using this
* routine. Without the following test a root
* directory 'sys' in a volume named 'sys' could
* never be looked up, because
* server->root->dir==server->root. */
&& (result != &(server->root)))
{
return result;

View File

@@ -29,6 +29,26 @@ ncp_ioctl (struct inode * inode, struct file * filp,
struct ncp_fs_info info;
struct ncp_server *server = NCP_SERVER(inode);
/*
* Binary compatible with 1.3.XX releases.
* Take this out in 2.1.0 development series.
* <mec@duracef.shout.net> 12 Mar 1996
*/
switch(cmd) {
case _IOR('n', 1, unsigned char *):
cmd = NCP_IOC_NCPREQUEST;
break;
case _IOR('u', 1, uid_t):
cmd = NCP_IOC_GETMOUNTUID;
break;
case _IO('l', 1):
cmd = NCP_IOC_CONN_LOGGED_IN;
break;
case _IOWR('i', 1, unsigned char *):
cmd = NCP_IOC_GET_FS_INFO;
break;
}
switch(cmd) {
case NCP_IOC_NCPREQUEST:
@@ -116,6 +136,8 @@ ncp_ioctl (struct inode * inode, struct file * filp,
info.mounted_uid = server->m.mounted_uid;
info.connection = server->connection;
info.buffer_size = server->buffer_size;
info.volume_number = NCP_ISTRUCT(inode)->volNumber;
info.directory_id = NCP_ISTRUCT(inode)->DosDirNum;
memcpy_tofs((struct ncp_fs_info *)arg, &info, sizeof(info));
return 0;

View File

@@ -1,6 +1,7 @@
MAN1= slist nprint pqlist
MAN1= slist nprint pqlist nsend pserver
MAN5= nwclient
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net ipx_route
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net \
ipx_route nwmsg

108
man/nsend.1 Normal file
View File

@@ -0,0 +1,108 @@
.TH NSEND 1 03/21/1996 nsend nsend
.SH NAME
nsend \- Send messages to users
.SH SYNOPSIS
.B nsend
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
] [
.B -P
.I password
|
.B -n
] [
.B -C
]
.I user message
.SH DESCRIPTION
With
.B nsend,
you can send messages to the user's workstations.
.B nsend
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 user
.RS 3
.B user
is the NetWare User-ID of the user to receive the message.
.RE
.B message
.RS 3
.B message
is the message to be sent. Please note that this has to be a single
command line argument. If you want to send a message that contains
spaces, you have to quote them on the command line. For example, to
annoy your system administrator, you should try
nsend supervisor 'I know how this works!'
.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, nsend 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 BUGS
nsend only supports servers with up to 255 connections. I do not know
the NCP functions for larger servers. If anybody knows them, please
tell me!
.SH SEE ALSO
.B nwclient(5), nprint(1), slist(1), ncpmount(8), ncpumount(8)
.SH CREDITS
nsend was written by looking at mars_nwe's message handling. Thanks to
Martin Stover <mstover@freeway.de>

View File

@@ -1,7 +1,7 @@
Begin3
Title: ncpfs
Version: 0.18
Entered-date: 09. March 1996
Version: 0.19
Entered-date: 22. March 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
@@ -13,7 +13,7 @@ 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/
~83k ncpfs-0.18.tgz
~ 1k ncpfs-0.18.lsm
~103k ncpfs-0.19.tgz
~ 1k ncpfs-0.19.lsm
Copying-policy: GPL
End

View File

@@ -2,7 +2,7 @@
# Makefile for the linux ncp-filesystem routines.
#
USERUTILS = slist pqlist nwfsinfo pserver nprint
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend
UIDUTILS = ncpmount ncpumount
SBINUTILS = nwmsg
@@ -23,25 +23,43 @@ install: all
for i in $(SBINUTILS); \
do install $(INTERM_BINDIR)/$$i -m 755 $(SBINDIR); done
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) ncplib.o
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) ncplib.o
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) libncp.a
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) -L. -lncp
ncplib.o: ncplib.c ncplib.h
ncplib.o: ncplib.c ncplib.h ncplib_err.h
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
COM_ERR_CFILES = com_err/com_err.c com_err/error_message.c com_err/et_name.c \
com_err/init_et.c
libncp.a: ncplib.o ncplib_err.o $(COM_ERR_CFILES)
make -C com_err
ar r libncp.a ncplib.o ncplib_err.o \
com_err/com_err.o com_err/error_message.o com_err/et_name.o \
com_err/init_et.o
ncplib_err.h: ncplib_err.et
com_err/compile_et ncplib_err
ncplib_err.c: ncplib_err.et
com_err/compile_et ncplib_err
test: test.o ncplib.o
$(CC) -o test test.o ncplib.o
ncptest: ncptest.o ncplib.o
$(CC) -o ncptest ncptest.o ncplib.o
ncptest: ncptest.o libncp.a
$(CC) -o ncptest ncptest.o -L. -lncp
dep:
dep: ncplib_err.h
make -C com_err dep
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f *.o *~ slist test ncptest
make -C com_err clean
rm -f *.o *~ slist test ncptest ncplib_err.[ch] libncp.a
realclean: clean
mrproper: clean
make -C com_err mrproper
rm -f $(UTILS) .depend $(DISTFILE)
#

1
util/com_err.h Symbolic link
View File

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

49
util/com_err/ChangeLog Normal file
View File

@@ -0,0 +1,49 @@
Wed Jan 31 11:06:08 1996 <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.02
Mon Sep 4 21:44:47 1995 Remy Card <card@bbj>
* Makefile.in: Added support for BSD shared libraries.
Sat Aug 12 03:11:28 1995 Remy Card <card@bbj>
* Makefile.in (install): Install static libraries in $(ulibdir)
(/usr/lib on Linux) instead of $(libdir) (/lib on Linux).
Sat Aug 5 11:44:17 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
* Makefile.in (DLL_INSTALL_DIR, ELF_INSTALL_DIR): Set the
installation directories correctly.
Thu Jun 15 23:39:51 1995 Remy Card <card@bbj>
* Makefile.in: Added support for ELF shared libraries.
Fixed typos in the compilation rules.
(distclean): Added compile_et.sh.
Sat Jun 10 19:56:13 1995 Theodore Y. Ts'o <tytso@lurch.mit.edu>
* compile_et.sh.in: Use ET_DIR instead of srcdir to determine the
location of the et directory.
Thu Jun 8 12:45:41 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu>
* vfprintf.c (vfprintf): Only compile this function if vfprintf
doesn't already exist and _doprnt does.
* compile_et.sh: Moved to compile_et.sh.in.
* Makefile.in: Rewritten to conform to GNU coding standards and
support separate compilation directories.
Don't preprocess compile_et.sh, as this is now done by configure.
Mon Nov 7 21:17:48 1994 Remy Card <card@bbj>
* Makefile: Added a dummy install target in case shared libraries
are not built.
Thu Sep 8 22:33:33 1994 (tytso@rsx-11)
* com_err.c (default_com_err_proc): Reversed order of \n\r to make
jik happy.

25
util/com_err/Makefile Normal file
View File

@@ -0,0 +1,25 @@
#
# Makefile for the com_err library
#
OBJECTS = com_err.o error_message.o et_name.o init_et.o
CFLAGS = -Wall -O2
all: $(OBJECTS)
dep:
$(CPP) -M $(INCLUDES) *.c > .depend
clean:
rm -f *.o
mrproper: clean
rm -f .depend
#
# include a dependency file if one exists
#
ifeq (.depend,$(wildcard .depend))
include .depend
endif

96
util/com_err/com_err.3 Normal file
View File

@@ -0,0 +1,96 @@
.\" Copyright (c) 1988 Massachusetts Institute of Technology,
.\" Student Information Processing Board. All rights reserved.
.\"
.\" $Header: /mit/krb5/.cvsroot/src/util/et/com_err.3,v 1.1 1993/06/03 12:29:34 tytso Exp $
.\"
.TH COM_ERR 3 "22 Nov 1988" SIPB
.SH NAME
com_err \- common error display routine
.SH SYNOPSIS
.nf
#include <com_err.h>
.PP
void com_err (whoami, code, format, ...);
const char *whoami;
long code;
const char *format;
.PP
proc = set_com_err_hook (proc);
.fi
void (*
.I proc
) (const char *, long, const char *, va_list);
.nf
.PP
proc = reset_com_err_hook ();
.PP
void initialize_XXXX_error_table ();
.fi
.SH DESCRIPTION
.I Com_err
displays an error message on the standard error stream
.I stderr
(see
.IR stdio (3S))
composed of the
.I whoami
string, which should specify the program name or some subportion of
a program, followed by an error message generated from the
.I code
value (derived from
.IR compile_et (1)),
and a string produced using the
.I format
string and any following arguments, in the same style as
.IR fprintf (3).
The behavior of
.I com_err
can be modified using
.I set_com_err_hook;
this defines a procedure which is called with the arguments passed to
.I com_err,
instead of the default internal procedure which sends the formatted
text to error output. Thus the error messages from a program can all
easily be diverted to another form of diagnostic logging, such as
.IR syslog (3).
.I Reset_com_err_hook
may be used to restore the behavior of
.I com_err
to its default form. Both procedures return the previous ``hook''
value. These ``hook'' procedures must have the declaration given for
.I proc
above in the synopsis.
The
.I initialize_XXXX_error_table
routine is generated mechanically by
.IR compile_et (1)
from a source file containing names and associated strings. Each
table has a name of up to four characters, which is used in place of
the
.B XXXX
in the name of the routine. These routines should be called before
any of the corresponding error codes are used, so that the
.I com_err
library will recognize error codes from these tables when they are
used.
The
.B com_err.h
header file should be included in any source file that uses routines
from the
.I com_err
library; executable files must be linked using
.I ``-lcom_err''
in order to cause the
.I com_err
library to be included.
.\" .IR for manual entries
.\" .PP for paragraph breaks
.SH "SEE ALSO"
compile_et (1), syslog (3).
Ken Raeburn, "A Common Error Description Library for UNIX".

114
util/com_err/com_err.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board.
*
* For copyright info, see mit-sipb-copyright.h.
*/
#include <stdio.h>
#include "com_err.h"
#include "mit-sipb-copyright.h"
#include "error_table.h"
#include "internal.h"
#if !defined(__STDC__) && !defined(STDARG_PROTOTYPES)
#include <varargs.h>
#define VARARGS
#endif
static void
#ifdef __STDC__
default_com_err_proc (const char *whoami, errcode_t code, const
char *fmt, va_list args)
#else
default_com_err_proc (whoami, code, fmt, args)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
#endif
{
if (whoami) {
fputs(whoami, stderr);
fputs(": ", stderr);
}
if (code) {
fputs(error_message(code), stderr);
fputs(" ", stderr);
}
if (fmt) {
vfprintf (stderr, fmt, args);
}
/* should do this only on a tty in raw mode */
putc('\r', stderr);
putc('\n', stderr);
fflush(stderr);
}
#ifdef __STDC__
typedef void (*errf) (const char *, errcode_t, const char *, va_list);
#else
typedef void (*errf) ();
#endif
errf com_err_hook = default_com_err_proc;
#ifdef __STDC__
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
va_list args)
#else
void com_err_va (whoami, code, fmt, args)
const char *whoami;
errcode_t code;
const char *fmt;
va_list args;
#endif
{
(*com_err_hook) (whoami, code, fmt, args);
}
#ifndef VARARGS
void com_err (const char *whoami,
errcode_t code,
const char *fmt, ...)
{
#else
void com_err (va_alist)
va_dcl
{
const char *whoami, *fmt;
errcode_t code;
#endif
va_list pvar;
if (!com_err_hook)
com_err_hook = default_com_err_proc;
#ifdef VARARGS
va_start (pvar);
whoami = va_arg (pvar, const char *);
code = va_arg (pvar, errcode_t);
fmt = va_arg (pvar, const char *);
#else
va_start(pvar, fmt);
#endif
com_err_va (whoami, code, fmt, pvar);
va_end(pvar);
}
errf set_com_err_hook (new_proc)
errf new_proc;
{
errf x = com_err_hook;
if (new_proc)
com_err_hook = new_proc;
else
com_err_hook = default_com_err_proc;
return x;
}
errf reset_com_err_hook () {
errf x = com_err_hook;
com_err_hook = default_com_err_proc;
return x;
}

40
util/com_err/com_err.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* Header file for common error description library.
*
* Copyright 1988, Student Information Processing Board of the
* Massachusetts Institute of Technology.
*
* For copyright and distribution info, see the documentation supplied
* with this package.
*/
#ifndef __COM_ERR_H
typedef long errcode_t;
#ifdef __STDC__
#include <stdarg.h>
/* ANSI C -- use prototypes etc */
void com_err (const char *, long, const char *, ...);
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
va_list args);
char const *error_message (long);
extern void (*com_err_hook) (const char *, long, const char *, va_list);
void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
(const char *, long, const char *, va_list);
void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
int init_error_table(const char * const *msgs, int base, int count);
#else
/* no prototypes */
void com_err ();
void com_err_va ();
char *error_message ();
extern void (*com_err_hook) ();
void (*set_com_err_hook ()) ();
void (*reset_com_err_hook ()) ();
int init_error_table();
#endif
#define __COM_ERR_H
#endif /* ! defined(__COM_ERR_H) */

View File

@@ -0,0 +1,554 @@
\input texinfo @c -*-texinfo-*-
@c $Header: /mit/krb5/.cvsroot/src/util/et/com_err.texinfo,v 1.1 1993/06/03 12:29:38 tytso Exp $
@c $Source: /mit/krb5/.cvsroot/src/util/et/com_err.texinfo,v $
@c $Locker: $
@c Note that although this source file is in texinfo format (more
@c or less), it is not yet suitable for turning into an ``info''
@c file. Sorry, maybe next time.
@c
@c In order to produce hardcopy documentation from a texinfo file,
@c run ``tex com_err.texinfo'' which will load in texinfo.tex,
@c provided in this distribution. (texinfo.tex is from the Free
@c Software Foundation, and is under different copyright restrictions
@c from the rest of this package.)
@ifinfo
@barfo
@end ifinfo
@iftex
@tolerance 10000
@c Mutate section headers...
@begingroup
@catcode#=6
@gdef@secheading#1#2#3{@secheadingi {#3@enspace #1}}
@endgroup
@end iftex
@setfilename com_err
@settitle A Common Error Description Library for UNIX
@ifinfo
This file documents the use of the Common Error Description library.
Copyright (C) 1987, 1988 Student Information Processing Board of the
Massachusetts Institute of Technology.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution of the software
without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
make no representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied warranty.
Note that the file texinfo.tex, provided with this distribution, is from
the Free Software Foundation, and is under different copyright restrictions
from the remainder of this package.
@end ifinfo
@ignore
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
@setchapternewpage odd
@titlepage
@center @titlefont{A Common Error Description}
@center @titlefont{Library for UNIX}
@sp 2
@center Ken Raeburn
@center Bill Sommerfeld
@sp 1
@center MIT Student Information Processing Board
@sp 3
@center last updated 1 January 1989
@center for version 1.2
@center ***DRAFT COPY ONLY***
@vskip 2in
@center @b{Abstract}
UNIX has always had a clean and simple system call interface, with a
standard set of error codes passed between the kernel and user
programs. Unfortunately, the same cannot be said of many of the
libraries layered on top of the primitives provided by the kernel.
Typically, each one has used a different style of indicating errors to
their callers, leading to a total hodgepodge of error handling, and
considerable amounts of work for the programmer. This paper describes
a library and associated utilities which allows a more uniform way for
libraries to return errors to their callers, and for programs to
describe errors and exceptional conditions to their users.
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1987, 1988 by the Student Information Processing
Board of the Massachusetts Institute of Technology.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution of the software
without specific, written prior permission. M.I.T. and the M.I.T. S.I.P.B.
make no representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied warranty.
Note that the file texinfo.tex, provided with this distribution, is from
the Free Software Foundation, and is under different copyright restrictions
from the remainder of this package.
@end titlepage
@ifinfo
@c should put a menu here someday....
@end ifinfo
@page
@section Why com_err?
In building application software packages, a programmer often has to
deal with a number of libraries, each of which can use a different
error-reporting mechanism. Sometimes one of two values is returned,
indicating simply SUCCESS or FAILURE, with no description of errors
encountered. Sometimes it is an index into a table of text strings,
where the name of the table used is dependent on the library being
used when the error is generated; since each table starts numbering at
0 or 1, additional information as to the source of the error code is
needed to determine which table to look at. Sometimes no text messages are
supplied at all, and the programmer must supply them at any point at which
he may wish to report error conditions.
Often, a global variable is assigned some value describing the error, but
the programmer has to know in each case whether to look at @code{errno},
@code{h_errno}, the return value from @code{hes_err()}, or whatever other
variables or routines are specified.
And what happens if something
in the procedure of
examining or reporting the error changes the same variable?
The package we have developed is an attempt to present a common
error-handling mechanism to manipulate the most common form of error code
in a fashion that does not have the problems listed above.
A list of up to 256 text messages is supplied to a translator we have
written, along with the three- to four-character ``name'' of the error
table. The library using this error table need only call a routine
generated from this error-table source to make the table ``known'' to the
com_err library, and any error code the library generates can be converted
to the corresponding error message. There is also a default format for
error codes accidentally returned before making the table known, which is
of the form @samp{unknown code foo 32}, where @samp{foo} would be the name
of the table.
@section Error codes
Error codes themselves are 32 bit (signed) integers, of which the high
order 24 bits are an identifier of which error table the error code is
from, and the low order 8 bits are a sequential error number within
the table. An error code may thus be easily decomposed into its component
parts. Only the lowest 32 bits of an error code are considered significant
on systems which support wider values.
Error table 0 is defined to match the UNIX system call error table
(@code{sys_errlist}); this allows @code{errno} values to be used directly
in the library (assuming that @code{errno} is of a type with the same width
as @t{long}). Other error table numbers are formed by compacting together
the first four characters of the error table name. The mapping between
characters in the name and numeric values in the error code are defined in
a system-independent fashion, so that two systems that can pass integral
values between them can reliably pass error codes without loss of meaning;
this should work even if the character sets used are not the same.
(However, if this is to be done, error table 0 should be avoided, since the
local system call error tables may differ.)
Any variable which is to contain an error code should be declared @t{long}.
The draft proposed American National Standard for C (as of May, 1988)
requires that @t{long} variables be at least 32 bits; any system which does
not support 32-bit @t{long} values cannot make use of this package (nor
much other software that assumes an ANSI-C environment base) without
significant effort.
@section Error table source file
The error table source file begins with the declaration of the table name,
as
@example
error_table @var{tablename}
@end example
Individual error codes are
specified with
@example
error_code @var{ERROR_NAME}, @var{"text message"}
@end example
where @samp{ec} can also be used as a short form of @samp{error_code}. To
indicate the end of the table, use @samp{end}. Thus, a (short) sample
error table might be:
@example
error_table dsc
error_code DSC_DUP_MTG_NAME,
"Meeting already exists"
ec DSC_BAD_PATH,
"A bad meeting pathname was given"
ec DSC_BAD_MODES,
"Invalid mode for this access control list"
end
@end example
@section The error-table compiler
The error table compiler is named @code{compile_et}. It takes one
argument, the pathname of a file (ending in @samp{.et}, e.g.,
@samp{dsc_err.et}) containing an error table source file. It parses the
error table, and generates two output files -- a C header file
(@samp{discuss_err.h}) which contains definitions of the numerical values
of the error codes defined in the error table, and a C source file which
should be compiled and linked with the executable. The header file must be
included in the source of a module which wishes to reference the error
codes defined; the object module generated from the C code may be linked in
to a program which wishes to use the printed forms of the error codes.
This translator accepts a @kbd{-language @var{lang}} argument, which
determines for which language (or language variant) the output should be
written. At the moment, @var{lang} is currently limited to @kbd{ANSI-C}
and @kbd{K&R-C}, and some abbreviated forms of each. Eventually, this will
be extended to include some support for C++. The default is currently
@kbd{K&R-C}, though the generated sources will have ANSI-C code
conditionalized on the symbol @t{__STDC__}.
@section Run-time support routines
Any source file which uses the routines supplied with or produced by the
com_err package should include the header file @file{<com_err.h>}. It
contains declarations and definitions which may be needed on some systems.
(Some functions cannot be referenced properly without the return type
declarations in this file. Some functions may work properly on most
architectures even without the header file, but relying on this is not
recommended.)
The run-time support routines and variables provided via this package
include the following:
@example
void initialize_@var{xxxx}_error_table (void);
@end example
One of these routines is built by the error compiler for each error table.
It makes the @var{xxxx} error table ``known'' to the error reporting
system. By convention, this routine should be called in the initialization
routine of the @var{xxxx} library. If the library has no initialization
routine, some combination of routines which form the core of the library
should ensure that this routine is called. It is not advised to leave it
the caller to make this call.
There is no harm in calling this routine more than once.
@example
#define ERROR_TABLE_BASE_@var{xxxx} @var{nnnnn}L
@end example
This symbol contains the value of the first error code entry in the
specified table.
This rarely needs be used by the
programmer.
@example
const char *error_message (long code);
@end example
This routine returns the character string error message associated
with @code{code}; if this is associated with an unknown error table, or
if the code is associated with a known error table but the code is not
in the table, a string of the form @samp{Unknown code @var{xxxx nn}} is
returned, where @var{xxxx} is the error table name produced by
reversing the compaction performed on the error table number implied
by that error code, and @var{nn} is the offset from that base value.
Although this routine is available for use when needed, its use should be
left to circumstances which render @code{com_err} (below) unusable.
@example
void com_err (const char *whoami, /* module reporting error */
long code, /* error code */
const char *format, /* format for additional detail */
...); /* (extra parameters) */
@end example
This routine provides an alternate way to print error messages to
standard error; it allows the error message to be passed in as a
parameter, rather than in an external variable. @emph{Provide grammatical
context for ``message.''}
If @var{format} is @code{(char *)NULL}, the formatted message will not be
printed. @var{format} may not be omitted.
@example
#include <stdarg.h>
void com_err_va (const char *whoami,
long code,
const char *format,
va_list args);
@end example
This routine provides an interface, equivalent to @code{com_err} above,
which may be used by higher-level variadic functions (functions which
accept variable numbers of arguments).
@example
#include <stdarg.h>
void (*set_com_err_hook (void (*proc) ())) ();
void (*@var{proc}) (const char *whoami, long code, va_list args);
void reset_com_err_hook ();
@end example
These two routines allow a routine to be dynamically substituted for
@samp{com_err}. After @samp{set_com_err_hook} has been called,
calls to @samp{com_err} will turn into calls to the new hook routine.
@samp{reset_com_err_hook} turns off this hook. This may intended to
be used in daemons (to use a routine which calls @var{syslog(3)}), or
in a window system application (which could pop up a dialogue box).
If a program is to be used in an environment in which simply printing
messages to the @code{stderr} stream would be inappropriate (such as in a
daemon program which runs without a terminal attached),
@code{set_com_err_hook} may be used to redirect output from @code{com_err}.
The following is an example of an error handler which uses @var{syslog(3)}
as supplied in BSD 4.3:
@example
#include <stdio.h>
#include <stdarg.h>
#include <syslog.h>
/* extern openlog (const char * name, int logopt, int facility); */
/* extern syslog (int priority, char * message, ...); */
void hook (const char * whoami, long code,
const char * format, va_list args)
@{
char buffer[BUFSIZ];
static int initialized = 0;
if (!initialized) @{
openlog (whoami,
LOG_NOWAIT|LOG_CONS|LOG_PID|LOG_NDELAY,
LOG_DAEMON);
initialized = 1;
@}
vsprintf (buffer, format, args);
syslog (LOG_ERR, "%s %s", error_message (code), buffer);
@}
@end example
After making the call
@code{set_com_err_hook (hook);},
any calls to @code{com_err} will result in messages being sent to the
@var{syslogd} daemon for logging.
The name of the program, @samp{whoami}, is supplied to the
@samp{openlog()} call, and the message is formatted into a buffer and
passed to @code{syslog}.
Note that since the extra arguments to @code{com_err} are passed by
reference via the @code{va_list} value @code{args}, the hook routine may
place any form of interpretation on them, including ignoring them. For
consistency, @code{printf}-style interpretation is suggested, via
@code{vsprintf} (or @code{_doprnt} on BSD systems without full support for
the ANSI C library).
@section Coding Conventions
The following conventions are just some general stylistic conventions
to follow when writing robust libraries and programs. Conventions
similar to this are generally followed inside the UNIX kernel and most
routines in the Multics operating system. In general, a routine
either succeeds (returning a zero error code, and doing some side
effects in the process), or it fails, doing minimal side effects; in
any event, any invariant which the library assumes must be maintained.
In general, it is not in the domain of non user-interface library
routines to write error messages to the user's terminal, or halt the
process. Such forms of ``error handling'' should be reserved for
failures of internal invariants and consistancy checks only, as it
provides the user of the library no way to clean up for himself in the
event of total failure.
Library routines which can fail should be set up to return an error
code. This should usually be done as the return value of the
function; if this is not acceptable, the routine should return a
``null'' value, and put the error code into a parameter passed by
reference.
Routines which use the first style of interface can be used from
user-interface levels of a program as follows:
@example
@{
if ((code = initialize_world(getuid(), random())) != 0) @{
com_err("demo", code,
"when trying to initialize world");
exit(1);
@}
if ((database = open_database("my_secrets", &code))==NULL) @{
com_err("demo", code,
"while opening my_secrets");
exit(1);
@}
@}
@end example
A caller which fails to check the return status is in error. It is
possible to look for code which ignores error returns by using lint;
look for error messages of the form ``foobar returns value which is
sometimes ignored'' or ``foobar returns value which is always
ignored.''
Since libraries may be built out of other libraries, it is often necessary
for the success of one routine to depend on another. When a lower level
routine returns an error code, the middle level routine has a few possible
options. It can simply return the error code to its caller after doing
some form of cleanup, it can substitute one of its own, or it can take
corrective action of its own and continue normally. For instance, a
library routine which makes a ``connect'' system call to make a network
connection may reflect the system error code @code{ECONNREFUSED}
(Connection refused) to its caller, or it may return a ``server not
available, try again later,'' or it may try a different server.
Cleanup which is typically necessary may include, but not be limited
to, freeing allocated memory which will not be needed any more,
unlocking concurrancy locks, dropping reference counts, closing file
descriptors, or otherwise undoing anything which the procedure did up
to this point. When there are a lot of things which can go wrong, it
is generally good to write one block of error-handling code which is
branched to, using a goto, in the event of failure. A common source
of errors in UNIX programs is failing to close file descriptors on
error returns; this leaves a number of ``zombied'' file descriptors
open, which eventually causes the process to run out of file
descriptors and fall over.
@example
@{
FILE *f1=NULL, *f2=NULL, *f3=NULL;
int status = 0;
if ( (f1 = fopen(FILE1, "r")) == NULL) @{
status = errno;
goto error;
@}
/*
* Crunch for a while
*/
if ( (f2 = fopen(FILE2, "w")) == NULL) @{
status = errno;
goto error;
@}
if ( (f3 = fopen(FILE3, "a+")) == NULL) @{
status = errno;
goto error;
@}
/*
* Do more processing.
*/
fclose(f1);
fclose(f2);
fclose(f3);
return 0;
error:
if (f1) fclose(f1);
if (f2) fclose(f2);
if (f3) fclose(f3);
return status;
@}
@end example
@section Building and Installation
The distribution of this package will probably be done as a compressed
``tar''-format file available via anonymous FTP from SIPB.MIT.EDU.
Retrieve @samp{pub/com_err.tar.Z} and extract the contents. A subdirectory
@t{profiled} should be created to hold objects compiled for profiling.
Running ``make all'' should then be sufficient to build the library and
error-table compiler. The files @samp{libcom_err.a},
@samp{libcom_err_p.a}, @samp{com_err.h}, and @samp{compile_et} should be
installed for use; @samp{com_err.3} and @samp{compile_et.1} can also be
installed as manual pages.
Potential problems:
@itemize @bullet
@item Use of @code{strcasecmp}, a routine provided in BSD for
case-insensitive string comparisons. If an equivalent routine is
available, you can modify @code{CFLAGS} in the makefile to define
@code{strcasecmp} to the name of that routine.
@item Compilers that defined @code{__STDC__} without providing the header
file @code{<stdarg.h>}. One such example is Metaware's High ``C''
compiler, as provided at Project Athena on the IBM RT/PC workstation; if
@code{__HIGHC__} is defined, it is assumed that @code{<stdarg.h>} is not
available, and therefore @code{<varargs.h>} must be used. If the symbol
@code{VARARGS} is defined (e.g., in the makefile), @code{<varargs.h>} will
be used.
@item If your linker rejects symbols that are simultaneously defined in two
library files, edit @samp{Makefile} to remove @samp{perror.c} from the
library. This file contains a version of @var{perror(3)} which calls
@code{com_err} instead of calling @code{write} directly.
@end itemize
As I do not have access to non-BSD systems, there are probably
bugs present that may interfere with building or using this package on
other systems. If they are reported to me, they can probably be fixed for
the next version.
@section Bug Reports
Please send any comments or bug reports to the principal author: Ken
Raeburn, @t{Raeburn@@Athena.MIT.EDU}.
@section Acknowledgements
I would like to thank: Bill Sommerfeld, for his help with some of this
documentation, and catching some of the bugs the first time around;
Honeywell Information Systems, for not killing off the @emph{Multics}
operating system before I had an opportunity to use it; Honeywell's
customers, who persuaded them not to do so, for a while; Ted Anderson of
CMU, for catching some problems before version 1.2 left the nest; Stan
Zanarotti and several others of MIT's Student Information Processing Board,
for getting us started with ``discuss,'' for which this package was
originally written; and everyone I've talked into --- I mean, asked to read
this document and the ``man'' pages.
@bye

11
util/com_err/compile_et Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
#
#
AWK=/usr/bin/awk
DIR=com_err/
ROOT=`echo $1 | sed -e s/.et$//`
BASE=`basename $ROOT`
$AWK -f ${DIR}/et_h.awk outfile=${BASE}.h $ROOT.et
$AWK -f ${DIR}/et_c.awk outfile=${BASE}.c $ROOT.et

79
util/com_err/compile_et.1 Normal file
View File

@@ -0,0 +1,79 @@
.\" Copyright (c) 1988 Massachusetts Institute of Technology,
.\" Student Information Processing Board. All rights reserved.
.\"
.\" $Header: /mit/krb5/.cvsroot/src/util/et/compile_et.1,v 1.1 1993/06/03 12:29:46 tytso Exp $
.\"
.TH COMPILE_ET 1 "22 Nov 1988" SIPB
.SH NAME
compile_et \- error table compiler
.SH SYNOPSIS
.B compile_et
file
.SH DESCRIPTION
.B Compile_et
converts a table listing error-code names and associated messages into
a C source file suitable for use with the
.IR com_err (3)
library.
The source file name must end with a suffix of ``.et''; the file
consists of a declaration supplying the name (up to four characters
long) of the error-code table:
.B error_table
.I name
followed by up to 256 entries of the form:
.B error_code
.I name,
"
.I string
"
and a final
.B end
to indicate the end of the table.
The name of the table is used to construct the name of a subroutine
.I initialize_XXXX_error_table
which must be called in order for the
.I com_err
library to recognize the error table.
The various error codes defined are assigned sequentially increasing
numbers (starting with a large number computed as a hash function of
the name of the table); thus for compatibility it is suggested that
new codes be added only to the end of an existing table, and that no
codes be removed from tables.
The names defined in the table are placed into a C header file with
preprocessor directives defining them as integer constants of up to
32 bits in magnitude.
A C source file is also generated which should be compiled and linked
with the object files which reference these error codes; it contains
the text of the messages and the initialization subroutine. Both C
files have names derived from that of the original source file, with
the ``.et'' suffix replaced by ``.c'' and ``.h''.
A ``#'' in the source file is treated as a comment character, and all
remaining text to the end of the source line will be ignored.
.SH BUGS
Since
.B compile_et
uses a very simple parser based on
.IR yacc (1),
its error recovery leaves much to be desired.
.\" .IR for manual entries
.\" .PP for paragraph breaks
.SH "SEE ALSO"
com_err (3).
Ken Raeburn, "A Common Error Description Library for UNIX".

View File

@@ -0,0 +1,82 @@
/*
* $Header: /mit/krb5/.cvsroot/src/util/et/error_message.c,v 5.0 1993/04/13 19:56:17 tytso Exp $
* $Source: /mit/krb5/.cvsroot/src/util/et/error_message.c,v $
* $Locker: $
*
* Copyright 1987 by the Student Information Processing Board
* of the Massachusetts Institute of Technology
*
* For copyright info, see "mit-sipb-copyright.h".
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "com_err.h"
#include "error_table.h"
#include "mit-sipb-copyright.h"
#include "internal.h"
static char buffer[25];
struct et_list * _et_list = (struct et_list *) NULL;
#ifdef __STDC__
const char * error_message (errcode_t code)
#else
const char * error_message (code)
errcode_t code;
#endif
{
int offset;
struct et_list *et;
int table_num;
int started = 0;
char *cp;
offset = code & ((1<<ERRCODE_RANGE)-1);
table_num = code - offset;
if (!table_num) {
#ifdef HAS_SYS_ERRLIST
if (offset < sys_nerr)
return(sys_errlist[offset]);
else
goto oops;
#else
cp = strerror(offset);
if (cp)
return(cp);
else
goto oops;
#endif
}
for (et = _et_list; et; et = et->next) {
if (et->table->base == table_num) {
/* This is the right table */
if (et->table->n_msgs <= offset)
goto oops;
return(et->table->msgs[offset]);
}
}
oops:
strcpy (buffer, "Unknown code ");
if (table_num) {
strcat (buffer, error_table_name (table_num));
strcat (buffer, " ");
}
for (cp = buffer; *cp; cp++)
;
if (offset >= 100) {
*cp++ = '0' + offset / 100;
offset %= 100;
started++;
}
if (started || offset >= 10) {
*cp++ = '0' + offset / 10;
offset %= 10;
}
*cp++ = '0' + offset;
*cp = '\0';
return(buffer);
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 1988 by the Student Information Processing Board of the
* Massachusetts Institute of Technology.
*
* For copyright info, see mit-sipb-copyright.h.
*/
#ifndef _ET_H
/* Are we using ANSI C? */
#ifndef __STDC__
#define const
#endif
struct error_table {
char const * const * msgs;
long base;
int n_msgs;
};
struct et_list {
struct et_list *next;
const struct error_table *table;
};
extern struct et_list * _et_list;
#define ERRCODE_RANGE 8 /* # of bits to shift table number */
#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
#ifdef __STDC__
extern const char *error_table_name(int num);
#else
extern const char *error_table_name();
#endif
#define _ET_H
#endif

185
util/com_err/et_c.awk Normal file
View File

@@ -0,0 +1,185 @@
BEGIN {
char_shift=64
## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
c2n["A"]=1
c2n["B"]=2
c2n["C"]=3
c2n["D"]=4
c2n["E"]=5
c2n["F"]=6
c2n["G"]=7
c2n["H"]=8
c2n["I"]=9
c2n["J"]=10
c2n["K"]=11
c2n["L"]=12
c2n["M"]=13
c2n["N"]=14
c2n["O"]=15
c2n["P"]=16
c2n["Q"]=17
c2n["R"]=18
c2n["S"]=19
c2n["T"]=20
c2n["U"]=21
c2n["V"]=22
c2n["W"]=23
c2n["X"]=24
c2n["Y"]=25
c2n["Z"]=26
c2n["a"]=27
c2n["b"]=28
c2n["c"]=29
c2n["d"]=30
c2n["e"]=31
c2n["f"]=32
c2n["g"]=33
c2n["h"]=34
c2n["i"]=35
c2n["j"]=36
c2n["k"]=37
c2n["l"]=38
c2n["m"]=39
c2n["n"]=40
c2n["o"]=41
c2n["p"]=42
c2n["q"]=43
c2n["r"]=44
c2n["s"]=45
c2n["t"]=46
c2n["u"]=47
c2n["v"]=48
c2n["w"]=49
c2n["x"]=50
c2n["y"]=51
c2n["z"]=52
c2n["0"]=53
c2n["1"]=54
c2n["2"]=55
c2n["3"]=56
c2n["4"]=57
c2n["5"]=58
c2n["6"]=59
c2n["7"]=60
c2n["8"]=61
c2n["9"]=62
c2n["_"]=63
}
/^#/ { next }
/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
table_number = 0
table_name = $2
mod_base = 1000000
for(i=1; i<=length(table_name); i++) {
table_number=(table_number*char_shift)+c2n[substr(table_name,i,1)]
}
# We start playing *_high, *low games here because the some
# awk programs do not have the necessary precision (sigh)
tab_base_low = table_number % mod_base
tab_base_high = int(table_number / mod_base)
tab_base_sign = 1;
# figure out: table_number_base=table_number*256
tab_base_low = tab_base_low * 256
tab_base_high = (tab_base_high * 256) + \
int(tab_base_low / mod_base)
tab_base_low = tab_base_low % mod_base
if (table_number > 128*256*256) {
# figure out: table_number_base -= 256*256*256*256
# sub_high, sub_low is 256*256*256*256
sub_low = 256*256*256 % mod_base
sub_high = int(256*256*256 / mod_base)
sub_low = sub_low * 256
sub_high = (sub_high * 256) + int(sub_low / mod_base)
sub_low = sub_low % mod_base
tab_base_low = sub_low - tab_base_low;
tab_base_high = sub_high - tab_base_high;
tab_base_sign = -1;
if (tab_base_low < 0) {
tab_base_low = tab_base_low + mod_base
tab_base_high--
}
}
print "/*" > outfile
print " * " outfile ":" > outfile
print " * This file is automatically generated; please do not edit it." > outfile
print " */" > outfile
print "#ifdef __STDC__" > outfile
print "#define NOARGS void" > outfile
print "#else" > outfile
print "#define NOARGS" > outfile
print "#define const" > outfile
print "#endif" > outfile
print "" > outfile
print "static const char * const text[] = {" > outfile
table_item_count = 0
}
/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*$/ {
skipone=1
next
}
/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,[ \t]*".*"[ \t]*$/ {
text=""
for (i=3; i<=NF; i++) {
text = text FS $i
}
text=substr(text,2,length(text)-1);
printf "\t%s,\n", text > outfile
table_item_count++
}
{
if (skipone) {
printf "\t%s,\n", $0 > outfile
table_item_count++
}
skipone=0
}
END {
print " 0" > outfile
print "};" > outfile
print "" > outfile
print "struct error_table {" > outfile
print " char const * const * msgs;" > outfile
print " long base;" > outfile
print " int n_msgs;" > outfile
print "};" > outfile
print "struct et_list {" > outfile
print " struct et_list *next;" > outfile
print " const struct error_table * table;" > outfile
print "};" > outfile
print "extern struct et_list *_et_list;" > outfile
print "" > outfile
if (tab_base_high == 0) {
print "static const struct error_table et = { text, " \
sprintf("%dL, %d };", tab_base_sign*tab_base_low, \
table_item_count) > outfile
} else {
print "static const struct error_table et = { text, " \
sprintf("%d%06dL, %d };", tab_base_sign*tab_base_high, \
tab_base_low, table_item_count) > outfile
}
print "" > outfile
print "static struct et_list link = { 0, 0 };" > outfile
print "" > outfile
print "void initialize_" table_name "_error_table (NOARGS);" > outfile
print "" > outfile
print "void initialize_" table_name "_error_table (NOARGS) {" > outfile
print " if (!link.table) {" > outfile
print " link.next = _et_list;" > outfile
print " link.table = &et;" > outfile
print " _et_list = &link;" > outfile
print " }" > outfile
print "}" > outfile
}

157
util/com_err/et_h.awk Normal file
View File

@@ -0,0 +1,157 @@
BEGIN {
char_shift=64
## "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
c2n["A"]=1
c2n["B"]=2
c2n["C"]=3
c2n["D"]=4
c2n["E"]=5
c2n["F"]=6
c2n["G"]=7
c2n["H"]=8
c2n["I"]=9
c2n["J"]=10
c2n["K"]=11
c2n["L"]=12
c2n["M"]=13
c2n["N"]=14
c2n["O"]=15
c2n["P"]=16
c2n["Q"]=17
c2n["R"]=18
c2n["S"]=19
c2n["T"]=20
c2n["U"]=21
c2n["V"]=22
c2n["W"]=23
c2n["X"]=24
c2n["Y"]=25
c2n["Z"]=26
c2n["a"]=27
c2n["b"]=28
c2n["c"]=29
c2n["d"]=30
c2n["e"]=31
c2n["f"]=32
c2n["g"]=33
c2n["h"]=34
c2n["i"]=35
c2n["j"]=36
c2n["k"]=37
c2n["l"]=38
c2n["m"]=39
c2n["n"]=40
c2n["o"]=41
c2n["p"]=42
c2n["q"]=43
c2n["r"]=44
c2n["s"]=45
c2n["t"]=46
c2n["u"]=47
c2n["v"]=48
c2n["w"]=49
c2n["x"]=50
c2n["y"]=51
c2n["z"]=52
c2n["0"]=53
c2n["1"]=54
c2n["2"]=55
c2n["3"]=56
c2n["4"]=57
c2n["5"]=58
c2n["6"]=59
c2n["7"]=60
c2n["8"]=61
c2n["9"]=62
c2n["_"]=63
}
/^#/ { next }
/^[ \t]*(error_table|et)[ \t]+[a-zA-Z][a-zA-Z0-9_]+/ {
table_number = 0
table_name = $2
mod_base = 1000000
for(i=1; i<=length(table_name); i++) {
table_number=(table_number*char_shift)+c2n[substr(table_name,i,1)]
}
# We start playing *_high, *low games here because the some
# awk programs do not have the necessary precision (sigh)
tab_base_low = table_number % mod_base
tab_base_high = int(table_number / mod_base)
tab_base_sign = 1;
# figure out: table_number_base=table_number*256
tab_base_low = tab_base_low * 256
tab_base_high = (tab_base_high * 256) + \
int(tab_base_low / mod_base)
tab_base_low = tab_base_low % mod_base
if (table_number > 128*256*256) {
# figure out: table_number_base -= 256*256*256*256
# sub_high, sub_low is 256*256*256*256
sub_low = 256*256*256 % mod_base
sub_high = int(256*256*256 / mod_base)
sub_low = sub_low * 256
sub_high = (sub_high * 256) + int(sub_low / mod_base)
sub_low = sub_low % mod_base
tab_base_low = sub_low - tab_base_low;
tab_base_high = sub_high - tab_base_high;
tab_base_sign = -1;
if (tab_base_low < 0) {
tab_base_low = tab_base_low + mod_base
tab_base_high--
}
}
curr_low = tab_base_low
curr_high = tab_base_high
curr_sign = tab_base_sign
print "/*" > outfile
print " * " outfile ":" > outfile
print " * This file is automatically generated; please do not edit it." > outfile
print " */" > outfile
print "#ifdef __STDC__" > outfile
print "#define NOARGS void" > outfile
print "#else" > outfile
print "#define NOARGS" > outfile
print "#define const" > outfile
print "#endif" > outfile
print "" > outfile
}
/^[ \t]*(error_code|ec)[ \t]+[A-Z_0-9]+,/ {
tag=substr($2,1,length($2)-1)
if (curr_high == 0) {
printf "#define %-40s (%dL)\n", tag, \
curr_sign*curr_low > outfile
} else {
printf "#define %-40s (%d%06dL)\n", tag, curr_high*curr_sign, \
curr_low > outfile
}
curr_low += curr_sign;
if (curr_low >= mod_base) {
curr_low -= mod_base;
curr_high++
}
if (curr_low < 0) {
cur_low += mod_base
cur_high--
}
}
END {
print "extern void initialize_" table_name "_error_table (NOARGS);" > outfile
if (tab_base_high == 0) {
print "#define ERROR_TABLE_BASE_" table_name " (" \
sprintf("%d", tab_base_sign*tab_base_low) \
"L)" > outfile
} else {
print "#define ERROR_TABLE_BASE_" table_name " (" \
sprintf("%d%06d", tab_base_sign*tab_base_high, \
tab_base_low) "L)" > outfile
}
print "" > outfile
print "/* for compatibility with older versions... */" > outfile
print "#define init_" table_name "_err_tbl initialize_" table_name "_error_table" > outfile
print "#define " table_name "_err_base ERROR_TABLE_BASE_" table_name > outfile
}

36
util/com_err/et_name.c Normal file
View File

@@ -0,0 +1,36 @@
/*
* Copyright 1987 by MIT Student Information Processing Board
*
* For copyright info, see mit-sipb-copyright.h.
*/
#include "error_table.h"
#include "mit-sipb-copyright.h"
#include "internal.h"
static const char char_set[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
static char buf[6];
const char * error_table_name(num)
int num;
{
int ch;
int i;
char *p;
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
p = buf;
num >>= ERRCODE_RANGE;
/* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
num &= 077777777;
/* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
for (i = 4; i >= 0; i--) {
ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
if (ch != 0)
*p++ = char_set[ch-1];
}
*p = '\0';
return(buf);
}

58
util/com_err/init_et.c Normal file
View File

@@ -0,0 +1,58 @@
/*
* $Header: /mit/krb5/.cvsroot/src/util/et/init_et.c,v 5.0 1993/04/13 19:56:25 tytso Exp $
* $Source: /mit/krb5/.cvsroot/src/util/et/init_et.c,v $
* $Locker: $
*
* Copyright 1986, 1987, 1988 by MIT Information Systems and
* the MIT Student Information Processing Board.
*
* For copyright info, see mit-sipb-copyright.h.
*/
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "com_err.h"
#include "error_table.h"
#include "mit-sipb-copyright.h"
#ifndef __STDC__
#define const
#endif
struct foobar {
struct et_list etl;
struct error_table et;
};
extern struct et_list * _et_list;
#ifdef __STDC__
int init_error_table(const char * const *msgs, int base, int count)
#else
int init_error_table(msgs, base, count)
const char * const * msgs;
int base;
int count;
#endif
{
struct foobar * new_et;
if (!base || !count || !msgs)
return 0;
new_et = (struct foobar *) malloc(sizeof(struct foobar));
if (!new_et)
return ENOMEM; /* oops */
new_et->etl.table = &new_et->et;
new_et->et.msgs = msgs;
new_et->et.base = base;
new_et->et.n_msgs= count;
new_et->etl.next = _et_list;
_et_list = &new_et->etl;
return 0;
}

22
util/com_err/internal.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* internal include file for com_err package
*/
#include "mit-sipb-copyright.h"
#ifndef __STDC__
#undef const
#define const
#endif
#include <errno.h>
#ifdef NEED_SYS_ERRLIST
extern char const * const sys_errlist[];
extern const int sys_nerr;
#endif
/* AIX and Ultrix have standard conforming header files. */
#if !defined(ultrix) && !defined(_AIX)
#ifdef __STDC__
void perror (const char *);
#endif
#endif

View File

@@ -0,0 +1,19 @@
/*
Copyright 1987, 1988 by the Student Information Processing Board
of the Massachusetts Institute of Technology
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
M.I.T. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
*/

32
util/ipx_sap_types Normal file
View File

@@ -0,0 +1,32 @@
0001 User
0002 User Group
0003 Print Queue
0004 File Server
0005 Job Server
0006 Gateway
0007 Print Server
0008 Archive Server
0009 Archive Server
000A Job Queue
000B Administration
0021 NAS SNA Gateway
0024 Remote Bridge
0026 Bridge Server
0027 TCP/IP Gateway
002D Time Synchronization VAP
002E Archive Server Dynamic SAP
0047 Advertising Print Server
004B Btrieve VAP 5.0
0050 Btrieve VAP
0053 Print Queue User
007A TES NetWare for VMS
0098 NetWare Access Server
009A Named Pipe Server
009E Portable NetWare Unix
0107 NetWare 386
0111 Test Server
0133 NetWare Name Service
0166 NetWare Management
026A NetWare Management
026B Time Server (NetWare 4.0)
0278 NetWare Directory Server (NetWare 4.0)

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
#include <time.h>
#include "ipxlib.h"
#include "com_err.h"
#ifndef memzero
#include <string.h>
@@ -83,41 +84,37 @@ struct ncp_search_seq {
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);
struct ncp_conn *
ncp_initialize(int *argc, char **argv,
int login_necessary, long *err);
/* You can login as another object by this procedure. As a first use
pserver comes to mind. */
int
ncp_initialize_as(struct ncp_conn *conn,
int *argc, char **argv,
int login_necessary, int login_type);
struct ncp_conn *
ncp_initialize_as(int *argc, char **argv,
int login_necessary, int login_type, long *err);
/* Open an existing permanent connection */
int
ncp_open(struct ncp_conn *conn,
const struct ncp_conn_spec *spec);
struct ncp_conn *
ncp_open(const struct ncp_conn_spec *spec, long *err);
/* Open a connection on an existing mount point */
int
ncp_open_mount(struct ncp_conn *conn,
const char *mount_point);
struct ncp_conn *
ncp_open_mount(const char *mount_point, long *err);
/* Detach from and destroy a permanent connection */
int
ncp_destroy_permanent(struct ncp_conn *conn);
/* Find a permanent connection that fits the spec, return NULL if
* there is none. */
char *
ncp_find_permanent(const struct ncp_conn_spec *spec);
/* Create a temporary connection */
int
ncp_open_temporary(struct ncp_conn *conn,
const struct ncp_conn_spec *spec);
/* Find the address of a file server */
struct sockaddr_ipx *
ncp_find_fileserver(const char *server_name, long *err);
/* Detach from a permanent connection or destroy a temporary
connection */
int
long
ncp_close(struct ncp_conn *conn);
/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable
@@ -140,124 +137,129 @@ ncp_get_conn_ent(FILE *filep);
struct ncp_conn_spec *
ncp_find_conn_spec(const char *server, const char *user, const char *password,
uid_t uid);
uid_t uid, long *err);
int
long
ncp_get_file_server_description_strings(struct ncp_conn *conn,
char target[512]);
int
long
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target);
int
ncp_get_connlist(struct ncp_conn *conn, __u32 last_id,
long
ncp_get_connlist(struct ncp_conn *conn,
__u16 object_type, const char *object_name,
int *returned_no, __u16 conn_numbers[256]);
int *returned_no, __u8 conn_numbers[256]);
int
long
ncp_send_broadcast(struct ncp_conn *conn,
__u8 no_conn, const __u8 *connections,
const char *message);
long
ncp_get_encryption_key(struct ncp_conn *conn,
char *target);
int
long
ncp_get_bindery_object_id(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
struct ncp_bindery_object *target);
int
long
ncp_scan_bindery_object(struct ncp_conn *conn,
__u32 last_id, __u16 object_type, char *search_string,
struct ncp_bindery_object *target);
int
long
ncp_read_property_value(struct ncp_conn *conn,
int object_type, const char *object_name,
int segment, const char *prop_name,
struct nw_property *target);
int
long
ncp_login_encrypted(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *passwd);
int
long
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,
const unsigned char *password);
int
long
ncp_get_volume_info_with_number(struct ncp_conn *conn, int n,
struct ncp_volume_info *target);
int
long
ncp_get_volume_number(struct ncp_conn *conn, const char *name,
int *target);
int
long
ncp_file_search_init(struct ncp_conn *conn,
int dir_handle, const char *path,
struct ncp_filesearch_info *target);
int
long
ncp_file_search_continue(struct ncp_conn *conn,
struct ncp_filesearch_info *fsinfo,
int attributes, const char *path,
struct ncp_file_info *target);
int
long
ncp_get_finfo(struct ncp_conn *conn,
int dir_handle, const char *path, const char *name,
struct ncp_file_info *target);
int
long
ncp_open_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr, int access,
struct ncp_file_info *target);
int
long
ncp_close_file(struct ncp_conn *conn, const char *file_id);
int
long
ncp_create_newfile(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
int
long
ncp_create_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr,
struct ncp_file_info *target);
int
long
ncp_erase_file(struct ncp_conn *conn,
int dir_handle, const char *path,
int attr);
int
long
ncp_rename_file(struct ncp_conn *conn,
int old_handle, const char *old_path,
int attr,
int new_handle, const char *new_path);
int
long
ncp_create_directory(struct ncp_conn *conn,
int dir_handle, const char *path,
int inherit_mask);
int
long
ncp_delete_directory(struct ncp_conn *conn,
int dir_handle, const char *path);
int
long
ncp_rename_directory(struct ncp_conn *conn,
int dir_handle,
const char *old_path, const char *new_path);
int
long
ncp_read(struct ncp_conn *conn, const char *file_id,
off_t offset, size_t count, char *target);
int
long
ncp_write(struct ncp_conn *conn, const char *file_id,
off_t offset, size_t count, const char *source);
int
long
ncp_copy_file(struct ncp_conn *conn,
const char source_file[6],
const char target_file[6],
@@ -266,24 +268,24 @@ ncp_copy_file(struct ncp_conn *conn,
__u32 count,
__u32 *copied_count);
int
long
ncp_do_lookup(struct ncp_conn *conn,
struct nw_info_struct *dir,
char *path, /* may only be one component */
struct nw_info_struct *target);
int
long
ncp_modify_file_or_subdir_dos_info(struct ncp_conn *conn,
struct nw_info_struct *file,
__u32 info_mask,
struct nw_modify_dos_info *info);
int
long
ncp_del_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *dir, char *name);
int
long
ncp_open_create_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *dir, char *name,
int open_create_mode,
@@ -291,63 +293,63 @@ ncp_open_create_file_or_subdir(struct ncp_conn *conn,
int desired_acc_rights,
struct nw_file_info *target);
int
long
ncp_initialize_search(struct ncp_conn *conn,
const struct nw_info_struct *dir,
int namespace,
struct ncp_search_seq *target);
int
long
ncp_search_for_file_or_subdir(struct ncp_conn *conn,
struct ncp_search_seq *seq,
struct nw_info_struct *target);
int
long
ncp_ren_or_mov_file_or_subdir(struct ncp_conn *conn,
struct nw_info_struct *old_dir, char *old_name,
struct nw_info_struct *new_dir, char *new_name);
int
long
ncp_create_queue_job_and_file(struct ncp_conn *conn,
__u32 queue_id,
struct queue_job *job);
int
long
ncp_close_file_and_start_job(struct ncp_conn *conn,
__u32 queue_id,
struct queue_job *job);
int
long
ncp_attach_to_queue(struct ncp_conn *conn,
__u32 queue_id);
int
long
ncp_detach_from_queue(struct ncp_conn *conn,
__u32 queue_id);
int
long
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
struct queue_job *job);
int
long
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number, __u32 charge_info);
int
long
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
__u32 job_number);
int
long
ncp_get_broadcast_message(struct ncp_conn *conn, char message[256]);
int
long
ncp_dealloc_dir_handle(struct ncp_conn *conn, __u8 dir_handle);
#define NCP_ALLOC_PERMANENT (0x0000)
#define NCP_ALLOC_TEMPORARY (0x0001)
#define NCP_ALLOC_SPECIAL (0x0002)
int
long
ncp_alloc_short_dir_handle(struct ncp_conn *conn,
struct nw_info_struct *dir,
__u16 alloc_mode,

21
util/ncplib_err.et Normal file
View File

@@ -0,0 +1,21 @@
error_table NCPL
ec NCPL_ET_NO_SERVER,
"No server found"
ec NCPL_ET_HOST_UNKNOWN,
"Server Unknown"
ec NCPL_ET_REQUEST_ERROR,
"NCP Request returned error code"
ec NCPL_ET_NAMETOOLONG,
"Name too long"
ec NCPL_ET_MSG_TOO_LONG,
"Message too long"
ec NCPL_ET_NO_SPEC,
"Could not find valid connection spec"
end

View File

@@ -45,6 +45,7 @@ extern pid_t waitpid(pid_t, int *, int);
#include <linux/ncp_fs.h>
#include <linux/ncp_mount.h>
#include "ncplib.h"
#include "com_err.h"
static char *progname;
static void usage(void);
@@ -153,9 +154,11 @@ main(int argc, char *argv[])
int fd, result;
struct sockaddr_ipx addr;
struct sockaddr_ipx *server_addr;
int addrlen;
int upcase_password;
long err;
int um;
unsigned int flags;
@@ -163,6 +166,7 @@ main(int argc, char *argv[])
char mount_point[MAXPATHLEN];
struct mntent ment;
FILE *mtab;
char *tmp_mount;
char *server = NULL;
char *user = NULL;
@@ -171,13 +175,13 @@ main(int argc, char *argv[])
uid_t conn_uid = getuid();
struct ncp_conn conn;
struct ncp_conn *conn;
int opt;
progname = argv[0];
memzero(data); memzero(spec); memzero(conn);
memzero(data); memzero(spec);
if (geteuid() != 0)
{
@@ -317,10 +321,10 @@ main(int argc, char *argv[])
}
}
if ((spec = ncp_find_conn_spec(server, user, password, data.uid))
if ((spec = ncp_find_conn_spec(server, user, password, data.uid, &err))
== NULL)
{
fprintf(stderr, "Could not find valid server/user\n");
com_err(progname, err, "in find_conn_spec");
exit(1);
}
@@ -376,32 +380,28 @@ main(int argc, char *argv[])
data.dir_mode |= S_IXOTH;
}
if (ncp_open(&conn, spec) != 0)
if ((tmp_mount = ncp_find_permanent(spec)) != NULL)
{
fprintf(stderr, "could not connect to server %s: %s\n",
server, strerror(errno));
exit(1);
}
if (conn.is_connected == CONN_PERMANENT)
{
fprintf(stderr,
"You already have mounted server %s\nas user "
"%s\non mount point %s\n", spec->server, spec->user,
conn.mount_point);
ncp_close(&conn);
tmp_mount);
exit(1);
}
data.serv_addr = conn.i.addr;
ncp_close(&conn);
if ((server_addr = ncp_find_fileserver(spec->server, &err)) == NULL)
{
com_err("ncpmount", err, "when trying to find %s",
spec->server);
exit(1);
}
data.serv_addr = *server_addr;
data.ncp_fd = socket(AF_IPX, SOCK_DGRAM, PF_IPX);
if (data.ncp_fd == -1)
{
fprintf(stderr, "could not open ncp socket: %s\n",
strerror(errno));
com_err("ncpmount", err, "opening ncp_socket");
exit(1);
}
@@ -472,7 +472,11 @@ main(int argc, char *argv[])
flags = MS_MGC_VAL;
result = mount(NULL, mount_point, "ncpfs", flags, (char *)&data);
strcpy(mount_name, spec->server);
strcat(mount_name, "/");
strcat(mount_name, spec->user);
result = mount(mount_name, mount_point, "ncpfs", flags, (char *)&data);
if (result < 0)
{
@@ -480,20 +484,17 @@ main(int argc, char *argv[])
exit(1);
}
if ( (ncp_open_mount(&conn, mount_point) != 0)
|| (ncp_login_user(&conn, spec->user, spec->password) != 0)
|| (ioctl(conn.mount_fid, NCP_IOC_CONN_LOGGED_IN, NULL) != 0))
if ( ((conn = ncp_open_mount(mount_point, &err)) == NULL)
|| ((err = ncp_login_user(conn, spec->user, spec->password)) != 0)
|| ((err = ioctl(conn->mount_fid, NCP_IOC_CONN_LOGGED_IN,
NULL)) != 0))
{
fprintf(stderr, "%s: login failed\n", strerror(errno));
ncp_close(&conn);
com_err("ncpmount", err, "in login");
ncp_close(conn);
umount(mount_point);
exit(1);
}
ncp_close(&conn);
strcpy(mount_name, spec->server);
strcat(mount_name, "/");
strcat(mount_name, spec->user);
ncp_close(conn);
ment.mnt_fsname = mount_name;
ment.mnt_dir = mount_point;

View File

@@ -38,115 +38,35 @@ extern pid_t waitpid(pid_t, int *, int);
#include "ncplib.h"
void
test_print(struct ncp_conn *conn)
{
struct ncp_bindery_object q;
struct queue_job j;
struct print_job_record pj;
int written;
if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE,
"Q_DJ500", &q) != 0) {
printf("get oid error\n");
return;
}
memset(&j, 0, sizeof(j));
j.j.TargetServerID = 0xffffffff; /* any server */
/* 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));
pj.Version = 0;
pj.TabSize = 8;
pj.Copies = htons(1);
pj.CtrlFlags = 0;
pj.Lines = htons(66);
pj.Rows = htons(80);
strcpy(pj.FormName, "test");
strcpy(pj.BannerName, "BannerName");
strcpy(pj.FnameBanner, "BannerFile");
strcpy(pj.FnameHeader, "HeaderName");
strcpy(pj.Path, "");
memcpy(j.j.ClientRecordArea, &pj, sizeof(pj));
if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0) {
printf("create error\n");
return;
}
if ((written = ncp_write(conn, j.file_handle, 0, 15,
"hallo, wie geht's?")) < 0) {
printf("write error\n");
return;
}
if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) {
printf("close error\n");
return;
}
return;
}
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];
__u8 conn_list[256] = {0,};
int no;
ncp_get_connlist(conn, 0, NCP_BINDERY_USER, "*", &no, conn_list);
ncp_get_connlist(conn, NCP_BINDERY_USER, "SUPERVISOR", &no,
conn_list);
return;
}
void
test_send(struct ncp_conn *conn)
{
__u8 conn_list[256] = {0,};
int no;
if (ncp_get_connlist(conn, NCP_BINDERY_USER, "ME", &no,
conn_list) != 0)
{
no = 0;
}
if (no > 0)
{
ncp_send_broadcast(conn, no, conn_list, "Hallo");
}
return;
}
void
test_create(struct ncp_conn *conn)
{
@@ -191,15 +111,16 @@ test_create(struct ncp_conn *conn)
int
main(int argc, char *argv[])
{
struct ncp_conn conn;
struct ncp_conn *conn;
long err;
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
perror("ncp_initialize");
com_err(argv[0], err, "in ncp_initialize");
return 1;
}
test_create(&conn);
ncp_close(&conn);
test_send(conn);
ncp_close(conn);
return 0;
}

View File

@@ -25,7 +25,7 @@ static void help(void);
void
main(int argc, char *argv[])
{
struct ncp_conn conn;
struct ncp_conn *conn;
char default_queue[] = "*";
char *queue = default_queue;
@@ -42,10 +42,11 @@ main(int argc, char *argv[])
char *file_name;
int file;
long err;
progname = argv[0];
memzero(j); memzero(pj); memzero(q); memzero(conn);
memzero(j); memzero(pj); memzero(q);
if ( (argc == 2)
&& (strcmp(argv[1], "-h") == 0))
@@ -54,9 +55,9 @@ main(int argc, char *argv[])
exit(0);
}
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
perror("Could not open connection");
com_err(argv[0], err, "in ncp_initialize");
exit(1);
}
@@ -82,7 +83,7 @@ main(int argc, char *argv[])
switch (opt) {
case 'h':
help();
ncp_close(&conn);
ncp_close(conn);
exit(1);
case 'p':
/* Path */
@@ -191,7 +192,7 @@ main(int argc, char *argv[])
{
printf("queue name too long: %s\n",
optarg);
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
queue = optarg;
@@ -212,7 +213,7 @@ main(int argc, char *argv[])
default:
usage();
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
}
@@ -220,7 +221,7 @@ main(int argc, char *argv[])
if (optind != argc-1)
{
usage();
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
@@ -236,7 +237,7 @@ main(int argc, char *argv[])
if (file < 0)
{
perror("could not open file");
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
@@ -268,18 +269,18 @@ main(int argc, char *argv[])
str_upper(queue);
if (ncp_scan_bindery_object(&conn, 0xffffffff, NCP_BINDERY_PQUEUE,
if (ncp_scan_bindery_object(conn, 0xffffffff, NCP_BINDERY_PQUEUE,
queue, &q) != 0)
{
printf("could not find queue %s\n", queue);
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
if (ncp_create_queue_job_and_file(&conn, q.object_id, &j) != 0)
if (ncp_create_queue_job_and_file(conn, q.object_id, &j) != 0)
{
printf("create error\n");
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
@@ -292,7 +293,7 @@ main(int argc, char *argv[])
break;
}
if (ncp_write(&conn, j.file_handle,
if (ncp_write(conn, j.file_handle,
written, read_this_time, buf) < read_this_time)
{
break;
@@ -303,13 +304,13 @@ main(int argc, char *argv[])
close(file);
if (ncp_close_file_and_start_job(&conn, q.object_id, &j) != 0) {
if (ncp_close_file_and_start_job(conn, q.object_id, &j) != 0) {
printf("close error\n");
ncp_close(&conn);
ncp_close(conn);
return;
}
ncp_close(&conn);
ncp_close(conn);
return;
}

65
util/nsend.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* nsend.c
*
* Send Messages to users
*
* 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;
__u8 conn_list[256] = {0,};
int no_conn;
char *message = NULL;
char *user = NULL;
long err;
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
exit(1);
}
if (argc != 3)
{
fprintf(stderr, "usage: %s [options] user message\n", argv[0]);
ncp_close(conn);
exit(1);
}
user = argv[1];
message = argv[2];
if ((err = ncp_get_connlist(conn, NCP_BINDERY_USER, user, &no_conn,
conn_list)) != 0)
{
com_err(argv[0], err, "in get_connlist");
ncp_close(conn);
exit(1);
}
if (no_conn == 0)
{
fprintf(stderr, "No connection found for %s\n", user);
ncp_close(conn);
exit(1);
}
if ((err = ncp_send_broadcast(conn, no_conn, conn_list, message)) != 0)
{
com_err(argv[0], err, "in send_broadcast");
ncp_close(conn);
exit(1);
}
ncp_close(conn);
return 0;
}

View File

@@ -14,12 +14,13 @@
int
main(int argc, char **argv)
{
struct ncp_conn conn;
struct ncp_conn *conn;
int opt;
long err;
if (ncp_initialize(&conn, &argc, argv, 0) != 0)
if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL)
{
perror("Could not open connection");
com_err(argv[0], err, "in ncp_initialize");
return 1;
}
@@ -32,12 +33,12 @@ main(int argc, char **argv)
char strings[512];
char *s;
if (ncp_get_file_server_description_strings(&conn,
if (ncp_get_file_server_description_strings(conn,
strings)
!= 0)
{
perror("could not get strings");
ncp_close(&conn);
ncp_close(conn);
return 1;
}
@@ -57,10 +58,10 @@ main(int argc, char **argv)
{
time_t t;
if (ncp_get_file_server_time(&conn, &t) != 0)
if (ncp_get_file_server_time(conn, &t) != 0)
{
perror("could not get server time");
ncp_close(&conn);
ncp_close(conn);
return 1;
}
@@ -73,6 +74,6 @@ main(int argc, char **argv)
}
}
ncp_close(&conn);
ncp_close(conn);
return 0;
}

62
util/nwlsobj.c Normal file
View File

@@ -0,0 +1,62 @@
/*
* nwlsobj.c
*
* List bindery objects
*
* 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 o;
int found = 0;
char default_pattern[] = "*";
char *pattern = default_pattern;
char *p;
long err;
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
return 1;
}
if (argc > 2)
{
fprintf(stderr, "usage: %s [options]\n", argv[0]);
return 1;
}
if (argc == 2)
{
pattern = argv[1];
}
for (p = pattern; *p != '\0'; p++)
{
*p = toupper(*p);
}
o.object_id = 0xffffffff;
while (ncp_scan_bindery_object(conn, o.object_id,
0xffff, pattern, &o) == 0)
{
found = 1;
printf("%s %08X %04X\n",
o.object_name, (unsigned int)o.object_id,
(unsigned int)o.object_type);
}
ncp_close(conn);
return 0;
}

View File

@@ -30,7 +30,7 @@ static char *progname;
void
main(int argc, char *argv[])
{
struct ncp_conn conn;
struct ncp_conn *conn;
char message[256];
struct ncp_fs_info info;
struct passwd *pwd;
@@ -39,6 +39,7 @@ main(int argc, char *argv[])
FILE *tty_file;
FILE *mtab;
struct mntent *mnt;
long err;
progname = argv[0];
@@ -52,18 +53,17 @@ main(int argc, char *argv[])
exit(1);
}
if (ncp_open_mount(&conn, argv[1]) != 0)
if ((conn = ncp_open_mount(argv[1], &err)) == NULL)
{
fprintf(stderr, "%s: could not open connection %s\n",
progname, argv[1]);
com_err(progname, err, "in ncp_open_mount");
exit(1);
}
if (ncp_get_broadcast_message(&conn, message) != 0)
if (ncp_get_broadcast_message(conn, message) != 0)
{
fprintf(stderr, "%s: could not get broadcast message\n",
progname);
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
@@ -78,15 +78,15 @@ main(int argc, char *argv[])
#endif
info.version = NCP_GET_FS_INFO_VERSION;
if (ioctl(conn.mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0)
if (ioctl(conn->mount_fid, NCP_IOC_GET_FS_INFO, &info) < 0)
{
fprintf(stderr, "%s: could not ioctl on connection: %s\n",
progname, strerror(errno));
ncp_close(&conn);
ncp_close(conn);
exit(1);
}
ncp_close(&conn);
ncp_close(conn);
if ((pwd = getpwuid(info.mounted_uid)) == NULL)
{
@@ -104,7 +104,7 @@ main(int argc, char *argv[])
while ((mnt = getmntent(mtab)) != NULL)
{
if (strcmp(mnt->mnt_dir, conn.mount_point) == 0)
if (strcmp(mnt->mnt_dir, conn->mount_point) == 0)
{
break;
}

View File

@@ -15,17 +15,18 @@
int
main(int argc, char **argv)
{
struct ncp_conn conn;
struct ncp_conn *conn;
struct ncp_bindery_object q;
int found = 0;
char default_pattern[] = "*";
char *pattern = default_pattern;
char *p;
long err;
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
if ((conn = ncp_initialize(&argc, argv, 1, &err)) == NULL)
{
perror("Could not open connection");
com_err(argv[0], err, "in ncp_initialize");
return 1;
}
@@ -47,7 +48,7 @@ main(int argc, char **argv)
if (isatty(1))
{
printf("\nServer: %s\n", conn.server);
printf("\nServer: %s\n", conn->server);
printf("%-52s%-10s\n"
"-----------------------------------------------"
"-------------\n",
@@ -57,8 +58,8 @@ main(int argc, char **argv)
q.object_id = 0xffffffff;
while (ncp_scan_bindery_object(&conn, q.object_id,
NCP_BINDERY_PQUEUE, "*", &q) == 0)
while (ncp_scan_bindery_object(conn, q.object_id,
NCP_BINDERY_PQUEUE, pattern, &q) == 0)
{
found = 1;
printf("%-52s", q.object_name);
@@ -70,6 +71,6 @@ main(int argc, char **argv)
printf("No queues found\n");
}
ncp_close(&conn);
ncp_close(conn);
return 0;
}

View File

@@ -107,12 +107,13 @@ daemon_init(void)
int
main(int argc, char *argv[])
{
struct ncp_conn conn;
struct ncp_conn *conn;
int poll_timeout = 30;
int opt;
int job_type = 0xffff;
int debug = 0;
int i;
long err;
char *queue_name = NULL;
@@ -146,9 +147,10 @@ main(int argc, char *argv[])
openlog("pserver", LOG_PID, LOG_LPR);
}
if (ncp_initialize_as(&conn, &argc, argv, 1, NCP_BINDERY_PSERVER) != 0)
if ((conn = ncp_initialize_as(&argc, argv, 1,
NCP_BINDERY_PSERVER, &err)) == NULL)
{
perror("Could not open connection");
com_err(argv[0], err, "in ncp_initialize");
return 1;
}
@@ -193,10 +195,10 @@ main(int argc, char *argv[])
return 1;
}
if (init_queue(&conn, queue_name, command, &q) != 0)
if (init_queue(conn, queue_name, command, &q) != 0)
{
perror("Could not init queue");
ncp_close(&conn);
ncp_close(conn);
return 1;
}
@@ -221,9 +223,9 @@ main(int argc, char *argv[])
sleep(poll_timeout);
}
ncp_detach_from_queue(&conn, q.queue_id);
ncp_detach_from_queue(conn, q.queue_id);
ncp_close(&conn);
ncp_close(conn);
return 0;
}

View File

@@ -17,12 +17,13 @@
void
main(int argc, char *argv[])
{
struct ncp_conn conn;
struct ncp_conn *conn;
struct ncp_bindery_object obj;
int found = 0;
char default_pattern[] = "*";
char *pattern = default_pattern;
char *p;
long err;
if (argc > 2)
{
@@ -40,9 +41,9 @@ main(int argc, char *argv[])
*p = toupper(*p);
}
if (ncp_initialize(&conn, &argc, argv, 0) != 0)
if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL)
{
perror("ncp_connect");
com_err(argv[0], err, "in ncp_initialize");
exit(1);
}
@@ -58,7 +59,7 @@ main(int argc, char *argv[])
obj.object_id = 0xffffffff;
while (ncp_scan_bindery_object(&conn, obj.object_id,
while (ncp_scan_bindery_object(conn, obj.object_id,
NCP_BINDERY_FSERVER, pattern,
&obj) == 0)
{
@@ -70,7 +71,7 @@ main(int argc, char *argv[])
printf("%-52s", obj.object_name);
if (ncp_read_property_value(&conn, NCP_BINDERY_FSERVER,
if (ncp_read_property_value(conn, NCP_BINDERY_FSERVER,
obj.object_name, 1, "NET_ADDRESS",
&prop) == 0)
{
@@ -86,6 +87,6 @@ main(int argc, char *argv[])
printf("No servers found\n");
}
ncp_close(&conn);
ncp_close(conn);
}