Intial commit
This commit is contained in:
7
prospero/lib/FILES
Normal file
7
prospero/lib/FILES
Normal file
@@ -0,0 +1,7 @@
|
||||
FILES
|
||||
FILES.ftp-only
|
||||
ardp
|
||||
filters
|
||||
pcompat
|
||||
pfs
|
||||
psrv
|
||||
4
prospero/lib/FILES.ftp-only
Normal file
4
prospero/lib/FILES.ftp-only
Normal file
@@ -0,0 +1,4 @@
|
||||
FILES.ftp-only
|
||||
ardp
|
||||
pfs
|
||||
psrv
|
||||
1
prospero/lib/ardp/.gitignore
vendored
Normal file
1
prospero/lib/ardp/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
32
prospero/lib/ardp/FILES
Normal file
32
prospero/lib/ardp/FILES
Normal file
@@ -0,0 +1,32 @@
|
||||
FILES
|
||||
Makefile
|
||||
ardp.doc
|
||||
ardp_abort.c
|
||||
ardp_accept.c
|
||||
ardp_add2req.c
|
||||
ardp_breply.c
|
||||
ardp_error.c
|
||||
ardp_get_nxt.c
|
||||
ardp_headers.c
|
||||
ardp_int_err.c
|
||||
ardp_mutexes.c
|
||||
ardp_perrno.c
|
||||
ardp_pr_actv.c
|
||||
ardp_ptalloc.c
|
||||
ardp_reply.c
|
||||
ardp_respond.c
|
||||
ardp_retriev.c
|
||||
ardp_rqalloc.c
|
||||
ardp_send.c
|
||||
ardp_showbuf.c
|
||||
ardp_snd_pkt.c
|
||||
ardp_srv_ini.c
|
||||
ardp_xmit.c
|
||||
dnscache_alloc.c
|
||||
dnscache_alloc.h
|
||||
flocks.c
|
||||
flocks.h
|
||||
hostname2adr.c
|
||||
p__th_self_num.c
|
||||
unixerrstr.c
|
||||
usc_lic_str.c
|
||||
246
prospero/lib/ardp/Makefile.in
Executable file
246
prospero/lib/ardp/Makefile.in
Executable file
@@ -0,0 +1,246 @@
|
||||
#
|
||||
# Makefile for Prospero Directory Service ARDP library.
|
||||
SOURCEBASE = ../..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
CFLAGS += -I$(ARCHIE_ROOT)/include
|
||||
|
||||
|
||||
CFILES = ardp_abort.c \
|
||||
ardp_accept.c \
|
||||
ardp_add2req.c \
|
||||
ardp_breply.c \
|
||||
ardp_error.c \
|
||||
ardp_get_nxt.c \
|
||||
ardp_headers.c \
|
||||
ardp_int_err.c \
|
||||
ardp_mutexes.c \
|
||||
ardp_perrno.c \
|
||||
ardp_pr_actv.c \
|
||||
ardp_ptalloc.c \
|
||||
ardp_reply.c \
|
||||
ardp_respond.c \
|
||||
ardp_retriev.c \
|
||||
ardp_rqalloc.c \
|
||||
ardp_send.c \
|
||||
ardp_showbuf.c \
|
||||
ardp_snd_pkt.c \
|
||||
ardp_srv_ini.c \
|
||||
ardp_xmit.c \
|
||||
dnscache_alloc.c \
|
||||
flocks.c \
|
||||
hostname2adr.c \
|
||||
p__th_self_num.c \
|
||||
restrict.c \
|
||||
unixerrstr.c \
|
||||
usc_lic_str.c
|
||||
|
||||
OBJECTS = ardp_abort.o \
|
||||
ardp_accept.o \
|
||||
ardp_add2req.o \
|
||||
ardp_breply.o \
|
||||
ardp_error.o \
|
||||
ardp_get_nxt.o \
|
||||
ardp_headers.o \
|
||||
ardp_int_err.o \
|
||||
ardp_mutexes.o \
|
||||
ardp_perrno.o \
|
||||
ardp_pr_actv.o \
|
||||
ardp_ptalloc.o \
|
||||
ardp_reply.o \
|
||||
ardp_respond.o \
|
||||
ardp_retriev.o \
|
||||
ardp_rqalloc.o \
|
||||
ardp_send.o \
|
||||
ardp_showbuf.o \
|
||||
ardp_snd_pkt.o \
|
||||
ardp_srv_ini.o \
|
||||
ardp_xmit.o \
|
||||
dnscache_alloc.o \
|
||||
flocks.o \
|
||||
hostname2adr.o \
|
||||
p__th_self_num.o \
|
||||
restrict.o \
|
||||
unixerrstr.o \
|
||||
usc_lic_str.o
|
||||
|
||||
all: ${RDP_LIB}
|
||||
|
||||
install:
|
||||
cp ${RDP_LIB} ${P_BINARIES}/${RDP_LIB}
|
||||
$(RANLIB) ${P_BINARIES}/${RDP_LIB}
|
||||
|
||||
${RDP_LIB}: ${OBJECTS}
|
||||
rm -f ${RDP_LIB}
|
||||
ar r${AR_FLAGS} ${RDP_LIB} ${OBJECTS}
|
||||
$(RANLIB) ${RDP_LIB}
|
||||
|
||||
# Dependencies
|
||||
ardp_abort.o : ../../include/posix_signal.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/implicit_fixes.h \
|
||||
../../include/ardp.h \
|
||||
../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h
|
||||
ardp_accept.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pserver.h ../../include/plog.h \
|
||||
../../include/pprot.h
|
||||
ardp_add2req.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_breply.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_error.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h
|
||||
ardp_get_nxt.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_headers.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_int_err.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_mutexes.o : ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_perrno.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_pr_actv.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h
|
||||
ardp_ptalloc.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/mitra_macros.h
|
||||
ardp_reply.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_respond.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/plog.h
|
||||
ardp_retriev.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h
|
||||
ardp_rqalloc.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
ardp_send.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h ../../include/pcompat.h
|
||||
ardp_showbuf.o :
|
||||
ardp_snd_pkt.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/plog.h \
|
||||
../../include/perrno.h
|
||||
ardp_srv_ini.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/plog.h
|
||||
ardp_xmit.o : \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
dnscache_alloc.o : dnscache_alloc.h ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/mitra_macros.h
|
||||
flocks.o : ../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/plog.h \
|
||||
flocks.h ../../include/mitra_macros.h
|
||||
hostname2adr.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h ../../include/string_with_strcasecmp.h \
|
||||
../../include/pserver.h dnscache_alloc.h ../../include/pcompat.h \
|
||||
../../include/mitra_macros.h
|
||||
p__th_self_num.o : ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
unixerrstr.o : ../../include/pmachine.h
|
||||
usc_lic_str.o :
|
||||
85
prospero/lib/ardp/Makefile.tmp
Executable file
85
prospero/lib/ardp/Makefile.tmp
Executable file
@@ -0,0 +1,85 @@
|
||||
#
|
||||
# Makefile for Prospero Directory Service ARDP library.
|
||||
SOURCEBASE = ../..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
CFILES = ardp_abort.c \
|
||||
ardp_accept.c \
|
||||
ardp_add2req.c \
|
||||
ardp_breply.c \
|
||||
ardp_error.c \
|
||||
ardp_get_nxt.c \
|
||||
ardp_headers.c \
|
||||
ardp_int_err.c \
|
||||
ardp_mutexes.c \
|
||||
ardp_perrno.c \
|
||||
ardp_pr_actv.c \
|
||||
ardp_ptalloc.c \
|
||||
ardp_reply.c \
|
||||
ardp_respond.c \
|
||||
ardp_retriev.c \
|
||||
ardp_rqalloc.c \
|
||||
ardp_send.c \
|
||||
ardp_showbuf.c \
|
||||
ardp_snd_pkt.c \
|
||||
ardp_srv_ini.c \
|
||||
ardp_xmit.c \
|
||||
dnscache_alloc.c \
|
||||
flocks.c \
|
||||
hostname2adr.c \
|
||||
p__th_self_num.c \
|
||||
unixerrstr.c \
|
||||
usc_lic_str.c
|
||||
|
||||
OBJECTS = ardp_abort.o \
|
||||
ardp_accept.o \
|
||||
ardp_add2req.o \
|
||||
ardp_breply.o \
|
||||
ardp_error.o \
|
||||
ardp_get_nxt.o \
|
||||
ardp_headers.o \
|
||||
ardp_int_err.o \
|
||||
ardp_mutexes.o \
|
||||
ardp_perrno.o \
|
||||
ardp_pr_actv.o \
|
||||
ardp_ptalloc.o \
|
||||
ardp_reply.o \
|
||||
ardp_respond.o \
|
||||
ardp_retriev.o \
|
||||
ardp_rqalloc.o \
|
||||
ardp_send.o \
|
||||
ardp_showbuf.o \
|
||||
ardp_snd_pkt.o \
|
||||
ardp_srv_ini.o \
|
||||
ardp_xmit.o \
|
||||
dnscache_alloc.o \
|
||||
flocks.o \
|
||||
hostname2adr.o \
|
||||
p__th_self_num.o \
|
||||
unixerrstr.o \
|
||||
usc_lic_str.o
|
||||
|
||||
all: ${RDP_LIB}
|
||||
|
||||
install:
|
||||
cp ${RDP_LIB} ${P_BINARIES}/${RDP_LIB}
|
||||
$(RANLIB) ${P_BINARIES}/${RDP_LIB}
|
||||
|
||||
${RDP_LIB}: ${OBJECTS}
|
||||
rm -f ${RDP_LIB}
|
||||
ar r${AR_FLAGS} ${RDP_LIB} ${OBJECTS}
|
||||
$(RANLIB) ${RDP_LIB}
|
||||
|
||||
# Dependencies
|
||||
setdependencies:
|
||||
gcc -M $(CFLAGS) $(CFILES) | sed \
|
||||
-e 's, [^ ]*\.c,,' \
|
||||
-e 's, /local/gnu/[^ ]*,,g' \
|
||||
-e 's, /usr/include/[^ ]*,,g' \
|
||||
-e 's, [./]*include/pthread\.h,,' \
|
||||
-e 's, [./]*include/pthread/[^ ]*,,g' \
|
||||
-e 's, [^ ]*/fsu_pthreads/include/[^ ]*,,g' \
|
||||
-e 's, [./]*include/usc-copyr\.h,,' \
|
||||
-e 's, [./]*include/usc-license\.h,,' \
|
||||
-e 's, [./]*include/uw-copyright\.h,,' \
|
||||
-e '/^[ ]*\\$$/d' | fixdep > dependency.list
|
||||
262
prospero/lib/ardp/ardp.doc
Normal file
262
prospero/lib/ardp/ardp.doc
Normal file
@@ -0,0 +1,262 @@
|
||||
To use the library, include the file <ardp.h>.
|
||||
|
||||
The current release has dependencies upon Prospero in a few places:
|
||||
|
||||
If you will not be using the Prospero pauth structure, undefine
|
||||
PROSPERO in ardp.h. The RREQ structure includes a reference to PAUTH
|
||||
by default.
|
||||
|
||||
The ARDP library server routines currently call the Prospero function
|
||||
plog(). A useful future direction is to make the logging function
|
||||
application-specific, and inactive by default.
|
||||
|
||||
The ardp_reply_bst() function depends upon Propero bstrings. It will
|
||||
not be included in the library if PROSPERO is not defined in ardp.h.
|
||||
|
||||
---
|
||||
Error handling: ARDP library functions return error codes between 1
|
||||
and 20. A return value of 0 is ARDP_SUCCESS. In addition, the global
|
||||
variable
|
||||
|
||||
extern int perrno;
|
||||
|
||||
is generally set to the number of the error. (We haven't actually
|
||||
checked every function in the ARDP library to guarantee this). This
|
||||
global variable is used in the ARDP library, and in the PFS library.
|
||||
|
||||
The function p_clear_errors() should be called from your application
|
||||
to clear this error indication. If you've linked with the PFS library
|
||||
version, then p_clear_errors() will also clear Prospero error and
|
||||
warning indications. This function is defined both in the PFS library
|
||||
and in the ARDP library; if you're a PFS library and an ARDP library
|
||||
user, place the PFS library version first in your link path. Its
|
||||
declaration is:
|
||||
extern void p_clear_errors(void);
|
||||
|
||||
Printed strings associated with these errors can be found in
|
||||
lib/pfs/perrmesg.c. These are not currently available through the
|
||||
ARDP library interface, although it does not depend upon them being
|
||||
present. A future direction is to make these strings available
|
||||
through the RDP library interface.
|
||||
|
||||
--
|
||||
The ARDP library is now completely safe for sending arbitrary
|
||||
length-coded binary data. (Until Prospero release Alpha.5.3, this was
|
||||
not the case -- the server library used to append nulls to packets.)
|
||||
|
||||
--
|
||||
Notes on the PTEXT structure:
|
||||
|
||||
The PTEXT structure has two members, ->text and ->start. On the user
|
||||
side, they are currently always the same; however, this is not always
|
||||
guaranteed to be the case in future releases of the ARDP library.
|
||||
->text is used for the start of data to be parsed by the higher-level
|
||||
application (e.g., Prospero). The ->length member of the PTEXT
|
||||
structure is relative to ->start, which in this case is the same as
|
||||
->text, but which is not guaranted to be so. Thus, if you need the
|
||||
length of the text (relative to the start of ->text), it is ->length -
|
||||
(->text - ->start).
|
||||
|
||||
--
|
||||
Notes on the functions:
|
||||
|
||||
In the functions that follow, more details on the function can be
|
||||
found in the header preceding the function in the source code. This
|
||||
documentation is solely for the purpose of helping you decide which
|
||||
functions to look at. (Another way of saying that we are well aware
|
||||
that this manual is pretty sketchy.) Functions in the library that
|
||||
are not described here should be considered internal and should not be
|
||||
called by the application.
|
||||
|
||||
The following functions are exported by the ardp library for use by
|
||||
the client side of a connection:
|
||||
|
||||
ardp_abort(req) Aborts the specified request, sending an
|
||||
abort message to the server if currently
|
||||
active. If req is null, will send aborts
|
||||
to servers for all active requests.
|
||||
|
||||
ardp_abort_on_int() Sets interrupt handler to abort any
|
||||
pending requests.
|
||||
|
||||
ardp_pr_active() Processes new responses to active requests.
|
||||
If making an asynchronous request (i.e. ttwait
|
||||
does not equal ARDP_WAIT_TILL_TO), then this
|
||||
function must be called periodically, either
|
||||
automatically within ardp_retrieve, explicitly,
|
||||
or initiated by an interrupt when
|
||||
a response becomes available on the UDP port.
|
||||
|
||||
ardp_retrieve(req,ttwait)
|
||||
Poll for, or wait for a pending request to
|
||||
complete.
|
||||
|
||||
ardp_send(req,dname,dest,ttwait)
|
||||
Sends request to host with domain name
|
||||
or socket address dest, and waits ttwait
|
||||
microseconds for response (-1 means till timeout).
|
||||
|
||||
ardp_set_retry(to,rt) Set retry time out (seconds) and count
|
||||
|
||||
The following functions are exported by the ardp library for use by
|
||||
the server side of a connection:
|
||||
|
||||
ardp_accept() Accepts new requests and places on appropriate
|
||||
queues for subsequent processing. This must
|
||||
be called periodically, either explicitly, or
|
||||
initiated by an interrupt when a request
|
||||
becomes available on the UDP port.
|
||||
|
||||
ardp_bind_port(portname)
|
||||
Takes the name of (or #number) of a port to
|
||||
be opened, on which the server will listen
|
||||
for requests.
|
||||
|
||||
RREQ ardp_get_nxt() Returns the next request to be processed.
|
||||
If none available, it will block until
|
||||
one is received.
|
||||
|
||||
|
||||
ardp_redirect(req,target)
|
||||
Sends a redirect to the client indicating the
|
||||
the request should be sent to a new target
|
||||
server identified in the second argument.
|
||||
|
||||
ardp_respond(req,opt) Used by a server to send the current response
|
||||
packet once filled in. It will add the packet
|
||||
to the transmission queue, and send it. To
|
||||
indicate completion of a response, the
|
||||
ARDP_RESP_COMPLETE option should be specified.
|
||||
If the ARDP_RESP_NOSEND option is specified,
|
||||
the packet will be added to the transmission queue
|
||||
but not sent.
|
||||
|
||||
ardp_refuse(req) Causes the specified request to be refused and
|
||||
notification sent to the client.
|
||||
|
||||
ardp_reply(req,flags,message)
|
||||
Queues message (appending it to the req structure)
|
||||
and possibly sends it and other queued data to the
|
||||
client. Will call ardp_respond() if any
|
||||
completed packets can be sent (i.e., sends a
|
||||
partial response to speed up client/server
|
||||
interaction). Message is a null-terminated buffer.
|
||||
Can't use this interface to send binary data
|
||||
that might contain nulls; see
|
||||
ardp_reply_bst() below.
|
||||
|
||||
ardp_rwait(req,timetowait,qpos,stime)
|
||||
This function is called by a server to specify
|
||||
a server requested time to wait for a response.
|
||||
This value is returned to the client which
|
||||
will treat it as an acknowledgment and will
|
||||
defer subsequent timeouts and retries until
|
||||
waiting the specified period. Non-zero values
|
||||
for qpos and stime will cause the current
|
||||
the specified queue position and expected
|
||||
system time to be provided to the client in
|
||||
the same message.
|
||||
|
||||
ardp_set_queuing_policy(pf,override)
|
||||
Sets a function used to determine queue
|
||||
ordering on the server.
|
||||
|
||||
ardp_set_prvport(fd) Sets a file descriptor that has already been
|
||||
opened as the input port on which the server
|
||||
will listen for requests.
|
||||
|
||||
The following functions are exported by the ardp library for use by
|
||||
both the client and server sides of a connection:
|
||||
|
||||
ardp_add2req(req,flags,buf,len)
|
||||
Adds text to a request which will subsequently
|
||||
be sent to the peer, and returns.
|
||||
|
||||
RREQ ardp_rqalloc() Allocate a new request structure
|
||||
ardp_rqfree(req) Free a request structure
|
||||
ardp_rqlfree(req) Free a list of request structures
|
||||
|
||||
PTEXT ardp_ptalloc() Allocate a new packet structure
|
||||
ardp_ptfree(pkt) Free a packet structure
|
||||
ardp_ptlfree(pkt) Free a list of packet structures
|
||||
|
||||
/********************/
|
||||
|
||||
Internal functions:
|
||||
ardp_showbuf() is used to display buffers that might contain
|
||||
nulls.
|
||||
|
||||
/******************/
|
||||
|
||||
Eventually to be built on top of the above:
|
||||
|
||||
rd_sbuf Synchronously send a buffer to a destination
|
||||
rd_sbufa Asynchronously send a buffer to a destination
|
||||
rd_sync Wait until all pending requests are complete
|
||||
|
||||
/********************/
|
||||
|
||||
The ARDP library respects the global integer variable pfs_debug.
|
||||
Levels of 9 or above cause the text of packets sent across the network
|
||||
to be displayed to stderr.
|
||||
|
||||
As of Prospero Alpha.5.3 release, an ARDP library pfs_debug level of
|
||||
11 or greater will cause \n and \t and \r to be printed as \n and \t
|
||||
and \r in the display of the contents of ARDP packets. Levels 9 and
|
||||
10 cause them to be displayed as themselves. All other control
|
||||
characters in packets are now displayed as a \ followed by the
|
||||
character's octal code. (In previous releases, they were displayed as
|
||||
literal text, and nulls in the packet caused the display of the packet
|
||||
text to be ignored.)
|
||||
|
||||
/*************/
|
||||
|
||||
The new ARDP_REPLY_BST() function accepts a Prospero BSTRING as its
|
||||
argument. This violates modularity of the ARDP library, since it
|
||||
requires the ARDP library to know about the bstrings layer. We need a
|
||||
new interface to ardp_reply() that will accept a length-coded buffer,
|
||||
and then a wrapper around it in the pfs library that will accept the
|
||||
bstring. Future directions for this function are noted at ISI in
|
||||
/nfs/pfs/notes/ardp-directions.
|
||||
|
||||
ardp_reply_bst(RREQ req, /* Request to which this is a response */
|
||||
int flags, /* Whether this is the final message */
|
||||
char *message) /* The data to be sent. Must be a bstring. */
|
||||
|
||||
/**** BUGS & future directions *****/
|
||||
|
||||
ardp_retrieve() and ardp_send() both call p_clear_errors() internally.
|
||||
This is inconsistent with the behavior of the rest of the ARDP library
|
||||
and of most of the PFs library, which do not clear error indications
|
||||
themselves.
|
||||
|
||||
|
||||
Look over ardp.h.
|
||||
-Make it independent of Prospero directory service: Put authentication
|
||||
stuff into ardp.h as a formal library. Alternatively, make the
|
||||
directory service use the 'app' optional member. (at least until the
|
||||
authentication stuff is better defined).
|
||||
|
||||
Make sure the app optional member is defined and explained in the ARDP stuff.
|
||||
|
||||
-Get rid of #define PROSPERO in ardp.h
|
||||
-ARDP_DEFAULT_PEER and ARDP_DEFAULT_PORT must become optional
|
||||
constants.
|
||||
|
||||
Change the ardp library interface so that the logging function is
|
||||
specified at runtime initialization.
|
||||
|
||||
ardp_reply should have the interface changed to accept a message
|
||||
length, just like ardp_add2req() does. Ditto any other functions in the
|
||||
libardp interface that expect just null terminated buffers. The ARDP
|
||||
library should be better documented for potential programmers.
|
||||
|
||||
Fix bug: ardp_respond() expects trailing null on buffer
|
||||
ardp_add2req() hands. (this is on the SWA todo list as a separate
|
||||
item).
|
||||
|
||||
SWA has rewritten ardp_add2req on paper; need to type in these
|
||||
simplifying changes.
|
||||
|
||||
|
||||
|
||||
109
prospero/lib/ardp/ardp_abort.c
Normal file
109
prospero/lib/ardp/ardp_abort.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1/93 to abort pending requests
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <posix_signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <pfs_threads.h>
|
||||
#include <list_macros.h>
|
||||
#include <implicit_fixes.h>
|
||||
#include <ardp.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern RREQ ardp_activeQ; /* Info about active requests */
|
||||
extern int ardp_port; /* Opened UDP port */
|
||||
extern int pfs_debug; /* Debug level */
|
||||
extern int ardp_activeQ_len; /* Length of ardp_activeQ */
|
||||
|
||||
/*
|
||||
* ardp_abort - abort a pending request
|
||||
*
|
||||
* ardp_abort takes a pointer to a request structure of a request to
|
||||
* be aborted, sends an abort request to the server handling the pending,
|
||||
* request, and immediately returns. If the request is null (NOREQ), then
|
||||
* all requests on the ardp_activeQ are aborted.
|
||||
*/
|
||||
int
|
||||
ardp_abort(req)
|
||||
RREQ req; /* Request to be aborted */
|
||||
{
|
||||
PTEXT ptmp = NOPKT; /* Abort packet to be sent */
|
||||
RREQ rtmp = NOREQ; /* Current request to abort */
|
||||
int ns; /* Number of bytes actually sent */
|
||||
|
||||
if(req && (req->status != ARDP_STATUS_ACTIVE)) return(ARDP_BAD_REQ);
|
||||
|
||||
if(req) rtmp = req;
|
||||
else rtmp = ardp_activeQ;
|
||||
|
||||
ptmp = ardp_ptalloc();
|
||||
|
||||
/* Add header */
|
||||
ptmp->start -= 13;
|
||||
ptmp->length += 13;
|
||||
*(ptmp->start) = (char) 13;
|
||||
/* An unsequenced control packet */
|
||||
bzero(ptmp->start+3,10);
|
||||
/* Cancel flag */
|
||||
*(ptmp->start+12) = 0x01;
|
||||
|
||||
while(rtmp) {
|
||||
bcopy2(&(rtmp->cid),ptmp->start+1);
|
||||
if (pfs_debug >= 6) {
|
||||
if(rtmp->peer.sin_family == AF_INET)
|
||||
fprintf(stderr,"\nSending abort message (cid=%d) to %s(%d)...",
|
||||
ntohs(rtmp->cid),inet_ntoa(rtmp->peer_addr),PEER_PORT(rtmp));
|
||||
else fprintf(stderr,"\nSending abort message...");
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
ns = sendto(ardp_port,(char *)(ptmp->start), ptmp->length, 0,
|
||||
&(rtmp->peer), S_AD_SZ);
|
||||
if(ns != ptmp->length) {
|
||||
if (pfs_debug) {
|
||||
fprintf(stderr,"\nsent only %d/%d: ",ns, ptmp->length);
|
||||
perror("");
|
||||
}
|
||||
ardp_ptfree(ptmp);
|
||||
return(ARDP_NOT_SENT);
|
||||
}
|
||||
if (pfs_debug >= 6) fprintf(stderr,"Sent.\n");
|
||||
|
||||
rtmp->status = ARDP_STATUS_ABORTED;
|
||||
EXTRACT_ITEM(rtmp,ardp_activeQ);
|
||||
--ardp_activeQ_len;
|
||||
if(req) rtmp = NOREQ;
|
||||
else rtmp = rtmp->next;
|
||||
}
|
||||
|
||||
ardp_ptfree(ptmp);
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_trap_int - signal handler to abort request on ^C
|
||||
*/
|
||||
SIGNAL_RET_TYPE ardp_trap_int()
|
||||
{
|
||||
ardp_abort(NOREQ);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_abort_on_int - set up signal handler to abort request on ^C
|
||||
*/
|
||||
int
|
||||
ardp_abort_on_int()
|
||||
{
|
||||
signal(SIGINT,ardp_trap_int);
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
752
prospero/lib/ardp/ardp_accept.c
Normal file
752
prospero/lib/ardp/ardp_accept.c
Normal file
@@ -0,0 +1,752 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*
|
||||
* Written by bcn 1991 as check_for_messages in rdgram.c (Prospero)
|
||||
* Modified by bcn 1/93 modularized and incorporated into new ardp library
|
||||
* Modified by swa 12/93 made handle arbitrary length ardp_runQ
|
||||
* Modified by swa 3/95 for bunyip; trapping errno 9 in bad rcvfrom.
|
||||
*/
|
||||
|
||||
/* This version of lib/ardp/ardp_accept.c will work both in Prospero
|
||||
Prealpha.17May94 and in the current (as of 3/21/95) working sources at ISI.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
/* Need types.h for u_short */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef AIX
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#ifdef SOLARIS
|
||||
#include <sys/signal.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <ardp.h>
|
||||
#include <pserver.h>
|
||||
#include <plog.h>
|
||||
#include <pprot.h>
|
||||
#include <pmachine.h>
|
||||
#include <pfs_threads.h> /* Mutex stuff */
|
||||
|
||||
#define LOG_PACKET(REQ,QP) \
|
||||
if((REQ)->priority || (pQlen > 4)) \
|
||||
if(pQNlen && (REQ)->priority) \
|
||||
plog(L_QUEUE_INFO, REQ, "Queued: %d of %d (%d) - Priority %d", \
|
||||
QP, pQlen, pQNlen, (REQ)->priority, 0); \
|
||||
else if(pQNlen) \
|
||||
plog(L_QUEUE_INFO, REQ, "Queued: %d of %d (%d)", \
|
||||
QP, pQlen, pQNlen, 0); \
|
||||
else if((REQ)->priority) \
|
||||
plog(L_QUEUE_INFO, REQ, "Queued: %d of %d - Priority %d", \
|
||||
QP, pQlen, (REQ)->priority, 0); \
|
||||
else if(QP != pQlen) \
|
||||
plog(L_QUEUE_INFO, REQ, "Queued: %d of %d", QP, pQlen, 0); \
|
||||
else plog(L_QUEUE_INFO, REQ, "Queued: %d", pQlen, 0);
|
||||
|
||||
|
||||
EXTERN_MUTEXED_DEF_INITIALIZER(RREQ,ardp_pendingQ,NOREQ); /*Pending requests*/
|
||||
int pQlen = 0; /* Length of pending queue */
|
||||
int pQNlen = 0; /* Number of niced requests */
|
||||
|
||||
static RREQ ardp_partialQ = NOREQ; /* Incomplete requests */
|
||||
int ptQlen = 0; /* Length of incomplete queue */
|
||||
int ptQmaxlen = 20; /* Max length of incomplete queue */
|
||||
EXTERN_MUTEXED_DEF_INITIALIZER(RREQ,ardp_runQ,NOREQ); /* Requests currently in
|
||||
progress */
|
||||
EXTERN_MUTEXED_DEF_INITIALIZER(RREQ,ardp_doneQ,NOREQ); /* Processed requests
|
||||
*/
|
||||
int dQlen = 0; /* Length of reply queue */
|
||||
/* Mutexed with ardp_doneQ */
|
||||
int dQmaxlen = 20; /* Max length of reply queue */
|
||||
|
||||
static struct timeval zerotime = {0, 0}; /* Used by select */
|
||||
|
||||
#define max(x,y) (x > y ? x : y)
|
||||
|
||||
extern int (*ardp_pri_func)(); /* Function to compare priorities */
|
||||
extern int ardp_pri_override; /* If 1, overide value in request */
|
||||
|
||||
/* C library error facility */
|
||||
|
||||
extern int ardp_srvport;
|
||||
extern int ardp_prvport;
|
||||
#ifdef ARCHIE
|
||||
#ifdef __STDC__
|
||||
extern int arch_get_etime(RREQ);
|
||||
#else
|
||||
extern int arch_get_etime();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static void ardp_update_cfields(RREQ existing, RREQ newvalues);
|
||||
static void ardp_header_ack_rwait(PTEXT tpkt, RREQ nreq, int is_ack_needed,
|
||||
int is_rwait_needed);
|
||||
|
||||
|
||||
int
|
||||
ardp_accept_and_wait(int timeout, int usec)
|
||||
{
|
||||
struct sockaddr_in from;
|
||||
int fromlen;
|
||||
int n = 0;
|
||||
PTEXT pkt;
|
||||
unsigned char flags1,flags2;
|
||||
unsigned short pid; /* protocol ID for higher-level protocol */
|
||||
int qpos; /* Position of new req in queue */
|
||||
int dpos; /* Position of dupe in queue */
|
||||
RREQ creq; /* Current request */
|
||||
RREQ treq; /* Temporary request pointer */
|
||||
RREQ nreq; /* New request pointer */
|
||||
RREQ areq = NOREQ; /* Request needing ack */
|
||||
RREQ match_in_runQ = NOREQ; /* if match found in runq for
|
||||
completed request. */
|
||||
int hdr_len;
|
||||
char *ctlptr;
|
||||
short stmp;
|
||||
int tmp;
|
||||
int check_for_ack = 1;
|
||||
fd_set readfds; /* Used for select */
|
||||
long now; /* Time - used for retries */
|
||||
long rr_time = 0; /* Time last retrans from done queue */
|
||||
|
||||
struct timeval time_out;
|
||||
time_out.tv_sec = timeout;
|
||||
time_out.tv_usec = usec;
|
||||
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
/* Changed from original interface. This will try the lock and return
|
||||
an error if unsuccessful. Otherwise it will get the lock */
|
||||
if (p_th_mutex_trylock(p_th_mutexARDP_ACCEPT))
|
||||
return ARDP_SUCCESS; /* Being retrieved */
|
||||
#endif
|
||||
check_for_more:
|
||||
/* This is initialized afresh before each select(). Some operating
|
||||
systems, such as LINUX, modify the time_out parameter to SELECT().
|
||||
--swa, 6/19/94 */
|
||||
|
||||
time_out.tv_sec = timeout;
|
||||
time_out.tv_usec = usec;
|
||||
now = time(NULL);
|
||||
|
||||
/* Check both the prived and unprived ports if necessary */
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(ardp_srvport, &readfds);
|
||||
if(ardp_prvport != -1) FD_SET(ardp_prvport, &readfds);
|
||||
tmp = select(max(ardp_srvport,ardp_prvport) + 1,
|
||||
&readfds,(fd_set *)0,(fd_set *)0,&time_out);
|
||||
|
||||
if(tmp == 0) {
|
||||
if(areq) ardp_acknowledge(areq); areq = NOREQ;
|
||||
p_th_mutex_unlock(p_th_mutexARDP_ACCEPT);
|
||||
return ARDP_SUCCESS;
|
||||
}
|
||||
if(tmp < 0) {
|
||||
p_th_mutex_unlock(p_th_mutexARDP_ACCEPT);
|
||||
return ARDP_SELECT_FAILED;
|
||||
}
|
||||
creq = ardp_rqalloc();
|
||||
pkt = ardp_ptalloc();
|
||||
|
||||
/* There is a message waiting, add it to the queue */
|
||||
|
||||
fromlen = sizeof(from);
|
||||
if((ardp_prvport >= 0) && FD_ISSET(ardp_prvport,&readfds))
|
||||
n = recvfrom(ardp_prvport, pkt->dat, ARDP_PTXT_LEN_R, 0,
|
||||
(struct sockaddr *) &from, &fromlen);
|
||||
else {
|
||||
assert(FD_ISSET(ardp_srvport, &readfds));
|
||||
n = recvfrom(ardp_srvport, pkt->dat, ARDP_PTXT_LEN_R, 0,
|
||||
(struct sockaddr *) &from, &fromlen);
|
||||
}
|
||||
if (n <= 0) {
|
||||
plog(L_NET_ERR,NOREQ,"Bad recvfrom n = %d errno = %d %s",
|
||||
n, errno, unixerrstr(), 0);
|
||||
|
||||
/* I added this in response to a problem experienced by Bunyip.
|
||||
--swa, 3/21/95 */
|
||||
if (errno == 9) {
|
||||
if ((ardp_prvport >= 0) && FD_ISSET(ardp_prvport, &readfds))
|
||||
plog(L_NET_ERR, NOREQ, "The bad descriptor was descriptor #%d,
|
||||
represented internally by the variable ardp_prvport", ardp_prvport);
|
||||
else if (FD_ISSET(ardp_srvport, &readfds))
|
||||
plog(L_NET_ERR, NOREQ, "The bad descriptor was descriptor #%d,
|
||||
represented internally by the variable ardp_srvport", ardp_srvport);
|
||||
else
|
||||
internal_error("Something is wrong with your system's version
|
||||
of select(). No descriptors are readable; unclear how we got here.");
|
||||
|
||||
plog(L_NET_ERR, NOREQ,
|
||||
"This should never happen. Attempting to restart server with SIGUSR1.");
|
||||
kill(getpid(), SIGUSR1); /* sending restart signal to Prospero
|
||||
server or to whatever we hand*/
|
||||
|
||||
}
|
||||
ardp_rqfree(creq); ardp_ptfree(pkt);
|
||||
p_th_mutex_unlock(p_th_mutexARDP_ACCEPT);
|
||||
return ARDP_BAD_RECV;
|
||||
}
|
||||
|
||||
|
||||
bcopy(&from,&(creq->peer),sizeof(creq->peer));
|
||||
creq->cid = 0; creq->peer_ardp_version = 0;
|
||||
creq->rcvd_time.tv_sec = now;
|
||||
creq->prcvd_thru = 0;
|
||||
|
||||
if ( ! verify_acl_list(&from) ) {
|
||||
ardp_breply(creq, ARDP_R_COMPLETE, acl_message(),0);
|
||||
ardp_ptfree(pkt);
|
||||
goto check_for_more;
|
||||
}
|
||||
|
||||
pkt->start = pkt->dat;
|
||||
pkt->length = n;
|
||||
*(pkt->start + pkt->length) = '\0';
|
||||
pkt->mbz = 0; /* force zeros to catch runaway strings */
|
||||
|
||||
pkt->seq = 1;
|
||||
if((hdr_len = (unsigned char) *(pkt->start)) < 32) {
|
||||
ctlptr = pkt->start + 1;
|
||||
pkt->seq = 0;
|
||||
if(hdr_len >= 3) { /* Connection ID */
|
||||
bcopy2(ctlptr,&stmp);
|
||||
if(stmp) creq->cid = ntohs(stmp);
|
||||
ctlptr += 2;
|
||||
}
|
||||
if(hdr_len >= 5) { /* Packet number */
|
||||
bcopy2(ctlptr,&stmp);
|
||||
pkt->seq = ntohs(stmp);
|
||||
}
|
||||
else { /* No packet number specified, so this is the only one */
|
||||
pkt->seq = 1;
|
||||
creq->rcvd_tot = 1;
|
||||
}
|
||||
ctlptr += 2;
|
||||
if(hdr_len >= 7) { /* Total number of packets */
|
||||
bcopy2(ctlptr,&stmp); /* 0 means don't know */
|
||||
if(stmp) creq->rcvd_tot = ntohs(stmp);
|
||||
}
|
||||
ctlptr += 2;
|
||||
if(hdr_len >= 9) { /* Receievd through */
|
||||
bcopy2(ctlptr,&stmp); /* 0 means don't know */
|
||||
if(stmp) {
|
||||
creq->prcvd_thru = ntohs(stmp);
|
||||
}
|
||||
}
|
||||
ctlptr += 2;
|
||||
if(hdr_len >= 11) { /* Backoff */
|
||||
/* Not supported by server */
|
||||
}
|
||||
ctlptr += 2;
|
||||
|
||||
flags1 = flags2 = 0;
|
||||
if(hdr_len >= 12) flags1 = *ctlptr++; /* Flags */
|
||||
if(hdr_len >= 13) flags2 = *ctlptr++; /* Flags */
|
||||
|
||||
if(flags2 == 1) { /* Cancel request */
|
||||
EXTERN_MUTEXED_LOCK(ardp_pendingQ);
|
||||
treq = ardp_pendingQ;
|
||||
while(treq) {
|
||||
if((treq->cid == creq->cid) &&
|
||||
(treq->peer_port == creq->peer_port) &&
|
||||
(treq->peer_addr.s_addr == creq->peer_addr.s_addr)){
|
||||
plog(L_QUEUE_INFO,treq,
|
||||
"Request canceled by client - dequeued",0);
|
||||
pQlen--;if(treq->priority > 0) pQNlen--;
|
||||
EXTRACT_ITEM(treq,ardp_pendingQ);
|
||||
ardp_rqfree(treq);
|
||||
ardp_rqfree(creq); ardp_ptfree(pkt);
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_pendingQ);
|
||||
goto check_for_more;
|
||||
}
|
||||
treq = treq->next;
|
||||
}
|
||||
plog(L_QUEUE_INFO,creq,
|
||||
"Request canceled by client - not on queue",0);
|
||||
ardp_rqfree(creq); ardp_ptfree(pkt);
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_pendingQ);
|
||||
goto check_for_more;
|
||||
}
|
||||
|
||||
/* If the client specifies option flags and doesn't specify control
|
||||
info to match them, we probably should log this; right now we just
|
||||
silently ignore it. */
|
||||
if (ctlptr < pkt->start + hdr_len) /* if still control info */ {
|
||||
/* Priority specified. */
|
||||
if(flags1 & 0x2) {
|
||||
bcopy2(ctlptr,&stmp);
|
||||
creq->priority = ntohs(stmp);
|
||||
ctlptr += 2;
|
||||
}
|
||||
}
|
||||
if (ctlptr < pkt->start + hdr_len) /* if still control info */ {
|
||||
/* Higher-level protocol ID follows. */
|
||||
/* N.B.: used to be a bug here where this was 0x1; this is in
|
||||
variance with the ARDP spec and I've corrected the
|
||||
implementation to conform to the spec. */
|
||||
if(flags1 & 0x4) {
|
||||
bcopy2(ctlptr,&stmp);
|
||||
pid = ntohs(stmp);
|
||||
ctlptr += 2;
|
||||
}
|
||||
}
|
||||
if (ctlptr < pkt->start + hdr_len) /* if still control info */ {
|
||||
/* Window size follows (2 octets of information). */
|
||||
if(flags1 & 0x8) {
|
||||
bcopy2(ctlptr,&stmp);
|
||||
creq->pwindow_sz = ntohs(stmp);
|
||||
ctlptr += 2;
|
||||
if (creq->pwindow_sz == 0) {
|
||||
creq->pwindow_sz = ARDP_DEFAULT_WINDOW_SZ;
|
||||
plog(L_NET_INFO, creq,
|
||||
"Client explicity reset window size to server \
|
||||
default (%d)",
|
||||
ARDP_DEFAULT_WINDOW_SZ);
|
||||
} else {
|
||||
if (creq->pwindow_sz > ARDP_MAX_WINDOW_SZ) {
|
||||
plog(L_NET_INFO, creq, "Client set window size \
|
||||
to %d; server will limit it to %d", creq->pwindow_sz, ARDP_MAX_WINDOW_SZ);
|
||||
creq->pwindow_sz = ARDP_MAX_WINDOW_SZ;
|
||||
} else {
|
||||
plog(L_NET_INFO, creq,
|
||||
"Client set window size to %d", creq->pwindow_sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((creq->priority < 0) && (creq->priority != -42)) {
|
||||
plog(L_NET_RDPERR, creq, "Priority %d requested - ignored", creq->priority, 0);
|
||||
creq->priority = 0;
|
||||
}
|
||||
|
||||
if(pkt->seq == 1) creq->rcvd_thru = max(creq->rcvd_thru, 1);
|
||||
|
||||
pkt->length -= hdr_len;
|
||||
pkt->start += hdr_len;
|
||||
pkt->text = pkt->start;
|
||||
}
|
||||
else {
|
||||
/* When we are no longer getting any of these old format */
|
||||
/* requests, we know that everyone is using the new */
|
||||
/* reliable datagram protocol, and that they also */
|
||||
/* have the singleton response bug fixed. We can then */
|
||||
/* get rid of the special casing for singleton responses */
|
||||
|
||||
/* Lower the priority to encourage people to upgrade */
|
||||
creq->priority = 1;
|
||||
creq->peer_ardp_version = -1;
|
||||
#ifdef LOGOLDFORMAT
|
||||
plog(L_DIR_PWARN,creq,"Old RDP format",0);
|
||||
#endif LOGOLDFORMAT
|
||||
pkt->seq = 1;
|
||||
creq->rcvd_tot = 1;
|
||||
creq->rcvd_thru = 1;
|
||||
}
|
||||
|
||||
/* Check to see if it is already on done, partial, or pending */
|
||||
|
||||
/* Done queue */
|
||||
EXTERN_MUTEXED_LOCK(ardp_doneQ);
|
||||
treq = ardp_doneQ;
|
||||
CHECK_HEAD(treq);
|
||||
while(treq) {
|
||||
if((treq->cid != 0) && (treq->cid == creq->cid) &&
|
||||
(bcmp((char *) &(treq->peer),
|
||||
(char *) &from,sizeof(from))==0)){
|
||||
/* Request is already on doneQ */
|
||||
if(creq->prcvd_thru > treq->prcvd_thru) {
|
||||
treq->prcvd_thru = creq->prcvd_thru;
|
||||
rr_time = 0; /* made progress, don't supress retransmission */
|
||||
}
|
||||
nreq = treq;
|
||||
|
||||
/* Retransmit reply if not completely received */
|
||||
/* and if we didn't retransmit it this second */
|
||||
if((nreq->prcvd_thru != nreq->trns_tot) &&
|
||||
((rr_time != now) || (nreq != ardp_doneQ))) {
|
||||
PTEXT tpkt; /* Temporary pkt pointer */
|
||||
|
||||
plog(L_QUEUE_INFO,nreq,"Retransmitting reply (%d of %d ack)",
|
||||
nreq->prcvd_thru, nreq->trns_tot, 0);
|
||||
/* Transmit all outstanding packets */
|
||||
for (tpkt = nreq->trns; tpkt; tpkt = tpkt->next) {
|
||||
if((tpkt->seq <= (nreq->prcvd_thru + nreq->pwindow_sz)) &&
|
||||
((tpkt->seq == 0) || (tpkt->seq > nreq->prcvd_thru))) {
|
||||
/* (A) Request an ack at the end of a window
|
||||
(B) Request an ack in the last packet if the
|
||||
service has rescinded a wait request, but we
|
||||
aren't sure that the client knows this.
|
||||
*/
|
||||
ardp_header_ack_rwait(tpkt, nreq,
|
||||
/* do set ACK BIT: */
|
||||
(/*A*/ tpkt->seq ==
|
||||
(nreq->prcvd_thru
|
||||
+ nreq->pwindow_sz))
|
||||
|| /*B*/
|
||||
((tpkt->seq == nreq->trns_tot)
|
||||
/* last pkt */
|
||||
&& (nreq->svc_rwait_seq >
|
||||
nreq->prcvd_thru)),
|
||||
/* Might an RWAIT be needed? */
|
||||
(nreq->svc_rwait_seq >
|
||||
nreq->prcvd_thru));
|
||||
ardp_snd_pkt(tpkt,nreq);
|
||||
}
|
||||
}
|
||||
rr_time = now; /* Remember time of retransmission */
|
||||
}
|
||||
/* Move matched request to front of queue */
|
||||
/* nreq is definitely in ardp_doneQ right now. */
|
||||
/* This replaces much icky special-case code that used to be here
|
||||
-- swa, Feb 9, 1994 */
|
||||
EXTRACT_ITEM(nreq, ardp_doneQ);
|
||||
PREPEND_ITEM(nreq, ardp_doneQ);
|
||||
ardp_rqfree(creq); ardp_ptfree(pkt);
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_doneQ);
|
||||
goto check_for_more;
|
||||
}
|
||||
/* While we're checking the done queue also see if any */
|
||||
/* replies require follow up requests for acknowledgments */
|
||||
/* This is currently used when the server has requested that the client
|
||||
wait for a long time, and then has rescinded that wait request
|
||||
(because the message is done). Such a rescinding of the wait
|
||||
request should be received by the client, and the server is
|
||||
expecting an ACK. */
|
||||
/* You can add additional tests here if there are other circumstances
|
||||
under which you want the server to expect the client to send an
|
||||
acknowledgement. */
|
||||
if(check_for_ack && (treq->svc_rwait_seq > treq->prcvd_thru) &&
|
||||
(treq->retries_rem > 0) && (now >= treq->wait_till.tv_sec)) {
|
||||
#define ARDP_LOG_SPONTANEOUS_RETRANSMISSIONS
|
||||
#ifdef ARDP_LOG_SPONTANEOUS_RETRANSMISSIONS
|
||||
plog(L_QUEUE_INFO,treq,"Requested ack not received - pinging client (%d of %d/%d ack)",
|
||||
treq->prcvd_thru, treq->svc_rwait_seq, treq->trns_tot, 0);
|
||||
#endif /* ARDP_LOG_SPONTANEOUS_RETRANSMISSIONS */
|
||||
/* Resend the final packet only - to wake the client */
|
||||
if(treq->trns) ardp_snd_pkt(treq->trns->previous,treq);
|
||||
treq->timeout_adj.tv_sec = ARDP_BACKOFF(treq->timeout_adj.tv_sec);
|
||||
treq->wait_till.tv_sec = now + treq->timeout_adj.tv_sec;
|
||||
treq->retries_rem--;
|
||||
}
|
||||
CHECK_NEXT(treq);
|
||||
treq = treq->next;
|
||||
} /*while*/
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_doneQ);
|
||||
check_for_ack = 0; /* Only check once per call to ardp_accept */
|
||||
|
||||
/* If unsequenced control packet free it and check for more */
|
||||
if(pkt->seq == 0) {
|
||||
ardp_rqfree(creq); ardp_ptfree(pkt);
|
||||
goto check_for_more;
|
||||
}
|
||||
|
||||
/* Check if incomplete and match up with other incomplete requests */
|
||||
if(creq->rcvd_tot != 1) { /* Look for rest of request */
|
||||
treq = ardp_partialQ;
|
||||
while(treq) {
|
||||
if((treq->cid != 0) && (treq->cid == creq->cid) &&
|
||||
(bcmp((char *) &(treq->peer),
|
||||
(char *) &from,sizeof(from))==0)) {
|
||||
/* We found the rest of the request */
|
||||
/* coallesce and log and check_for more */
|
||||
PTEXT tpkt; /* Temporary pkt pointer */
|
||||
|
||||
ardp_update_cfields(treq,creq);
|
||||
if(creq->rcvd_tot) treq->rcvd_tot = creq->rcvd_tot;
|
||||
tpkt = treq->rcvd;
|
||||
while(tpkt) {
|
||||
if(tpkt->seq == treq->rcvd_thru+1) treq->rcvd_thru++;
|
||||
if(tpkt->seq == pkt->seq) {
|
||||
/* Duplicate - discard */
|
||||
plog(L_NET_INFO,creq,"Multi-packet duplicate received (pkt %d of %d)",
|
||||
pkt->seq, creq->rcvd_tot, 0);
|
||||
if(areq != treq) {
|
||||
if(areq) {
|
||||
ardp_acknowledge(areq);
|
||||
}
|
||||
areq = treq;
|
||||
}
|
||||
ardp_rqfree(creq); ardp_ptfree(pkt);
|
||||
goto check_for_more;
|
||||
}
|
||||
if(tpkt->seq > pkt->seq) {
|
||||
/* Insert new packet in rcvd */
|
||||
pkt->next = tpkt;
|
||||
pkt->previous = tpkt->previous;
|
||||
if(treq->rcvd == tpkt) treq->rcvd = pkt;
|
||||
else tpkt->previous->next = pkt;
|
||||
tpkt->previous = pkt;
|
||||
if(pkt->seq == treq->rcvd_thru+1) treq->rcvd_thru++;
|
||||
while(tpkt && (tpkt->seq == treq->rcvd_thru+1)) {
|
||||
treq->rcvd_thru++;
|
||||
tpkt = tpkt->next;
|
||||
}
|
||||
pkt = NOPKT;
|
||||
break;
|
||||
}
|
||||
tpkt = tpkt->next;
|
||||
}
|
||||
if(pkt) { /* Append at end of rcvd */
|
||||
APPEND_ITEM(pkt,treq->rcvd);
|
||||
if(pkt->seq == treq->rcvd_thru+1) treq->rcvd_thru++;
|
||||
pkt = NOPKT;
|
||||
}
|
||||
if(treq->rcvd_tot && (treq->rcvd_thru == treq->rcvd_tot)) {
|
||||
if(areq == treq) areq = NOREQ;
|
||||
creq = treq; EXTRACT_ITEM(creq, ardp_partialQ); --ptQlen;
|
||||
plog(L_NET_INFO,creq,"Multi-packet request complete",0);
|
||||
goto req_complete;
|
||||
}
|
||||
else {
|
||||
if(areq != treq) {
|
||||
if(areq) {
|
||||
ardp_acknowledge(areq);
|
||||
}
|
||||
areq = treq;
|
||||
}
|
||||
plog(L_NET_INFO, creq,
|
||||
"Multi-packet request continued (rcvd %d of %d)",
|
||||
creq->rcvd_thru, creq->rcvd_tot, 0);
|
||||
goto check_for_more;
|
||||
}
|
||||
}
|
||||
treq = treq->next;
|
||||
}
|
||||
/* This is the first packet we received in the request */
|
||||
/* log it and queue it and check for more */
|
||||
plog(L_NET_INFO,creq,"Multi-packet request received (pkt %d of %d)",
|
||||
pkt->seq, creq->rcvd_tot, 0);
|
||||
APPEND_ITEM(pkt,creq->rcvd);
|
||||
APPEND_ITEM(creq,ardp_partialQ); /* Add at end of incomp queue */
|
||||
if(++ptQlen > ptQmaxlen) {
|
||||
treq = ardp_partialQ; /* Remove from head of queue */
|
||||
EXTRACT_ITEM(ardp_partialQ,ardp_partialQ); ptQlen--;
|
||||
plog(L_NET_ERR, treq,
|
||||
"Too many incomplete requests - dropped (rthru %d of %d)",
|
||||
treq->rcvd_thru, treq->rcvd_tot, 0);
|
||||
ardp_rqfree(treq);
|
||||
}
|
||||
goto check_for_more;
|
||||
}
|
||||
|
||||
plog(L_NET_INFO, creq, "Received packet", 0);
|
||||
|
||||
req_complete:
|
||||
|
||||
qpos = 0; dpos = 1;
|
||||
|
||||
/* Insert this message at end of pending but make sure the */
|
||||
/* request is not already in pending */
|
||||
nreq = creq; creq = NOREQ;
|
||||
EXTERN_MUTEXED_LOCK(ardp_pendingQ);
|
||||
treq = ardp_pendingQ;
|
||||
|
||||
if(pkt) {
|
||||
nreq->rcvd_tot = 1;
|
||||
APPEND_ITEM(pkt,nreq->rcvd);
|
||||
}
|
||||
|
||||
EXTERN_MUTEXED_LOCK(ardp_runQ);
|
||||
for (match_in_runQ = ardp_runQ; match_in_runQ;
|
||||
match_in_runQ = match_in_runQ->next) {
|
||||
if((match_in_runQ->cid == nreq->cid) && (match_in_runQ->cid != 0) &&
|
||||
(bcmp((char *) &(match_in_runQ->peer),
|
||||
(char *) &(nreq->peer),sizeof(nreq->peer))==0)) {
|
||||
/* Request is running right now */
|
||||
ardp_update_cfields(match_in_runQ,nreq);
|
||||
plog(L_QUEUE_INFO,match_in_runQ,"Duplicate discarded (presently executing)",0);
|
||||
/*!! This looks strange - freeing but not removing from ardp_runQ*/
|
||||
ardp_rqfree(nreq);
|
||||
nreq = match_in_runQ;
|
||||
break; /* leave match_in_runQ set to nreq */
|
||||
}
|
||||
}
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_runQ);
|
||||
if (match_in_runQ) {
|
||||
/* do nothing; handled above. */
|
||||
} else if(ardp_pendingQ) {
|
||||
int keep_looking = 1; /* Keep looking for dup. Initially say to
|
||||
keep on looking. */
|
||||
|
||||
while(treq) {
|
||||
if((treq->cid != 0) && (treq->cid == nreq->cid) &&
|
||||
(bcmp((char *) &(treq->peer),
|
||||
(char *) &(nreq->peer),sizeof(treq->peer))==0)){
|
||||
/* Request is already on queue */
|
||||
ardp_update_cfields(treq,nreq);
|
||||
plog(L_QUEUE_INFO,treq,"Duplicate discarded (%d of %d)",dpos,pQlen,0);
|
||||
ardp_rqfree(nreq);
|
||||
nreq = treq;
|
||||
keep_looking = 0; /* We found the duplicate */
|
||||
break;
|
||||
}
|
||||
if((ardp_pri_override && ardp_pri_func && (ardp_pri_func(nreq,treq) < 0)) ||
|
||||
(!ardp_pri_override && ((nreq->priority < treq->priority) ||
|
||||
((treq->priority == nreq->priority) && ardp_pri_func &&
|
||||
(ardp_pri_func(nreq,treq) < 0))))) {
|
||||
if(ardp_pendingQ == treq) {
|
||||
nreq->previous = ardp_pendingQ->previous;
|
||||
nreq->next = ardp_pendingQ;
|
||||
ardp_pendingQ->previous = nreq;
|
||||
ardp_pendingQ = nreq;
|
||||
}
|
||||
else {
|
||||
nreq->next = treq;
|
||||
nreq->previous = treq->previous;
|
||||
nreq->previous->next = nreq;
|
||||
treq->previous = nreq;
|
||||
}
|
||||
pQlen++;
|
||||
if(nreq->priority > 0) pQNlen++;
|
||||
LOG_PACKET(nreq, dpos);
|
||||
qpos = dpos;
|
||||
keep_looking = 1; /* There may still be a duplicate */
|
||||
break;
|
||||
}
|
||||
if(!treq->next) {
|
||||
treq->next = nreq;
|
||||
nreq->previous = treq;
|
||||
ardp_pendingQ->previous = nreq;
|
||||
pQlen++;
|
||||
if(nreq->priority > 0) pQNlen++;
|
||||
LOG_PACKET(nreq,dpos+1);
|
||||
qpos = dpos+1;
|
||||
keep_looking = 0; /* Nothing more to check */
|
||||
break;
|
||||
}
|
||||
treq = treq->next;
|
||||
dpos++;
|
||||
}
|
||||
/* Save queue position to send to client if appropriate */
|
||||
qpos = dpos;
|
||||
/* If not added at end of queue, check behind packet for dup */
|
||||
if(keep_looking) {
|
||||
while(treq) {
|
||||
if((treq->cid == nreq->cid) && (treq->cid != 0) &&
|
||||
(bcmp((char *) &(treq->peer),
|
||||
(char *) &(nreq->peer),
|
||||
sizeof(treq->peer))==0)){
|
||||
/* Found a dup */
|
||||
plog(L_QUEUE_INFO,treq,"Duplicate replaced (removed at %d)", dpos, 0);
|
||||
pQlen--;if(treq->priority > 0) pQNlen--;
|
||||
EXTRACT_ITEM(treq,ardp_pendingQ);
|
||||
ardp_rqfree(treq);
|
||||
break;
|
||||
}
|
||||
treq = treq->next;
|
||||
dpos++;
|
||||
}
|
||||
} /* if keep_looking */
|
||||
}
|
||||
else {
|
||||
nreq->next = NULL;
|
||||
ardp_pendingQ = nreq;
|
||||
ardp_pendingQ->previous = nreq;
|
||||
pQlen++;if(nreq->priority > 0) pQNlen++;
|
||||
LOG_PACKET(nreq, dpos);
|
||||
qpos = dpos;
|
||||
}
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_pendingQ);
|
||||
|
||||
/* Fill in queue position and system time */
|
||||
nreq->inf_queue_pos = qpos;
|
||||
/* nreq->inf_sys_time = **compute-system-time-here** */
|
||||
|
||||
#ifdef ARCHIE
|
||||
nreq -> inf_sys_time = arch_get_etime(nreq);
|
||||
#endif
|
||||
|
||||
/* Here we can optionally send a message telling the */
|
||||
/* client to back off. How long should depend on the */
|
||||
/* queue length and the mean service time */
|
||||
/* 15 min for now - the archie server is overloaded */
|
||||
#ifdef ARCHIE
|
||||
/* This is an old version of the Prospero clients that only archie servers
|
||||
will need to be able to talk to, so don't bother doing this test
|
||||
for anything but an archie server. */
|
||||
if((nreq->peer_ardp_version >= 0) && (sindex(nreq->rcvd->start,"VERSION 1")))
|
||||
nreq->peer_ardp_version = -2;
|
||||
/* Archie servers should request a longer wait. Other heavily used
|
||||
databases may want to have this command defined too. */
|
||||
ardp_rwait(nreq,900,nreq->inf_queue_pos,nreq->inf_sys_time);
|
||||
#endif
|
||||
|
||||
goto check_for_more;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
void
|
||||
ardp_update_cfields(RREQ existing,RREQ newvalues)
|
||||
{
|
||||
if(newvalues->prcvd_thru > existing->prcvd_thru)
|
||||
existing->prcvd_thru = newvalues->prcvd_thru;
|
||||
}
|
||||
|
||||
/* Rewrite the header of TPKT to conform to the status in nreq. The only
|
||||
fields
|
||||
we need to set are possibly the ACK bit in octet 11 and possibly the rwait
|
||||
field in octets 9 & 10. We always send the received-through field for the
|
||||
sake of simplicity of implementation. */
|
||||
static void ardp_header_ack_rwait(PTEXT tpkt, RREQ nreq, int is_ack_needed,
|
||||
int is_rwait_needed)
|
||||
{
|
||||
int new_hlength; /* new header length. */
|
||||
int old_hlength; /* old header length */
|
||||
unsigned short us_tmp; /* tmp for values. */
|
||||
old_hlength = tpkt->text - tpkt->start;
|
||||
/* If rwait needed, leave room for it. */
|
||||
new_hlength = 9; /* Include room for received-through count */
|
||||
if (is_rwait_needed)
|
||||
new_hlength = 11;
|
||||
if (is_ack_needed) new_hlength = 12;
|
||||
|
||||
/* Allocate space for new header. */
|
||||
tpkt->start = tpkt->text - new_hlength;
|
||||
tpkt->length += new_hlength - old_hlength;
|
||||
/* Set the header length and version # (zeroth octet) */
|
||||
/* Version # is zero in this version of the ARDP library; last 6 bytes
|
||||
of octet are header length. */
|
||||
*(tpkt->start) = (char) new_hlength;
|
||||
/* Set octets 1 through 8 of header */
|
||||
/* Connection ID (octets 1 & 2) */
|
||||
bcopy2(&(nreq->cid),tpkt->start+1);
|
||||
/* Sequence number (octets 3 & 4) */
|
||||
us_tmp = htons(tpkt->seq);
|
||||
bcopy2(&us_tmp,tpkt->start+3);
|
||||
/* Total packet count (octets 5 & 6) */
|
||||
us_tmp = htons(nreq->trns_tot);
|
||||
bcopy2(&us_tmp,tpkt->start+5);
|
||||
/* Received through (octets 7 & 8) */
|
||||
us_tmp = htons(nreq->rcvd_thru);
|
||||
bcopy2(&us_tmp,tpkt->start+7);
|
||||
/* Now set any options. */
|
||||
/* expected time 'till response */
|
||||
if (new_hlength > 9) {
|
||||
us_tmp = htons(nreq->svc_rwait);
|
||||
bcopy2(&us_tmp, tpkt->start+9);
|
||||
}
|
||||
if (new_hlength > 11) {
|
||||
tpkt->start[11] =
|
||||
is_ack_needed ? 0x80 /* ACK BIT */ : 0x00 /* Don't ack */;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ardp_accept() {
|
||||
return ardp_accept_and_wait(0,0);
|
||||
}
|
||||
|
||||
|
||||
163
prospero/lib/ardp/ardp_add2req.c
Normal file
163
prospero/lib/ardp/ardp_add2req.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 2/93 to add text to a request
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <sys/types.h> /* so pmachine.h won't redefine it. */
|
||||
#include <pmachine.h> /* for bcopy() */
|
||||
|
||||
#define max(x,y) (x > y ? x : y)
|
||||
#define min(x,y) (x < y ? x : y)
|
||||
|
||||
/*
|
||||
* ardp_add2req - add text to request structure
|
||||
*
|
||||
* ardp_add2req takes a request structure, flags, a buffer containing text
|
||||
* to be added to the output queue of the request, and the length of the
|
||||
* buffer.
|
||||
*
|
||||
* If the specified length of the buffer is 0, ardp_add2req calculates
|
||||
* it using strlen (if the lenght is zero, the assumption is that the
|
||||
* buffer is null terminated).
|
||||
* If the buffer is a NULL pointer and the specified length is 0, then
|
||||
* it treated as a true zero-length buffer.
|
||||
*
|
||||
* If the flag ARDP_A2R_NOSPLITB is set, the request will not be split
|
||||
* across packets. If ARDP_A2R_NOSPLITL, the lines may not be split
|
||||
* across packets, and text added to a request without a trailing new
|
||||
* line will be deferred until a newline is added or ardp_add2req is called
|
||||
* without ARDP_A2R_NOSPLITL set. If ARDP_A2R_COMPLETE is specified, it
|
||||
* indicates this is the final text to be added to the request structure,
|
||||
* and no text will remain buffered. If there is still deferred text,
|
||||
* a newline will be added. If the flag ARDP_A2R_TAGLENGTH is specified,
|
||||
* the data written to the request will be tagged with a four octet length
|
||||
* field in network byte order.
|
||||
*
|
||||
* NOTE: If you use this function to add text to a request, then you
|
||||
* should use only this function. If this function is called on
|
||||
* a request previously constructed by hand, unexpected failures
|
||||
* may result.
|
||||
*
|
||||
* BUGS: ARDP_A2R_NOSPLITL is not currently supported unless
|
||||
* ARDP_A2R_NOSPLITB is also set.
|
||||
* ARDP_A2R_TAGLENGTH is not presently supported.
|
||||
* An ardp_flush_partial_line() is needed to handle some manifestations
|
||||
* of the ARDP_TOOLONG error. Alternatively, we might specify an
|
||||
* additional flag to ardp_add2req() to specify the behavior on an
|
||||
* ARDP_TOOLONG error.
|
||||
*/
|
||||
int
|
||||
ardp_add2req(RREQ req, /* Request to get the text */
|
||||
int flags, /* Options to add2req */
|
||||
char *buf, /* New text for request */
|
||||
int buflen) /* Length of the new text */
|
||||
{
|
||||
int remaining; /* Space remaining in pkt */
|
||||
int written; /* # Octets written */
|
||||
char *newline; /* last nl in string */
|
||||
int deflen; /* Length of deferred text */
|
||||
int extra; /* Extra space needed */
|
||||
long taglen; /* Length in net byte ord */
|
||||
PTEXT pkt = NOPKT; /* Current packet */
|
||||
PTEXT ppkt; /* Previous packet */
|
||||
|
||||
/* Note: New text gets written after pkt->ioptr. If */
|
||||
/* there is text waiting for a newline, then ->ioptr */
|
||||
/* may be beyond ->start+->length, which will be the */
|
||||
/* text up to the final newline seen so far */
|
||||
|
||||
/* XXX For now if NOSPLITL, must also specify NOSPLITB */
|
||||
if((flags & ARDP_A2R_NOSPLITL) && !(flags & ARDP_A2R_NOSPLITB))
|
||||
return(ARDP_FAILURE);
|
||||
|
||||
if(buf && !buflen) buflen = strlen(buf);
|
||||
if(!buf) buf = "";
|
||||
|
||||
keep_writing:
|
||||
|
||||
/* Find ot allocate last packet in ->outpkt */
|
||||
if(req->outpkt) pkt = req->outpkt->previous;
|
||||
if(!pkt) {
|
||||
if((pkt = ardp_ptalloc()) == NOPKT) return(ARDP_FAILURE);
|
||||
APPEND_ITEM(pkt,req->outpkt);
|
||||
}
|
||||
|
||||
deflen = pkt->ioptr - (pkt->start + pkt->length);
|
||||
|
||||
extra = deflen;
|
||||
if(flags & ARDP_A2R_NOSPLITL) extra += 1;
|
||||
if(flags & ARDP_A2R_TAGLENGTH) extra += 4;
|
||||
|
||||
if((flags & ARDP_A2R_NOSPLITB) && (buflen + extra > ARDP_PTXT_LEN))
|
||||
return(ARDP_TOOLONG);
|
||||
|
||||
remaining = ARDP_PTXT_LEN - (pkt->ioptr - pkt->start);
|
||||
|
||||
if(((flags & ARDP_A2R_NOSPLITB) && (remaining < buflen + 1)) ||
|
||||
((flags & ARDP_A2R_TAGLENGTH) && (remaining < 4)) ||
|
||||
(remaining == 0)) {
|
||||
ppkt = pkt;
|
||||
if((pkt = ardp_ptalloc()) == NOPKT) return(ARDP_FAILURE);
|
||||
if(ppkt->start + ppkt->length != ppkt->ioptr) {
|
||||
/* Must move deferred text to new packet */
|
||||
bcopy(ppkt->start+ppkt->length, pkt->start, deflen);
|
||||
ppkt->ioptr = ppkt->start + ppkt->length;
|
||||
*(ppkt->ioptr) = '\0';
|
||||
pkt->ioptr += deflen;
|
||||
}
|
||||
APPEND_ITEM(pkt,req->outpkt);
|
||||
remaining = ARDP_PTXT_LEN;
|
||||
}
|
||||
|
||||
if(flags & ARDP_A2R_TAGLENGTH) {
|
||||
taglen = htonl(buflen);
|
||||
bcopy4(&buflen,pkt->ioptr);
|
||||
pkt->ioptr += 4;
|
||||
remaining -= 4;
|
||||
}
|
||||
|
||||
written = min(remaining,buflen);
|
||||
bcopy(buf,pkt->ioptr,written);
|
||||
pkt->ioptr += written;
|
||||
if(flags & ARDP_A2R_NOSPLITL) {
|
||||
*(pkt->ioptr) = '\0'; /* To catch runaway strrchar */
|
||||
/* Find last newline */
|
||||
newline = strrchr(pkt->start + pkt->length,'\n');
|
||||
if(newline) pkt->length = newline + 1 - pkt->start;
|
||||
}
|
||||
else pkt->length = pkt->ioptr - pkt->start;
|
||||
/* Always need to stick on trailing NULL for sake of ardp_respond(),
|
||||
which expects it. */
|
||||
*pkt->ioptr = '\0';
|
||||
|
||||
/* In this case, ARDP_A@R_NOSPLITB was not specified, split it */
|
||||
if(written != buflen) {
|
||||
buf += written;
|
||||
buflen -= written;
|
||||
goto keep_writing;
|
||||
}
|
||||
|
||||
if(flags & ARDP_A2R_COMPLETE) {
|
||||
deflen = pkt->ioptr - (pkt->start + pkt->length);
|
||||
/* If deferred, write a newline */
|
||||
if(deflen) {
|
||||
*(pkt->ioptr++) = '\n';
|
||||
pkt->length = pkt->ioptr - pkt->start;
|
||||
/* Always need to stick on trailing NULL for sake of
|
||||
ardp_respond(), which expects it. */
|
||||
*pkt->ioptr = '\0';
|
||||
}
|
||||
}
|
||||
return ARDP_SUCCESS;
|
||||
}
|
||||
|
||||
68
prospero/lib/ardp/ardp_breply.c
Normal file
68
prospero/lib/ardp/ardp_breply.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Written by bcn 2/93 to send reply to request
|
||||
* Hacked by swa 11/94 to send length-coded reply to request.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ardp.h>
|
||||
|
||||
/*
|
||||
* ardp_breply - send a reply to a request that might contain binary data
|
||||
*
|
||||
* ardp_breply reply takes request to which a reply is to be sent
|
||||
* a flags field, and a message to be sent to the client in response
|
||||
* to the request, and a length count for the message. ardp_breply then adds
|
||||
* the response to the output queue for the request.
|
||||
*
|
||||
* A length count of 0 indicates that the buffer is null-terminated.
|
||||
* (implementation note: by passing the 0 down to ardp_add2req, we
|
||||
* allow there to be only one pass through the buffer instead of 2.)
|
||||
*
|
||||
* If space remains in the packet, the response is buffered pending
|
||||
* subsequent replies, unless the ARDP_REPL_COMPLETE has been specified,
|
||||
* in which case all data is sent. If the size of the buffered response
|
||||
* approaches the maximum packet size, the buffered data is sent, and
|
||||
* and a new packet is started to hold any remaining data from the current
|
||||
* message.
|
||||
*
|
||||
* The lower level function (ardp_respond) assigns packet numbers and
|
||||
* tags outgoing packets if necessary or a multi packet response.
|
||||
*/
|
||||
|
||||
int
|
||||
ardp_breply(RREQ req, /* Request to which this is a response */
|
||||
int flags, /* Whether this is the final message */
|
||||
char *message, /* The data to be sent. */
|
||||
int len) /* message length; 0 means null-terminated */
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = ardp_add2req(req,flags,message,len);
|
||||
if (tmp) return tmp;
|
||||
if(flags&ARDP_R_COMPLETE) return(ardp_respond(req,ARDP_R_COMPLETE));
|
||||
|
||||
/* Check to see if any packets are done */
|
||||
#if 1
|
||||
if(req->outpkt && req->outpkt->next) {
|
||||
#else
|
||||
/* This always yields the same results as the previous line but appears
|
||||
clunkier to me. */
|
||||
if(req->outpkt && (req->outpkt->previous != req->outpkt)) {
|
||||
#endif
|
||||
PTEXT tpkt; /* Temp to hold active packet */
|
||||
/* Hold out final packet */
|
||||
tpkt = req->outpkt->previous;
|
||||
EXTRACT_ITEM(tpkt,req->outpkt);
|
||||
tmp = ardp_respond(req,ARDP_R_INCOMPLETE);
|
||||
APPEND_ITEM(tpkt,req->outpkt);
|
||||
if (tmp) return tmp;
|
||||
}
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
34
prospero/lib/ardp/ardp_error.c
Normal file
34
prospero/lib/ardp/ardp_error.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Written by swa 11/93 to handle error reporting consistently in libardp
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <perrno.h> /* For perrno */
|
||||
|
||||
/* See lib/ardp/usc_lic_str.c */
|
||||
extern char *usc_license_string;
|
||||
/* This is used in Prospero in lib/pfs/perrmesg.c. Change it there too if you
|
||||
change it here. */
|
||||
char *ardp___please_do_not_optimize_me_out_of_existence;
|
||||
|
||||
/* perrno is declared in ardp_perrno.c in case some older applications
|
||||
have explicitly declared their own perrno variable (a practice we now
|
||||
discourage). */
|
||||
|
||||
/* This function definition is shadowed in lib/pfs/perrmesg.c. Change it there
|
||||
too if you change it here. */
|
||||
|
||||
void
|
||||
p_clear_errors(void)
|
||||
{
|
||||
ardp___please_do_not_optimize_me_out_of_existence = usc_license_string;
|
||||
perrno = 0;
|
||||
}
|
||||
|
||||
88
prospero/lib/ardp/ardp_get_nxt.c
Normal file
88
prospero/lib/ardp/ardp_get_nxt.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*
|
||||
* Written by bcn 1991 as get_next_request in rdgram.c (Prospero)
|
||||
* Modified by bcn 1/93 modularized and incorporated into new ardp library
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef AIX
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <ardp.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern RREQ ardp_pendingQ;
|
||||
EXTERN_MUTEXED_DECL(RREQ,ardp_runQ);
|
||||
extern int pQNlen;
|
||||
extern int pQlen;
|
||||
extern int ardp_srvport;
|
||||
extern int ardp_prvport;
|
||||
|
||||
#define max(x,y) (x > y ? x : y)
|
||||
|
||||
/*
|
||||
* ardp_get_nxt - return next request for server
|
||||
*
|
||||
* ardp_get_nxt returns the next request to be processed by the server.
|
||||
* If no requests are pending, ardp_get_nxt waits until a request
|
||||
* arrives, then returns it.
|
||||
*/
|
||||
/* Called outside multithraded stuff; doesn't need to be mutexed. */
|
||||
RREQ
|
||||
ardp_get_nxt(void)
|
||||
{
|
||||
RREQ nextreq;
|
||||
fd_set readfds;
|
||||
int tmp;
|
||||
|
||||
tryagain:
|
||||
if (nextreq = ardp_get_nxt_nonblocking())
|
||||
return nextreq;
|
||||
/* if queue is empty, then wait till somethings comes */
|
||||
/* in, then go back to start */
|
||||
FD_ZERO(&readfds);
|
||||
if(ardp_srvport != -1) FD_SET(ardp_srvport, &readfds);
|
||||
if(ardp_prvport != -1) FD_SET(ardp_prvport, &readfds);
|
||||
tmp = select(max(ardp_srvport,ardp_prvport) + 1, &readfds,
|
||||
(fd_set *)0, (fd_set *)0, NULL);
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Nonblocking version of the above.
|
||||
* Returns NULL if no pending items.
|
||||
*/
|
||||
RREQ
|
||||
ardp_get_nxt_nonblocking(void)
|
||||
{
|
||||
ardp_accept();
|
||||
|
||||
/* return next message in queue */
|
||||
if (ardp_pendingQ) {
|
||||
/* Atomic test; save ourselves the trouble of going through the kernel
|
||||
if nothing in queue */
|
||||
EXTERN_MUTEXED_LOCK(ardp_pendingQ);
|
||||
if(ardp_pendingQ) {
|
||||
RREQ nextreq = ardp_pendingQ;
|
||||
|
||||
EXTRACT_ITEM(nextreq, ardp_pendingQ);
|
||||
pQlen--;if(nextreq->priority > 0) pQNlen--;
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_pendingQ);
|
||||
nextreq->svc_start_time.tv_sec = time(NULL);
|
||||
EXTERN_MUTEXED_LOCK(ardp_runQ);
|
||||
APPEND_ITEM(nextreq,ardp_runQ);
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_runQ);
|
||||
return(nextreq);
|
||||
}
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_pendingQ);
|
||||
}
|
||||
return NOREQ;
|
||||
}
|
||||
124
prospero/lib/ardp/ardp_headers.c
Normal file
124
prospero/lib/ardp/ardp_headers.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1/93 For use in adrp_send
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pmachine.h> /* for bcopy() */
|
||||
|
||||
extern int ardp_priority; /* Override for 0 priority */
|
||||
extern int pfs_debug;
|
||||
|
||||
/*
|
||||
* ardp_headers - Add headers to packets to be sent to server
|
||||
*
|
||||
* ardp_headers takes pointer to a request structure and adds headers to
|
||||
* all the packets in the trns list. The fields for the headers are
|
||||
* taken from other fields in the request structure. If the priority is
|
||||
* zero, it is taken from the global vairable ardp_priority.
|
||||
*
|
||||
* If ardp_headers is called more than once, subsequent calls will
|
||||
* update the headers to conform to changes in the request fields.
|
||||
*/
|
||||
int
|
||||
ardp_headers(RREQ req)
|
||||
{
|
||||
PTEXT ptmp; /* Temporary packet pointer */
|
||||
|
||||
for(ptmp = req->trns; ptmp; ptmp = ptmp->next) {
|
||||
int old_hlength; /* Old header length */
|
||||
int new_hlength; /* New header length, whatever it may
|
||||
be. */
|
||||
unsigned short ftmp; /* Temporary for values of fields */
|
||||
/* Boolean: do we stamp this packet with the window size? */
|
||||
/* We will add an explicity window-size stamp to the first sent, if
|
||||
an explicit window size was set. This packet is the one stamped
|
||||
with sequence number 1. Thus we know that the window size message
|
||||
won't be lost. */
|
||||
int stamp_window_size = (req->flags & ARDP_FLAG_SEND_MY_WINDOW_SIZE)
|
||||
&& (ptmp->seq == 1);
|
||||
int stamp_priority = (req->priority || ardp_priority)
|
||||
&& (ptmp->seq == 1);
|
||||
|
||||
old_hlength = ptmp->text - ptmp->start;
|
||||
|
||||
/* XXX Should do further tests to make sure all packets present */
|
||||
if(ptmp->seq == 0) {
|
||||
if (pfs_debug >= 1)
|
||||
fprintf(stderr, "ardp: sequence number not set in packet\n");
|
||||
fflush(stderr);
|
||||
return(ARDP_BAD_REQ);
|
||||
}
|
||||
|
||||
/* If priority stamp or explicit client window size, need octets 11 and
|
||||
12 to be present. */
|
||||
if (stamp_priority || stamp_window_size) {
|
||||
new_hlength = 13; /* room for octets through 12 */
|
||||
if(req->priority || ardp_priority)
|
||||
new_hlength += 2; /* 2 octets for priority argument. */
|
||||
if (stamp_window_size)
|
||||
new_hlength += 2; /* 2 octets for window size */
|
||||
} else {
|
||||
new_hlength = 9; /* room for octets through 8 (received-through)
|
||||
*/
|
||||
}
|
||||
/* New header length now set. */
|
||||
|
||||
/* Allocate space for the new header */
|
||||
ptmp->start = ptmp->text - new_hlength;
|
||||
ptmp->length += new_hlength - old_hlength;
|
||||
/* Set the header length and version # (zeroth octet) */
|
||||
/* Version # is zero in this version of the ARDP library; last 6 bytes
|
||||
of octet are header length. */
|
||||
*(ptmp->start) = (char) new_hlength;
|
||||
/* Set octets 1 through 8 of header */
|
||||
/* Connection ID (octets 1 & 2) */
|
||||
bcopy2(&(req->cid),ptmp->start+1);
|
||||
/* Sequence number (octets 3 & 4) */
|
||||
ftmp = htons(ptmp->seq);
|
||||
bcopy2(&ftmp,ptmp->start+3);
|
||||
/* Total packet count (octets 5 & 6) */
|
||||
ftmp = htons(req->trns_tot);
|
||||
bcopy2(&ftmp,ptmp->start+5);
|
||||
/* Received through (octets 7 & 8) */
|
||||
ftmp = htons(req->rcvd_thru);
|
||||
bcopy2(&ftmp,ptmp->start+7);
|
||||
/* Now set any options. */
|
||||
if (new_hlength > 9) {
|
||||
char * optiondata; /* where options go. */
|
||||
/* zero out octets 9 and 10 (expected time 'till response). It is
|
||||
not defined for the client to specify this to the server,so
|
||||
it is always zero. */
|
||||
bzero2(ptmp->start + 9);
|
||||
/* set octet 11 (flags) initially clear */
|
||||
ptmp->start[11] = 0;
|
||||
/* Here Octet 12 (option) is zero (no special options). */
|
||||
ptmp->start[12] = 0;
|
||||
optiondata = ptmp->start + 13; /* additional octets start here */
|
||||
/* Priority */
|
||||
if(stamp_priority) {
|
||||
*(ptmp->start+11) |= 0x02; /* priority flag */
|
||||
if(req->priority) ftmp = htons(req->priority);
|
||||
else ftmp = htons(ardp_priority);
|
||||
bcopy2(&ftmp, optiondata);
|
||||
optiondata += 2;
|
||||
}
|
||||
if(stamp_window_size) {
|
||||
*(ptmp->start+11) |= 0x08; /* Set window size flag */
|
||||
ftmp = htons(req->window_sz);
|
||||
bcopy2(&ftmp, optiondata);
|
||||
optiondata += 2;
|
||||
}
|
||||
assert(optiondata == ptmp->start + new_hlength);
|
||||
}
|
||||
}
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
17
prospero/lib/ardp/ardp_int_err.c
Normal file
17
prospero/lib/ardp/ardp_int_err.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Written by swa 12/93 to handle error reporting consistently in libardp
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <ardp.h>
|
||||
|
||||
|
||||
/* Data definition. This may be reset by any client. */
|
||||
int (*internal_error_handler)(const char file[], int line, const char mesg[]) = 0;
|
||||
|
||||
85
prospero/lib/ardp/ardp_mutexes.c
Normal file
85
prospero/lib/ardp/ardp_mutexes.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 1993-1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pfs_threads.h>
|
||||
#include <ardp.h>
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
p_th_mutex p_th_mutexARDP_ACCEPT; /* declaration */
|
||||
p_th_mutex p_th_mutexPTEXT; /* declared in ardp_mutexes.c */
|
||||
p_th_mutex p_th_mutexARDP_RQALLOC; /* declared in ardp_mutexes.c */
|
||||
p_th_mutex p_th_mutexGETHOSTBYNAME; /* declared in pfs_mutexes.c */
|
||||
p_th_mutex p_th_mutexARDP_SELFNUM; /* declared in pfs_mutexes.c */
|
||||
p_th_mutex p_th_mutexDNSCACHE; /* declared in pfs_mutexes.c */
|
||||
p_th_mutex p_th_mutexALLDNSCACHE; /* declared in pfs_mutexes.c */
|
||||
p_th_mutex p_th_mutexFILES; /* declared on p__self_num.c */
|
||||
p_th_mutex p_th_mutexFILELOCK; /* declared in flock.c */
|
||||
#endif
|
||||
|
||||
void
|
||||
ardp_init_mutexes(void)
|
||||
{
|
||||
#ifdef PFS_THREADS
|
||||
EXTERN_MUTEXED_INIT_MUTEX(ardp_doneQ);
|
||||
EXTERN_MUTEXED_INIT_MUTEX(ardp_runQ);
|
||||
|
||||
p_th_mutex_init(p_th_mutexGETHOSTBYNAME);
|
||||
p_th_mutex_init(p_th_mutexARDP_ACCEPT);
|
||||
p_th_mutex_init(p_th_mutexPTEXT);
|
||||
p_th_mutex_init(p_th_mutexARDP_RQALLOC);
|
||||
p_th_mutex_init(p_th_mutexARDP_SELFNUM);
|
||||
p_th_mutex_init(p_th_mutexDNSCACHE);
|
||||
p_th_mutex_init(p_th_mutexALLDNSCACHE);
|
||||
p_th_mutex_init(p_th_mutexFILES);
|
||||
p_th_mutex_init(p_th_mutexFILELOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
void
|
||||
ardp_diagnose_mutexes(void)
|
||||
{
|
||||
#ifdef PFS_THREADS
|
||||
DIAGMUTEX(ardp_doneQ,"ardp_doneQ");
|
||||
DIAGMUTEX(ardp_runQ,"ardp_runQ");
|
||||
DIAGMUTEX(GETHOSTBYNAME,"GETHOSTBYNAME");
|
||||
DIAGMUTEX(ARDP_ACCEPT,"ARDP_ACCEPT");
|
||||
DIAGMUTEX(PTEXT,"PTEXT");
|
||||
DIAGMUTEX(ARDP_RQALLOC,"ARDP_RQALLOC");
|
||||
DIAGMUTEX(ARDP_SELFNUM,"ARDP_SELFNUM");
|
||||
DIAGMUTEX(DNSCACHE,"DNSCACHE");
|
||||
DIAGMUTEX(ALLDNSCACHE,"ALLDNSCACHE");
|
||||
DIAGMUTEX(FILES,"FILES");
|
||||
DIAGMUTEX(FILELOCK,"FILELOCK");
|
||||
#endif
|
||||
}
|
||||
#endif /*NDEBUG*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
19
prospero/lib/ardp/ardp_perrno.c
Normal file
19
prospero/lib/ardp/ardp_perrno.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Written by swa 11/93 to handle error reporting consistently in libardp
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <ardp.h>
|
||||
#include <pfs_threads.h>
|
||||
|
||||
#ifdef NEVERDEFINED
|
||||
int perrno = 0; /* Declare it. */
|
||||
#endif
|
||||
|
||||
EXTERN_INT_DEF(perrno);
|
||||
|
||||
420
prospero/lib/ardp/ardp_pr_actv.c
Normal file
420
prospero/lib/ardp/ardp_pr_actv.c
Normal file
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright (c) 1991, 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*
|
||||
* Written by bcn 1989-92 as part of dirsend.c in the Prospero distribution
|
||||
* Modified by bcn 1/93 moved to ardp library - added asynchrony
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifdef AIX
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <ardp.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h> /* for bcopy() */
|
||||
|
||||
extern RREQ ardp_activeQ; /* Info about active requests */
|
||||
extern RREQ ardp_completeQ; /* Info about completed reqs */
|
||||
extern int ardp_port; /* Opened UDP port */
|
||||
extern int pfs_debug; /* Debug level */
|
||||
int ardp_activeQ_len; /* Length of activeQ */
|
||||
|
||||
static struct timeval zerotime = {0, 0}; /* Used by select */
|
||||
|
||||
#define max(x,y) (x > y ? x : y)
|
||||
|
||||
static ardp__pr_ferror(int errcode);
|
||||
|
||||
/*
|
||||
* ardp_process_active - process active requests
|
||||
*
|
||||
* ardp_process_active takes no arguments. It checks to see if any responses
|
||||
* are pending on the UDP port, and if so processes them, adding them
|
||||
* to the request structures on ardp_activeQ. If no requests are pending
|
||||
* ardp_process_active processes and requests requiring retries then
|
||||
* returns.
|
||||
*
|
||||
*/
|
||||
int
|
||||
ardp_process_active()
|
||||
{
|
||||
fd_set readfds; /* Used for select */
|
||||
struct sockaddr_in from; /* Reply received from */
|
||||
int from_sz; /* Size of address structure */
|
||||
int hdr_len; /* Header Length */
|
||||
char *ctlptr; /* Pointer to control field */
|
||||
unsigned short cid = 0; /* Connection ID from rcvd pkt */
|
||||
unsigned char rdflag11; /* First byte of flags (bit vect)*/
|
||||
unsigned char rdflag12; /* Second byte of flags (int) */
|
||||
unsigned char tchar; /* For decoding extra fields */
|
||||
unsigned short stmp; /* Temp short for conversions */
|
||||
unsigned long ltmp; /* Temp long for converions */
|
||||
int tmp; /* Temporaty return value */
|
||||
int nr; /* Number octest received */
|
||||
long now; /* The current time */
|
||||
|
||||
RREQ req = NOREQ; /* To store request info */
|
||||
PTEXT pkt = NOPKT; /* Packet being processed */
|
||||
PTEXT ptmp = NOPKT; /* Packet being processed */
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* something_received not MT-Safe */
|
||||
check_for_pending:
|
||||
|
||||
/* Set list of file descriptors to be checked by select */
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(ardp_port, &readfds);
|
||||
|
||||
/* select - either recv is ready, or not */
|
||||
/* see if timeout or error or wrong descriptor */
|
||||
tmp = select(ardp_port + 1, &readfds, (fd_set *)0, (fd_set *)0, &zerotime);
|
||||
|
||||
/* If tmp is zero, then nothing to process, check for timeouts */
|
||||
if(tmp == 0) {
|
||||
now = time(NULL);
|
||||
req = ardp_activeQ;
|
||||
while(req) {
|
||||
if (req->status == ARDP_STATUS_ACKPEND) {
|
||||
ardp_xmit(req, -1 /* just ACK; send no data packets */);
|
||||
req->status = ARDP_STATUS_ACTIVE;
|
||||
}
|
||||
if((req->wait_till.tv_sec) && (now >= req->wait_till.tv_sec)) {
|
||||
if(req->retries_rem-- > 0) {
|
||||
req->timeout_adj.tv_sec = ARDP_BACKOFF(req->timeout_adj.tv_sec);
|
||||
if (pfs_debug >= 8) {
|
||||
fprintf(stderr,"Connection %d timed out - Setting timeout to %d seconds.\n",
|
||||
ntohs(req->cid), (int) req->timeout_adj.tv_sec);
|
||||
}
|
||||
req->wait_till.tv_sec = now + req->timeout_adj.tv_sec;
|
||||
ardp_xmit(req, req->pwindow_sz);
|
||||
} else {
|
||||
if(pfs_debug >= 8) {
|
||||
fprintf(stderr,"Connection %d timed out - Retry count exceeded.\n",
|
||||
ntohs(req->cid) );
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
req->status = ARDP_TIMEOUT;
|
||||
EXTRACT_ITEM(req,ardp_activeQ);
|
||||
--ardp_activeQ_len;
|
||||
APPEND_ITEM(req,ardp_completeQ);
|
||||
}
|
||||
}
|
||||
req = req->next;
|
||||
}
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
/* If negative, then return an error */
|
||||
if((tmp < 0) || !FD_ISSET(ardp_port, &readfds)) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "select failed : returned %d port=%d\n",
|
||||
tmp, ardp_port);
|
||||
|
||||
return(ardp__pr_ferror(ARDP_SELECT_FAILED));
|
||||
}
|
||||
|
||||
/* Process incoming packets */
|
||||
pkt = ardp_ptalloc();
|
||||
pkt->start = pkt->dat;
|
||||
from_sz = sizeof(from);
|
||||
|
||||
if ((nr = recvfrom(ardp_port, pkt->start, sizeof(pkt->dat),
|
||||
0, &from, &from_sz)) < 0) {
|
||||
if (pfs_debug) perror("recvfrom");
|
||||
ardp_ptlfree(pkt);
|
||||
return(ardp__pr_ferror(ARDP_BAD_RECV));
|
||||
}
|
||||
pkt->length = nr;
|
||||
*(pkt->start + pkt->length) = '\0';
|
||||
|
||||
if (pfs_debug >= 6)
|
||||
fprintf(stderr,"Received packet from %s\n", inet_ntoa(from.sin_addr));
|
||||
|
||||
/* If the first byte is greater than 31 we have an old version */
|
||||
/* response - return error */
|
||||
if((hdr_len = (unsigned char) *(pkt->start)) > 31) {
|
||||
ardp_ptfree(pkt);
|
||||
if(ardp_activeQ->next == NOREQ)
|
||||
return(ardp__pr_ferror(ARDP_BAD_VERSION));
|
||||
else goto check_for_pending;
|
||||
}
|
||||
|
||||
/* For the current format, the first two bits are a version number */
|
||||
/* and the next six are the header length (including the first byte). */
|
||||
ctlptr = pkt->start + 1;
|
||||
|
||||
if(hdr_len >= 3) { /* Connection ID */
|
||||
bcopy2(ctlptr,&stmp);
|
||||
if(stmp) cid = stmp;
|
||||
ctlptr += 2;
|
||||
}
|
||||
|
||||
/* Match up response with request */
|
||||
req = ardp_activeQ;
|
||||
while(req) {
|
||||
if(cid == req->cid) break;
|
||||
req = req->next;
|
||||
}
|
||||
if(!req) { /* The request isn't on the active queue */
|
||||
if (pfs_debug>=6)
|
||||
fprintf(stderr,"Packet received for inactive request (cid %d)\n",
|
||||
ntohs(cid));
|
||||
ardp_ptfree(pkt);
|
||||
/* The following can be removed when old servers are gone */
|
||||
if((cid == 0) && (ardp_activeQ->next == NOREQ))
|
||||
return(ardp__pr_ferror(ARDP_BAD_VERSION));
|
||||
goto check_for_pending;
|
||||
}
|
||||
|
||||
if(hdr_len >= 5) { /* Packet number */
|
||||
bcopy2(ctlptr,&stmp);
|
||||
pkt->seq = ntohs(stmp);
|
||||
ctlptr += 2;
|
||||
}
|
||||
else { /* No packet number specified, so this is the only one */
|
||||
pkt->seq = 1;
|
||||
req->rcvd_tot = 1;
|
||||
}
|
||||
if(hdr_len >= 7) { /* Total number of packets */
|
||||
bcopy2(ctlptr,&stmp); /* 0 means don't know */
|
||||
if(stmp) req->rcvd_tot = ntohs(stmp);
|
||||
ctlptr += 2;
|
||||
}
|
||||
if(hdr_len >= 9) { /* Receievd through */
|
||||
bcopy2(ctlptr,&stmp); /* 1 means received request */
|
||||
req->prcvd_thru = max(ntohs(stmp),req->prcvd_thru);
|
||||
ctlptr += 2;
|
||||
}
|
||||
if(hdr_len >= 11) { /* Service requested wait */
|
||||
bcopy2(ctlptr,&stmp);
|
||||
if(stmp || (req->svc_rwait != ntohs(stmp))) {
|
||||
now = time(NULL);
|
||||
/* New or non-zero requested wait value */
|
||||
req->svc_rwait = ntohs(stmp);
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"Service asked us to wait %d seconds\n",
|
||||
req->svc_rwait);
|
||||
/* Adjust out timeout */
|
||||
req->timeout_adj.tv_sec = max(req->timeout.tv_sec,req->svc_rwait);
|
||||
req->wait_till.tv_sec = now + req->timeout_adj.tv_sec;
|
||||
/* Reset the retry count */
|
||||
req->retries_rem = req->retries;
|
||||
}
|
||||
ctlptr += 2;
|
||||
}
|
||||
if(hdr_len >= 12) { /* Flags (1st byte) */
|
||||
bcopy1(ctlptr,&rdflag11);
|
||||
if(rdflag11 & 0x80) {
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"Ack requested\n");
|
||||
req->status = ARDP_STATUS_ACKPEND;
|
||||
}
|
||||
if(rdflag11 & 0x40) {
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"Sequenced control packet\n");
|
||||
pkt->length = -1;
|
||||
}
|
||||
ctlptr += 1;
|
||||
}
|
||||
if(hdr_len >= 13) { /* Flags (2nd byte) */
|
||||
/* Reserved for future use */
|
||||
bcopy1(ctlptr,&rdflag12);
|
||||
ctlptr += 1;
|
||||
if(rdflag12 == 2) {
|
||||
/* Attempt to set back prcvd_thru */
|
||||
bcopy2(pkt->start+7,&stmp);
|
||||
req->prcvd_thru = ntohs(stmp);
|
||||
}
|
||||
if(rdflag12 == 1) {
|
||||
/* ARDP Connection Refused */
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"***ARDP connection refused by server***\n");
|
||||
req->status = ARDP_REFUSED;
|
||||
EXTRACT_ITEM(req,ardp_activeQ);
|
||||
--ardp_activeQ_len;
|
||||
APPEND_ITEM(req,ardp_completeQ);
|
||||
goto check_for_pending;
|
||||
}
|
||||
if(rdflag12 == 4) {
|
||||
/* Server Redirect */
|
||||
bcopy4(ctlptr,&(req->peer_addr));
|
||||
ctlptr += 4;
|
||||
bcopy2(ctlptr,&(req->peer_port));
|
||||
ctlptr += 2;
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"***ARDP redirect to %s(%d)***\n",
|
||||
inet_ntoa(req->peer_addr),PEER_PORT(req));
|
||||
ardp_xmit(req, req->pwindow_sz);
|
||||
}
|
||||
if(rdflag12 == 254) {
|
||||
tchar = *ctlptr;
|
||||
ctlptr++;
|
||||
if(tchar & 0x1) { /* Queue position */
|
||||
bcopy2(ctlptr,&stmp);
|
||||
req->inf_queue_pos = ntohs(stmp);
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"Current queue position on server is %d\n",
|
||||
req->inf_queue_pos);
|
||||
ctlptr += 2;
|
||||
}
|
||||
if(tchar & 0x2) { /* Expected system time */
|
||||
bcopy4(ctlptr,<mp);
|
||||
req->inf_sys_time = ntohl(ltmp);
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"Expected system time is %d seconds\n",
|
||||
req->inf_sys_time);
|
||||
ctlptr += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If ->seq 0, then an unsequenced control packet */
|
||||
if(pkt->seq == 0) {
|
||||
ardp_ptfree(pkt);
|
||||
goto check_for_pending;
|
||||
}
|
||||
if(pkt->length >= 0) pkt->length -= hdr_len;
|
||||
pkt->start += hdr_len;
|
||||
pkt->text = pkt->start;
|
||||
pkt->ioptr = pkt->start;
|
||||
|
||||
if(pfs_debug >= 8) fprintf(stderr,"Packet %d of %d (cid=%d)\n", pkt->seq,
|
||||
req->rcvd_tot, ntohs(req->cid));
|
||||
|
||||
if (req->rcvd == NOPKT) {
|
||||
/* Add it as the head of empty doubly linked list */
|
||||
req->rcvd = pkt;
|
||||
pkt->previous = pkt;
|
||||
if(pkt->seq == 1) {
|
||||
req->comp_thru = pkt;
|
||||
req->rcvd_thru = 1;
|
||||
/* If only one packet, then return it. We will assume */
|
||||
/* that it is not a sequenced control packet */
|
||||
if(req->rcvd_tot == 1) goto req_complete;
|
||||
}
|
||||
goto ins_done;
|
||||
}
|
||||
|
||||
if(req->comp_thru && (pkt->seq <= req->rcvd_thru))
|
||||
ardp_ptfree(pkt); /* Duplicate */
|
||||
else if(pkt->seq < req->rcvd->seq) { /* First (sequentially) */
|
||||
pkt->next = req->rcvd;
|
||||
pkt->previous = req->rcvd->previous;
|
||||
req->rcvd->previous = pkt;
|
||||
req->rcvd = pkt;
|
||||
if(req->rcvd->seq == 1) {
|
||||
req->comp_thru = req->rcvd;
|
||||
req->rcvd_thru = 1;
|
||||
}
|
||||
}
|
||||
else { /* Insert later in the packet list unless duplicate */
|
||||
ptmp = (req->comp_thru ? req->comp_thru : req->rcvd);
|
||||
while (pkt->seq > ptmp->seq) {
|
||||
if(ptmp->next == NULL) {
|
||||
/* Insert at end */
|
||||
ptmp->next = pkt;
|
||||
pkt->previous = ptmp;
|
||||
pkt->next = NULL;
|
||||
req->rcvd->previous = pkt;
|
||||
goto ins_done;
|
||||
}
|
||||
ptmp = ptmp->next;
|
||||
}
|
||||
if(ptmp->seq == pkt->seq) /* Duplicate */
|
||||
ardp_ptfree(pkt);
|
||||
else { /* insert before ptmp (we know were not first) */
|
||||
ptmp->previous->next = pkt;
|
||||
pkt->previous = ptmp->previous;
|
||||
pkt->next = ptmp;
|
||||
ptmp->previous = pkt;
|
||||
}
|
||||
}
|
||||
|
||||
ins_done:
|
||||
/* Find out how much is complete and remove sequenced control packets */
|
||||
while(req->comp_thru && req->comp_thru->next &&
|
||||
(req->comp_thru->next->seq == (req->comp_thru->seq + 1))) {
|
||||
/* We have added one more in sequence */
|
||||
if(pfs_debug >= 8)
|
||||
fprintf(stderr,"Packets now received through %d\n",
|
||||
req->comp_thru->next->seq);
|
||||
|
||||
if(req->comp_thru->length == -1) {
|
||||
/* Old comp_thru was a sequenced control packet */
|
||||
ptmp = req->comp_thru;
|
||||
req->comp_thru = req->comp_thru->next;
|
||||
req->rcvd_thru = req->comp_thru->seq;
|
||||
EXTRACT_ITEM(ptmp,req->rcvd);
|
||||
ardp_ptfree(ptmp);
|
||||
}
|
||||
else {
|
||||
/* Old comp_thru was a data packet */
|
||||
req->comp_thru = req->comp_thru->next;
|
||||
req->rcvd_thru = req->comp_thru->seq;
|
||||
}
|
||||
|
||||
/* Update outgoing packets */
|
||||
ardp_headers(req);
|
||||
|
||||
/* We've made progress, so reset timeout and retry count */
|
||||
req->timeout_adj.tv_sec = max(req->timeout.tv_sec,req->svc_rwait);
|
||||
req->retries_rem = req->retries;
|
||||
}
|
||||
|
||||
/* See if there are any gaps - possibly toggle GAP status */
|
||||
if(!req->comp_thru || req->comp_thru->next) {
|
||||
if (req->status == ARDP_STATUS_ACTIVE) req->status = ARDP_STATUS_GAPS;
|
||||
}
|
||||
else if (req->status == ARDP_STATUS_GAPS) req->status = ARDP_STATUS_ACTIVE;
|
||||
|
||||
/* If incomplete, wait for more */
|
||||
if (!(req->comp_thru) || (req->comp_thru->seq != req->rcvd_tot))
|
||||
goto check_for_pending;
|
||||
|
||||
req_complete:
|
||||
|
||||
if (pfs_debug >= 7) {
|
||||
fprintf(stderr,"The complete response has been received.\n");
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
|
||||
if(req->status == ARDP_STATUS_ACKPEND) {
|
||||
if (pfs_debug >= 7) {
|
||||
if (req->peer.sin_family == AF_INET)
|
||||
fprintf(stderr,"Acknowledging final packet to %s(%d)\n",
|
||||
inet_ntoa(req->peer_addr), PEER_PORT(req));
|
||||
else fprintf(stderr,"Acknowledging final packet\n");
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
ardp_xmit(req, req->pwindow_sz);
|
||||
}
|
||||
|
||||
req->status = ARDP_STATUS_COMPLETE;
|
||||
req->inpkt = req->rcvd;
|
||||
EXTRACT_ITEM(req,ardp_activeQ);
|
||||
--ardp_activeQ_len;
|
||||
APPEND_ITEM(req,ardp_completeQ);
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
ardp__pr_ferror(int errcode)
|
||||
{
|
||||
RREQ creq;
|
||||
|
||||
while(ardp_activeQ) {
|
||||
creq = ardp_activeQ;
|
||||
ardp_activeQ->status = errcode;
|
||||
EXTRACT_ITEM(creq,ardp_activeQ);
|
||||
--ardp_activeQ_len;
|
||||
APPEND_ITEM(creq,ardp_completeQ);
|
||||
}
|
||||
perrno = errcode;
|
||||
return(errcode);
|
||||
}
|
||||
73
prospero/lib/ardp/ardp_ptalloc.c
Normal file
73
prospero/lib/ardp/ardp_ptalloc.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1989-91 as part of the Prospero distribution
|
||||
* Modified by bcn 1/93 changed to conform to ardp.h
|
||||
* Modified by swa 12/93 threads added.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
#include <ardp.h>
|
||||
#include <stdlib.h> /* For malloc or free */
|
||||
#include <pfs_threads.h>
|
||||
#include <mitra_macros.h>
|
||||
|
||||
/* "free" conflicted with free() - Mitra */
|
||||
static PTEXT lfree = NOPKT; /* locked with p_th_mutexPTEXT */
|
||||
int ptext_count = 0;
|
||||
int ptext_max = 0;
|
||||
|
||||
/*
|
||||
* ardp_ptalloc - allocate and initialize ptext structure
|
||||
*
|
||||
* ardp_ptalloc returns a pointer to an initialized structure of type
|
||||
* PTEXT. If it is unable to allocate such a structure, it
|
||||
* returns NULL (NOPKT).
|
||||
*/
|
||||
PTEXT
|
||||
ardp_ptalloc()
|
||||
{
|
||||
PTEXT pt;
|
||||
TH_STRUC_ALLOC(ptext,PTEXT,pt);
|
||||
|
||||
/* Initialize and fill in default values. */
|
||||
pt->seq = 0;
|
||||
pt->length = 0;
|
||||
/* The offset is to leave room for additional headers */
|
||||
pt->start = pt->dat + ARDP_PTXT_HDR;
|
||||
pt->text = pt->start;
|
||||
pt->ioptr = pt->start;
|
||||
pt->mbz = 0;
|
||||
return(pt);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_ptfree - free a PTEXT structure
|
||||
*
|
||||
* ardp_ptfree takes a pointer to a PTEXT structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void ardp_ptfree(pt)
|
||||
PTEXT pt;
|
||||
{
|
||||
TH_STRUC_FREE(ptext,PTEXT,pt);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_ptlfree - free a PTEXT structure
|
||||
*
|
||||
* ardp_ptlfree takes a pointer to a PTEXT structure frees it and any linked
|
||||
* PTEXT structures. It is used to free an entrie list of PTEXT
|
||||
* structures.
|
||||
*/
|
||||
void ardp_ptlfree(pt)
|
||||
PTEXT pt;
|
||||
{
|
||||
TH_STRUC_LFREE(PTEXT,pt,ardp_ptfree);
|
||||
}
|
||||
|
||||
38
prospero/lib/ardp/ardp_reply.c
Normal file
38
prospero/lib/ardp/ardp_reply.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Written by bcn 2/93 to send reply to request
|
||||
* Gutted by swa 11/93 functionality moved to ardp_breply().
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ardp.h>
|
||||
|
||||
/*
|
||||
* ardp_reply - send a null-terminated string as a reply to a request
|
||||
*
|
||||
* ardp_reply reply takes request to which a reply is to be sent
|
||||
* a flags field, and a message to be sent to the client in response
|
||||
* to the request. ardp_reply then calls ardp_reply() to do the work.
|
||||
*
|
||||
* If space remains in the packet, the response is buffered pending
|
||||
* subsequent replies, unless the ARDP_REPL_COMPLETE has been specified,
|
||||
* in which case all data is sent. If the size of the buffered response
|
||||
* approaches the maximum packet size, the buffered data is sent, and
|
||||
* and a new packet is started to hold any remaining data from the current
|
||||
* message. (This is implemented by ardp_breply()).
|
||||
*/
|
||||
|
||||
int
|
||||
ardp_reply(RREQ req, /* Request to which this is a response */
|
||||
int flags, /* Whether this is the final message */
|
||||
char *message) /* The data to be sent */
|
||||
{
|
||||
return ardp_breply(req, flags, message, 0);
|
||||
}
|
||||
|
||||
471
prospero/lib/ardp/ardp_respond.c
Normal file
471
prospero/lib/ardp/ardp_respond.c
Normal file
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
* Copyright (c) 1991 by the University of Washington
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1991 as transmit in rdgram.c (Prospero)
|
||||
* Modified by bcn 1/93 modularized and incorporated into new ardp library
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ardp.h>
|
||||
#include <pmachine.h> /* for bcopy() */
|
||||
#include <plog.h>
|
||||
|
||||
EXTERN_MUTEXED_DECL(RREQ,ardp_doneQ);
|
||||
EXTERN_MUTEXED_DECL(RREQ,ardp_runQ);
|
||||
extern int ardp_srvport;
|
||||
extern int ardp_prvport;
|
||||
extern int dQlen; /* mutexed with ardp_doneQ */
|
||||
extern int dQmaxlen;
|
||||
int ardp_clear_doneQ_loginfo = 0; /* Clear log info from the doneQ.
|
||||
Set by the -n option to
|
||||
dirsrv. */
|
||||
|
||||
|
||||
/*
|
||||
* ardp_respond - respond to request
|
||||
*
|
||||
* ardp_respond takes a request block whose ->outpkt element is a pointer
|
||||
* to a list of packets that have not yet been returned. It moves the
|
||||
* packets to the transmission queue of the request (->trns) and assigns a
|
||||
* sequence number to each packet. If options is ARDP_R_COMPLETE, it
|
||||
* also sets the ->trns_tot field of the request indicating the total
|
||||
* number of packets in the response. if the ARDP_R_NOSEND option is
|
||||
* not specified, the current packet is also sent to the client.
|
||||
*
|
||||
* ardp_respond() expects the text of the packet to have a trailing null
|
||||
* at the end of it, which is transmitted for safety's sake.
|
||||
* (noted: swa, 8/5/93). This explains some bugs...
|
||||
*/
|
||||
int
|
||||
ardp_respond(req, options)
|
||||
RREQ req;
|
||||
int options;
|
||||
{
|
||||
char buf[ARDP_PTXT_DSZ];
|
||||
int sent;
|
||||
int retval = ARDP_SUCCESS; /* Return value */
|
||||
unsigned short cid = htons(req->cid);
|
||||
unsigned short nseq = 0;
|
||||
unsigned short ntotal = 0;
|
||||
unsigned short rcvdthru = 0;
|
||||
unsigned short bkoff = 0;
|
||||
PTEXT tpkt; /* Temporary pkt pointer */
|
||||
|
||||
*buf = '\0';
|
||||
|
||||
if(req->peer_ardp_version < 0) cid = 0;
|
||||
|
||||
if(req->status == ARDP_STATUS_FREE)
|
||||
internal_error("Attempt to respond to free RREQ\n");
|
||||
|
||||
if(!req->outpkt) return(ARDP_BAD_REQ);
|
||||
|
||||
more_to_process:
|
||||
|
||||
if(!req->trns) req->outpkt->seq = 1;
|
||||
else req->outpkt->seq = req->trns->previous->seq + 1;
|
||||
|
||||
if((options & ARDP_R_COMPLETE) && (req->outpkt->next == NOPKT)) {
|
||||
/* It's the last packet to send. */
|
||||
req->trns_tot = req->outpkt->seq; /* set the total # of packets; now
|
||||
known. */
|
||||
|
||||
/* Test this condition later to see if the server (us) needs to request
|
||||
that the client ACK. The server will request an ACK if we had
|
||||
previously told the client to back off and now are rescinding that.
|
||||
*/
|
||||
}
|
||||
nseq = htons((u_short) req->outpkt->seq);
|
||||
ntotal = htons((u_short) req->trns_tot);
|
||||
|
||||
if((req->peer_ardp_version < 0)&&(req->peer_ardp_version != -2)) {
|
||||
if(req->trns_tot) sprintf(buf, "MULTI-PACKET %d OF %d",
|
||||
req->outpkt->seq, req->trns_tot);
|
||||
else sprintf(buf,"MULTI-PACKET %d\n",req->outpkt->seq);
|
||||
}
|
||||
|
||||
/* Note that in the following, we don't have to make sure */
|
||||
/* there is room for the header in the packet because we */
|
||||
/* are the only one that moves back the start, and ptalloc */
|
||||
/* allocates space for us in all packets it creates */
|
||||
|
||||
/* If a single message and no connection ID to return, */
|
||||
/* and no pending server requested wait pending then */
|
||||
/* we can leave the control fields out */
|
||||
if((req->trns_tot == 1) && (req->svc_rwait == 0)) {
|
||||
/* Once V4 clients gone, the next if condition can be removed */
|
||||
if((req->peer_ardp_version > -1)||(req->peer_ardp_version == -2)) {
|
||||
if(req->cid == 0) {
|
||||
req->outpkt->start -= 1;
|
||||
req->outpkt->length += 1;
|
||||
*req->outpkt->start = (char) 1;
|
||||
}
|
||||
else {
|
||||
req->outpkt->start -= 3;
|
||||
req->outpkt->length += 3;
|
||||
*req->outpkt->start = (char) 3;
|
||||
bcopy2(&cid,req->outpkt->start+1); /* Conn ID */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Fill in the control fields */
|
||||
else {
|
||||
/* For old versions, assume that svc_rwait of > 5 is too long. */
|
||||
/* For new versions, if we set the svc_rwait before to any non-default
|
||||
value, now set it to 0. (client's default). */
|
||||
|
||||
/* if we might have to set octet 11 flags (in this case, the ACK flag),
|
||||
then we need to send an 11-byte request.
|
||||
This is the case either:
|
||||
(a) if we need to clear a service requested wait or
|
||||
(b) if we are sending the last packet of a window, so that the
|
||||
client should ACK (or request a retry) before the next one goes.
|
||||
*/
|
||||
if (/* Case (A) -- clear wait */
|
||||
((req->peer_ardp_version < 0 && req->svc_rwait > 5)
|
||||
|| (req->peer_ardp_version == 0 && req->svc_rwait)
|
||||
|| (req->svc_rwait_seq > req->prcvd_thru))
|
||||
|| /* Case (B) -- sending last packet of a window */
|
||||
(req->outpkt->seq == req->prcvd_thru + req->pwindow_sz)) {
|
||||
req->outpkt->start -= 12;
|
||||
req->outpkt->length += 12;
|
||||
*req->outpkt->start = (char) 12;
|
||||
|
||||
rcvdthru = htons((u_short) req->rcvd_thru);
|
||||
bcopy2(&rcvdthru,req->outpkt->start+7); /* Recvd Through */
|
||||
|
||||
/* XXX Note that when all clients V5, new wait will be 0 */
|
||||
/* Assume we should cancel the wait and remember when reset */
|
||||
if((req->peer_ardp_version < 0 && req->svc_rwait > 5)
|
||||
|| (req->peer_ardp_version == 0 && req->svc_rwait)) {
|
||||
if(req->peer_ardp_version < 0)
|
||||
req->svc_rwait = 5;
|
||||
else
|
||||
req->svc_rwait = 0;
|
||||
req->svc_rwait_seq = req->outpkt->seq; /* This was the sequence
|
||||
number it was reset
|
||||
on. */
|
||||
/* We'll ask for an acknowledgement when we send the last
|
||||
packet of the response. */
|
||||
}
|
||||
bkoff = htons((u_short) req->svc_rwait);
|
||||
bcopy2(&bkoff,req->outpkt->start+9); /* New ttwait */
|
||||
/* Send an ACK IF: */
|
||||
if ((/* (A1) It's the last packet */
|
||||
(req->trns_tot && req->outpkt->seq == req->trns_tot)
|
||||
&& /* (A2) If we reduced a previously requested wait, and haven't
|
||||
yet had that reduction acknowledged, then ask for an
|
||||
acknowledgement. */
|
||||
(req->svc_rwait_seq > req->prcvd_thru))
|
||||
|| /* OR: Case (B) -- sending last packet of a window */
|
||||
(req->outpkt->seq == req->prcvd_thru + req->pwindow_sz)) {
|
||||
|
||||
req->retries_rem = 4;
|
||||
req->wait_till.tv_sec = time(NULL) + req->timeout_adj.tv_sec;
|
||||
*(req->outpkt->start+11) = 0x80; /* Request ack */
|
||||
} else {
|
||||
*(req->outpkt->start+11) = 0x00; /* Don't request ack */
|
||||
}
|
||||
}
|
||||
else {
|
||||
req->outpkt->start -= 7;
|
||||
req->outpkt->length += 7;
|
||||
*req->outpkt->start = (char) 7;
|
||||
}
|
||||
|
||||
bcopy2(&cid,req->outpkt->start+1); /* Conn ID */
|
||||
bcopy2(&nseq,req->outpkt->start+3); /* Pkt no */
|
||||
bcopy2(&ntotal,req->outpkt->start+5); /* Total */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* commented out by swa@isi.edu, since nulls in packets are now significant
|
||||
to the ARDP library. Therefore, one should NOT be appended to each
|
||||
packet in the data area. */
|
||||
/* Make room for the trailing null */
|
||||
req->outpkt->length += 1;
|
||||
#endif
|
||||
|
||||
/* Only send if packet not yet received. */
|
||||
/* Do honor the window of req->pwindow_sz packets. */
|
||||
if((!(options & ARDP_R_NOSEND)) &&
|
||||
(req->outpkt->seq <= (req->prcvd_thru + req->pwindow_sz)) &&
|
||||
(req->outpkt->seq > req->prcvd_thru) /* This packet not yet received */
|
||||
) {
|
||||
retval = ardp_snd_pkt(req->outpkt,req);
|
||||
}
|
||||
|
||||
|
||||
/* Add packet to req->trns */
|
||||
tpkt = req->outpkt;
|
||||
EXTRACT_ITEM(tpkt,req->outpkt);
|
||||
APPEND_ITEM(tpkt,req->trns);
|
||||
|
||||
if(req->outpkt) goto more_to_process;
|
||||
|
||||
/* If complete then add request structure to done */
|
||||
/* queue in case we have to retry. */
|
||||
if(options & ARDP_R_COMPLETE) {
|
||||
RREQ match_in_runQ; /* Variable for indexing ardp_runQ */
|
||||
|
||||
/* Request has been processed, here you can accumulate */
|
||||
/* statistics on system time or service time */
|
||||
plog(L_QUEUE_COMP, req, "Requested service completed");
|
||||
|
||||
arch_set_etime(req); /* bajan */
|
||||
|
||||
EXTERN_MUTEXED_LOCK(ardp_runQ);
|
||||
for (match_in_runQ = ardp_runQ; match_in_runQ; match_in_runQ = match_in_runQ->next) {
|
||||
if(match_in_runQ == req) {
|
||||
EXTRACT_ITEM(req, ardp_runQ);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* At this point, 'req' is the completed request structure. It is
|
||||
definitely not on the ardp_runQ, and if it was, it's been removed.
|
||||
*/
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_runQ);
|
||||
if((req->cid == 0) || (dQmaxlen <= 0)) {
|
||||
/* If request has no CID (can't be matched on a retry) or
|
||||
if done-Q max length is <= 0 (i.e., don't keep a doneQ), then
|
||||
just throw away the request now that it's done. --swa */
|
||||
#if 0 /* ask BCN about this. Should never be
|
||||
necessary, since req->outpkt is always going
|
||||
to be NULL or we wouldn't be here. */
|
||||
req->outpkt = NULL;
|
||||
#endif
|
||||
ardp_rqfree(req);
|
||||
}
|
||||
else {
|
||||
/* This item should be put on the doneQ; don't just throw it away.
|
||||
*/
|
||||
/* Note that this code will not handle a reduction in the size of
|
||||
dQmaxlen; if anywhere you reset it to a smaller value, that code
|
||||
will have to truncate the queue. */
|
||||
EXTERN_MUTEXED_LOCK(ardp_doneQ);
|
||||
if(dQlen <= dQmaxlen) {
|
||||
/* Add to start */
|
||||
#ifndef NDEBUG /* this helps debugging and slightly cuts down
|
||||
on memory usage of the doneq. */
|
||||
if (ardp_clear_doneQ_loginfo)
|
||||
ardp_rq_partialfree(req);
|
||||
#endif
|
||||
PREPEND_ITEM(req, ardp_doneQ);
|
||||
dQlen++;
|
||||
} else {
|
||||
/* The last item in the queue is ardp_doneQ->previous. */
|
||||
/* Use a variable to denote it, so that the EXTRACT_ITEM macro
|
||||
doesn't encounter problems (since it internally modifies the
|
||||
referent of the name ardp_doneQ->previous). */
|
||||
register RREQ doneQ_lastitem = ardp_doneQ->previous;
|
||||
/* Add new request to start */
|
||||
#ifndef NDEBUG /* this helps debugging and slightly cuts down
|
||||
on memory usage of the doneq. */
|
||||
if (ardp_clear_doneQ_loginfo)
|
||||
ardp_rq_partialfree(req);
|
||||
#endif
|
||||
PREPEND_ITEM(req, ardp_doneQ);
|
||||
|
||||
/* Now, prepare to remove the last item in the queue */
|
||||
/* If the request to remove was not acknowledged by the
|
||||
clients, log the fact */
|
||||
if(doneQ_lastitem->svc_rwait_seq >
|
||||
doneQ_lastitem->prcvd_thru) {
|
||||
plog(L_QUEUE_INFO,doneQ_lastitem,
|
||||
"Requested ack never received (%d of %d/%d ack)",
|
||||
doneQ_lastitem->prcvd_thru,
|
||||
doneQ_lastitem->svc_rwait_seq,
|
||||
doneQ_lastitem->trns_tot);
|
||||
}
|
||||
/* Now do the removal and free it. */
|
||||
EXTRACT_ITEM(doneQ_lastitem, ardp_doneQ);
|
||||
ardp_rqfree(doneQ_lastitem);
|
||||
}
|
||||
EXTERN_MUTEXED_UNLOCK(ardp_doneQ);
|
||||
}
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_rwait - sends a message to a client requesting
|
||||
* that it wait for service. This message indicates that
|
||||
* there may be a delay before the request can be processed.
|
||||
* The recipient should not attempt any retries until the
|
||||
* time specified in this message has elapsed. Depending on the
|
||||
* protocol version in use by the client, the additional
|
||||
* queue position and system time arguments may be returned.
|
||||
*/
|
||||
int
|
||||
ardp_rwait(RREQ req, /* Request to which this is a reply */
|
||||
int timetowait, /* How long client should wait */
|
||||
short qpos, /* Queue position */
|
||||
/* Note stime is a System call in solaris, changed to systemtime */
|
||||
int systemtime) /* System time */
|
||||
{
|
||||
PTEXT r = ardp_ptalloc();
|
||||
short cid = htons(req->cid);
|
||||
short nseq = 0;
|
||||
short zero = 0;
|
||||
short backoff;
|
||||
short stmp;
|
||||
int ltmp;
|
||||
int tmp;
|
||||
|
||||
if(req->peer_ardp_version < 0) cid = 0;
|
||||
|
||||
/* Remember that we sent a server requested wait and assume */
|
||||
/* it took effect, though request will be unsequenced */
|
||||
/* This seems bogus to me. Rather, more appropriate would be to send an
|
||||
unsequenced control packet if the requested wait is being extended and
|
||||
a sequenced packet if the wait is being shortened, since the shortening
|
||||
of the wait is an event which requires an acknowledgement. */
|
||||
/* Note, however, that this shortening is a way the current function is not
|
||||
used. */
|
||||
req->svc_rwait_seq = req->prcvd_thru; /* Mark the latest requested wait as
|
||||
definitely having been received.
|
||||
This is not necessary, actually --
|
||||
leaving this set to zero is ok. */
|
||||
req->svc_rwait = timetowait;
|
||||
|
||||
|
||||
|
||||
*r->start = (char) 11;
|
||||
r->length = 11;
|
||||
|
||||
backoff = htons((u_short) timetowait);
|
||||
|
||||
bcopy2(&cid,r->start+1); /* Connection ID */
|
||||
bcopy2(&nseq,r->start+3); /* Packet number */
|
||||
bcopy2(&zero,r->start+5); /* Total packets */
|
||||
bcopy2(&zero,r->start+7); /* Received through */
|
||||
bcopy2(&backoff,r->start+9); /* Backoff */
|
||||
|
||||
if((req->peer_ardp_version >= 0) && (qpos || systemtime)) {
|
||||
r->length = 14;
|
||||
bzero3(r->start+11);
|
||||
*(r->start+12) = (unsigned char) 254;
|
||||
if(qpos) *(r->start+13) |= (unsigned char) 1;
|
||||
if(systemtime) *(r->start+13) |= (unsigned char) 2;
|
||||
if(qpos) {
|
||||
stmp = htons(qpos);
|
||||
bcopy2(&stmp,r->start+r->length);
|
||||
r->length += 2;
|
||||
}
|
||||
if(systemtime) {
|
||||
ltmp = htonl(systemtime);
|
||||
bcopy4(<mp,r->start+r->length);
|
||||
r->length += 4;
|
||||
|
||||
}
|
||||
*r->start = (char) r->length;
|
||||
}
|
||||
|
||||
tmp = ardp_snd_pkt(r,req);
|
||||
ardp_ptfree(r);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_refuse - sends a message to the recipient indicating
|
||||
* that its connection attempt has been refused.
|
||||
*/
|
||||
int
|
||||
ardp_refuse(RREQ req)
|
||||
{
|
||||
PTEXT r;
|
||||
short cid = htons(req->cid);
|
||||
short zero = 0;
|
||||
int tmp;
|
||||
|
||||
/* If old version won't understand refused */
|
||||
if(req->peer_ardp_version < 0) return(ARDP_FAILURE);
|
||||
|
||||
r = ardp_ptalloc();
|
||||
*r->start = (char) 13;
|
||||
r->length = 13;
|
||||
|
||||
bcopy2(&cid,r->start+1); /* Connection ID */
|
||||
bcopy2(&zero,r->start+3); /* Packet number */
|
||||
bcopy2(&zero,r->start+5); /* Total packets */
|
||||
bcopy2(&zero,r->start+7); /* Received through */
|
||||
bcopy2(&zero,r->start+9); /* Backoff */
|
||||
bzero2(r->start+11); /* Flags */
|
||||
*(r->start + 12) = (unsigned char) 1; /* Refused */
|
||||
|
||||
tmp = ardp_snd_pkt(r,req);
|
||||
ardp_ptfree(r);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ardp_redirect - sends a message to the recipient indicating that
|
||||
* all unacknowledged packets should be sent to a new target destination.
|
||||
* The target specifies the host address and the UDP port in network
|
||||
* byte order. For now, redirections should only occur before any
|
||||
* request packets have been acknowledged, or response packets sent.
|
||||
*/
|
||||
int
|
||||
ardp_redirect(RREQ req, /* Request to be redirected */
|
||||
struct sockaddr_in *target) /* Address of new server */
|
||||
{
|
||||
PTEXT r;
|
||||
short cid = htons(req->cid);
|
||||
int tmp;
|
||||
|
||||
/* Old versions don't support redirection */
|
||||
if(req->peer_ardp_version < 0) return(ARDP_FAILURE);
|
||||
|
||||
r = ardp_ptalloc();
|
||||
|
||||
*r->start = (char) 19;
|
||||
r->length = 19;
|
||||
|
||||
bcopy2(&cid,r->start+1); /* Connection ID */
|
||||
bzero(r->start+3,9); /* Pktno, total, rcvd, swait, flags1 */
|
||||
*(r->start + 12) = '\004'; /* Redirect option */
|
||||
bcopy4(&(target->sin_addr),r->start+13);
|
||||
bcopy2(&(target->sin_port),r->start+17);
|
||||
|
||||
tmp = ardp_snd_pkt(r,req);
|
||||
ardp_ptfree(r);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ardp_ack - sends an acknowledgment message to the client indicating
|
||||
* that all packets through req->rcvd_thru have been recived. It is
|
||||
* only called on receipt of a multi-packet server request.
|
||||
*/
|
||||
int
|
||||
ardp_acknowledge(RREQ req) /* Request to which this is a reply */
|
||||
{
|
||||
PTEXT r = ardp_ptalloc();
|
||||
short cid = htons(req->cid);
|
||||
short rcvd = htons(req->rcvd_thru);
|
||||
short zero = 0;
|
||||
int tmp;
|
||||
|
||||
*r->start = (char) 9;
|
||||
r->length = 9;
|
||||
|
||||
bcopy2(&cid,r->start+1); /* Connection ID */
|
||||
bcopy2(&zero,r->start+3); /* Packet number */
|
||||
bcopy2(&zero,r->start+5); /* Total packets */
|
||||
bcopy2(&rcvd,r->start+7); /* Received through */
|
||||
|
||||
tmp = ardp_snd_pkt(r,req);
|
||||
ardp_ptfree(r);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
114
prospero/lib/ardp/ardp_retriev.c
Normal file
114
prospero/lib/ardp/ardp_retriev.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1/93 to check and/or wait for completion of request
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef AIX
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <ardp.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern RREQ ardp_activeQ; /* Info about active requests */
|
||||
extern RREQ ardp_completeQ;/* Info about completed reqs */
|
||||
extern int ardp_port; /* Opened UDP port */
|
||||
extern int pfs_debug; /* Debug level */
|
||||
|
||||
/*
|
||||
* ardp_retrieve - check and/or wait for completion of request
|
||||
*
|
||||
* ardp_retrieve takes a request and a time to wait. It will check to
|
||||
* see if the request is complete and if so, returns ARDP_SUCCESS.
|
||||
* If not complete, ardp_retrieve will wait up till the time to wait
|
||||
* before returning. If still incomplete it will return ARDP_PENDING.
|
||||
* A time to wait of -1 indicates that one should not return until
|
||||
* complete, or until a timeout occurs. On any failure (other than
|
||||
* still pending), an error code is returned.
|
||||
*
|
||||
* BUGS: Right now, only accepts ttwait values of 0 and -1. If
|
||||
* positive, it is currently treated as -1.
|
||||
*/
|
||||
int
|
||||
ardp_retrieve(req,ttwait)
|
||||
RREQ req; /* Request to wait for */
|
||||
int ttwait; /* Time to wait in microseconds */
|
||||
{
|
||||
fd_set readfds; /* Used for select */
|
||||
struct timeval *selwait; /* Time to wait for select */
|
||||
int tmp; /* Hold value returned by select */
|
||||
|
||||
/* XXX For now only support ttwait values of 0 and -1 */
|
||||
if(ttwait > 0) return(ARDP_FAILURE);
|
||||
|
||||
p_clear_errors();
|
||||
|
||||
if(req->status == ARDP_STATUS_FREE) {
|
||||
fprintf(stderr,"Attempt to retrieve free RREQ\n");
|
||||
abort();
|
||||
return(ARDP_BAD_REQ);
|
||||
}
|
||||
|
||||
if(req->status == ARDP_STATUS_NOSTART) {
|
||||
perrno = ARDP_BAD_REQ;
|
||||
return(perrno);
|
||||
}
|
||||
|
||||
check_for_more:
|
||||
|
||||
ardp_process_active();
|
||||
if((req->status == ARDP_STATUS_COMPLETE) || (req->status > 0)) {
|
||||
EXTRACT_ITEM(req,ardp_completeQ);
|
||||
if(pfs_debug >= 9) {
|
||||
PTEXT ptmp; /* debug-step through req->rcvd */
|
||||
if(req->status > 0) fprintf(stderr,"Request failed (error %d)!",
|
||||
req->status);
|
||||
else fprintf(stderr,"Packets received...");
|
||||
ptmp = req->rcvd;
|
||||
while(ptmp) {
|
||||
fprintf(stderr,"Packet %d:\n",ptmp->seq);
|
||||
ardp_showbuf(ptmp->start, ptmp->length, stderr);
|
||||
putc('\n', stderr);
|
||||
ptmp = ptmp->next;
|
||||
}
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
if(req->status == ARDP_STATUS_COMPLETE) return(ARDP_SUCCESS);
|
||||
else {
|
||||
perrno = req->status; /* Specific error */
|
||||
return(perrno);
|
||||
}
|
||||
}
|
||||
if(ttwait == 0) return(ARDP_PENDING);
|
||||
|
||||
/* Here we should figure out how long to wait, a minimum of */
|
||||
/* ttwait, or the first retry timer for any pending request */
|
||||
/* For the time being, we use the retry timer of the */
|
||||
/* current request. */
|
||||
|
||||
if (pfs_debug >= 6) fprintf(stderr,"Waiting for reply...");
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(ardp_port, &readfds);
|
||||
|
||||
selwait = &(req->timeout_adj);
|
||||
|
||||
/* select - either recv is ready, or timeout */
|
||||
/* see if timeout or error or wrong descriptor */
|
||||
tmp = select(ardp_port + 1, &readfds, (fd_set *)0, (fd_set *)0, selwait);
|
||||
|
||||
/* Packet received, or timeout - both handled by ardp_process_active */
|
||||
if(tmp >= 0) goto check_for_more;
|
||||
|
||||
if (pfs_debug) fprintf(stderr, "select failed: returned %d\n", tmp);
|
||||
perrno = ARDP_SELECT_FAILED;
|
||||
return(perrno);
|
||||
}
|
||||
240
prospero/lib/ardp/ardp_rqalloc.c
Normal file
240
prospero/lib/ardp/ardp_rqalloc.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*
|
||||
* Written by bcn 1991 as part of the Prospero distribution
|
||||
* Modified by bcn 1/93 extended rreq structure
|
||||
* Modified by swa 11/93 multithreaded
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <stdio.h>
|
||||
#include <ardp.h>
|
||||
#include <stdlib.h> /* malloc or free */
|
||||
#include <pmachine.h> /* for bzero() */
|
||||
#include <pfs.h> /* for pafree and stfree */
|
||||
|
||||
/* When debugging the ARDP window flow control stuff, use these definitions. */
|
||||
/* Defaults are set here. */
|
||||
#if 0
|
||||
#define ARDP_MY_WINDOW_SZ 2 /* Our window size;currently only implemented on
|
||||
the client. Here, the client asks for a
|
||||
window size of 2, for testing. */
|
||||
#undef ARDP_DEFAULT_WINDOW_SZ /* Peer window size the server will use for its
|
||||
default flow-control strategy. */ */
|
||||
#define ARDP_DEFAULT_WINDOW_SZ 1 /* for testing. */
|
||||
#endif
|
||||
|
||||
static ardp_default_timeout = ARDP_DEFAULT_TIMEOUT;
|
||||
static ardp_default_retry = ARDP_DEFAULT_RETRY;
|
||||
int ardp_priority = 0; /* Default priority */
|
||||
|
||||
static RREQ lfree = NOREQ;
|
||||
int rreq_count = 0;
|
||||
int rreq_max = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
static int rreq_member_of_list(RREQ rr, RREQ list);
|
||||
#endif
|
||||
|
||||
extern RREQ ardp_pendingQ, ardp_runQ, ardp_doneQ;
|
||||
|
||||
|
||||
/*
|
||||
* rralloc - allocate and initialize an rreq structure
|
||||
*
|
||||
* ardp_rqalloc returns a pointer to an initialized structure of type
|
||||
* RREQ. If it is unable to allocate such a structure, it
|
||||
* returns NOREQ (NULL).
|
||||
*/
|
||||
RREQ
|
||||
ardp_rqalloc()
|
||||
{
|
||||
RREQ rq;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexARDP_RQALLOC);
|
||||
if(lfree) {
|
||||
rq = lfree;
|
||||
lfree = lfree->next;
|
||||
}
|
||||
else {
|
||||
rq = (RREQ) malloc(sizeof(RREQ_ST));
|
||||
if (!rq) return(NOREQ);
|
||||
rreq_max++;
|
||||
}
|
||||
rreq_count++;
|
||||
p_th_mutex_unlock(p_th_mutexARDP_RQALLOC);
|
||||
|
||||
rq->status = ARDP_STATUS_NOSTART;
|
||||
#ifdef ARDP_MY_WINDOW_SZ
|
||||
rq->flags = ARDP_FLAG_SEND_MY_WINDOW_SIZE; /* used by clients. */
|
||||
#else
|
||||
rq->flags = 0;
|
||||
#endif
|
||||
rq->cid = 0;
|
||||
rq->priority = ardp_priority;
|
||||
rq->pf_priority = 0;
|
||||
rq->peer_ardp_version = 0;
|
||||
rq->inpkt = NOPKT;
|
||||
rq->rcvd_tot = 0;
|
||||
rq->rcvd = NOPKT;
|
||||
rq->rcvd_thru = 0;
|
||||
#ifdef ARDP_MY_WINDOW_SZ /* This sets the window size we'll ask for */
|
||||
rq->window_sz = ARDP_MY_WINDOW_SZ;
|
||||
#else
|
||||
rq->window_sz = 0;
|
||||
#endif
|
||||
rq->pwindow_sz = ARDP_DEFAULT_WINDOW_SZ; /* sets the window size we assume
|
||||
our peer will accept in the
|
||||
absence of an explicit
|
||||
request. */
|
||||
rq->comp_thru = NOPKT;
|
||||
rq->outpkt = NOPKT;
|
||||
rq->trns_tot = 0;
|
||||
rq->trns = NOPKT;
|
||||
rq->prcvd_thru = 0;
|
||||
bzero(&(rq->peer),sizeof(rq->peer));
|
||||
rq->rcvd_time.tv_sec = 0;
|
||||
rq->rcvd_time.tv_usec = 0;
|
||||
rq->svc_start_time.tv_sec = 0;
|
||||
rq->svc_start_time.tv_usec = 0;
|
||||
rq->svc_comp_time.tv_sec = 0;
|
||||
rq->svc_comp_time.tv_usec = 0;
|
||||
rq->timeout.tv_sec = ardp_default_timeout;
|
||||
rq->timeout.tv_usec = 0;
|
||||
rq->timeout_adj.tv_sec = ardp_default_timeout;
|
||||
rq->timeout_adj.tv_usec = 0;
|
||||
rq->wait_till.tv_sec = 0;
|
||||
rq->wait_till.tv_usec = 0;
|
||||
rq->retries = ardp_default_retry;
|
||||
rq->retries_rem = ardp_default_retry;
|
||||
rq->svc_rwait = 0;
|
||||
rq->svc_rwait_seq = 0;
|
||||
rq->inf_queue_pos = 0;
|
||||
rq->inf_sys_time = 0;
|
||||
#ifdef PROSPERO
|
||||
rq->auth_info = NULL;
|
||||
#endif /* PROSPERO */
|
||||
rq->client_name = NULL;
|
||||
rq->peer_sw_id = NULL;
|
||||
rq->cfunction = NULL;
|
||||
rq->cfunction_args = NULL;
|
||||
rq->previous = NOREQ;
|
||||
rq->next = NOREQ;
|
||||
return(rq);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_rqfree - free a RREQ structure
|
||||
*
|
||||
* ardp_rqfree takes a pointer to a RREQ structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void ardp_rqfree(rq)
|
||||
RREQ rq;
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
/* This is different from the way we do consistency checking in the PFS
|
||||
library, because here the status field is just sitting to be used. */
|
||||
assert(rq->status != ARDP_STATUS_FREE);
|
||||
rq->status = ARDP_STATUS_FREE;
|
||||
CHECK_OFFLIST(rq); /* MITRA macro; probably does the same as those
|
||||
listed below. Might never be defined. */
|
||||
assert(!rreq_member_of_list(rq, ardp_pendingQ));
|
||||
assert(!rreq_member_of_list(rq, ardp_runQ));
|
||||
assert(!rreq_member_of_list(rq, ardp_doneQ));
|
||||
#endif
|
||||
/* Don't free inpkt or comp_thru, already on rcvd */
|
||||
if(rq->rcvd) ardp_ptlfree(rq->rcvd);
|
||||
/* But outpkt has not been added to trns */
|
||||
if(rq->outpkt) ardp_ptlfree(rq->outpkt);
|
||||
if(rq->trns) ardp_ptlfree(rq->trns);
|
||||
#ifdef PROSPERO
|
||||
if (rq->auth_info) pafree(rq->auth_info);
|
||||
#endif /* PROSPERO */
|
||||
if (rq->client_name) stfree(rq->client_name);
|
||||
if (rq->peer_sw_id) stfree(rq->peer_sw_id);
|
||||
|
||||
p_th_mutex_lock(p_th_mutexARDP_RQALLOC);
|
||||
rq->next = lfree;
|
||||
rq->previous = NOREQ;
|
||||
lfree = rq;
|
||||
rreq_count--;
|
||||
p_th_mutex_unlock(p_th_mutexARDP_RQALLOC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Free just the fields that are needed only while processing the request
|
||||
but not the fields that will be used for a request that is on the ardp_doneQ
|
||||
so that the results can be retransmitted. This is only needed when
|
||||
debugging the server. It is used in ardp_respond() and is #ifdef'd NDEBUG.
|
||||
*/
|
||||
void
|
||||
ardp_rq_partialfree(RREQ rq)
|
||||
{
|
||||
#ifdef PROSPERO
|
||||
if (rq->auth_info) { pafree(rq->auth_info); rq->auth_info = NULL; }
|
||||
#endif /* PROSPERO */
|
||||
if (rq->client_name) { stfree(rq->client_name); rq->client_name = NULL; }
|
||||
if (rq->peer_sw_id) { stfree(rq->peer_sw_id); rq->peer_sw_id = NULL; }
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* ardp_rqlfree - free many RREQ structures
|
||||
*
|
||||
* ardp_rqlfree takes a pointer to a RREQ structure frees it and any linked
|
||||
* RREQ structures. It is used to free an entrie list of RREQ
|
||||
* structures.
|
||||
*/
|
||||
|
||||
void
|
||||
ardp_rqlfree(rq)
|
||||
RREQ rq;
|
||||
{
|
||||
RREQ nxt;
|
||||
|
||||
while(rq != NOREQ) {
|
||||
nxt = rq->next;
|
||||
ardp_rqfree(rq);
|
||||
rq = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ardp_set_retry - change default values for timeout
|
||||
*
|
||||
* ardp_set_retry takes a value for timout in seconds and a count
|
||||
* of the number of retries to allow. It sets static variables in this
|
||||
* file used by pralloc to set the default values in request structures
|
||||
* it allocates.
|
||||
*/
|
||||
int
|
||||
ardp_set_retry(int to, int rt)
|
||||
{
|
||||
/* XXX This is a critical section, but it is safe as long as we are not on
|
||||
a multiprocessor and don't block. So no mutexes. */
|
||||
ardp_default_timeout = to;
|
||||
ardp_default_retry = rt;
|
||||
/*** XXX End Critical section */
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Return 1 if the RREQ rr is a member of the list LIST. */
|
||||
static int
|
||||
rreq_member_of_list(RREQ rr, RREQ list)
|
||||
{
|
||||
for ( ; list; list = list->next) {
|
||||
if (rr == list) return 1;
|
||||
}
|
||||
return 0; /* false */
|
||||
}
|
||||
#endif
|
||||
305
prospero/lib/ardp/ardp_send.c
Normal file
305
prospero/lib/ardp/ardp_send.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 1991-1993 by the University of Southern California
|
||||
*
|
||||
* Written by bcn 1989-92 as dirsend.c in the Prospero distribution
|
||||
* Modified by bcn 1/93 separate library and add support for asynchrony
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
#define OLD_GETHOSTBYNAME /* do it the old way, since we're on the client
|
||||
*/
|
||||
#ifdef PROSPERO
|
||||
#include <pcompat.h>
|
||||
#else /* not PROSPERO */
|
||||
#define DISABLE_PFS_START()
|
||||
#define DISABLE_PFS_END()
|
||||
#endif /* not PROSPERO */
|
||||
|
||||
RREQ ardp_activeQ = NOREQ; /* Info about active requests */
|
||||
RREQ ardp_completeQ = NOREQ;/* Completed requests */
|
||||
static unsigned short ardp_def_port_no = 0; /* Default UDP port to use */
|
||||
int ardp_port = -1; /* Opened UDP port */
|
||||
|
||||
extern int pfs_debug; /* Debug level */
|
||||
|
||||
static ardp_init();
|
||||
static short ardp_next_cid();
|
||||
|
||||
/*
|
||||
* ardp_send - send a request and possibly wait for response
|
||||
*
|
||||
* ardp_send takes a pointer to a structure of type RREQ, an optional
|
||||
* hostname, an optional pointer to the desination address, and the time to
|
||||
* wait before returning in microseconds.
|
||||
*
|
||||
* If a destination address was specified, the address is inserted
|
||||
* into the RREQ structure. If not, but a hostname was specified, the
|
||||
* hostname is resolved, and its address inserted into the RREQ
|
||||
* structure. The hostname may be followed by a port number in
|
||||
* parentheses in which case the port field is filled in. If not
|
||||
* specified, the Prospero directory server port is used as the default.
|
||||
* If the host address is a non-null pointer to an empty address, then
|
||||
* the address is also filled in.
|
||||
*
|
||||
* ardp_send then sends the packets specified by the request structure
|
||||
* to the address in the request structure. If the time to wait is
|
||||
* -1, it waits until the complete response has been received and
|
||||
* returns PSUCCESS or PFAILURE depending on the outcome. Any
|
||||
* returned packets are left in the RREQ strucure. If the time to
|
||||
* wait is 0, ardp_send returns immediately. The prereq strucure will
|
||||
* be filled in as the response is received if calls are made to
|
||||
* ardp_check_messages (which may be called by an interrupt, or
|
||||
* explicitly at appropriate points in the application. If the time
|
||||
* to wait is positive, then ardp_send waits the specified lenght of
|
||||
* time before returning.
|
||||
*
|
||||
* If ardp_send returns before the complete response has been
|
||||
* received, it returns ARDP_PENDING (-1). This means that only
|
||||
* the status field in the RREQ structure may be used until the status
|
||||
* field indicates ARDP_STATUS_COMPLETE. In no event shall it be legal
|
||||
* for the application to modify fields in the RREQ structure while a
|
||||
* request is pending. If the request completes during the call to
|
||||
* ardp_send, it returns ARDP_SUCCESS (0). On error, a positive
|
||||
* return or status value indicates the error that occured.
|
||||
*
|
||||
* In attempting to obtain the response, the ARDP library will wait
|
||||
* for a response and retry an appropriate number of times as defined
|
||||
* by timeout and retries (both static variables). It will collect
|
||||
* however many packets form the reply, and return them in the
|
||||
* request structue.
|
||||
*
|
||||
* ARGS: req Request structure holding packets to send
|
||||
* and to receive the response
|
||||
* hname Hostname including optional port in parentheses
|
||||
* dest Pointer to destination address
|
||||
* ttwait Time to wait in microseconds
|
||||
*
|
||||
* MODIFIES: dest If pointer to empty address
|
||||
* req Fills in ->recv and frees ->trns
|
||||
*
|
||||
* NOTE: In preparing packets for transmission, the packets
|
||||
* are modified. Once the full response has been received,
|
||||
* the packets that were sent are freed.
|
||||
*/
|
||||
int
|
||||
ardp_send(RREQ req, /* Request structure to use (in, out) */
|
||||
char *dname, /* Hostname (and port) of destination */
|
||||
struct sockaddr_in *dest, /* Pointer to destination address */
|
||||
int ttwait) /* Time to wait in microseconds */
|
||||
{
|
||||
char hostnoport[400];/* Hostname without port */
|
||||
char *openparen; /* Start of port in dname */
|
||||
int req_udp_port; /* UDP port from hostname */
|
||||
#ifdef OLD_GETHOSTBYNAME /* unused */
|
||||
struct hostent *host; /* Host info from gethostbyname */
|
||||
#endif
|
||||
|
||||
PTEXT ptmp; /* Temporary packet pointer */
|
||||
int DpfStmp; /* Used when disabling prospero */
|
||||
int tmp; /* To temporarily hold return values */
|
||||
|
||||
p_clear_errors();
|
||||
|
||||
if((ardp_port < 0) && (tmp = ardp_init())) return(tmp);
|
||||
|
||||
if(req->status == ARDP_STATUS_FREE) {
|
||||
fprintf(stderr,"Attempt to send free RREQ\n");
|
||||
abort();
|
||||
return(perrno = ARDP_BAD_REQ);
|
||||
}
|
||||
|
||||
while(req->outpkt) {
|
||||
req->outpkt->seq = ++(req->trns_tot);
|
||||
ptmp = req->outpkt;
|
||||
EXTRACT_ITEM(ptmp,req->outpkt);
|
||||
APPEND_ITEM(ptmp,req->trns);
|
||||
}
|
||||
|
||||
if(pfs_debug >= 9) {
|
||||
fprintf(stderr, "In ardp_send - sending to %s\n", dname);
|
||||
ptmp = req->trns;
|
||||
while(ptmp) {
|
||||
fprintf(stderr,"Packet %d:\n",ptmp->seq);
|
||||
ardp_showbuf(ptmp->text, ptmp->length, stderr);
|
||||
putc('\n', stderr);
|
||||
ptmp = ptmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assign connection ID */
|
||||
req->cid = ardp_next_cid();
|
||||
|
||||
/* Resolve the host name, address, and port arguments */
|
||||
|
||||
/* If we were given the host address, then use it. Otherwise */
|
||||
/* lookup the hostname. If we were passed a host address of */
|
||||
/* 0, we must lookup the host name, then replace the old value */
|
||||
if(!dest || (dest->sin_addr.s_addr == 0)) {
|
||||
/* I we have a null host name, return an error */
|
||||
if((dname == NULL) || (*dname == '\0')) {
|
||||
if (pfs_debug >= 1)
|
||||
fprintf(stderr, "ardp_send: Null hostname specified\n");
|
||||
return(perrno = ARDP_BAD_HOSTNAME);
|
||||
}
|
||||
/* If a port is included, save it away */
|
||||
if(openparen = strchr(dname,'(')) {
|
||||
sscanf(openparen+1,"%d",&req_udp_port);
|
||||
if(req_udp_port) req->peer_port = htons(req_udp_port);
|
||||
strncpy(hostnoport,dname,399);
|
||||
if((openparen - dname) < 400) {
|
||||
*(hostnoport + (openparen - dname)) = '\0';
|
||||
dname = hostnoport;
|
||||
}
|
||||
}
|
||||
#ifdef OLD_GETHOSTBYNAME
|
||||
DISABLE_PFS_START();
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
if((host = gethostbyname(dname)) == NULL) {
|
||||
DISABLE_PFS_END();
|
||||
/* Check if a numeric address */
|
||||
req->peer.sin_family = AF_INET;
|
||||
req->peer_addr.s_addr = inet_addr(dname);
|
||||
if(req->peer_addr.s_addr == -1) {
|
||||
if (pfs_debug >= 1)
|
||||
fprintf(stderr, "ardp: Can't resolve host %s\n", dname);
|
||||
return(perrno = ARDP_BAD_HOSTNAME);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DISABLE_PFS_END();
|
||||
req->peer.sin_family = host->h_addrtype;
|
||||
bcopy(host->h_addr, (char *)&(req->peer_addr),
|
||||
host->h_length);
|
||||
}
|
||||
#else
|
||||
/* New way of doing things */
|
||||
if (ardp_hostname2addr(dname, &req->peer_addr))
|
||||
return perrno = ARDP_BAD_HOSTNAME;
|
||||
|
||||
#endif
|
||||
}
|
||||
else bcopy(dest, &(req->peer), S_AD_SZ);
|
||||
|
||||
/* If no port set, use default port */
|
||||
if(req->peer_port == 0) req->peer_port = ardp_def_port_no;
|
||||
|
||||
/* If dest was set, but zero, fill it in */
|
||||
if(dest && (dest->sin_addr.s_addr == 0))
|
||||
bcopy(&(req->peer), dest, S_AD_SZ);
|
||||
|
||||
if(tmp = ardp_headers(req)) return(tmp);
|
||||
|
||||
req->status = ARDP_STATUS_ACTIVE;
|
||||
APPEND_ITEM(req,ardp_activeQ);
|
||||
req->wait_till.tv_sec = time(NULL) + req->timeout_adj.tv_sec;
|
||||
ardp_xmit(req, req->pwindow_sz);
|
||||
return(ardp_retrieve(req,ttwait));
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_init - Open socket and bind port for network operations
|
||||
*
|
||||
* ardp_init attempts to determine the default destination port.
|
||||
* It then opens a socket for network operations and attempts
|
||||
* to bind it to an available privleged port. It tries to bind to a
|
||||
* privileged port so that its peer can tell it is communicating with
|
||||
* a "trusted" program. If it can not bind a priveleged port, then
|
||||
* it also returns successfully since the system will automatically
|
||||
* assign a non-priveleged port later, in which case the peer will
|
||||
* assume that it is communicating with a non-trusted program. It
|
||||
* is expected that in the normal case, we will fail to bind the
|
||||
* port since most applications calling this routine should NOT
|
||||
* be setuid.
|
||||
*/
|
||||
static int
|
||||
ardp_init()
|
||||
{
|
||||
struct servent *sp; /* Entry from services file */
|
||||
struct sockaddr_in us; /* Our address */
|
||||
int DpfStmp;/* Used when disabling prospero */
|
||||
int tmp; /* For stepping through ports */
|
||||
|
||||
/* Determine default udp port to use */
|
||||
DISABLE_PFS_START();
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*SOLARIS: getservbyname MT-Unsafe */
|
||||
if ((sp = getservbyname(ARDP_DEFAULT_PEER,"udp")) == 0) {
|
||||
if (pfs_debug >= 10)
|
||||
fprintf(stderr, "ardp: udp/%s unknown service - using %d\n",
|
||||
ARDP_DEFAULT_PEER, ARDP_DEFAULT_PORT);
|
||||
ardp_def_port_no = htons((u_short) ARDP_DEFAULT_PORT);
|
||||
}
|
||||
else ardp_def_port_no = sp->s_port;
|
||||
DISABLE_PFS_END();
|
||||
if (pfs_debug >= 10)
|
||||
fprintf(stderr,"default udp port is %d\n", ntohs(ardp_def_port_no));
|
||||
|
||||
|
||||
/* Open the local socket from which packets will be sent */
|
||||
errno=0;
|
||||
if((ardp_port = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
if (pfs_debug >= 1)
|
||||
fprintf(stderr,"ardp: Can't open socket - %s\n",
|
||||
unixerrstr());
|
||||
return(perrno = ARDP_UDP_CANT);
|
||||
}
|
||||
|
||||
#ifndef ARDP_NONPRIVED
|
||||
/* Try to bind it to a privileged port - loop through candidate */
|
||||
/* ports trying to bind. If failed, that's OK, we will let the */
|
||||
/* system assign a non-privileged port later */
|
||||
bzero((char *)&us, sizeof(us));
|
||||
us.sin_family = AF_INET;
|
||||
for(tmp = ARDP_FIRST_PRIVP; tmp < ARDP_FIRST_PRIVP+ARDP_NUM_PRIVP;tmp++) {
|
||||
us.sin_port = htons((u_short) tmp);
|
||||
if(bind(ardp_port, (struct sockaddr *)&us, sizeof(us)) == 0)
|
||||
return(ARDP_SUCCESS);
|
||||
if(errno != EADDRINUSE) return(ARDP_SUCCESS);
|
||||
}
|
||||
#endif /* ARDP_NONPRIVED */
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* ardp_next_cid - return next connection ID in network byte order
|
||||
*
|
||||
* ardp_next_cid returns the next connection ID to be used
|
||||
* after first converting it to network byte order.
|
||||
*/
|
||||
static short ardp_next_cid()
|
||||
{
|
||||
static unsigned short next_conn_id = 0; /* Next conn id to use */
|
||||
static int last_pid = 0; /* Reset after forks */
|
||||
int pid = getpid();
|
||||
|
||||
/* If we did a fork, reinitialize */
|
||||
if(last_pid != pid) {
|
||||
if(ardp_port >= 0) close(ardp_port);
|
||||
ardp_port = -1;
|
||||
next_conn_id = 0;
|
||||
ardp_init();
|
||||
}
|
||||
/* Find first connection ID */
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* rand and srand are unsafe */
|
||||
if(next_conn_id == 0) {
|
||||
srand(pid+time(0));
|
||||
next_conn_id = rand();
|
||||
last_pid = pid;
|
||||
}
|
||||
if(++next_conn_id == 0) ++next_conn_id;
|
||||
return(htons(next_conn_id));
|
||||
}
|
||||
61
prospero/lib/ardp/ardp_showbuf.c
Normal file
61
prospero/lib/ardp/ardp_showbuf.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern Calfornia
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static void showc(char c, FILE *outf);
|
||||
|
||||
/* Return non-zero if string ends in a newline. */
|
||||
/* Like fputs, but for bstrings. */
|
||||
void
|
||||
ardp_showbuf(const char *bst, int len, FILE *out)
|
||||
{
|
||||
while (len-- > 0) {
|
||||
showc(*bst++, out);
|
||||
}
|
||||
}
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
static void
|
||||
showc(char c, FILE *outf)
|
||||
{
|
||||
if (c == '\\') {
|
||||
putc('\\', outf);
|
||||
putc('\\', outf);
|
||||
} else if (isprint(c)) {
|
||||
putc(c, outf);
|
||||
} else if ((c == '\n')) {
|
||||
if (pfs_debug >= 11) {
|
||||
putc('\\', outf);
|
||||
putc('n', outf);
|
||||
} else {
|
||||
putc('\n', outf);
|
||||
}
|
||||
} else if ((c == '\t')) {
|
||||
if (pfs_debug >= 11) {
|
||||
putc('\\', outf);
|
||||
putc('t', outf);
|
||||
} else {
|
||||
putc('\t', outf);
|
||||
}
|
||||
} else if ((c == '\r')) {
|
||||
if (pfs_debug >= 11) {
|
||||
putc('\\', outf);
|
||||
putc('r', outf);
|
||||
} else {
|
||||
putc('\r', outf);
|
||||
}
|
||||
} else {
|
||||
fprintf(outf, "\\%#03o", c);
|
||||
}
|
||||
}
|
||||
47
prospero/lib/ardp/ardp_snd_pkt.c
Normal file
47
prospero/lib/ardp/ardp_snd_pkt.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1/93 to send a single packet to a peer
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ardp.h>
|
||||
#include <plog.h>
|
||||
#include <errno.h>
|
||||
#include <perrno.h>
|
||||
|
||||
extern int ardp_srvport;
|
||||
extern int ardp_prvport;
|
||||
|
||||
/*
|
||||
* ardp_snd_pkt - transmits a single packet to address in req
|
||||
*
|
||||
* ardp_snd_pkt takes a pointer to a packet of type PTEXT to be
|
||||
* sent to a peer identified by req->peer. It then send the packet to
|
||||
* the peer. If the packet was sent successfully, ARDP_SUCCESS is
|
||||
* returned. Successful transmission of the packet does not provide
|
||||
* any assurance of receipt by the peer. If the attempt to send
|
||||
* the packet fails, ARDP_NOT_SENT is returned.
|
||||
*/
|
||||
int
|
||||
ardp_snd_pkt(pkt,req)
|
||||
PTEXT pkt;
|
||||
RREQ req;
|
||||
{
|
||||
int sent;
|
||||
|
||||
sent = sendto(((ardp_prvport != -1) ? ardp_prvport : ardp_srvport),
|
||||
pkt->start, pkt->length, 0, &(req->peer), S_AD_SZ);
|
||||
|
||||
if(sent == pkt->length) return(ARDP_SUCCESS);
|
||||
|
||||
plog(L_NET_ERR, req, "Attempt to send message failed (errno %d %s)",
|
||||
errno, unixerrstr(), 0);
|
||||
|
||||
return(ARDP_NOT_SENT);
|
||||
}
|
||||
107
prospero/lib/ardp/ardp_srv_ini.c
Normal file
107
prospero/lib/ardp/ardp_srv_ini.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1991 by the University of Washington
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1991 as part of rdgram.c in Prospero distribution
|
||||
* Modified by bcn 1/93 modularized and incorporated into new ardp library
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <plog.h>
|
||||
|
||||
int (*ardp_pri_func)() = NULL; /* Function to compare priorities */
|
||||
int ardp_pri_override = 0; /* If 1, then oveeride value in request */
|
||||
|
||||
int ardp_srvport = -1;
|
||||
int ardp_prvport = -1;
|
||||
|
||||
|
||||
/*
|
||||
* ardp_set_queueing_plicy - set function for queueing policy
|
||||
*
|
||||
* ardp_set_queuing_policy allows one to provide a function that will set
|
||||
* priorities for requests. When passed two req structures, r1 and r2, the
|
||||
* function should return a negative number if r1 should be executed first
|
||||
* (i.e. r1 has a lower numerical priority) and positive if r2 should be
|
||||
* executed first. If the function returns 0, it means the two have the
|
||||
* same priority and should be executed FCFS. If override is non-zero, then
|
||||
* the priority function is to be applied to all requests. If non-zero,
|
||||
* it is only applied to those with identical a priori priorities (as
|
||||
* specified in the datagram itself.
|
||||
*/
|
||||
int
|
||||
ardp_set_queuing_policy(pf,override)
|
||||
int (*pf)(); /* Function to compare priorities */
|
||||
int override; /* If 1, then oveeride value in request */
|
||||
{
|
||||
ardp_pri_func = pf;
|
||||
ardp_pri_override = override;
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ardp_set_prvport(port)
|
||||
int port;
|
||||
{
|
||||
ardp_prvport = port;
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
ardp_bind_port(portname)
|
||||
char *portname;
|
||||
{
|
||||
struct sockaddr_in s_in = {AF_INET};
|
||||
struct servent *sp;
|
||||
int on = 1;
|
||||
int port_no = 0;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*getpwuid MT-Unsafe*/
|
||||
if(*portname == '#') {
|
||||
sscanf(portname+1,"%d",&port_no);
|
||||
if(port_no == 0) {
|
||||
fprintf(stderr, "ardp_bind_port: port number must follow #\n");
|
||||
exit(1);
|
||||
}
|
||||
s_in.sin_port = htons((ushort) port_no);
|
||||
}
|
||||
else if((sp = getservbyname(portname, "udp")) != NULL) {
|
||||
s_in.sin_port = sp->s_port;
|
||||
}
|
||||
else if(strcmp(portname,ARDP_DEFAULT_PEER) == 0) {
|
||||
fprintf(stderr, "ardp_bind_port: udp/%s unknown service - using %d\n",
|
||||
ARDP_DEFAULT_PEER, ARDP_DEFAULT_PORT);
|
||||
s_in.sin_port = htons((ushort) ARDP_DEFAULT_PORT);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "ardp_bind_port: udp/%s unknown service\n",portname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ardp_srvport = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
plog(L_STATUS,NOREQ,"Startup - Can't open socket",0);
|
||||
fprintf(stderr, "ardp_bind_port: Can't open socket\n");
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(ardp_srvport, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
fprintf(stderr, "dirsrv: setsockopt (SO_REUSEADDR)\n");
|
||||
|
||||
if (bind(ardp_srvport, (struct sockaddr *) &s_in, S_AD_SZ) < 0) {
|
||||
plog(L_STATUS,NOREQ,"Startup - Can't bind socket",0);
|
||||
fprintf(stderr, "dirsrv: Can not bind socket\n");
|
||||
exit(1);
|
||||
}
|
||||
return(ntohs(s_in.sin_port));
|
||||
}
|
||||
|
||||
103
prospero/lib/ardp/ardp_xmit.c
Normal file
103
prospero/lib/ardp/ardp_xmit.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Written by bcn 1/93 to send a list of packets to a destination
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ardp.h>
|
||||
#include <pmachine.h> /* for bcopy() and select() */
|
||||
|
||||
extern int pfs_debug; /* Debug level */
|
||||
extern int ardp_port; /* Opened UDP port */
|
||||
|
||||
/*
|
||||
* ardp_xmit - transmits packets in req->trns
|
||||
*
|
||||
* ardp_xmit takes a pointer to a request structure of type RREQ and a
|
||||
* window size. It then sends the packet on the request structure
|
||||
* transmit queue to the peer address in the request structure starting after
|
||||
* the indicated peer rcvd_thru value, and up to the number of packets
|
||||
* specified by the window size. It returns ARDP_SUCCESS on success and
|
||||
* returns an error code on failure.
|
||||
*
|
||||
* This is called on both the client and server side, called respectively by
|
||||
* ardp_send() and ardp_pr_actv().
|
||||
*/
|
||||
|
||||
int
|
||||
ardp_xmit(RREQ req, /* Request structure with packets to send */
|
||||
int window) /* Max packets to send at once. Note that
|
||||
right now this is always identical to
|
||||
req->pwindow_sz.
|
||||
0 means infinite window size
|
||||
-1 means just send an ACK; don't send any
|
||||
data packets. */
|
||||
{
|
||||
PTEXT ptmp; /* Packet pointer for stepping through trns */
|
||||
unsigned short stmp; /* Temp short for conversions */
|
||||
int ns; /* Number of bytes actually sent */
|
||||
static PTEXT ack = NOPKT; /* Only an ack to be sent */
|
||||
|
||||
if(window < 0 || req->prcvd_thru >= req->trns_tot) {
|
||||
/* All our packets got through, send acks only */
|
||||
if(ack == NOPKT) {
|
||||
ack = ardp_ptalloc();
|
||||
/* Add header */
|
||||
ack->start -= 9;
|
||||
ack->length += 9;
|
||||
*(ack->start) = (char) 9;
|
||||
/* An unsequenced control packet */
|
||||
bzero4(ack->start+3);
|
||||
}
|
||||
/* Received Through */
|
||||
stmp = htons(req->rcvd_thru);
|
||||
bcopy2(&stmp,ack->start+7);
|
||||
/* Connection ID */
|
||||
bcopy2(&(req->cid),ack->start+1);
|
||||
ptmp = ack;
|
||||
}
|
||||
else ptmp = req->trns;
|
||||
|
||||
/* Note that we don't want to get rid of packts before the */
|
||||
/* peer received through since the peer might later tell */
|
||||
/* us it forgot them and ask us to send them again */
|
||||
/* XXX whether this is allowable should be an application */
|
||||
/* specific configration option. */
|
||||
while(ptmp) {
|
||||
if((window > 0) && (ptmp->seq > req->prcvd_thru + window)) break;
|
||||
if((ptmp->seq == 0) || (ptmp->seq > req->prcvd_thru)) {
|
||||
if (pfs_debug >= 6) {
|
||||
if (req->peer.sin_family == AF_INET)
|
||||
fprintf(stderr,
|
||||
"Sending message%s (cid=%d) (seq=%d) to %s(%d)...",
|
||||
(ptmp == ack) ? " (ACK only)" : "",
|
||||
ntohs(req->cid), ntohs(ptmp->seq),
|
||||
inet_ntoa(req->peer_addr), PEER_PORT(req));
|
||||
else fprintf(stderr,"Sending message...");
|
||||
(void) fflush(stderr);
|
||||
}
|
||||
ns = sendto(ardp_port,(char *)(ptmp->start), ptmp->length, 0,
|
||||
&(req->peer), S_AD_SZ);
|
||||
if(ns != ptmp->length) {
|
||||
if (pfs_debug >= 1) {
|
||||
fprintf(stderr,"\nsent only %d/%d: ",ns, ptmp->length);
|
||||
perror("");
|
||||
}
|
||||
return(ARDP_NOT_SENT);
|
||||
}
|
||||
if (pfs_debug >= 6) fprintf(stderr,"Sent.\n");
|
||||
}
|
||||
ptmp = ptmp->next;
|
||||
}
|
||||
return(ARDP_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
0
prospero/lib/ardp/dependency.list
Normal file
0
prospero/lib/ardp/dependency.list
Normal file
72
prospero/lib/ardp/dnscache_alloc.c
Normal file
72
prospero/lib/ardp/dnscache_alloc.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Copyright (c) 1993, by Pandora Systems */
|
||||
/* Author: Mitra <mitra@path.net> */
|
||||
/* Allocation code copied and adapted from:
|
||||
prospero/alpha.5.2a+/lib/pfs/flalloc */
|
||||
|
||||
#include "dnscache_alloc.h"
|
||||
#include <pfs.h>
|
||||
#include <pfs_threads.h>
|
||||
#include <mitra_macros.h>
|
||||
|
||||
static DNSCACHE lfree = NULL; /* Free dnscaches */
|
||||
/* These are global variables which will be read by dirsrv.c
|
||||
Too bad C doesn't have better methods for structuring such global data. */
|
||||
|
||||
int dnscache_count = 0;
|
||||
int dnscache_max = 0;
|
||||
|
||||
|
||||
/************* Standard routines to alloc, free and copy *************/
|
||||
/*
|
||||
* dnscache_alloc - allocate and initialize DNSCACHE structure
|
||||
*
|
||||
* returns a pointer to an initialized structure of type
|
||||
* DNSCACHE. If it is unable to allocate such a structure, it
|
||||
* signals out_of_memory();
|
||||
*/
|
||||
|
||||
DNSCACHE
|
||||
dnscache_alloc()
|
||||
{
|
||||
DNSCACHE acache;
|
||||
|
||||
TH_STRUC_ALLOC(dnscache,DNSCACHE,acache);
|
||||
acache->name = NULL;
|
||||
acache->usecount = 0;
|
||||
bzero(&acache->sockad,sizeof(acache->sockad));
|
||||
return(acache);
|
||||
}
|
||||
|
||||
/*
|
||||
* dnscache_free - free a DNSCACHE structure
|
||||
*
|
||||
* dnscache_free takes a pointer to a DNSCACHE structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
dnscache_free(DNSCACHE acache)
|
||||
{
|
||||
stfree(acache->name) ; acache->name = NULL;
|
||||
TH_STRUC_FREE(dnscache,DNSCACHE,acache);
|
||||
}
|
||||
|
||||
/*
|
||||
* dnscache_lfree - free a linked list of DNSCACHE structures.
|
||||
*
|
||||
* dnscache_lfree takes a pointer to a dnscache structure frees it and
|
||||
* any linked
|
||||
* DNSCACHE structures. It is used to free an entire list of WAISMSGBUFF
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
dnscache_lfree(acache)
|
||||
DNSCACHE acache;
|
||||
{
|
||||
TH_STRUC_LFREE(DNSCACHE,acache,dnscache_free);
|
||||
}
|
||||
|
||||
void
|
||||
dnscache_freespares()
|
||||
{
|
||||
TH_FREESPARES(dnscache,DNSCACHE);
|
||||
}
|
||||
33
prospero/lib/ardp/dnscache_alloc.h
Normal file
33
prospero/lib/ardp/dnscache_alloc.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef dnscache_alloc_h
|
||||
#define dnscache_alloc_h
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pfs_threads.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
struct dnscache {
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
int consistency;
|
||||
#endif
|
||||
char *name;
|
||||
struct sockaddr_in sockad;
|
||||
int usecount; /* For determining size of cache */
|
||||
struct dnscache *next;
|
||||
struct dnscache *previous;
|
||||
};
|
||||
typedef struct dnscache *DNSCACHE;
|
||||
typedef struct dnscache DNSCACHE_ST;
|
||||
|
||||
extern DNSCACHE dnscache_alloc();
|
||||
extern void dnscache_free(DNSCACHE acache);
|
||||
extern void dnscache_lfree(DNSCACHE acache);
|
||||
extern void dnscache_freespares();
|
||||
extern int dnscache_count, dnscache_max;
|
||||
/*extern DNSCACHE dnscache_copy(DNSCACHE f, int r);*/
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
extern p_th_mutex p_th_mutexDNSCACHE;
|
||||
extern p_th_mutex p_th_mutexALLDNSCACHE;
|
||||
#endif
|
||||
|
||||
#endif /*dnscache_alloc_h*/
|
||||
221
prospero/lib/ardp/flocks.c
Normal file
221
prospero/lib/ardp/flocks.c
Normal file
@@ -0,0 +1,221 @@
|
||||
/* Copyright (c) 1993, by Pandora Systems */
|
||||
/* Author: Mitra <mitra@path.net> */
|
||||
/* Allocation code copied and adapted from:
|
||||
lib/pfs/flalloc.c in the Prospero Alpha.5.2a release. */
|
||||
|
||||
#include <pfs.h>
|
||||
#include <plog.h>
|
||||
#include "flocks.h"
|
||||
|
||||
#include "mitra_macros.h"
|
||||
#ifdef PFS_THREADS
|
||||
extern p_th_mutex p_th_mutexFILES;
|
||||
#endif
|
||||
|
||||
/* FileLocks are currently unused by dirsrv.c, and not linked into the ardp
|
||||
library. So dirsrv will not report on them in replies to a STATUS message.
|
||||
*/
|
||||
|
||||
static FILELOCK lfree = NULL; /* Free filelocks */
|
||||
/* These are global variables which will be read by dirsrv.c
|
||||
Too bad C doesn't have better methods for structuring such global data. */
|
||||
|
||||
int filelock_count = 0;
|
||||
int filelock_max = 0;
|
||||
int filelock_open = 0;
|
||||
int filelock_open_max = 0;
|
||||
int filelock_sepwaits = 0;
|
||||
int filelock_secwaits = 0;
|
||||
FILELOCK filelock_locked = NULL;
|
||||
|
||||
/************* Standard routines to alloc, free and copy *************/
|
||||
/*
|
||||
* filelock_alloc - allocate and initialize FILELOCK structure
|
||||
*
|
||||
* returns a pointer to an initialized structure of type
|
||||
* FILELOCK. If it is unable to allocate such a structure, it
|
||||
* signals out_of_memory();
|
||||
*/
|
||||
|
||||
FILELOCK
|
||||
filelock_alloc()
|
||||
{
|
||||
FILELOCK fl;
|
||||
|
||||
TH_STRUC_ALLOC(filelock,FILELOCK,fl);
|
||||
fl->name = NULL;
|
||||
fl->readers = 0;
|
||||
return(fl);
|
||||
}
|
||||
|
||||
/*
|
||||
* filelock_free - free a FILELOCK structure
|
||||
*
|
||||
* filelock_free takes a pointer to a FILELOCK structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
filelock_free(FILELOCK fl)
|
||||
{
|
||||
stfree(fl->name); fl->name = NULL;
|
||||
fl->readers = 0;
|
||||
TH_STRUC_FREE(filelock, FILELOCK, fl);
|
||||
}
|
||||
|
||||
/*
|
||||
* filelock_lfree - free a linked list of FILELOCK structures.
|
||||
*
|
||||
* filelock_lfree takes a pointer to a filelock structure frees it and
|
||||
* any linked
|
||||
* FILELOCK structures. It is used to free an entire list of FILELOCK
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
filelock_lfree(fl)
|
||||
FILELOCK fl;
|
||||
{
|
||||
TH_STRUC_LFREE(FILELOCK,fl,filelock_free);
|
||||
}
|
||||
|
||||
static void
|
||||
filelock_unreaders(FILELOCK flock)
|
||||
{
|
||||
/* Assumes p_th_mutexFILES is locked already */
|
||||
assert(flock->readers > 0);
|
||||
if (!(--flock->readers)) {
|
||||
EXTRACT_ITEM(flock,filelock_locked);
|
||||
filelock_free(flock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
filelock_unwriters(FILELOCK flock)
|
||||
{
|
||||
/* Assumes p_th_mutexFILES is locked already */
|
||||
assert(flock->readers == -1);
|
||||
EXTRACT_ITEM(flock, filelock_locked);
|
||||
filelock_free(flock);
|
||||
}
|
||||
|
||||
void
|
||||
filelock_freespares()
|
||||
/* This is used for filelocks to free up space in the child */
|
||||
{
|
||||
TH_FREESPARES(filelock,FILELOCK);
|
||||
}
|
||||
|
||||
void
|
||||
filelock_release(const char *filename, int readonly)
|
||||
{
|
||||
FILELOCK flock;
|
||||
p_th_mutex_lock(p_th_mutexFILES);
|
||||
flock = filelock_locked;
|
||||
FIND_FNCTN_LIST(flock, name, filename, stequal);
|
||||
assert(flock); /* it better be locked */
|
||||
if (readonly) {
|
||||
filelock_unreaders(flock); /* May destroy flock */
|
||||
} else {
|
||||
filelock_unwriters(flock); /* May destroy flock */
|
||||
}
|
||||
filelock_open--;
|
||||
p_th_mutex_unlock(p_th_mutexFILES);
|
||||
}
|
||||
|
||||
int
|
||||
locked_fclose_A(FILE *afile, const char *filename, int readonly)
|
||||
{
|
||||
int retval;
|
||||
/* Assumes already obtained filelock for filename */
|
||||
retval = fclose(afile);
|
||||
/* At least on solaris, this can return an error for no apparent reason */
|
||||
#if 0
|
||||
assert(!retval);
|
||||
#endif
|
||||
filelock_release(filename, readonly);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
void
|
||||
filelock_obtain(const char *filename, int readonly)
|
||||
{
|
||||
FILELOCK(flock);
|
||||
int haswaited = 0;
|
||||
for (;;) {
|
||||
p_th_mutex_lock(p_th_mutexFILES);
|
||||
flock = filelock_locked;
|
||||
FIND_FNCTN_LIST(flock, name, filename,stequal);
|
||||
if (!flock) { /* didnt find a matching lock */
|
||||
flock = filelock_alloc();
|
||||
flock->name = stcopy(filename);
|
||||
flock->readers = 0;
|
||||
APPEND_ITEM(flock,filelock_locked);
|
||||
}
|
||||
/* Found, or created a matching lock */
|
||||
if (readonly) {
|
||||
if (flock->readers >= 0) {
|
||||
flock->readers++;
|
||||
break;
|
||||
}
|
||||
/* Drops thru here, if we want it readonly, but someone else writing*/
|
||||
} else {
|
||||
if (flock->readers == 0) {
|
||||
flock->readers = -1; /* Special code for writer */
|
||||
break;
|
||||
}
|
||||
/* Drops thru here, if we want to write, but someone else
|
||||
is reading/writing */
|
||||
}
|
||||
/* At this point we cant lock it, so unlock mutex, wait, and try again*/
|
||||
p_th_mutex_unlock(p_th_mutexFILES);
|
||||
plog(L_QUEUE_INFO,NOREQ, "Waiting for filelock for %s", filename, 0);
|
||||
if (!haswaited) filelock_sepwaits++;
|
||||
filelock_secwaits++;
|
||||
sleep(1); /* Maybe too long */
|
||||
} /*for*/
|
||||
if (++filelock_open > filelock_open_max) {
|
||||
filelock_open_max = filelock_open;
|
||||
}
|
||||
/* break is always done with mutex locked */
|
||||
p_th_mutex_unlock(p_th_mutexFILES);
|
||||
}
|
||||
|
||||
|
||||
FILE *
|
||||
locked_fopen(const char *filename, const char *mode)
|
||||
{
|
||||
FILELOCK flock;
|
||||
FILE *retval;
|
||||
int readonly = stequal(mode,"r");
|
||||
filelock_obtain(filename,readonly); /* Will wait till available */
|
||||
if (!(retval = fopen(filename,mode))) {
|
||||
filelock_release(filename, readonly);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Suuitable sequence for creating a file via a temporary
|
||||
filelock_obtain(filename,FALSE);
|
||||
if (!(afile = locked_fopen(tmpfilename, "w")) )
|
||||
filelock_release(filename,FALSE);
|
||||
written stuff to the file - retval set if fails
|
||||
return(locked_fclose_and_rename(afile, tmpfilename, filenam,retvale));
|
||||
*/
|
||||
|
||||
int
|
||||
locked_fclose_and_rename(
|
||||
FILE *afile, /* Open "w" temporary file */
|
||||
const char *tmpfilename, /* Name of temp file */
|
||||
const char *filename, /* Name desired */
|
||||
int retval) /* FALSE if ok to rename, TRUE cleanup*/
|
||||
{
|
||||
|
||||
if (fflush(afile) || ferror(afile)) { retval = PFAILURE; }
|
||||
if (locked_fclose_A(afile, tmpfilename, FALSE)) { retval = PFAILURE; }
|
||||
if (!retval) { /* Dont attempt to rename if failed */
|
||||
if (rename(tmpfilename, filename)) { retval = PFAILURE; }
|
||||
}
|
||||
unlink(tmpfilename);
|
||||
filelock_release(filename,FALSE);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
28
prospero/lib/ardp/flocks.h
Normal file
28
prospero/lib/ardp/flocks.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef rmg_filelock_h
|
||||
#define rmg_filelock_h
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
struct filelock {
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
int consistency;
|
||||
#endif
|
||||
char *name;
|
||||
int readers; /* -1 for writing */
|
||||
/* Note we dont keep the fileno here since each locker opens seperately*/
|
||||
struct filelock *next;
|
||||
struct filelock *previous;
|
||||
};
|
||||
typedef struct filelock *FILELOCK;
|
||||
typedef struct filelock FILELOCK_ST;
|
||||
|
||||
extern FILELOCK filelock_alloc();
|
||||
extern void filelock_free(FILELOCK chan);
|
||||
extern void filelock_lfree(FILELOCK chan);
|
||||
extern void filelock_freespares();
|
||||
extern FILELOCK filelock_copy(FILELOCK f, int r);
|
||||
#ifdef PFS_THREADS
|
||||
extern p_th_mutex p_th_mutexFILELOCK;
|
||||
#endif
|
||||
|
||||
#endif /*rmg_filelock_h*/
|
||||
204
prospero/lib/ardp/hostname2adr.c
Normal file
204
prospero/lib/ardp/hostname2adr.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 1991-1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <ardp.h>
|
||||
#include <perrno.h>
|
||||
|
||||
#include <sys/types.h> /* for gethostbyname() */
|
||||
#include <sys/socket.h> /* for gethostbyname */
|
||||
#include <netdb.h> /* for gethostbyname. */
|
||||
#include <netinet/in.h> /* for struct sockaddr_in */
|
||||
#include <pmachine.h> /* for bzero */
|
||||
#include <string_with_strcasecmp.h> /* for strcasecmp */
|
||||
|
||||
#ifdef PROSPERO
|
||||
#include <pserver.h> /* For DNSCACHE_MAX */
|
||||
#ifdef DNSCACHE_MAX
|
||||
#include "dnscache_alloc.h"
|
||||
#endif
|
||||
#include <pcompat.h>
|
||||
#else /* not PROSPERO */
|
||||
#define DISABLE_PFS_START()
|
||||
#define DISABLE_PFS_END()
|
||||
#endif /* not PROSPERO */
|
||||
|
||||
extern int stcaseequal(const char *s1,const char *s2);
|
||||
|
||||
/*
|
||||
* This function serves as a thread-safe version of gethostbyname(),
|
||||
* which is not a re-entrant function since it uses static data.
|
||||
*
|
||||
* It normally accepts a hostname and initializes the socket address
|
||||
* appropriately, then returns PSUCCESS. Also accepts numeric addresses.
|
||||
* Does not currently handle the port #, although that would be a useful future
|
||||
* extension.
|
||||
*
|
||||
* It returns ARDP_BAD_HOSTNAME if the hostname could not be resolved.
|
||||
* gethostbyname should not be called anywhere else in multi-threaded versions
|
||||
* of the Prospero code; to this end, an error define occurs for it in
|
||||
* pfs_threads.h
|
||||
*
|
||||
* Oh no there isn't a definition in pfs_threads.h - Mitra
|
||||
*
|
||||
* Note that gethostbyname() is not multi-threaded internally, and
|
||||
* does block, so we might block on name resolution as a bottleneck.
|
||||
* Probably want a multithreaded name resolver library. Release such a thing
|
||||
* as freeware?
|
||||
*
|
||||
* It also converts numeric addresses appropriately.
|
||||
*/
|
||||
/* If change this - uncomment/comment initialization in server/dirsrv.c */
|
||||
|
||||
#ifdef DNSCACHE_MAX
|
||||
#include "dnscache_alloc.h"
|
||||
#include <mitra_macros.h> /* FIND_FNCTN_LIST */
|
||||
#include <string.h> /* For strcmp */
|
||||
|
||||
DNSCACHE alldnscaches = NULL;
|
||||
int alldnscache_count = 0;
|
||||
|
||||
void
|
||||
sockaddr_copy(struct sockaddr_in *src, struct sockaddr_in *destn)
|
||||
{
|
||||
/* Nothing in a sockaddr_in is a pointer */
|
||||
memcpy(destn, src, sizeof(struct sockaddr_in));
|
||||
}
|
||||
#endif /*DNSCACHE_MAX*/
|
||||
|
||||
/* Caching has been added, to this - take care that it does what you
|
||||
want, I'm certainly open to changes if this isnt what we need.
|
||||
Currently it is called by something at a higher layer, with a
|
||||
hostname of the name to cache, and a hostaddr of NULL.
|
||||
Currently this is used to cache all the hostnames hard coded
|
||||
into include/* on the assumption that these are unlikely to move around
|
||||
while a server is running. Later, we may want to delete a cached
|
||||
entry periodically, or if it fails.
|
||||
|
||||
The first thing in alldnscaches is always a copy of the last thing
|
||||
found, to allow really quick returns on repeat requests.
|
||||
|
||||
Note - great care is taken here to
|
||||
a) avoid deadlock between GETHOSTBYNAME and DNSCACHE mutexes
|
||||
b) avoid requirement for GETHOSTBYNAME mutex, if found in cache
|
||||
This allows multiple cached results to be returned while a
|
||||
single thread calls gethostbyname
|
||||
*/
|
||||
|
||||
void
|
||||
ardp_hostname2addr_initcache()
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dnscache_clean()
|
||||
{
|
||||
DNSCACHE dc, nextdc;
|
||||
if (alldnscache_count > DNSCACHE_MAX) {
|
||||
if (! p_th_mutex_trylock(p_th_mutexALLDNSCACHE)) {
|
||||
/* Since this is only optimisation, skip if its locked already */
|
||||
for (dc = alldnscaches; dc ; dc = nextdc) {
|
||||
nextdc = dc->next;
|
||||
if (!(--dc->usecount)) {
|
||||
EXTRACT_ITEM(dc,alldnscaches);
|
||||
dnscache_free(dc);
|
||||
alldnscache_count--;
|
||||
}
|
||||
}
|
||||
p_th_mutex_unlock(p_th_mutexALLDNSCACHE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ardp_hostname2addr(const char *hostname, struct sockaddr_in *hostaddr)
|
||||
{
|
||||
struct hostent *hp; /* Remote host we're connecting to. */
|
||||
int retval; /* Value to return */
|
||||
#define RETURN(rv) { retval = (rv); goto cleanup; }
|
||||
#ifdef PROSPERO
|
||||
int DpfStmp; /* for DISABLE_PFS_START() */
|
||||
#endif
|
||||
#ifdef DNSCACHE_MAX
|
||||
DNSCACHE acache = NULL;
|
||||
|
||||
acache = alldnscaches;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexALLDNSCACHE);
|
||||
/* Cant use TH_FIND_FNCTN_LIST because must retain lock */
|
||||
FIND_FNCTN_LIST(acache, name, hostname, stcaseequal);
|
||||
if(acache) {
|
||||
acache->usecount++;
|
||||
if (hostaddr) {
|
||||
/* Note is is pointless, but not harmfull to call again
|
||||
for same hostaddr - may just want to rerun*/
|
||||
sockaddr_copy(&(acache->sockad),hostaddr);
|
||||
}
|
||||
p_th_mutex_unlock(p_th_mutexALLDNSCACHE); /* Also released below*/
|
||||
return(ARDP_SUCCESS); /* Dont free acache */
|
||||
}
|
||||
p_th_mutex_unlock(p_th_mutexALLDNSCACHE); /* Note also released above*/
|
||||
acache = dnscache_alloc(); /*locks DNSCACHE temporarily*/
|
||||
acache->name = stcopy(hostname);
|
||||
if (!hostaddr) { hostaddr = &(acache->sockad); }
|
||||
#endif /*DNSCACHE_MAX*/
|
||||
|
||||
DISABLE_PFS_START(); /* Turn off compatibility library if on */
|
||||
p_th_mutex_lock(p_th_mutexGETHOSTBYNAME);
|
||||
hp = gethostbyname((char *) hostname); /* cast to char * in case bad prototype.
|
||||
*/
|
||||
DISABLE_PFS_END(); /* Restore compat. lib. */
|
||||
if (hp == NULL) {
|
||||
p_th_mutex_unlock(p_th_mutexGETHOSTBYNAME);
|
||||
/* Try to see if it might be a numeric address. */
|
||||
/* Check if a numeric address */
|
||||
hostaddr->sin_family = AF_INET;
|
||||
hostaddr->sin_addr.s_addr = inet_addr(hostname);
|
||||
if(hostaddr->sin_addr.s_addr == -1) {
|
||||
p_clear_errors(); /* clear p_err_string if set. */
|
||||
RETURN(perrno = ARDP_BAD_HOSTNAME);
|
||||
}
|
||||
RETURN(ARDP_SUCCESS);
|
||||
}
|
||||
bzero((char *) hostaddr, sizeof *hostaddr);
|
||||
memcpy((char *)&hostaddr->sin_addr, hp->h_addr, hp->h_length);
|
||||
hostaddr->sin_family = hp->h_addrtype;
|
||||
/* Don't unlock the mutex until we're no longer reading from hp. */
|
||||
p_th_mutex_unlock(p_th_mutexGETHOSTBYNAME); /* Note can be unlocked above*/
|
||||
/* Copy last result into cache */
|
||||
#ifdef DNSCACHE_MAX
|
||||
if (alldnscaches == NULL)
|
||||
ardp_hostname2addr_initcache();
|
||||
sockaddr_copy(hostaddr,&(acache->sockad));
|
||||
/* Boost initially, to bias towards keeping recent*/
|
||||
acache->usecount = 5;
|
||||
p_th_mutex_lock(p_th_mutexALLDNSCACHE);
|
||||
APPEND_ITEM(acache,alldnscaches);
|
||||
alldnscache_count++;
|
||||
p_th_mutex_unlock(p_th_mutexALLDNSCACHE);
|
||||
dnscache_clean(); /* Only does anything if cache too big */
|
||||
#endif /*DNSCACHE_MAX*/
|
||||
return(ARDP_SUCCESS); /* Dont free acache */
|
||||
|
||||
cleanup:
|
||||
#ifdef DNSCACHE_MAX
|
||||
if (acache) dnscache_free(acache);
|
||||
#endif
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/* Prototype needs to go into here, not just in pfs.h. */
|
||||
int
|
||||
stcaseequal(const char *s1,const char *s2)
|
||||
{
|
||||
if (s1 == s2) /* test for case when both NULL*/
|
||||
return TRUE;
|
||||
if (!s1 || !s2) /* test for one NULL */
|
||||
return FALSE;
|
||||
return (strcasecmp(s1, s2) == 0);
|
||||
}
|
||||
|
||||
141
prospero/lib/ardp/p__th_self_num.c
Normal file
141
prospero/lib/ardp/p__th_self_num.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 1991-1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pfs_threads.h>
|
||||
#include <ardp.h> /* for internal error stuff. */
|
||||
|
||||
/* This is the only section of code which calls the pthread_ routines directly.
|
||||
Everything else is through the interface in pfs_threads.h. */
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
/* Don't compile this if !PFS_THREADS, because it overrides macro definitions
|
||||
*/
|
||||
static struct {
|
||||
p_th_t thread;
|
||||
int inuse;
|
||||
} thread_map[P_MAX_NUM_THREADS];
|
||||
|
||||
#ifdef PFS_THREADS_SOLARIS
|
||||
thread_key_t thread_map_key;
|
||||
#endif
|
||||
|
||||
int
|
||||
p__th_self_num(void)
|
||||
{
|
||||
#if defined(PFS_THREADS_FLORIDA) || !defined(NDEBUG)
|
||||
p_th_t self = p_th_self();
|
||||
#endif
|
||||
|
||||
#ifdef PFS_THREADS_FLORIDA
|
||||
int i;
|
||||
|
||||
for (i = 0; i < P_MAX_NUM_THREADS; ++i) {
|
||||
if (thread_map[i].inuse
|
||||
&& p_th_equal(thread_map[i].thread, self))
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
#ifdef PFS_THREADS_SOLARIS
|
||||
long val;
|
||||
|
||||
if (!thread_map_key) return 0; /* Assume not threading */
|
||||
if (!thr_getspecific(thread_map_key,(void *)&val)) {
|
||||
assert(p_th_equal(thread_map[val].thread, self));
|
||||
assert(val < P_MAX_NUM_THREADS); /* i.e. 0 .. MAX-1 */
|
||||
return val;
|
||||
}
|
||||
#endif /*PFS_THREADS_SOLARIS*/
|
||||
internal_error("p__th_self_num() called for a thread that didn't have its \
|
||||
number set with p__th_allocate_self_num() or p__th_set_self_master()");
|
||||
return -1 ; /* Keep Gcc happy */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
p__th_set_self_master(void)
|
||||
{
|
||||
assert(!thread_map[0].inuse);
|
||||
thread_map[0].inuse = 1;
|
||||
thread_map[0].thread = p_th_self();
|
||||
#ifdef PFS_THREADS_SOLARIS
|
||||
assert(!thread_map_key);
|
||||
thr_keycreate(&thread_map_key, NULL);
|
||||
thr_setspecific(thread_map_key, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This allocates a number to this thread.
|
||||
* It also does consistency checking to make sure the function is called
|
||||
* only on a thread that doesn't have a number already allocated.
|
||||
*/
|
||||
void
|
||||
p_th_allocate_self_num(void)
|
||||
{
|
||||
int allocated = 0;
|
||||
p_th_t self = p_th_self();
|
||||
int i;
|
||||
|
||||
CHECK_MEM();
|
||||
assert(thread_map_key); /* Better be initialized*/
|
||||
/* I think this needs mutexing */
|
||||
p_th_mutex_lock(p_th_mutexARDP_SELFNUM);
|
||||
for (i = 0; i < P_MAX_NUM_THREADS; ++i) {
|
||||
if (!thread_map[i].inuse) {
|
||||
if (!allocated) {
|
||||
thread_map[i].thread = self;
|
||||
thread_map[i].inuse = 1;
|
||||
++allocated;
|
||||
CHECK_MEM();
|
||||
#ifdef PFS_THREADS_SOLARIS
|
||||
thr_setspecific(thread_map_key,(void *)i);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if(p_th_equal(thread_map[i].thread, self)) {
|
||||
internal_error("Shouldn't allocate a number to a thread twice.");
|
||||
}
|
||||
}
|
||||
}
|
||||
p_th_mutex_unlock(p_th_mutexARDP_SELFNUM);
|
||||
}
|
||||
|
||||
void
|
||||
p_th_deallocate_self_num(void)
|
||||
{
|
||||
int i = p__th_self_num();
|
||||
thread_map[i].inuse = 0;
|
||||
}
|
||||
|
||||
extern p_th_mutex p_th_mutexFILES;
|
||||
|
||||
#ifndef NDEBUG
|
||||
char mutex_locked_msg[] = "Mutex %s locked\n";
|
||||
#endif
|
||||
|
||||
#ifdef PFS_THREADS_SOLARIS
|
||||
/* Return true if fails to lock - i.e was already locked */
|
||||
int
|
||||
p_th_mutex_islocked(mutex_t *mp)
|
||||
{
|
||||
int retval;
|
||||
if (retval = mutex_trylock(mp)) {
|
||||
return retval;
|
||||
} else {
|
||||
return mutex_unlock(mp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* PFS_THREADS_SOLARIS */
|
||||
|
||||
#endif /*PFS_THREADS*/
|
||||
|
||||
324
prospero/lib/ardp/restrict.c
Normal file
324
prospero/lib/ardp/restrict.c
Normal file
@@ -0,0 +1,324 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#if !defined(AIX) && !defined(SOLARIS)
|
||||
#include <vfork.h>
|
||||
#endif
|
||||
#include <malloc.h>
|
||||
#include <search.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include "typedef.h"
|
||||
#include "db_files.h"
|
||||
#include "host_db.h"
|
||||
#include "header.h"
|
||||
#include "error.h"
|
||||
#include "archie_strings.h"
|
||||
#include "files.h"
|
||||
#include "master.h"
|
||||
#include "protos.h"
|
||||
#include "db_ops.h"
|
||||
|
||||
/* This performs a simple ACL based on ip addresses */
|
||||
|
||||
typedef struct {
|
||||
int ip[4]; /* Composes the ip address a.b.c.d */
|
||||
} ip_t;
|
||||
|
||||
|
||||
#define DIRSRV_ACL_FILE "dirsrv.acl"
|
||||
#define DIRSRV_ACL_MESSAGE_FILE "dirsrv.acl.mesg"
|
||||
|
||||
#define DIRSRV_ACL_MESSAGE_DEFAULT "Access to this server is restricted"
|
||||
|
||||
static ip_t *acl_list = NULL;
|
||||
static int acl_list_num = 0;
|
||||
static int acl_list_max = 0;
|
||||
static int acl_not_present = 0;
|
||||
|
||||
static char acl_err_mesg[100];
|
||||
|
||||
|
||||
#define IP_STAR 257
|
||||
|
||||
extern int errno;
|
||||
|
||||
|
||||
|
||||
static int qcompare_ip(a,b)
|
||||
ip_t *a, *b;
|
||||
{
|
||||
if ( a->ip[0] != b->ip[0] )
|
||||
return a->ip[0]- b->ip[0];
|
||||
|
||||
if ( a->ip[1] != b->ip[1] )
|
||||
return a->ip[1]- b->ip[1];
|
||||
|
||||
if ( a->ip[2] != b->ip[2] )
|
||||
return a->ip[2]- b->ip[2];
|
||||
|
||||
return a->ip[3]- b->ip[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int compare_ip(a,b) /* Assuming that can contain * */
|
||||
ip_t *a, *b;
|
||||
{
|
||||
if ( b->ip[0] == IP_STAR )
|
||||
return 0;
|
||||
|
||||
if ( a->ip[0] != b->ip[0] )
|
||||
return a->ip[0]- b->ip[0];
|
||||
|
||||
if ( b->ip[1] == IP_STAR )
|
||||
return 0;
|
||||
|
||||
if ( a->ip[1] != b->ip[1] )
|
||||
return a->ip[1]- b->ip[1];
|
||||
|
||||
if ( b->ip[2] == IP_STAR )
|
||||
return 0;
|
||||
|
||||
if ( a->ip[2] != b->ip[2] )
|
||||
return a->ip[2]- b->ip[2];
|
||||
|
||||
if ( b->ip[3] == IP_STAR )
|
||||
return 0;
|
||||
|
||||
return a->ip[3]- b->ip[3];
|
||||
|
||||
}
|
||||
|
||||
static int file_proc(ft,name,present)
|
||||
file_info_t *ft;
|
||||
char *name;
|
||||
int *present;
|
||||
{
|
||||
struct stat st;
|
||||
*present = 1;
|
||||
if ( ft == NULL ) {
|
||||
error(A_ERR,"file_proc", "Unable to create ft file pointer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf(ft->filename,"%s/%s/%s",get_archie_home(),DEFAULT_ETC_DIR,name);
|
||||
if ( stat(ft->filename,&st) == -1 ) {
|
||||
if ( errno == ENOENT ) {
|
||||
*present = 0;
|
||||
return 0;
|
||||
}
|
||||
error(A_ERR,"file_proc","Error finding ft: %s, errno = %d",ft->filename,errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( open_file(ft, O_RDONLY) == ERROR ) {
|
||||
error(A_ERR,"file_proc", "Error opening acl file: %s",ft->filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void read_acl_message()
|
||||
{
|
||||
char buff[100];
|
||||
int i;
|
||||
|
||||
file_info_t *acl_mesg = create_finfo();
|
||||
|
||||
strcpy(acl_err_mesg, DIRSRV_ACL_MESSAGE_DEFAULT);
|
||||
|
||||
if ( file_proc(acl_mesg,DIRSRV_ACL_MESSAGE_FILE,&i) ) {
|
||||
if ( fgets(buff,99,acl_mesg->fp_or_dbm.fp) != NULL ) {
|
||||
*(strrchr(buff,'\n')) = '\0';
|
||||
strcpy(acl_err_mesg,buff);
|
||||
}
|
||||
close_file(acl_mesg);
|
||||
destroy_finfo(acl_mesg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int read_acl_file()
|
||||
{
|
||||
char buff[100];
|
||||
int i,j;
|
||||
char **av;
|
||||
file_info_t *acl_file = create_finfo();
|
||||
|
||||
if (! file_proc(acl_file,DIRSRV_ACL_FILE,&j) ) {
|
||||
if ( j == 0 ) {
|
||||
acl_not_present = 1;
|
||||
destroy_finfo(acl_file);
|
||||
return 1;
|
||||
}
|
||||
destroy_finfo(acl_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Count the number of items */
|
||||
fseek(acl_file->fp_or_dbm.fp, 0L ,0);
|
||||
i = 0;
|
||||
while (fgets(buff,99,acl_file->fp_or_dbm.fp) != NULL ) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( i == 0 ) {
|
||||
error(A_INFO,"read_acl_file","ACL file is empty");
|
||||
acl_not_present = 1;
|
||||
destroy_finfo(acl_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( acl_list_max == 0 ) { /* New */
|
||||
acl_list_max = i+10;
|
||||
acl_list = (ip_t*)malloc(sizeof(ip_t)*acl_list_max);
|
||||
if ( acl_list == NULL ) {
|
||||
error(A_ERR,"read_acl_file","Unable to allocate memory");
|
||||
destroy_finfo(acl_file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ip_t *tmp;
|
||||
if ( acl_list_max <= i ) {
|
||||
acl_list_max = i+10;
|
||||
tmp = (ip_t*)realloc(acl_list, sizeof(ip_t)*acl_list_max);
|
||||
if ( tmp == NULL ) {
|
||||
error(A_ERR,"read_acl_file", "Unable to expand allocated memory");
|
||||
}
|
||||
acl_list = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
acl_list_num = 0;
|
||||
|
||||
fseek(acl_file->fp_or_dbm.fp, 0L ,0);
|
||||
while (fgets(buff,99,acl_file->fp_or_dbm.fp) != NULL ) {
|
||||
av = str_sep(buff,'.');
|
||||
if ( av == NULL ) {
|
||||
error(A_ERR,"read_acl_file", "Unable to decompose string: %s",buff);
|
||||
}
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
if ( av[i] == NULL|| av[i][0] == '*' ) {
|
||||
break;
|
||||
}
|
||||
acl_list[acl_list_num].ip[i] = atoi(av[i]);
|
||||
}
|
||||
for ( ; i < 4; i++ ) {
|
||||
acl_list[acl_list_num].ip[i] = IP_STAR;
|
||||
}
|
||||
acl_list_num++;
|
||||
}
|
||||
|
||||
close_file(acl_file);
|
||||
|
||||
qsort(acl_list,acl_list_num, sizeof(ip_t),qcompare_ip);
|
||||
|
||||
read_acl_message();
|
||||
|
||||
destroy_finfo(acl_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int verify_acl_list(from)
|
||||
struct sockaddr_in *from;
|
||||
{
|
||||
ip_t ip;
|
||||
int i;
|
||||
char **av;
|
||||
char *ip_addr;
|
||||
|
||||
|
||||
if ( acl_not_present )
|
||||
return 1;
|
||||
|
||||
if ( acl_list == NULL ) {
|
||||
if (!read_acl_file() )
|
||||
return 0;
|
||||
if ( acl_not_present )
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ip_addr = inet_ntoa(from->sin_addr);
|
||||
printf("%s\n",ip_addr);
|
||||
/* decompose address */
|
||||
av = str_sep(ip_addr,'.');
|
||||
if ( av == NULL ) {
|
||||
error(A_ERR,"verify_acl_list","Unable to decompsoe ip address: %s. Accepting",ip_addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ip.ip[0] = atoi(av[0]);
|
||||
ip.ip[1] = atoi(av[1]);
|
||||
ip.ip[2] = atoi(av[2]);
|
||||
ip.ip[3] = atoi(av[3]);
|
||||
|
||||
|
||||
if ( ip.ip[0] == 127 && ip.ip[1] == 0 && ip.ip[2] == 0 && ip.ip[3] == 1 ) {
|
||||
free_opts(av);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
for ( i = 0; i < acl_list_num; i++ ) {
|
||||
int ret;
|
||||
|
||||
ret = compare_ip(&ip, &acl_list[i]);
|
||||
if ( ret == 0 ){
|
||||
free_opts(av);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( ret < 0 ) {
|
||||
free_opts(av);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
free_opts(av);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *acl_message()
|
||||
{
|
||||
return acl_err_mesg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
char *prog;
|
||||
|
||||
int main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char buff[100];
|
||||
struct sockaddr_in from;
|
||||
|
||||
prog = argv[0];
|
||||
while ( fgets(buff,99,stdin) != NULL ) {
|
||||
*(strrchr(buff,'\n')) = '\0';
|
||||
printf("Checking %s, ",buff);
|
||||
|
||||
from.sin_addr.s_addr = inet_addr(buff);
|
||||
|
||||
if ( verify_acl_list(&from) )
|
||||
printf("Ok\n");
|
||||
else
|
||||
printf("No:%s\n",acl_message());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
41
prospero/lib/ardp/unixerrstr.c
Normal file
41
prospero/lib/ardp/unixerrstr.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1991-1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
|
||||
#include <pmachine.h>
|
||||
#if defined(HAVESTRERROR)
|
||||
#include <errno.h>
|
||||
#include <string.h> /* For stringerr*/
|
||||
#else
|
||||
#include <errno.h> /* For sys_nerr and sys_errlist*/
|
||||
#ifndef SOLARIS
|
||||
/* definitely needed under SunOS; probably under almost everything right
|
||||
now. Solaris's <errno.h> declares these; others don't. */
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
#endif /* ndef SOLARIS */
|
||||
#undef HAVESTRERROR
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
const char *
|
||||
unixerrstr(void)
|
||||
{
|
||||
#ifdef HAVESTRERROR
|
||||
/* sys_errlist is not in SOLARIS, replace with strerror()
|
||||
which may not be thread safe in some applications
|
||||
there doesnt appear to be a posix compliant equivalent */
|
||||
return strerror(errno);
|
||||
#else
|
||||
/* Would be nice to have the message include the error #. */
|
||||
return errno < sys_nerr ? sys_errlist[errno] : "Unprintable Error";
|
||||
#endif
|
||||
}
|
||||
|
||||
15
prospero/lib/ardp/usc_lic_str.c
Normal file
15
prospero/lib/ardp/usc_lic_str.c
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
/* This string is modified in ardp_xmit.c. That forces the C compiler to
|
||||
include it in the Prospero binaries. If you know a less kludgy way to
|
||||
force a fancy optimizing C compiler to include it in the binaries, please
|
||||
let us know.
|
||||
*/
|
||||
char *usc_license_string = "PROSPERO(TM) Copyright (c) 1991-1993 University of Southern California\nPROSPERO is a trademark of the University of Southern California\n";
|
||||
1
prospero/lib/filters/.gitignore
vendored
Normal file
1
prospero/lib/filters/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
7
prospero/lib/filters/FILES
Normal file
7
prospero/lib/filters/FILES
Normal file
@@ -0,0 +1,7 @@
|
||||
FILES
|
||||
Makefile.nofil
|
||||
apply_fil.c
|
||||
flist2string.c
|
||||
helpers.c
|
||||
nl_apply_fil.c
|
||||
reorder_dir.c
|
||||
35
prospero/lib/filters/Makefile.in
Executable file
35
prospero/lib/filters/Makefile.in
Executable file
@@ -0,0 +1,35 @@
|
||||
# lib/filters/Makefile
|
||||
# This is the makefile for the version of the Prospero Directory Service
|
||||
# where client-side filters are not loadable.
|
||||
# This is the default distributed version.
|
||||
|
||||
SOURCEBASE=../..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
CFILES = \
|
||||
nl_apply_fil.c
|
||||
|
||||
OBJECTS = \
|
||||
nl_apply_fil.o
|
||||
|
||||
|
||||
|
||||
all: ${FIL_LIB}
|
||||
|
||||
${FIL_LIB}: ${OBJECTS}
|
||||
rm -f ${FIL_LIB}
|
||||
ar rv ${FIL_LIB} ${OBJECTS}
|
||||
$(RANLIB) ${FIL_LIB}
|
||||
|
||||
install:
|
||||
|
||||
# cp ${FIL_LIB} ${P_BINARIES}/${FIL_LIB}
|
||||
# $(RANLIB) ${P_BINARIES}/${FIL_LIB}
|
||||
|
||||
# Dependencies
|
||||
nl_apply_fil.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
138
prospero/lib/filters/apply_fil.c
Normal file
138
prospero/lib/filters/apply_fil.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
typedef char *(*STR_function)();
|
||||
|
||||
/*!! No way is this thread safe!!! */
|
||||
STR_function filter;
|
||||
STR_function select_filter();
|
||||
|
||||
/* Variables that may be accessed by the filter */
|
||||
char *FlT_htype = P_MACHINE_TYPE; /* Current Host Type */
|
||||
char *FlT_ostype = P_OS_TYPE; /* Current Host Type */
|
||||
|
||||
/*
|
||||
* apply_filters - Apply filters to a directroy
|
||||
*
|
||||
* APPLY_FILTERS takes a pointer to a directory, a list of
|
||||
* filters to be to be applied to the directory.
|
||||
* It also takes a pointer to the link to the directory
|
||||
* which is made available to the filter. The last
|
||||
* argument specifies whether a single filter is to
|
||||
* be applied, or all filters in a list.
|
||||
*
|
||||
* The filters are then applied one by one
|
||||
* to the directory, and the result returned. Filters may
|
||||
* be defined by the user. The arguments may be modified,
|
||||
* and the returned directory will be the same directory as
|
||||
* passed as an argument.
|
||||
*
|
||||
* ARGS: dir - The directory to be filtered (will be modified)
|
||||
* filters - A list of the filters to be applied
|
||||
* dl - Directory link
|
||||
* oa - 0 = One, 1 = All
|
||||
*
|
||||
* MODIFIES: apply_filters might modify any of its arguments.
|
||||
* 'dir' is always modified to contain the result of
|
||||
* applying the filters. The return value is a pointer
|
||||
* to dir.
|
||||
*
|
||||
* apply_filters might also modify any of the following global
|
||||
* variables:
|
||||
*
|
||||
* FILTERS: Have access to read or modify the arguments, the
|
||||
* global variables listed above, and the following
|
||||
* local variables:
|
||||
*
|
||||
*
|
||||
* RETURNS: A pointer to the resulting directory.
|
||||
* 0 on failure with the error code in perrno.
|
||||
*
|
||||
*
|
||||
* BUGS: Doesn't trap failures in filters
|
||||
*/
|
||||
|
||||
#define MAX_FILTER_ARGS 20 /* good round number for starters. We should
|
||||
dynamically allocate the array instead, of
|
||||
course. */
|
||||
|
||||
VDIR
|
||||
apply_filters(dir,filters,dl,oa)
|
||||
VDIR dir;
|
||||
FILTER filters;
|
||||
VLINK dl;
|
||||
int oa;
|
||||
{
|
||||
VLINK curfil;
|
||||
VDIR result = dir;
|
||||
|
||||
char npath[MAXPATHLEN];
|
||||
char *argarray[MAX_FILTER_ARGS];
|
||||
char *miscarray[2];
|
||||
int argcount = 0;
|
||||
int retval;
|
||||
|
||||
/* "" means don't load a symbol table */
|
||||
DISABLE_PFS(initialize_loader(""));
|
||||
|
||||
curfil = filters;
|
||||
|
||||
while(curfil) {
|
||||
TOKEN argi; /* argument index */
|
||||
|
||||
assert(curfil->execution_location == FIL_CLIENT);
|
||||
assert(curfil->type == FIL_DIRECTORY || curfil->type == FIL_HIERARCHY);
|
||||
argarray[0] = NULL;
|
||||
|
||||
/* Additional arguments to the filter */
|
||||
|
||||
miscarray[0] = (char *) dl;
|
||||
miscarray[1] = (char *) filters;
|
||||
|
||||
for (argi = curfil->args, argcount = 0; argi; argi = argi->next) {
|
||||
argarray[argcount++] = stcopy(argi->token);
|
||||
assert(argcount <= MAX_FILTER_ARGS);
|
||||
}
|
||||
|
||||
retval = mapname(curfil,npath,MAP_READONLY);
|
||||
if(retval) {
|
||||
perrno = retval;
|
||||
return(0);
|
||||
}
|
||||
|
||||
DISABLE_PFS(load_filter(npath));
|
||||
|
||||
/* I'm amazed this works - we have a struc filter in pfs.h,
|
||||
and a variable filter hereh*/
|
||||
filter = select_filter("filter");
|
||||
result = (VDIR) filter(result,miscarray,argcount,argarray);
|
||||
|
||||
if(oa) curfil = curfil->next;
|
||||
else curfil = NULL;
|
||||
}
|
||||
|
||||
if(result != dir) vdir_copy(result,dir);
|
||||
|
||||
reorder_dir(dir);
|
||||
return(dir);
|
||||
}
|
||||
|
||||
|
||||
61
prospero/lib/filters/flist2string.c
Normal file
61
prospero/lib/filters/flist2string.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990 by the University of Washington
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <uw-copyright.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
|
||||
#ifdef NEVERDEFINED_NOTUSED
|
||||
char *
|
||||
flist2string(flist)
|
||||
VLINK flist;
|
||||
{
|
||||
static char fstring[1000];
|
||||
char *p = fstring;
|
||||
|
||||
*p = '\0';
|
||||
|
||||
while(flist) {
|
||||
sprintf(p,"{%c,%s,%s,%s,%s,%s}",flist->linktype,flist->hosttype,
|
||||
flist->host,flist->hsonametype,flist->hsoname,flist->args);
|
||||
p += strlen(p);
|
||||
flist = flist->next;
|
||||
}
|
||||
|
||||
return(fstring);
|
||||
|
||||
}
|
||||
#endif /*NEVERDEFINED*/
|
||||
#ifdef NEVERDEFINEDBUGGYASANYTHING
|
||||
VLINK
|
||||
fstring2list(st)
|
||||
char *st;
|
||||
{
|
||||
VLINK flist = NULL;
|
||||
VLINK fl = NULL;
|
||||
VLINK nf;
|
||||
|
||||
char *sp = st;
|
||||
|
||||
while(*sp) { /* This is bizarre sp never changes!! */
|
||||
nf = vlalloc();
|
||||
if(fl) fl->next = nf;
|
||||
else flist = nf;
|
||||
fl = nf;
|
||||
|
||||
sscanf(sp,"{%c,%s,%s,%s,%s, %[^}]",&(fl->linktype),fl->hosttype,
|
||||
fl->host,fl->hsonametype,fl->hsoname,fl->args);
|
||||
flist = flist->next;
|
||||
}
|
||||
|
||||
return(flist); /* Also bizarre - always null!! */
|
||||
|
||||
}
|
||||
#endif /*NEVERDEFINED*/
|
||||
134
prospero/lib/filters/helpers.c
Normal file
134
prospero/lib/filters/helpers.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990 by the University of Washington
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <uw-copyright.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* */
|
||||
/* helpers.c */
|
||||
/* */
|
||||
/* Routines to help Prospero interface with the EI. */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#include "ei/arbBA/ei.h"
|
||||
#include "ei/arbBA/symtab.h"
|
||||
#include "ei/arbBA/node.h"
|
||||
#include "ei/arbBA/arb.h"
|
||||
#include "ei/arbBA/map.h"
|
||||
#include <pfs.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*typedef char *(*STR_function)();*/
|
||||
|
||||
STR_function filter;
|
||||
|
||||
|
||||
/*
|
||||
* load_filter - a crude but adequate procedure for loading in a filter.
|
||||
* When called several times in succession, cascades the filters
|
||||
* in nested `focuses'. This assures that the currently loaded file
|
||||
* is the one first looked at, and then it searches upward. A better
|
||||
* model might build a very bushy tree instead, which would prevent a
|
||||
* bad reference being accidentally resolved by a filter loaded earlier.
|
||||
*/
|
||||
load_filter(filter_file_name)
|
||||
char *filter_file_name;
|
||||
{
|
||||
struct node *app_node;
|
||||
struct node *ext_node;
|
||||
|
||||
int fnl; /* Filter name length */
|
||||
|
||||
fnl = strlen(filter_file_name);
|
||||
|
||||
if(strcmp(filter_file_name+fnl-2,".o")==0) {
|
||||
*(filter_file_name+fnl-2) = '\0';
|
||||
}
|
||||
|
||||
app_node = EIRegister(CURRENT,filter_file_name);
|
||||
ext_node = ext(app_node);
|
||||
change_focus(ext_node);
|
||||
}
|
||||
|
||||
|
||||
STR_function select_filter(filter_name)
|
||||
char *filter_name;
|
||||
{
|
||||
return (STR_function) C_select(CURRENT,filter_name);
|
||||
}
|
||||
|
||||
|
||||
initialize_loader(fullpath)
|
||||
char *fullpath;
|
||||
{
|
||||
ei_initialize(1,&fullpath);
|
||||
}
|
||||
|
||||
struct sym_ent {
|
||||
char *symbol;
|
||||
long addr;
|
||||
};
|
||||
|
||||
/* The following is the list of variables and procedures that */
|
||||
/* are to be accessible from within filters. */
|
||||
/* */
|
||||
/* The values of these variables should be constant, though */
|
||||
/* an errant filter might change them. */
|
||||
|
||||
extern int atlfree();
|
||||
extern char *index();
|
||||
extern PATTRIB pget_at();
|
||||
extern int printf();
|
||||
extern VLINK rd_vlink();
|
||||
extern char *stcopy();
|
||||
extern char *stcopyr();
|
||||
extern char *strncpy();
|
||||
extern VLINK vlalloc();
|
||||
extern VLINK vlcopy();
|
||||
extern int vllfree();
|
||||
extern VLINK vl_delete();
|
||||
extern int vl_insert();
|
||||
extern int wcmatch();
|
||||
extern char *FlT_htype;
|
||||
extern char *FlT_ostype;
|
||||
|
||||
static struct sym_ent
|
||||
filter_externals[] = {{"_atlfree",(long)atlfree},
|
||||
{"_index",(long)index},
|
||||
{"_pget_at",(long)pget_at},
|
||||
{"_printf",(long)printf},
|
||||
{"_rd_vlink",(long)rd_vlink},
|
||||
{"_sprintf",(long)sprintf},
|
||||
{"_stcopy",(long)stcopy},
|
||||
{"_stcopyr",(long)stcopyr},
|
||||
{"_vlalloc",(long)vlalloc},
|
||||
{"_vlcopy",(long)vlcopy},
|
||||
{"_vllfree",(long)vllfree},
|
||||
{"_vl_delete",(long)vl_delete},
|
||||
{"_vl_insert",(long)vl_insert},
|
||||
{"_wcmatch",(long)wcmatch},
|
||||
{"_FlT_hosttype",(long)&FlT_htype},
|
||||
{"_FlT_ostype",(long)&FlT_ostype},
|
||||
{"",0}};
|
||||
|
||||
/*
|
||||
* symbol_find - take a name passed from the C dynamic linker and look it
|
||||
* up in this table for prospero filters. Returns its address, or -1 on
|
||||
* failure.
|
||||
*/
|
||||
long symbol_find(name)
|
||||
char *name;
|
||||
{
|
||||
struct sym_ent *sym;
|
||||
for (sym = filter_externals ; sym->addr != 0; sym++) {
|
||||
if (strcmp(name,sym->symbol) == 0)
|
||||
return(sym->addr);
|
||||
}
|
||||
return -1; /* failure */
|
||||
}
|
||||
|
||||
88
prospero/lib/filters/nl_apply_fil.c
Normal file
88
prospero/lib/filters/nl_apply_fil.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990 by the University of Washington
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
/*
|
||||
* apply_filters - Apply filters to a directory NULL VERSION
|
||||
*
|
||||
* This was the null version of apply filters. It is used
|
||||
* in those implementations that do not support filters.
|
||||
*
|
||||
* Added a predefined filter, from server/list.c
|
||||
*/
|
||||
VDIR
|
||||
dummy_filter(VDIR dir, TOKEN args)
|
||||
{
|
||||
printf("Do dummy filter");
|
||||
return dir;
|
||||
}
|
||||
|
||||
VDIR (*user_filter1)() = dummy_filter;
|
||||
VDIR (*user_filter2)() = dummy_filter;
|
||||
VDIR (*user_filter3)() = dummy_filter;
|
||||
VDIR (*user_filter4)() = dummy_filter;
|
||||
VDIR (*user_filter5)() = dummy_filter;
|
||||
|
||||
#define MAX_FILTER_ARGS 30 /* See note elsewhere about this*/
|
||||
|
||||
VDIR
|
||||
apply_filters(dir,filters, dl, oa)
|
||||
VDIR dir;
|
||||
FILTER filters;
|
||||
VLINK dl;
|
||||
int oa;
|
||||
{
|
||||
FILTER curfil;
|
||||
VDIR result = dir;
|
||||
|
||||
curfil = filters;
|
||||
|
||||
while(curfil) {
|
||||
|
||||
#ifdef NEVER_DEFINED
|
||||
if (strequal(curfil->name, "XYZ") {
|
||||
char *argarray[MAX_FILTER_ARGS];
|
||||
int argcount = 0;
|
||||
TOKEN argi; /* argument index */
|
||||
for (argi = curfil->args, argcount = 0; argi; argi = argi->next) {
|
||||
argarray[argcount++] = stcopy(argi->token);
|
||||
assert(argcount <= MAX_FILTER_ARGS);
|
||||
}
|
||||
return(xyz_filter(dir,argcount,argarray);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strequal(curfil->name, "USER1"))
|
||||
result = (user_filter1(result,curfil->args)) ;
|
||||
if (strequal(curfil->name, "USER2"))
|
||||
result = (user_filter2(result,curfil->args)) ;
|
||||
if (strequal(curfil->name, "USER3"))
|
||||
result = (user_filter3(result,curfil->args)) ;
|
||||
if (strequal(curfil->name, "USER4"))
|
||||
result = (user_filter4(result,curfil->args)) ;
|
||||
if (strequal(curfil->name, "USER5"))
|
||||
result = (user_filter5(result,curfil->args)) ;
|
||||
|
||||
if (oa)
|
||||
curfil = curfil->next;
|
||||
else
|
||||
curfil = NULL;
|
||||
}
|
||||
if (result != dir) {
|
||||
vdir_copy(result,dir);
|
||||
};
|
||||
|
||||
return(dir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
47
prospero/lib/filters/reorder_dir.c
Normal file
47
prospero/lib/filters/reorder_dir.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <uw-copyright.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
reorder_dir(dir)
|
||||
VDIR dir;
|
||||
{
|
||||
VLINK cl;
|
||||
VLINK tl;
|
||||
|
||||
cl = dir->links;
|
||||
|
||||
while(cl) {
|
||||
if((cl->linktype == 'U') || (cl->linktype == '-'))
|
||||
{
|
||||
if(cl->previous == NULL) dir->links = cl->next;
|
||||
else cl->previous->next = cl->next;
|
||||
if(cl->next) cl->next->previous = cl->previous;
|
||||
}
|
||||
tl = cl;
|
||||
cl = cl->next;
|
||||
if(tl->linktype == 'U') ul_insert(tl,dir,NULL);
|
||||
}
|
||||
|
||||
cl = dir->ulinks;
|
||||
|
||||
while(cl) {
|
||||
if(cl->linktype != 'U')
|
||||
{
|
||||
if(cl->previous == NULL) dir->ulinks = cl->next;
|
||||
else cl->previous->next = cl->next;
|
||||
if(cl->next) cl->next->previous = cl->previous;
|
||||
}
|
||||
tl = cl;
|
||||
cl = cl->next;
|
||||
if((tl->linktype != 'U') && (tl->linktype != '-'))
|
||||
vl_insert(tl,dir,VLI_ALLOW_CONF);
|
||||
}
|
||||
}
|
||||
1
prospero/lib/pcompat/.gitignore
vendored
Normal file
1
prospero/lib/pcompat/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
17
prospero/lib/pcompat/FILES
Normal file
17
prospero/lib/pcompat/FILES
Normal file
@@ -0,0 +1,17 @@
|
||||
FILES
|
||||
Makefile
|
||||
closedir.c
|
||||
creat.c
|
||||
execve.c
|
||||
getvdirent.c
|
||||
open.c
|
||||
opendir.c
|
||||
pcompat_init.c
|
||||
pfs_access.c
|
||||
pfs_default.c
|
||||
pfs_quiet.c
|
||||
readdir.c
|
||||
scandir.c
|
||||
seekdir.c
|
||||
stat.c
|
||||
telldir.c
|
||||
129
prospero/lib/pcompat/Makefile.in
Executable file
129
prospero/lib/pcompat/Makefile.in
Executable file
@@ -0,0 +1,129 @@
|
||||
SOURCEBASE = ../..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
# There used to be a lib/pcompat/Makefile.pcompat and a separate
|
||||
# lib/pcompat/Makefile.nopcompat.
|
||||
# This is no longer the case.
|
||||
|
||||
CFILES = \
|
||||
closedir.c \
|
||||
creat.c \
|
||||
execve.c \
|
||||
getvdirent.c \
|
||||
open.c \
|
||||
opendir.c \
|
||||
pcompat_init.c \
|
||||
pfs_access.c \
|
||||
pfs_default.c \
|
||||
pfs_quiet.c \
|
||||
readdir.c \
|
||||
scandir.c \
|
||||
seekdir.c \
|
||||
stat.c \
|
||||
telldir.c
|
||||
|
||||
|
||||
OBJECTS = \
|
||||
closedir.o \
|
||||
creat.o \
|
||||
execve.o \
|
||||
getvdirent.o \
|
||||
open.o \
|
||||
opendir.o \
|
||||
pcompat_init.o \
|
||||
pfs_access.o \
|
||||
pfs_default.o \
|
||||
pfs_quiet.o \
|
||||
readdir.o \
|
||||
scandir.o \
|
||||
seekdir.o \
|
||||
stat.o \
|
||||
telldir.o
|
||||
|
||||
all: ${CMP_LIB}
|
||||
|
||||
${CMP_LIB}: ${OBJECTS}
|
||||
rm -f ${CMP_LIB}
|
||||
ar rv ${CMP_LIB} ${OBJECTS}
|
||||
ranlib ${CMP_LIB}
|
||||
|
||||
install:
|
||||
|
||||
# $(INSTALL) -o $(OWNER) -g $(GROUP) ${CMP_LIB} ${P_BINARIES}/${CMP_LIB}
|
||||
# ranlib ${P_BINARIES}/${CMP_LIB}
|
||||
|
||||
|
||||
# Dependencies
|
||||
closedir.o : \
|
||||
../../include/pmachine.h
|
||||
creat.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h
|
||||
execve.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h
|
||||
getvdirent.o : \
|
||||
../../include/pmachine.h \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pcompat.h ../../include/perrno.h
|
||||
open.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h \
|
||||
../../include/perrno.h
|
||||
opendir.o : \
|
||||
../../include/pmachine.h
|
||||
pcompat_init.o : ../../include/pcompat.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/pmachine.h \
|
||||
../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h
|
||||
pfs_access.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/psite.h ../../include/pcompat.h \
|
||||
../../include/perrno.h
|
||||
pfs_default.o : ../../include/pcompat.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/pmachine.h
|
||||
pfs_quiet.o : ../../include/pcompat.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/pmachine.h
|
||||
readdir.o : \
|
||||
../../include/pmachine.h
|
||||
scandir.o : \
|
||||
../../include/pmachine.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h
|
||||
seekdir.o : \
|
||||
../../include/pmachine.h
|
||||
stat.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h \
|
||||
../../include/perrno.h
|
||||
telldir.o : \
|
||||
../../include/pmachine.h
|
||||
74
prospero/lib/pcompat/closedir.c
Normal file
74
prospero/lib/pcompat/closedir.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Derived from Berkeley source code. Those parts are
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)closedir.c 5.8 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* close a directory.
|
||||
*/
|
||||
#ifdef CLOSEDIR_RET_TYPE_VOID
|
||||
void
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
closedir(dirp)
|
||||
register DIR *dirp;
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = dirp->dd_fd;
|
||||
dirp->dd_fd = -1;
|
||||
dirp->dd_loc = 0;
|
||||
(void)free((void *)dirp->dd_buf);
|
||||
(void)free((void *)dirp);
|
||||
if(fd < 0) {
|
||||
if(p__delvdirentries(fd)) {
|
||||
errno = EBADF;
|
||||
#ifdef CLOSEDIR_RET_TYPE_VOID
|
||||
return;
|
||||
#else
|
||||
return(-1);
|
||||
#endif
|
||||
}
|
||||
#ifdef CLOSEDIR_RET_TYPE_VOID
|
||||
return;
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
#ifdef CLOSEDIR_RET_TYPE_VOID
|
||||
else return;
|
||||
#else
|
||||
else return(close(fd));
|
||||
#endif
|
||||
}
|
||||
48
prospero/lib/pcompat/creat.c
Normal file
48
prospero/lib/pcompat/creat.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/syscall.h>
|
||||
#else
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
|
||||
/* syscall is not MT-safe (at least under Solaris)
|
||||
#ifndef PFS_THREADS
|
||||
creat(const char *name,
|
||||
#ifdef OPEN_MODE_ARG_IS_INT
|
||||
int mode
|
||||
#else
|
||||
mode_t mode
|
||||
#endif
|
||||
)
|
||||
{
|
||||
char npath[MAXPATHLEN];
|
||||
|
||||
int tmp;
|
||||
|
||||
tmp = pfs_access(name, npath, sizeof npath, PFA_CRMAP);
|
||||
|
||||
if(tmp) return(-1);
|
||||
|
||||
return(syscall(SYS_creat,npath,mode));
|
||||
}
|
||||
#endif /*PFS_THREADS*/
|
||||
39
prospero/lib/pcompat/execve.c
Normal file
39
prospero/lib/pcompat/execve.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/syscall.h>
|
||||
#else
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
|
||||
|
||||
/* syscall is not MT-safe (at least under Solaris) */
|
||||
#ifndef PFS_THREADS
|
||||
int
|
||||
execve(const char *name, char * const*argv, char * const *envp)
|
||||
{
|
||||
char npath[MAXPATHLEN];
|
||||
|
||||
int tmp;
|
||||
|
||||
tmp = pfs_access(name, npath, sizeof npath, PFA_MAP);
|
||||
|
||||
/* Should figure out what correct error return should be */
|
||||
if(tmp) return(-1);
|
||||
|
||||
return(syscall(SYS_execve,npath,argv,envp));
|
||||
}
|
||||
#endif /*PFS_THREADS*/
|
||||
186
prospero/lib/pcompat/getvdirent.c
Normal file
186
prospero/lib/pcompat/getvdirent.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 1991-1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#define DIRSIZ_MACRO /* needed for HPUX; does no harm otherwise. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For malloc or free */
|
||||
|
||||
#include <pmachine.h>
|
||||
/* Needed if not already included. */
|
||||
#ifdef USE_SYS_DIR_H /* Support for SYS_DIR_H may be finally dead.
|
||||
I hope. */
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/* Maximum open virtual directories */
|
||||
#define MAX_VDDESC 16
|
||||
|
||||
static struct dirent *dirbuf[MAX_VDDESC + 1] = {NULL};
|
||||
static int dirpos[MAX_VDDESC + 1] = {0};
|
||||
static int dirbsz[MAX_VDDESC + 1] = {0};
|
||||
|
||||
int
|
||||
p__getvdirentries(int fd, char *buf, int nbytes, int *basep)
|
||||
{
|
||||
int bytes = 0;
|
||||
struct dirent *dp;
|
||||
char *bp;
|
||||
|
||||
if(fd > -1) return(0);
|
||||
if(fd < - MAX_VDDESC) return(0);
|
||||
|
||||
dp = (struct dirent *) ((char *)dirbuf[-fd] + dirpos[-fd]);
|
||||
|
||||
while(dp->d_reclen && (dp->d_reclen <= nbytes)) {
|
||||
bcopy(dp,buf,dp->d_reclen);
|
||||
nbytes = nbytes - (unsigned short) dp->d_reclen;
|
||||
buf = buf + (unsigned short) dp->d_reclen;
|
||||
bytes = bytes + (unsigned short) dp->d_reclen;
|
||||
bp = (char *) dp;bp += dp->d_reclen;dp = (struct dirent *) bp;
|
||||
}
|
||||
|
||||
*basep = dirpos[-fd];
|
||||
dirpos[-fd] = dirpos[-fd] + bytes;
|
||||
return(bytes);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
p__readvdirentries(char *dirname)
|
||||
{
|
||||
VDIR_ST dir_st;
|
||||
VDIR dir= &dir_st;
|
||||
VLINK l;
|
||||
|
||||
long dsize = 0;
|
||||
int dirnum = 0;
|
||||
struct dirent *dp;
|
||||
int tmp;
|
||||
|
||||
vdir_init(dir);
|
||||
|
||||
check_pfs_default();
|
||||
|
||||
/* If disabled, do no mapping */
|
||||
if(pfs_enable == PMAP_DISABLE) return(PSUCCESS);
|
||||
|
||||
/* This is a kludge. We should not be modifying the */
|
||||
/* path arg, but... */
|
||||
if(pfs_enable == PMAP_ATSIGN) {
|
||||
if(*dirname == '@') {
|
||||
strcpy(dirname,dirname+1);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
if(pfs_enable == PMAP_COLON) {
|
||||
if(*dirname == ':') dirname++;
|
||||
else return(PSUCCESS);
|
||||
}
|
||||
|
||||
p__compat_initialize();
|
||||
tmp = rd_vdir(dirname,0,dir,RVD_LREMEXP);
|
||||
|
||||
if(tmp) return(tmp);
|
||||
|
||||
l = dir->links;
|
||||
|
||||
while(l) {
|
||||
/* The next statement should track the DIRSIZ macro */
|
||||
dsize = dsize + (sizeof(struct dirent) - (MAXNAMLEN+1)) +
|
||||
((strlen(l->name)+1 +3) & ~3);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
/* This is just in case */
|
||||
dsize = dsize + 256;
|
||||
|
||||
dirnum = 0;
|
||||
while(dirnum++ <= MAX_VDDESC) {
|
||||
if(!dirbuf[dirnum]) break;
|
||||
}
|
||||
if(dirnum > MAX_VDDESC) RETURNPFAILURE;
|
||||
|
||||
dp = (struct dirent *) malloc(dsize);
|
||||
dirbuf[dirnum] = dp;
|
||||
dirpos[dirnum] = 0;
|
||||
dirbsz[dirnum] = dsize;
|
||||
|
||||
l = dir->links;
|
||||
|
||||
while(l) {
|
||||
dp->d_ino = (unsigned long) 999;
|
||||
#if !defined (SOLARIS)
|
||||
dp->d_namlen = (unsigned short) strlen(l->name);
|
||||
#endif
|
||||
dp->d_reclen = (unsigned short) DIRSIZ(dp);
|
||||
strcpy(dp->d_name,l->name);
|
||||
dp = (struct dirent *) ((char *) dp + dp->d_reclen);
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
dp->d_ino = (unsigned long) 0;
|
||||
dp->d_reclen = (unsigned short) 0;
|
||||
#if !defined (SOLARIS)
|
||||
dp->d_namlen = (unsigned short) 0;
|
||||
#endif
|
||||
*(dp->d_name) = '\0';
|
||||
|
||||
vllfree(dir->links);
|
||||
vllfree(dir->ulinks);
|
||||
|
||||
return(-dirnum);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
p__delvdirentries(int desc)
|
||||
{
|
||||
if(desc > -1) RETURNPFAILURE;
|
||||
if(desc < - MAX_VDDESC) RETURNPFAILURE;
|
||||
|
||||
if(dirbuf[- desc]) {
|
||||
free(dirbuf[- desc]);
|
||||
dirbuf[- desc] = NULL;
|
||||
return(PSUCCESS);
|
||||
}
|
||||
RETURNPFAILURE;
|
||||
}
|
||||
|
||||
int
|
||||
p__seekvdir(int desc, int pos)
|
||||
{
|
||||
if(desc > -1) RETURNPFAILURE;
|
||||
if(desc < - MAX_VDDESC) RETURNPFAILURE;
|
||||
if(!dirbuf[- desc]) RETURNPFAILURE;
|
||||
dirpos[-desc] = pos;
|
||||
return(PSUCCESS);
|
||||
}
|
||||
|
||||
int
|
||||
p__getvdbsize(int desc, int pos)
|
||||
{
|
||||
if(desc > -1) RETURNPFAILURE;
|
||||
if(desc < - MAX_VDDESC) RETURNPFAILURE;
|
||||
if(!dirbuf[- desc]) RETURNPFAILURE;
|
||||
return(dirbsz[-desc]);
|
||||
}
|
||||
|
||||
87
prospero/lib/pcompat/open.c
Normal file
87
prospero/lib/pcompat/open.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1992,1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
/* Originally written by Cliff Neuman, 1989
|
||||
Modified by Steven Augart, 1992, 1994
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/syscall.h>
|
||||
#else
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern int pfs_quiet;
|
||||
|
||||
/* HPUX prototype: extern int open(const char *, int, ...);
|
||||
SunOS prototype: int open() */
|
||||
|
||||
int
|
||||
#ifndef PROTOTYPE_FOR_OPEN_HAS_EMPTY_ARGLIST
|
||||
open(const char *path, int flags, ...)
|
||||
{
|
||||
va_list ap;
|
||||
#ifdef OPEN_MODE_ARG_IS_INT
|
||||
int mode;
|
||||
#else
|
||||
mode_t mode;
|
||||
#endif
|
||||
#else
|
||||
open(path, flags, mode)
|
||||
char *path;
|
||||
int flags;
|
||||
#ifdef OPEN_MODE_ARG_IS_INT
|
||||
int mode;
|
||||
#else
|
||||
mode_t mode;
|
||||
#endif
|
||||
{
|
||||
#endif
|
||||
char npath[MAXPATHLEN];
|
||||
|
||||
int pfaflags;
|
||||
int tmp;
|
||||
int open_return;
|
||||
|
||||
#ifndef PROTOTYPE_FOR_OPEN_HAS_EMPTY_ARGLIST
|
||||
va_start(ap, flags);
|
||||
#ifdef OPEN_MODE_ARG_IS_INT
|
||||
mode = va_arg(ap, int);
|
||||
#else
|
||||
mode = va_arg(ap, mode_t);
|
||||
#endif
|
||||
#endif
|
||||
if(flags & O_CREAT) pfaflags = PFA_CRMAP;
|
||||
else pfaflags = PFA_MAP;
|
||||
if((flags & (O_ACCMODE)) == O_RDONLY) pfaflags |= PFA_RO;
|
||||
|
||||
tmp = pfs_access(path,npath, sizeof npath, pfaflags);
|
||||
|
||||
if(tmp && (tmp != PMC_DELETE_ON_CLOSE)) {
|
||||
if(!pfs_quiet) printf("open failed: %s\n",p_err_text[tmp]);
|
||||
errno = ENOENT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
open_return = syscall(SYS_open,npath,flags,mode);
|
||||
if(tmp == PMC_DELETE_ON_CLOSE) unlink(npath);
|
||||
|
||||
return(open_return);
|
||||
}
|
||||
105
prospero/lib/pcompat/opendir.c
Normal file
105
prospero/lib/pcompat/opendir.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Derived from Berkeley source code. Those parts are
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)opendir.c 5.10 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#if defined(AIX) && defined(__GNUC__) /* lucb */
|
||||
#define dd_bsize dd_size
|
||||
#endif
|
||||
|
||||
#ifndef DIRBLKSIZ
|
||||
#define DIRBLKSIZ 512
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> /* For malloc */
|
||||
long _rewinddir;
|
||||
|
||||
/*
|
||||
* open a directory.
|
||||
*/
|
||||
DIR *
|
||||
opendir(const char *name)
|
||||
{
|
||||
register DIR *dirp;
|
||||
register int fd;
|
||||
|
||||
fd = p__readvdirentries(name);
|
||||
|
||||
if(fd > 0) {
|
||||
errno = ENOENT;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(fd == 0) {
|
||||
if ((fd = open(name, 0, 0)) == -1)
|
||||
return NULL;
|
||||
if (fcntl(fd, F_SETFD, 1) == -1) {
|
||||
close (fd);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) return(NULL);
|
||||
|
||||
/*
|
||||
* If CLSIZE is an exact multiple of DIRBLKSIZ, use a CLSIZE
|
||||
* buffer that it cluster boundary aligned.
|
||||
* Hopefully this can be a big win someday by allowing page trades
|
||||
* to user space to be done by getdirentries()
|
||||
*/
|
||||
#ifdef CLSIZE
|
||||
if ((CLSIZE % DIRBLKSIZ) == 0) {
|
||||
dirp->dd_buf = malloc(CLSIZE);
|
||||
dirp->dd_bsize = CLSIZE;
|
||||
} else {
|
||||
#endif
|
||||
dirp->dd_buf = malloc(DIRBLKSIZ);
|
||||
dirp->dd_bsize = DIRBLKSIZ;
|
||||
#ifdef CLSIZE
|
||||
}
|
||||
#endif
|
||||
if (dirp->dd_buf == NULL) {
|
||||
close (fd);
|
||||
return NULL;
|
||||
}
|
||||
dirp->dd_fd = fd;
|
||||
dirp->dd_loc = 0;
|
||||
#ifdef SUNOS /* lucb */
|
||||
dirp->dd_bbase = 0;
|
||||
#endif
|
||||
/*
|
||||
* Set up seek point for rewinddir.
|
||||
*/
|
||||
_rewinddir = telldir(dirp);
|
||||
return dirp;
|
||||
}
|
||||
29
prospero/lib/pcompat/pcompat_init.c
Normal file
29
prospero/lib/pcompat/pcompat_init.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pcompat.h> /* prototype for p__compat_initialize() */
|
||||
#include <pfs.h> /* prototype for p_initialize() */
|
||||
|
||||
/* Author: Steven Seger Augart, Mar. 30, 1994 */
|
||||
/* This file contains automatic initialization routines for the PCOMPAT
|
||||
library. No Prospero functions should be called before p_initialize() has
|
||||
been called. This makes the pcompat library self-initializing. */
|
||||
|
||||
/* This function can be safely called more than once. */
|
||||
|
||||
static int initialized = 0;
|
||||
|
||||
void
|
||||
p__compat_initialize(void)
|
||||
{
|
||||
if (!initialized) {
|
||||
++initialized;
|
||||
p_initialize("uclP", 0, (struct p_initialize_st *) NULL);
|
||||
}
|
||||
}
|
||||
110
prospero/lib/pcompat/pfs_access.c
Normal file
110
prospero/lib/pcompat/pfs_access.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <psite.h>
|
||||
#include <pcompat.h>
|
||||
#include <pmachine.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/*
|
||||
* see pcompat.h for the meanings of the flage
|
||||
*/
|
||||
int
|
||||
pfs_access(const char *path, char *npath, int npathlen, int flags)
|
||||
{
|
||||
|
||||
char cpath[MAXPATHLEN];
|
||||
char *prefix;
|
||||
char *suffix;
|
||||
VLINK vl;
|
||||
int tmp;
|
||||
|
||||
suffix = "";
|
||||
|
||||
check_pfs_default();
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* If disabled, do no mapping */
|
||||
if(pfs_enable == PMAP_DISABLE) {
|
||||
strcpy(npath,path);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
|
||||
if(pfs_enable == PMAP_COLON) {
|
||||
if(*path == ':') path++;
|
||||
else if(index(path,':'));
|
||||
else {strcpy(npath,path); return(PSUCCESS);}
|
||||
}
|
||||
|
||||
if((pfs_enable == PMAP_ATSIGN_NF) || (pfs_enable == PMAP_ATSIGN)) {
|
||||
if(*path == '@') {
|
||||
path++;
|
||||
strcpy(npath,path);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
p__compat_initialize();
|
||||
/* I should probably choose better values for errno */
|
||||
vl = rd_vlink(path);
|
||||
if((perrno || !vl) && ((flags == PFA_CRMAP)||(flags == PFA_CREATE))) {
|
||||
strcpy(cpath,path);
|
||||
prefix = cpath;
|
||||
suffix = strrchr(cpath,'/');
|
||||
if(suffix) {
|
||||
if(suffix == prefix) prefix = "/";
|
||||
*(suffix++) = '\0';
|
||||
vl = rd_vlink(prefix);
|
||||
if(vl) {
|
||||
sprintf(cpath,"%s/%s",vl->hsoname,suffix);
|
||||
vl->hsoname = stcopyr(cpath,vl->hsoname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If not found, but PMAP_ATSIGN_NF, then check if a real file */
|
||||
if(((perrno == PFS_DIR_NOT_FOUND) || (perrno == RVD_DIR_NOT_THERE) ||
|
||||
(!perrno && !vl)) &&
|
||||
(pfs_enable == PMAP_ATSIGN_NF) &&
|
||||
(*path == '/') && ((strncmp(path,"/tmp",4) == 0) ||
|
||||
((flags != PFA_CRMAP) && (flags != PFA_CREATE)))) {
|
||||
strcpy(npath,path);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
|
||||
if(perrno) {errno = ENOENT;return(perrno);}
|
||||
if(!vl) {errno = ENOENT;return(PFS_FILE_NOT_FOUND);}
|
||||
|
||||
#ifdef PCOMPAT_SUPPORT_FTP
|
||||
/* P_AM_FTP requires prompting for a password, which is not something
|
||||
transparent to the user. That's why without the special
|
||||
PCOMPAT_SUPPORT_FTP definition, mapname isn't called with the
|
||||
MAP_PROMPT_OK option. */
|
||||
tmp = mapname(vl,npath, npathlen,
|
||||
MAP_PROMPT_OK | ((flags & PFA_RO) ?
|
||||
MAP_READONLY : MAP_READWRITE));
|
||||
#else
|
||||
tmp = mapname(vl,npath, npathlen, ((flags & PFA_RO) ?
|
||||
MAP_READONLY : MAP_READWRITE));
|
||||
#endif
|
||||
vllfree(vl);
|
||||
if(tmp && (tmp != PMC_DELETE_ON_CLOSE)) errno = ENOENT;
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
39
prospero/lib/pcompat/pfs_default.c
Normal file
39
prospero/lib/pcompat/pfs_default.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pcompat.h>
|
||||
|
||||
int pfs_default = -1;
|
||||
|
||||
char *getenv();
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
void
|
||||
p__get_pfs_default(void)
|
||||
{
|
||||
char *pfs_default_string;
|
||||
char *pfs_debug_string;
|
||||
|
||||
/* if pfs_disable_flag is set to disable, skip as there */
|
||||
/* is probably a reason for it */
|
||||
if(pfs_enable == PMAP_DISABLE) return;
|
||||
|
||||
/* Check PFS_DEFAULT and if set, set pfs_disable_flag */
|
||||
if(pfs_default == -1) {
|
||||
pfs_default_string = getenv("PFS_DEFAULT");
|
||||
if(pfs_default_string == 0) pfs_default = -2;
|
||||
else if(sscanf(pfs_default_string,"%d",&pfs_default) != 1)
|
||||
pfs_default = -2;
|
||||
else pfs_enable = pfs_default;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
28
prospero/lib/pcompat/pfs_quiet.c
Normal file
28
prospero/lib/pcompat/pfs_quiet.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pcompat.h>
|
||||
|
||||
|
||||
/* Written: Cliff Neuman, 1989, 1991. */
|
||||
/* Updated documentation and declarations: swa@ISI.EDU, 1994. */
|
||||
|
||||
/*
|
||||
* pfs_quiet - Printing of error messages on prospero failure
|
||||
*
|
||||
* This file initializes pfs_quiet to 0. It is included
|
||||
* the pcompat library library in case it is left out
|
||||
* by an application. A value of 0 means that open and
|
||||
* other redefined system calls will print an error
|
||||
* message on the standard error stream before returning
|
||||
* if an error was detected by Prospero.
|
||||
*
|
||||
*/
|
||||
|
||||
int pfs_quiet = 0;
|
||||
77
prospero/lib/pcompat/readdir.c
Normal file
77
prospero/lib/pcompat/readdir.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Derived from Berkeley source code. Those parts are
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)readdir.c 5.7 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get next entry in a directory.
|
||||
*/
|
||||
struct dirent *
|
||||
readdir(dirp)
|
||||
register DIR *dirp;
|
||||
{
|
||||
register struct dirent *dp;
|
||||
|
||||
for (;;) {
|
||||
if (dirp->dd_loc == 0) {
|
||||
if(dirp->dd_fd >= 0)
|
||||
#if defined(SUNOS)
|
||||
dirp->dd_size = getdents(dirp->dd_fd,
|
||||
dirp->dd_buf, dirp->dd_bsize);
|
||||
#else
|
||||
dirp->dd_size = getdirentries(dirp->dd_fd,
|
||||
dirp->dd_buf, dirp->dd_bsize, &dirp->dd_bbase);
|
||||
#endif
|
||||
else
|
||||
dirp->dd_size = p__getvdirentries(dirp->dd_fd,
|
||||
dirp->dd_buf, dirp->dd_bsize, &dirp->dd_bbase);
|
||||
if (dirp->dd_size <= 0)
|
||||
return NULL;
|
||||
}
|
||||
if (dirp->dd_loc >= dirp->dd_size) {
|
||||
dirp->dd_loc = 0;
|
||||
continue;
|
||||
}
|
||||
dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
|
||||
if ((int)dp & 03) /* bogus pointer check */
|
||||
return NULL;
|
||||
#if defined(SUNOS)
|
||||
dirp->dd_bbase = dp->d_off;
|
||||
#endif
|
||||
if (dp->d_reclen <= 0 ||
|
||||
dp->d_reclen > dirp->dd_bsize + 1 - dirp->dd_loc)
|
||||
return NULL;
|
||||
dirp->dd_loc += dp->d_reclen;
|
||||
if (dp->d_ino == 0)
|
||||
continue;
|
||||
return (dp);
|
||||
}
|
||||
}
|
||||
142
prospero/lib/pcompat/scandir.c
Normal file
142
prospero/lib/pcompat/scandir.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted provided
|
||||
* that: (1) source distributions retain this entire copyright notice and
|
||||
* comment, and (2) distributions including binaries display the following
|
||||
* acknowledgement: ``This product includes software developed by the
|
||||
* University of California, Berkeley and its contributors'' in the
|
||||
* documentation or other materials provided with the distribution and in
|
||||
* all advertising materials mentioning features or use of this software.
|
||||
* Neither the name of the University nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)scandir.c 5.9 (Berkeley) 6/24/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Scan the directory dirname calling select to make a list of selected
|
||||
* directory entries then sort using qsort and compare routine dcomp.
|
||||
* Returns the number of entries and a pointer to a list of pointers to
|
||||
* struct dirent (through namelist). Returns -1 if there were any errors.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h> /* For malloc and free */
|
||||
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include <pfs_threads.h> /* For PFS_THREADS */
|
||||
/*
|
||||
* The DIRSIZ macro gives the minimum record length which will hold
|
||||
* the directory entry. This requires the amount of space in struct dirent
|
||||
* without the d_name field, plus enough space for the name with a terminating
|
||||
* null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
|
||||
*/
|
||||
#undef DIRSIZ
|
||||
#define DIRSIZ(dp) \
|
||||
((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
|
||||
|
||||
int
|
||||
scandir(const char *dirname, struct dirent ***namelist,
|
||||
int (*select)(const struct dirent *),
|
||||
int (*dcomp)(const struct dirent **, const struct dirent **))
|
||||
{
|
||||
register struct dirent *d, *p, **names;
|
||||
register int nitems;
|
||||
struct stat stb;
|
||||
long arraysz;
|
||||
DIR *dirp;
|
||||
/* The next variable shuts up GCC thinking that dcomp is of a different
|
||||
type from int (*)() */
|
||||
int (*dcomp_qsort_losing_prototype)() = (int (*)()) dcomp;
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
struct {
|
||||
struct dirent a;
|
||||
char b[_POSIX_PATH_MAX];
|
||||
} readdir_result_st;
|
||||
struct dirent *readdir_result = (struct dirent *) &readdir_result_st;
|
||||
#endif
|
||||
if ((dirp = opendir(dirname)) == NULL) {
|
||||
return(-1);
|
||||
}
|
||||
if (fstat(dirp->dd_fd, &stb) < 0) {
|
||||
closedir(dirp);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* estimate the array size by taking the size of the directory file
|
||||
* and dividing it by a multiple of the minimum size entry.
|
||||
*/
|
||||
arraysz = (stb.st_size / 24);
|
||||
names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *));
|
||||
if (names == NULL)
|
||||
return(-1);
|
||||
|
||||
nitems = 0;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*SOLARIS: readdir is MT-Unsafe */
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
while ((d = readdir_r(dirp,readdir_result)) != NULL) {
|
||||
#else
|
||||
while ((d = readdir(dirp)) != NULL) {
|
||||
#endif
|
||||
if (select != NULL && !(*select)(d))
|
||||
continue; /* just selected names */
|
||||
/*
|
||||
* Make a minimum size copy of the data
|
||||
*/
|
||||
p = (struct dirent *)malloc(DIRSIZ(d));
|
||||
if (p == NULL)
|
||||
return(-1);
|
||||
p->d_ino = d->d_ino;
|
||||
p->d_reclen = d->d_reclen;
|
||||
p->d_namlen = d->d_namlen;
|
||||
bcopy(d->d_name, p->d_name, p->d_namlen + 1);
|
||||
/*
|
||||
* Check to make sure the array has space left and
|
||||
* realloc the maximum size.
|
||||
*/
|
||||
if (++nitems >= arraysz) {
|
||||
if (fstat(dirp->dd_fd, &stb) < 0)
|
||||
return(-1); /* just might have grown */
|
||||
arraysz = stb.st_size / 12;
|
||||
names = (struct dirent **)realloc((char *)names,
|
||||
arraysz * sizeof(struct dirent *));
|
||||
if (names == NULL)
|
||||
return(-1);
|
||||
}
|
||||
names[nitems-1] = p;
|
||||
}
|
||||
closedir(dirp);
|
||||
if (nitems && dcomp != NULL)
|
||||
qsort(names, nitems, sizeof(struct dirent *),
|
||||
dcomp_qsort_losing_prototype);
|
||||
*namelist = names;
|
||||
return(nitems);
|
||||
}
|
||||
|
||||
/*
|
||||
* Alphabetic order comparison routine for those who want it.
|
||||
*/
|
||||
int
|
||||
alphasort(const struct dirent **d1, const struct dirent **d2)
|
||||
{
|
||||
return strcmp((*d1)->d_name, (*d2)->d_name);
|
||||
}
|
||||
42
prospero/lib/pcompat/seekdir.c
Normal file
42
prospero/lib/pcompat/seekdir.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)seekdir.c 5.7 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Seek to an entry in a directory.
|
||||
* p__seekdir is in telldir.c so that it can share opaque data structures.
|
||||
*/
|
||||
void
|
||||
seekdir(DIR *dirp, long loc)
|
||||
{
|
||||
|
||||
p__seekdir(dirp, loc);
|
||||
}
|
||||
136
prospero/lib/pcompat/stat.c
Normal file
136
prospero/lib/pcompat/stat.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 1993, 1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/syscall.h>
|
||||
#else
|
||||
#include <syscall.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <pmachine.h> /* for bzero */
|
||||
#include <perrno.h> /* for testing against errors returned by
|
||||
prospero subfunctions. */
|
||||
|
||||
static int stat_l(const char *path, struct stat *buf, int lflag);
|
||||
|
||||
/* syscall is not MT-safe (at least under Solaris) */
|
||||
#ifndef PFS_THREADS
|
||||
/* Call stat_l indicating normal stat */
|
||||
int
|
||||
stat(const char *path, struct stat *buf)
|
||||
{
|
||||
return(stat_l(path,buf,0));
|
||||
}
|
||||
|
||||
|
||||
/* Call stat_l indicating lstat */
|
||||
int
|
||||
lstat(const char *path, struct stat *buf)
|
||||
{
|
||||
return(stat_l(path,buf,1));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
stat_l(const char *path, struct stat *buf, int lflag)
|
||||
{
|
||||
VDIR_ST dir_st;
|
||||
VDIR dir= &dir_st;
|
||||
PATTRIB ap,nextap;
|
||||
int tmp;
|
||||
|
||||
vdir_init(dir);
|
||||
check_pfs_default();
|
||||
|
||||
/* If disabled, make system call */
|
||||
if(pfs_enable == PMAP_DISABLE) {
|
||||
return(syscall((lflag ? SYS_lstat : SYS_stat), path, buf));
|
||||
}
|
||||
|
||||
if(pfs_enable == PMAP_COLON) {
|
||||
if(*path == ':') path++;
|
||||
else if(index(path,':'));
|
||||
else return(syscall((lflag ? SYS_lstat : SYS_stat), path, buf));
|
||||
}
|
||||
|
||||
if((pfs_enable == PMAP_ATSIGN_NF) || (pfs_enable == PMAP_ATSIGN)) {
|
||||
if(*path == '@') {
|
||||
path++;
|
||||
return(syscall((lflag ? SYS_lstat : SYS_stat), path, buf));
|
||||
}
|
||||
}
|
||||
|
||||
bzero(buf,sizeof(struct stat));
|
||||
buf->st_uid = (uid_t) -1;
|
||||
buf->st_gid = (gid_t) -1;
|
||||
|
||||
p__compat_initialize();
|
||||
/* I should probably choose better values for errno */
|
||||
tmp = rd_vdir(path,0,dir,RVD_DFILE_ONLY|RVD_ATTRIB);
|
||||
if((dir->links == NULL) || (tmp && (tmp != DIRSRV_NOT_DIRECTORY))) {
|
||||
|
||||
if(((tmp == PFS_DIR_NOT_FOUND)||(tmp == RVD_DIR_NOT_THERE)|| !tmp)&&
|
||||
(pfs_enable == PMAP_ATSIGN_NF) && (*path == '/')) {
|
||||
return(syscall((lflag ? SYS_lstat : SYS_stat), path, buf));
|
||||
}
|
||||
errno = ENOENT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if(tmp == 0) buf->st_mode |= (S_IFDIR | 0555);
|
||||
else buf->st_mode |= 0444;
|
||||
|
||||
if(strncmp(dir->links->target,"EXTERNAL",8) == 0) ap = NULL;
|
||||
else ap = pget_at(dir->links,"#ALL");
|
||||
|
||||
/* If can't get real attributes, try those stored with link */
|
||||
if((ap == NULL) && dir->links->lattrib) {
|
||||
ap = dir->links->lattrib;
|
||||
dir->links->lattrib = NULL;
|
||||
}
|
||||
|
||||
while(ap) {
|
||||
switch (*(ap->aname)) {
|
||||
case 'L':
|
||||
if((strcmp(ap->aname,"LAST-MODIFIED") == 0) &&
|
||||
ap->avtype == ATR_SEQUENCE ) {
|
||||
buf->st_mtime = asntotime(ap->value.sequence->token);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
if((strcmp(ap->aname,"SIZE") == 0) &&
|
||||
ap->avtype == ATR_SEQUENCE) {
|
||||
int size;
|
||||
qsscanf(ap->value.sequence->token,"%d",&size);
|
||||
buf->st_size = size;
|
||||
/* The following is a good guess at number of blocks */
|
||||
buf->st_blocks = (size+511) / 512;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
nextap = ap->next;
|
||||
atfree(ap);
|
||||
ap = nextap;
|
||||
}
|
||||
vllfree(dir->links);
|
||||
vllfree(dir->ulinks);
|
||||
return(0);
|
||||
}
|
||||
#endif /*PFS_THREADS*/
|
||||
129
prospero/lib/pcompat/telldir.c
Normal file
129
prospero/lib/pcompat/telldir.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Derived from Berkeley source code. Those parts are
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)telldir.c 5.8 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <pmachine.h>
|
||||
#include <stdlib.h> /* For malloc and free */
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#if defined(AIX) && defined(__GNUC__) /* lucb */
|
||||
#define dd_bsize dd_size
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The option SINGLEUSE may be defined to say that a telldir
|
||||
* cookie may be used only once before it is freed. This option
|
||||
* is used to avoid having memory usage grow without bound.
|
||||
*/
|
||||
#define SINGLEUSE
|
||||
|
||||
/*
|
||||
* One of these structures is malloced to describe the current directory
|
||||
* position each time telldir is called. It records the current magic
|
||||
* cookie returned by getdirentries and the offset within the buffer
|
||||
* associated with that return value.
|
||||
*/
|
||||
struct ddloc {
|
||||
struct ddloc *loc_next;/* next structure in list */
|
||||
long loc_index; /* key associated with structure */
|
||||
long loc_seek; /* magic cookie returned by getdirentries */
|
||||
long loc_loc; /* offset of entry in buffer */
|
||||
};
|
||||
|
||||
#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */
|
||||
#define LOCHASH(i) ((i)&(NDIRHASH-1))
|
||||
|
||||
static long dd_loccnt; /* Index of entry for sequential readdir's */
|
||||
static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
|
||||
|
||||
/*
|
||||
* return a pointer into a directory
|
||||
*/
|
||||
long
|
||||
telldir(dirp)
|
||||
DIR *dirp;
|
||||
{
|
||||
register int index;
|
||||
register struct ddloc *lp;
|
||||
|
||||
if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
|
||||
return (-1);
|
||||
index = dd_loccnt++;
|
||||
lp->loc_index = index;
|
||||
lp->loc_seek = dirp->dd_bbase;
|
||||
lp->loc_loc = dirp->dd_loc;
|
||||
lp->loc_next = dd_hash[LOCHASH(index)];
|
||||
dd_hash[LOCHASH(index)] = lp;
|
||||
return (index);
|
||||
}
|
||||
|
||||
/*
|
||||
* seek to an entry in a directory.
|
||||
* Only values returned by "telldir" should be passed to seekdir.
|
||||
*/
|
||||
void
|
||||
p__seekdir(register DIR *dirp, long loc)
|
||||
{
|
||||
register struct ddloc *lp;
|
||||
register struct ddloc **prevlp;
|
||||
struct dirent *dp;
|
||||
extern long lseek();
|
||||
|
||||
prevlp = &dd_hash[LOCHASH(loc)];
|
||||
lp = *prevlp;
|
||||
while (lp != NULL) {
|
||||
if (lp->loc_index == loc)
|
||||
break;
|
||||
prevlp = &lp->loc_next;
|
||||
lp = lp->loc_next;
|
||||
}
|
||||
if (lp == NULL)
|
||||
return;
|
||||
if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_bbase)
|
||||
goto found;
|
||||
|
||||
if(dirp->dd_fd < 0)
|
||||
p__seekvdir(dirp->dd_fd,lp->loc_seek);
|
||||
else
|
||||
(void) lseek(dirp->dd_fd, lp->loc_seek, 0);
|
||||
|
||||
dirp->dd_bbase = lp->loc_seek;
|
||||
dirp->dd_loc = 0;
|
||||
while (dirp->dd_loc < lp->loc_loc) {
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*SOLARIS: readdir MT-Unsafe */
|
||||
dp = readdir(dirp);
|
||||
if (dp == NULL)
|
||||
break;
|
||||
}
|
||||
found:
|
||||
#ifdef SINGLEUSE
|
||||
*prevlp = lp->loc_next;
|
||||
free((caddr_t)lp);
|
||||
#endif
|
||||
}
|
||||
|
||||
1
prospero/lib/pfs/.gitignore
vendored
Normal file
1
prospero/lib/pfs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
117
prospero/lib/pfs/FILES
Normal file
117
prospero/lib/pfs/FILES
Normal file
@@ -0,0 +1,117 @@
|
||||
FILES
|
||||
Makefile
|
||||
acalloc.c
|
||||
acltypes.c
|
||||
add_vlink.c
|
||||
asntotime.c
|
||||
atalloc.c
|
||||
atr_build.c
|
||||
atr_lookup.c
|
||||
bindecode.c
|
||||
binencode.c
|
||||
charset.h
|
||||
cl_qoprintf.c
|
||||
copyfile.c
|
||||
del_vlink.c
|
||||
elt.c
|
||||
equal_atrs.c
|
||||
equal_seq.c
|
||||
filetoin.c
|
||||
fl_insert.c
|
||||
flalloc.c
|
||||
fputbst.c
|
||||
get_acl.c
|
||||
in_acl.c
|
||||
in_atrs.c
|
||||
in_filter.c
|
||||
in_forwarded.c
|
||||
in_id.c
|
||||
in_line.c
|
||||
in_link.c
|
||||
in_nextline.c
|
||||
in_readc.c
|
||||
in_select.c
|
||||
in_sequence.c
|
||||
internal_err.c
|
||||
is_file.c
|
||||
length.c
|
||||
mapname.c
|
||||
mk_vdir.c
|
||||
mkdirs.c
|
||||
modify_acl.c
|
||||
month_sname.c
|
||||
myhost.c
|
||||
oballoc.c
|
||||
obother.c
|
||||
opentcp.c
|
||||
out_acl.c
|
||||
out_atr.c
|
||||
out_atrs.c
|
||||
out_filter.c
|
||||
out_link.c
|
||||
out_sequence.c
|
||||
p__qbstokenize.c
|
||||
p__qbstscanf.c
|
||||
p__req.c
|
||||
p_get_dir.c
|
||||
p_initialize.c
|
||||
p_uln_index.c
|
||||
paalloc.c
|
||||
penviron.c
|
||||
perrmesg.c
|
||||
pfalloc.c
|
||||
pfs_debug.c
|
||||
pfs_enable.c
|
||||
pfs_fopen.c
|
||||
pfs_mutexes.c
|
||||
pfs_open.c
|
||||
pget_am.c
|
||||
pget_at.c
|
||||
pmap_cache.c
|
||||
pmap_nfs.c
|
||||
pset_at.c
|
||||
pset_linkat.c
|
||||
qbstp_stcopyr.c
|
||||
qfprintf.c
|
||||
qindex.c
|
||||
qoprintf.c
|
||||
qrindex.c
|
||||
qscanf.c
|
||||
qsp_stcopyr.c
|
||||
qsprintf.c
|
||||
qsscanf.c
|
||||
qtokenize.c
|
||||
rd_vdir.c
|
||||
rd_vlink.c
|
||||
re_comp_exec.c
|
||||
readheader.c
|
||||
scan_error.c
|
||||
sindex.c
|
||||
slashpath.c
|
||||
slashpath2.c
|
||||
socket.c
|
||||
stat.c
|
||||
stcopy.c
|
||||
stequal.c
|
||||
strccmp.c
|
||||
strpbrk.c
|
||||
strspn.c
|
||||
timetoasn.c
|
||||
tkalloc.c
|
||||
tklistcmp.c
|
||||
tokeniz_mcmp.c
|
||||
ucase.c
|
||||
ul_insert.c
|
||||
unquote.c
|
||||
update_link.c
|
||||
vfsetenv.c
|
||||
vl_add_atrs.c
|
||||
vl_comp.c
|
||||
vl_delete.c
|
||||
vl_insert.c
|
||||
vlalloc.c
|
||||
vqfprintf.c
|
||||
vqscanf.c
|
||||
vqsprintf.c
|
||||
wcmatch.c
|
||||
wholefiltoin.c
|
||||
933
prospero/lib/pfs/Makefile.in
Executable file
933
prospero/lib/pfs/Makefile.in
Executable file
@@ -0,0 +1,933 @@
|
||||
#
|
||||
# Makefile for Prospero Directory Service PFS library.
|
||||
SOURCEBASE = ../..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
CFILES = \
|
||||
acalloc.c \
|
||||
acltypes.c \
|
||||
add_vlink.c \
|
||||
asntotime.c \
|
||||
atalloc.c \
|
||||
atr_build.c \
|
||||
atr_lookup.c \
|
||||
bindecode.c \
|
||||
binencode.c \
|
||||
cl_qoprintf.c \
|
||||
copyfile.c \
|
||||
del_vlink.c \
|
||||
elt.c \
|
||||
equal_atrs.c \
|
||||
equal_seq.c \
|
||||
filetoin.c \
|
||||
flalloc.c \
|
||||
fl_insert.c \
|
||||
fputbst.c \
|
||||
get_acl.c \
|
||||
in_acl.c \
|
||||
in_atrs.c \
|
||||
in_filter.c \
|
||||
in_forwarded.c \
|
||||
in_id.c \
|
||||
in_line.c \
|
||||
in_link.c \
|
||||
in_nextline.c \
|
||||
in_readc.c \
|
||||
in_select.c \
|
||||
in_sequence.c \
|
||||
internal_err.c \
|
||||
is_file.c \
|
||||
length.c \
|
||||
mapname.c \
|
||||
mk_vdir.c \
|
||||
mkdirs.c \
|
||||
month_sname.c \
|
||||
modify_acl.c \
|
||||
myhost.c \
|
||||
oballoc.c \
|
||||
obother.c \
|
||||
opentcp.c \
|
||||
out_acl.c \
|
||||
out_atr.c \
|
||||
out_atrs.c \
|
||||
out_filter.c \
|
||||
out_link.c \
|
||||
out_sequence.c \
|
||||
p__qbstokenize.c \
|
||||
p__qbstscanf.c \
|
||||
p__req.c \
|
||||
p_get_dir.c \
|
||||
p_initialize.c \
|
||||
p_uln_index.c \
|
||||
paalloc.c \
|
||||
penviron.c \
|
||||
perrmesg.c \
|
||||
pfalloc.c \
|
||||
pfs_debug.c \
|
||||
pfs_enable.c \
|
||||
pfs_fopen.c \
|
||||
pfs_mutexes.c \
|
||||
pfs_open.c \
|
||||
pget_am.c \
|
||||
pget_at.c \
|
||||
pmap_cache.c \
|
||||
pmap_nfs.c \
|
||||
pset_at.c \
|
||||
pset_linkat.c \
|
||||
qbstp_stcopyr.c \
|
||||
qfprintf.c \
|
||||
qindex.c \
|
||||
qoprintf.c \
|
||||
qrindex.c \
|
||||
qscanf.c \
|
||||
qsp_stcopyr.c \
|
||||
qsprintf.c \
|
||||
qsscanf.c \
|
||||
qtokenize.c \
|
||||
rd_vdir.c \
|
||||
rd_vlink.c \
|
||||
re_comp_exec.c \
|
||||
readheader.c \
|
||||
scan_error.c \
|
||||
sindex.c \
|
||||
slashpath.c \
|
||||
slashpath2.c \
|
||||
socket.c \
|
||||
stat.c \
|
||||
stcopy.c \
|
||||
stequal.c \
|
||||
strccmp.c \
|
||||
strpbrk.c \
|
||||
strspn.c \
|
||||
timetoasn.c \
|
||||
tkalloc.c \
|
||||
tokeniz_mcmp.c \
|
||||
ucase.c \
|
||||
ul_insert.c \
|
||||
unquote.c \
|
||||
update_link.c \
|
||||
vfsetenv.c \
|
||||
vl_add_atrs.c \
|
||||
vqfprintf.c \
|
||||
vqscanf.c \
|
||||
vqsprintf.c \
|
||||
vl_comp.c \
|
||||
vl_delete.c \
|
||||
vl_insert.c \
|
||||
vlalloc.c \
|
||||
wcmatch.c \
|
||||
wholefiltoin.c
|
||||
|
||||
OBJECTS = \
|
||||
acalloc.o \
|
||||
acltypes.o \
|
||||
add_vlink.o \
|
||||
asntotime.o \
|
||||
atalloc.o \
|
||||
atr_build.o \
|
||||
atr_lookup.o \
|
||||
bindecode.o \
|
||||
binencode.o \
|
||||
cl_qoprintf.o \
|
||||
copyfile.o \
|
||||
del_vlink.o \
|
||||
elt.o \
|
||||
equal_atrs.o \
|
||||
equal_seq.o \
|
||||
filetoin.o \
|
||||
flalloc.o \
|
||||
fl_insert.o \
|
||||
fputbst.o \
|
||||
get_acl.o \
|
||||
in_acl.o \
|
||||
in_atrs.o \
|
||||
in_filter.o \
|
||||
in_forwarded.o \
|
||||
in_id.o \
|
||||
in_line.o \
|
||||
in_link.o \
|
||||
in_nextline.o \
|
||||
in_readc.o \
|
||||
in_sequence.o \
|
||||
in_select.o \
|
||||
internal_err.o \
|
||||
is_file.o \
|
||||
length.o \
|
||||
mapname.o \
|
||||
mk_vdir.o \
|
||||
mkdirs.o \
|
||||
month_sname.o \
|
||||
modify_acl.o \
|
||||
myhost.o \
|
||||
oballoc.o \
|
||||
obother.o \
|
||||
opentcp.o \
|
||||
out_acl.o \
|
||||
out_atr.o \
|
||||
out_atrs.o \
|
||||
out_filter.o \
|
||||
out_link.o \
|
||||
out_sequence.o \
|
||||
p__qbstokenize.o \
|
||||
p__qbstscanf.o \
|
||||
p__req.o \
|
||||
p_get_dir.o \
|
||||
p_initialize.o \
|
||||
p_uln_index.o \
|
||||
paalloc.o \
|
||||
penviron.o \
|
||||
perrmesg.o \
|
||||
pfalloc.o \
|
||||
pfs_debug.o \
|
||||
pfs_enable.o \
|
||||
pfs_fopen.o \
|
||||
pfs_mutexes.o \
|
||||
pfs_open.o \
|
||||
pget_am.o \
|
||||
pget_at.o \
|
||||
pmap_cache.o \
|
||||
pmap_nfs.o \
|
||||
pset_at.o \
|
||||
pset_linkat.o \
|
||||
qbstp_stcopyr.o \
|
||||
qfprintf.o \
|
||||
qindex.o \
|
||||
qoprintf.o \
|
||||
qrindex.o \
|
||||
qscanf.o \
|
||||
qsp_stcopyr.o \
|
||||
qsprintf.o \
|
||||
qsscanf.o \
|
||||
qtokenize.o \
|
||||
rd_vdir.o \
|
||||
rd_vlink.o \
|
||||
re_comp_exec.o \
|
||||
readheader.o \
|
||||
scan_error.o \
|
||||
sindex.o \
|
||||
slashpath.o \
|
||||
slashpath2.o \
|
||||
socket.o \
|
||||
stat.o \
|
||||
stcopy.o \
|
||||
stequal.o \
|
||||
strccmp.o \
|
||||
strpbrk.o \
|
||||
strspn.o \
|
||||
timetoasn.o \
|
||||
tkalloc.o \
|
||||
tokeniz_mcmp.o \
|
||||
ucase.o \
|
||||
ul_insert.o \
|
||||
unquote.o \
|
||||
update_link.o \
|
||||
vfsetenv.o \
|
||||
vl_add_atrs.o \
|
||||
vqfprintf.o \
|
||||
vqscanf.o \
|
||||
vqsprintf.o \
|
||||
vl_comp.o \
|
||||
vl_delete.o \
|
||||
vl_insert.o \
|
||||
vlalloc.o \
|
||||
wcmatch.o \
|
||||
wholefiltoin.o
|
||||
|
||||
all: ${PFS_LIB}
|
||||
|
||||
SPECIAL_OTHERTARGETS = $(PFS_LIB)
|
||||
|
||||
install:
|
||||
# We currently don't install this library
|
||||
# cp ${PFS_LIB} ${P_BINARIES}/${PFS_LIB}
|
||||
# $(RANLIB) ${P_BINARIES}/${PFS_LIB}
|
||||
|
||||
${PFS_LIB}: ${OBJECTS}
|
||||
rm -f ${PFS_LIB}
|
||||
ar r${AR_FLAGS} ${PFS_LIB} ${OBJECTS}
|
||||
$(RANLIB) ${PFS_LIB}
|
||||
|
||||
## This will cuse there to be too many dependencies for TAGS and ETAGS
|
||||
## include $(SOURCEBASE)/Makefile.boilerplate
|
||||
|
||||
# Dependencies
|
||||
acalloc.o : ../../include/pmachine.h \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h
|
||||
acltypes.o :
|
||||
add_vlink.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pprot.h \
|
||||
../../include/pparse.h \
|
||||
../../include/perrno.h
|
||||
asntotime.o :
|
||||
atalloc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
atr_build.o : ../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
atr_lookup.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pprot.h ../../include/pparse.h
|
||||
bindecode.o :
|
||||
binencode.o :
|
||||
cl_qoprintf.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pparse.h
|
||||
copyfile.o : ../../include/perrno.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
del_vlink.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pprot.h ../../include/pparse.h \
|
||||
../../include/perrno.h
|
||||
elt.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
equal_atrs.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
equal_seq.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
filetoin.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
flalloc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
fl_insert.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
fputbst.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
get_acl.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
in_acl.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
in_atrs.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/perrno.h ../../include/pprot.h
|
||||
in_filter.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
in_forwarded.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
in_id.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h ../../include/pparse.h \
|
||||
../../include/pprot.h
|
||||
in_line.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/perrno.h
|
||||
in_link.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
in_nextline.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pparse.h
|
||||
in_readc.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pparse.h
|
||||
in_select.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h ../../include/pparse.h \
|
||||
../../include/pprot.h
|
||||
in_sequence.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
internal_err.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
is_file.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
length.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
mapname.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/psite.h ../../include/pcompat.h \
|
||||
../../include/perrno.h
|
||||
mk_vdir.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pprot.h ../../include/perrno.h ../../include/pparse.h
|
||||
mkdirs.o : \
|
||||
../../include/pmachine.h \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h
|
||||
month_sname.o :
|
||||
modify_acl.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pprot.h ../../include/perrno.h ../../include/pparse.h
|
||||
myhost.o : ../../include/pcompat.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h
|
||||
oballoc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
obother.o : ../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
opentcp.o : \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h ../../include/sockettime.h
|
||||
out_acl.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
out_atr.o : ../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h
|
||||
out_atrs.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
out_filter.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
out_link.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
out_sequence.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h
|
||||
p__qbstokenize.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
p__qbstscanf.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
p__req.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/psite.h ../../include/pprot.h ../../include/perrno.h \
|
||||
../../include/pcompat.h
|
||||
p_get_dir.o : \
|
||||
../../include/pprot.h \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/perrno.h ../../include/pparse.h
|
||||
p_initialize.o : ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h ../../include/pcompat.h
|
||||
p_uln_index.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
paalloc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
penviron.o : \
|
||||
../../include/pcompat.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/psite.h ../../include/perrno.h
|
||||
perrmesg.o : ../../include/perrno.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h
|
||||
pfalloc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
pfs_debug.o :
|
||||
pfs_enable.o : ../../include/pcompat.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/pmachine.h
|
||||
pfs_fopen.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h \
|
||||
../../include/perrno.h
|
||||
pfs_mutexes.o : ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
pfs_open.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h \
|
||||
../../include/perrno.h
|
||||
pget_am.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
pget_at.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pprot.h ../../include/perrno.h ../../include/pparse.h
|
||||
pmap_cache.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pcompat.h \
|
||||
../../include/psite.h ../../include/perrno.h ../../include/mitra_macros.h
|
||||
pmap_nfs.o : ../../include/psite.h
|
||||
pset_at.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pparse.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
pset_linkat.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pparse.h \
|
||||
../../include/perrno.h
|
||||
qbstp_stcopyr.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
qfprintf.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pprot.h
|
||||
qindex.o : ../../include/pfs.h ../../include/pfs_utils.h \
|
||||
../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
qoprintf.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
qrindex.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
qscanf.o : ../../include/pparse.h \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
qsp_stcopyr.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
qsprintf.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
qsscanf.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h
|
||||
qtokenize.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pprot.h
|
||||
rd_vdir.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
rd_vlink.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
re_comp_exec.o : ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h
|
||||
readheader.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
scan_error.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
sindex.o : \
|
||||
../../include/pmachine.h \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/implicit_fixes.h
|
||||
slashpath.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
slashpath2.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
socket.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h ../../include/posix_signal.h \
|
||||
../../include/sockettime.h
|
||||
stat.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
stcopy.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h ../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h \
|
||||
../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h
|
||||
stequal.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
strccmp.o :
|
||||
strpbrk.o :
|
||||
strspn.o :
|
||||
timetoasn.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
tkalloc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/mitra_macros.h
|
||||
tokeniz_mcmp.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pprot.h
|
||||
ucase.o :
|
||||
ul_insert.o : \
|
||||
../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
unquote.o : \
|
||||
../../include/pfs_threads.h ../../include/pfs_utils.h
|
||||
update_link.o : \
|
||||
../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h ../../include/../lib/ardp/flocks.h ../../include/pfs.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
vfsetenv.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/psite.h ../../include/perrno.h
|
||||
vl_add_atrs.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/perrno.h
|
||||
vqfprintf.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pprot.h ../../include/perrno.h
|
||||
vqscanf.o : \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h ../../include/pfs.h ../../include/ardp.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
charset.h
|
||||
vqsprintf.o : ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/pfs_utils.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/pfs.h ../../include/pmachine.h \
|
||||
../../include/implicit_fixes.h \
|
||||
charset.h
|
||||
vl_comp.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h
|
||||
vl_delete.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
vl_insert.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/perrno.h
|
||||
vlalloc.o : \
|
||||
../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/mitra_macros.h
|
||||
wcmatch.o : \
|
||||
../../include/pmachine.h
|
||||
wholefiltoin.o : ../../include/pfs.h \
|
||||
../../include/pfs_utils.h ../../include/ardp.h \
|
||||
../../include/pfs_threads.h \
|
||||
../../include/list_macros.h \
|
||||
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
|
||||
../../include/pmachine.h \
|
||||
../../include/pparse.h \
|
||||
../../include/perrno.h
|
||||
149
prospero/lib/pfs/acalloc.c
Normal file
149
prospero/lib/pfs/acalloc.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994 by the University of Southern California
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
/* Munged by swa to handle multiple principals. */
|
||||
|
||||
#include <pmachine.h>
|
||||
#ifdef SOLARIS /* don't know why this was included. */
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <usc-license.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For malloc */
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
static ACL aclflist = NULL;
|
||||
int acl_count = 0;
|
||||
int acl_max = 0;
|
||||
|
||||
/*
|
||||
* acalloc - allocate and initialize access control list structure
|
||||
*
|
||||
* ACALLOC returns a pointer to an initialized structure of type
|
||||
* ACL. If it is unable to allocate such a structure, it
|
||||
* returns NULL.
|
||||
*/
|
||||
ACL
|
||||
acalloc()
|
||||
{
|
||||
ACL acl_ent;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexACALLOC);
|
||||
if(aclflist) {
|
||||
acl_ent = aclflist;
|
||||
aclflist = aclflist->next;
|
||||
}
|
||||
else {
|
||||
acl_ent = (ACL) malloc(sizeof(ACL_ST));
|
||||
if (!acl_ent) out_of_memory();
|
||||
acl_max++;
|
||||
}
|
||||
|
||||
acl_count++;
|
||||
p_th_mutex_unlock(p_th_mutexACALLOC);
|
||||
|
||||
/* Initialize and fill in default values */
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
acl_ent->consistency = INUSE_PATTERN;
|
||||
#endif
|
||||
acl_ent->acetype = 0;
|
||||
acl_ent->atype = NULL;
|
||||
acl_ent->rights = NULL;
|
||||
acl_ent->principals = NULL;
|
||||
acl_ent->restrictions = NULL;
|
||||
acl_ent->app.ptr = NULL; /* On every architecture I ever heard of,
|
||||
acl_ent->app.flg is now 0 too */
|
||||
acl_ent->previous = NULL;
|
||||
acl_ent->next = NULL;
|
||||
return(acl_ent);
|
||||
}
|
||||
|
||||
static void (*acappfreefunc)(ACL) = NULL;
|
||||
|
||||
/*
|
||||
* Specify which special freeing function (if any) to be used to free the
|
||||
* app.ptr member of the ACL structure, if set.
|
||||
*/
|
||||
void
|
||||
acappfree(void (* appfreefunc)(ACL))
|
||||
{
|
||||
acappfreefunc = appfreefunc;
|
||||
}
|
||||
|
||||
/*
|
||||
* acfree - free an ACL structure
|
||||
*
|
||||
* ACFREE takes a pointer to an ACL structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
acfree(acl_ent)
|
||||
ACL acl_ent;
|
||||
{
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(acl_ent->consistency == INUSE_PATTERN);
|
||||
acl_ent->consistency = FREE_PATTERN;
|
||||
#endif
|
||||
acl_ent->acetype = 0;
|
||||
if(acl_ent->atype) stfree(acl_ent->atype);
|
||||
if(acl_ent->rights) stfree(acl_ent->rights);
|
||||
if(acl_ent->principals) {
|
||||
tklfree(acl_ent->principals);
|
||||
acl_ent->principals = NULL;
|
||||
}
|
||||
/* If acl_ent->restrictions, error since not yet implemented */
|
||||
assert(!acl_ent->restrictions);
|
||||
if(acappfreefunc && acl_ent->app.ptr) {
|
||||
(*acappfreefunc)(acl_ent->app.ptr); acl_ent->app.ptr = NULL;
|
||||
}
|
||||
p_th_mutex_lock(p_th_mutexACALLOC);
|
||||
acl_ent->next = aclflist;
|
||||
if(aclflist) aclflist->previous = acl_ent;
|
||||
acl_ent->previous = NULL;
|
||||
aclflist = acl_ent;
|
||||
acl_count--;
|
||||
p_th_mutex_unlock(p_th_mutexACALLOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* aclfree - free an ACL structure
|
||||
*
|
||||
* ACLFREE takes a pointer to an ACL structure frees it and any linked
|
||||
* ACL structures. It is used to free an entrie list of ACL
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
aclfree(acl_ent)
|
||||
ACL acl_ent;
|
||||
{
|
||||
ACL nxt;
|
||||
|
||||
while(acl_ent != NULL) {
|
||||
nxt = acl_ent->next;
|
||||
acfree(acl_ent);
|
||||
acl_ent = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ACL
|
||||
aclcopy(ACL acl)
|
||||
{
|
||||
ACL retval = NULL;
|
||||
for ( ;acl ; acl = acl->next) {
|
||||
ACL new = acalloc();
|
||||
new->acetype = acl->acetype;
|
||||
if(acl->atype) new->atype = stcopyr(acl->atype,new->atype);
|
||||
if(acl->rights) new->rights = stcopyr(acl->rights,new->rights);
|
||||
if(acl->principals) new->principals = tkcopy(acl->principals);
|
||||
/* If struct restrict ever used, will need to copy that too. */
|
||||
assert(!acl->restrictions);
|
||||
APPEND_ITEM(new, retval);
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
32
prospero/lib/pfs/acltypes.c
Normal file
32
prospero/lib/pfs/acltypes.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 1991 by the University of Washington
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#define NULL 0
|
||||
|
||||
char *acltypes[] = {
|
||||
/* 0 */ "UNINITIALIZED ACL -- You should never see this message.",
|
||||
/* 1 */ "NONE",
|
||||
/* 2 */ "DEFAULT",
|
||||
/* 3 */ "SYSTEM",
|
||||
/* 4 */ "OWNER",
|
||||
/* 5 */ "DIRECTORY",
|
||||
/* 6 */ "CONTAINER",
|
||||
/* 7 */ "ANY",
|
||||
/* 8 */ "AUTHENT",
|
||||
/* 9 */ "LGROUP",
|
||||
/* 10 */ "GROUP",
|
||||
/* 11 */ "ASRTHOST",
|
||||
/* 12 */ "TRSTHOST",
|
||||
/* 13 */ "IETF-AAC",
|
||||
/* 14 */ "SUBSCRIPTION",
|
||||
/* 15 */ "DEFCONT ACL -- You should never see this message.",
|
||||
/* 16 */ NULL};
|
||||
|
||||
163
prospero/lib/pfs/add_vlink.c
Normal file
163
prospero/lib/pfs/add_vlink.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h> /* declare fprintf() */
|
||||
#include <string.h> /* SOLARIS doesnt have strings.h */
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
#include <pparse.h>
|
||||
#include <perrno.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
/*
|
||||
*/
|
||||
int
|
||||
add_vlink(
|
||||
const char *direct, /* Virtual name for the directory */
|
||||
const char *lname, /* Name of the new link */
|
||||
VLINK l, /* Link to be inserted */
|
||||
int flags) /* Options for link to add */
|
||||
{
|
||||
VLINK dlink; /* Link to remote directory. This points to
|
||||
memory in the DIR structure; it is
|
||||
freed when we call vdir_freelinks(dir). */
|
||||
VDIR_ST dir_st;
|
||||
VDIR dir = &dir_st;
|
||||
|
||||
RREQ req; /* Text of request to dir server. Free before
|
||||
return. */
|
||||
|
||||
int fwdcnt = MAX_FWD_DEPTH;
|
||||
OUTPUT_ST out_st;
|
||||
OUTPUT out = &out_st;
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
PATTRIB ca; /* current attribute */
|
||||
|
||||
int tmp;
|
||||
|
||||
vdir_init(dir);
|
||||
|
||||
/* If magic number has been modified, set it back to 0 */
|
||||
if(l->f_magic_no < 0) l->f_magic_no = 0;
|
||||
|
||||
/* We must first find the directory into which the link */
|
||||
/* will be inserted */
|
||||
|
||||
tmp = rd_vdir(direct,0,dir,RVD_ATTRIB|RVD_DFILE_ONLY);
|
||||
if (tmp || (dir->links == NULL)) {
|
||||
vdir_freelinks(dir);
|
||||
return(DIRSRV_NOT_DIRECTORY);
|
||||
}
|
||||
dlink = dir->links;
|
||||
|
||||
startover:
|
||||
|
||||
req = p__start_req(dlink->host);
|
||||
requesttoout(req, out);
|
||||
p__add_req(req,
|
||||
"DIRECTORY ASCII %'s\nCREATE-LINK '' %c %'s %'s %s %'s %s %'s %d",
|
||||
dlink->hsoname, ((flags & AVL_INVISIBLE) ? 'I' :
|
||||
((flags& AVL_UNION) ? 'U' : 'L')),
|
||||
l->target, lname, l->hosttype,l->host,
|
||||
l->hsonametype, l->hsoname,l->version);
|
||||
if (l->dest_exp) {
|
||||
char *cp = NULL;
|
||||
p__add_req(req, " DEST-EXP %s",
|
||||
cp = p_timetoasn_stcopyr(l->dest_exp, cp));
|
||||
stfree(cp);
|
||||
}
|
||||
p__add_req(req, "\n");
|
||||
if (l->f_magic_no) p__add_req(req, "ID REMOTE %d\n", l->f_magic_no);
|
||||
for (ca = l->lattrib; ca; ca = ca->next) {
|
||||
/* Convert attributes of OBJECT precedence to CACHED precedence. */
|
||||
/* Don't leave the link modified that we passed to this function. */
|
||||
if (ca->precedence == ATR_PREC_OBJECT) {
|
||||
ca->precedence = ATR_PREC_CACHED;
|
||||
out_atr(out, ca, 0);
|
||||
ca->precedence = ATR_PREC_OBJECT;
|
||||
} else {
|
||||
out_atr(out, ca, 0);
|
||||
}
|
||||
}
|
||||
|
||||
tmp = ardp_send(req,dlink->host,0,ARDP_WAIT_TILL_TO);
|
||||
|
||||
if(pfs_debug && tmp) {
|
||||
fprintf(stderr,"Dirsend failed: %d\n",tmp);
|
||||
}
|
||||
|
||||
if(req->rcvd == NOPKT) {
|
||||
ardp_rqfree(req);
|
||||
vdir_freelinks(dir);
|
||||
return(perrno);
|
||||
}
|
||||
/* Here we must parse reponse - While looking at each packet */
|
||||
rreqtoin(req, in);
|
||||
while(!in_eof(in)) {
|
||||
char *line;
|
||||
char *next_word;
|
||||
|
||||
if (tmp = in_line(in, &line, &next_word)) {
|
||||
ardp_rqfree(req);
|
||||
vdir_freelinks(dir);
|
||||
return(tmp);
|
||||
}
|
||||
switch (*line) {
|
||||
|
||||
case 'F': /* FAILURE or FORWARDED */
|
||||
/* FORWARDED */
|
||||
if(strncmp(line,"FORWARDED",9) == 0) {
|
||||
if(fwdcnt-- <= 0) {
|
||||
ardp_rqfree(req);
|
||||
vdir_freelinks(dir);
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
return(perrno);
|
||||
}
|
||||
/* parse and start over */
|
||||
tmp = qsscanf(line,"FORWARDED %*s %'&s %*s %'&s %*d %*d",
|
||||
&dlink->host, &dlink->hsoname);
|
||||
|
||||
if(tmp < 2) {
|
||||
ardp_rqfree(req);
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
ardp_rqfree(req);
|
||||
goto startover;
|
||||
}
|
||||
/* If FAILURE or anything else scan error */
|
||||
goto scanerr;
|
||||
|
||||
case 'S': /* SUCCESS */
|
||||
if(strncmp(line,"SUCCESS",7) == 0) {
|
||||
ardp_rqfree(req);
|
||||
vdir_freelinks(dir);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
goto scanerr;
|
||||
|
||||
scanerr:
|
||||
default:
|
||||
if(*line && (tmp = scan_error(line, req))) {
|
||||
ardp_rqfree(req);
|
||||
vdir_freelinks(dir);
|
||||
return(tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
ardp_rqfree(req);
|
||||
vdir_freelinks(dir);
|
||||
return(perrno);
|
||||
}
|
||||
47
prospero/lib/pfs/asntotime.c
Normal file
47
prospero/lib/pfs/asntotime.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1991 by the University of Washington
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <time.h>
|
||||
|
||||
static month_start[12] = {0, 31, 59, 90, 120, 151,
|
||||
181, 212, 243, 273, 304, 334};
|
||||
|
||||
time_t
|
||||
asntotime(timestring)
|
||||
char *timestring;
|
||||
{
|
||||
int tmp;
|
||||
struct tm ts;
|
||||
long seconds;
|
||||
int numleap;
|
||||
|
||||
tmp = sscanf(timestring,"%4d%2d%2d%2d%2d%2d", &(ts.tm_year),
|
||||
&(ts.tm_mon), &(ts.tm_mday), &(ts.tm_hour), &(ts.tm_min),
|
||||
&(ts.tm_sec));
|
||||
if(tmp != 6) return(0);
|
||||
|
||||
ts.tm_mon = ts.tm_mon - 1;
|
||||
ts.tm_year = ts.tm_year - 1900;
|
||||
|
||||
/* The following may not be portable */
|
||||
seconds = (ts.tm_year - 70) * 365 * 24 * 60 * 60;
|
||||
seconds = seconds + (month_start[ts.tm_mon] * 24 * 60 * 60);
|
||||
seconds = seconds + (ts.tm_mday * 24 * 60 * 60);
|
||||
seconds = seconds + (ts.tm_hour * 60 * 60);
|
||||
seconds = seconds + (ts.tm_min * 60);
|
||||
seconds = seconds + ts.tm_sec;
|
||||
|
||||
/* Account for leap years (good until 2100) */
|
||||
numleap = ts.tm_year - 72;
|
||||
numleap = numleap / 4;
|
||||
if((ts.tm_mon > 1) && ((ts.tm_year % 4) == 0)) numleap++;
|
||||
seconds = seconds + (numleap * 24 * 60 * 60);
|
||||
|
||||
return(seconds);
|
||||
}
|
||||
207
prospero/lib/pfs/atalloc.c
Normal file
207
prospero/lib/pfs/atalloc.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
static PATTRIB lfree = NULL;
|
||||
int pattrib_count = 0;
|
||||
int pattrib_max = 0;
|
||||
|
||||
/*
|
||||
* atalloc - allocate and initialize vlink structure
|
||||
*
|
||||
* ATALLOC returns a pointer to an initialized structure of type
|
||||
* PATTRIB. If it is unable to allocate such a structure, it
|
||||
* returns NULL.
|
||||
*/
|
||||
PATTRIB
|
||||
atalloc(void)
|
||||
{
|
||||
PATTRIB at;
|
||||
p_th_mutex_lock(p_th_mutexATALLOC);
|
||||
if(lfree) {
|
||||
at = lfree;
|
||||
lfree = lfree->next;
|
||||
} else {
|
||||
at = (PATTRIB) malloc(sizeof(PATTRIB_ST));
|
||||
if (!at) out_of_memory();
|
||||
pattrib_max++;
|
||||
}
|
||||
|
||||
pattrib_count++;
|
||||
p_th_mutex_unlock(p_th_mutexATALLOC);
|
||||
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
at->consistency = INUSE_PATTERN;
|
||||
#endif
|
||||
/* Initialize and fill in default values */
|
||||
at->precedence = ATR_PREC_OBJECT;
|
||||
at->nature = ATR_NATURE_UNKNOWN;
|
||||
at->avtype = ATR_UNKNOWN;
|
||||
at->aname = NULL;
|
||||
at->value.sequence = NULL;
|
||||
at->app.ptr = NULL; /* On every architecture I ever heard of,
|
||||
at->app.flg is now 0 too */
|
||||
at->previous = NULL;
|
||||
at->next = NULL;
|
||||
return(at);
|
||||
}
|
||||
|
||||
static void (*atappfreefunc)(PATTRIB) = NULL;
|
||||
|
||||
/*
|
||||
* Specify which special freeing function (if any) to be used to free the
|
||||
* app.ptr member of the PATTRIB structure, if set.
|
||||
*/
|
||||
void
|
||||
atappfree(void (* appfreefunc)(PATTRIB))
|
||||
{
|
||||
atappfreefunc = appfreefunc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* atfree - free a PATTRIB structure
|
||||
*
|
||||
* ATFREE takes a pointer to a PATTRRIB structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
atfree(PATTRIB at)
|
||||
{
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(at->consistency == INUSE_PATTERN);
|
||||
at->consistency = FREE_PATTERN;
|
||||
#endif
|
||||
if(at->aname) stfree(at->aname);
|
||||
|
||||
switch(at->avtype) {
|
||||
case ATR_UNKNOWN:
|
||||
break;
|
||||
case ATR_SEQUENCE:
|
||||
if (at->value.sequence)
|
||||
tklfree(at->value.sequence);
|
||||
break;
|
||||
case ATR_FILTER:
|
||||
if(at->value.filter)
|
||||
flfree(at->value.filter);
|
||||
break;
|
||||
case ATR_LINK:
|
||||
if (at->value.link)
|
||||
vlfree(at->value.link);
|
||||
break;
|
||||
default:
|
||||
internal_error("Illegal avtype");
|
||||
}
|
||||
|
||||
if(atappfreefunc && at->app.ptr) {
|
||||
(*atappfreefunc)(at->app.ptr); at->app.ptr = NULL;
|
||||
}
|
||||
p_th_mutex_lock(p_th_mutexATALLOC);
|
||||
at->next = lfree;
|
||||
at->previous = NULL;
|
||||
lfree = at;
|
||||
pattrib_count--;
|
||||
p_th_mutex_unlock(p_th_mutexATALLOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* atlfree - free a PATTRIB structure
|
||||
*
|
||||
* ATLFREE takes a pointer to a PATTRIB structure frees it and any linked
|
||||
* PATTRIB structures. It is used to free an entrie list of PATTRIB
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
atlfree(PATTRIB at)
|
||||
{
|
||||
PATTRIB nxt;
|
||||
|
||||
while(at != NULL) {
|
||||
nxt = at->next;
|
||||
atfree(at);
|
||||
at = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PATTRIB
|
||||
atcopy(PATTRIB at)
|
||||
{
|
||||
PATTRIB newat;
|
||||
|
||||
if (!at) return(at); /* Copying NULL gets NULL */
|
||||
/* Of course, many callers wont do anything sensible if returned NULL!*/
|
||||
newat = atalloc();
|
||||
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(at->consistency == INUSE_PATTERN);
|
||||
#endif
|
||||
newat->precedence = at->precedence;
|
||||
newat->nature = at->nature;
|
||||
newat->avtype = at->avtype;
|
||||
newat->aname = stcopyr(at->aname, newat->aname);
|
||||
#ifdef NEVERDEFINED
|
||||
/* WARNING - this typicaly copies a pointer to a token, leaving two pattrib
|
||||
pointing into the same token, free-ing one will leave the other
|
||||
with an invalid (and core-dump-able) pointer - Mitra*/
|
||||
newat->value = at->value;
|
||||
#else
|
||||
switch(at->avtype) {
|
||||
case ATR_UNKNOWN:
|
||||
break;
|
||||
case ATR_SEQUENCE:
|
||||
if (at->value.sequence)
|
||||
newat->value.sequence = tkcopy(at->value.sequence);
|
||||
break;
|
||||
case ATR_FILTER:
|
||||
if(at->value.filter)
|
||||
newat->value.filter = flcopy(at->value.filter,TRUE);
|
||||
break;
|
||||
case ATR_LINK:
|
||||
if (at->value.link)
|
||||
newat->value.link = vlcopy(at->value.link,TRUE);
|
||||
break;
|
||||
default:
|
||||
internal_error("Illegal avtype");
|
||||
}
|
||||
#endif
|
||||
/* leave previous and next unset. */
|
||||
return newat;
|
||||
}
|
||||
|
||||
|
||||
PATTRIB
|
||||
atlcopy(PATTRIB atl)
|
||||
{
|
||||
PATTRIB retval = NULL;
|
||||
|
||||
for ( ; atl; atl = atl->next) {
|
||||
PATTRIB newat = atcopy(atl); /*Note atcopy fixed to copy data */
|
||||
APPEND_ITEM(newat, retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
int
|
||||
at_nlinks(PATTRIB atl)
|
||||
{
|
||||
int i;
|
||||
for (i=0; atl; atl=atl->next) {
|
||||
if (atl->avtype == ATR_LINK)
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif /*NDEBUG*/
|
||||
|
||||
45
prospero/lib/pfs/atr_build.c
Normal file
45
prospero/lib/pfs/atr_build.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Build an attribute
|
||||
|
||||
Author - Mitra
|
||||
|
||||
(Steve - feel free to incorporate as you wish)
|
||||
*/
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
|
||||
/* Build a PATTRIB, with its list of tokens */
|
||||
/* Note convention that calling routing passes last arg as (char *)0 */
|
||||
/* Also note , that passing (char *)1 will force the next argument to
|
||||
be pointed to, rather than copied (which is what tkappend does) */
|
||||
/* Return it - this fills in defaults, caller can override */
|
||||
PATTRIB
|
||||
vatbuild(char *name, va_list ap)
|
||||
{
|
||||
char *s;
|
||||
PATTRIB at = atalloc();
|
||||
|
||||
at->aname = stcopy(name);
|
||||
/* If any of these arent reasonable defaults move up to callers */
|
||||
at->avtype = ATR_SEQUENCE;
|
||||
if (strequal(name, "ACCESS-METHOD"))
|
||||
at->nature = ATR_NATURE_FIELD;
|
||||
else if strequal(name,"CONTENTS")
|
||||
at->nature = ATR_NATURE_INTRINSIC;
|
||||
else
|
||||
at->nature = ATR_NATURE_APPLICATION;
|
||||
at->precedence = ATR_PREC_OBJECT;
|
||||
while(s = va_arg(ap, char *)) {
|
||||
if (s == (char *) 1) {
|
||||
at->value.sequence =
|
||||
tkappend(NULL,at->value.sequence);
|
||||
s = va_arg(ap, char *);
|
||||
at->value.sequence->previous->token = s;
|
||||
} else
|
||||
at->value.sequence =
|
||||
tkappend(s, at->value.sequence);
|
||||
}
|
||||
|
||||
return(at);
|
||||
}
|
||||
|
||||
125
prospero/lib/pfs/atr_lookup.c
Normal file
125
prospero/lib/pfs/atr_lookup.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
/* This file will probably go away after we define REALLY_NEW_FIELD
|
||||
*/
|
||||
#include <usc-copyr.h>
|
||||
|
||||
/* Written by swa@ISI.EDU, Sept. 21--24, 1992 */
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
#include <pparse.h>
|
||||
|
||||
static struct atr_type_by_field_name {
|
||||
char *name;
|
||||
char type;
|
||||
} atr_type_by_field_name[] = {
|
||||
/* Not all fields are defined here yet. */
|
||||
"ACCESS-METHOD", ATR_SEQUENCE,
|
||||
"BASE-TYPE", ATR_SEQUENCE,
|
||||
"CLOSURE", ATR_LINK,
|
||||
"DEST-EXP", ATR_SEQUENCE,
|
||||
"FILTER", ATR_FILTER,
|
||||
"HOST", ATR_SEQUENCE,
|
||||
"HOST-TYPE", ATR_SEQUENCE,
|
||||
"HSONAME", ATR_SEQUENCE,
|
||||
"HSONAME-TYPE", ATR_SEQUENCE,
|
||||
"ID", ATR_SEQUENCE,
|
||||
"LINK-TYPE", ATR_SEQUENCE,
|
||||
"NAME-COMPONENT", ATR_SEQUENCE,
|
||||
"OWNER", ATR_SEQUENCE,
|
||||
"TARGET", ATR_SEQUENCE,
|
||||
"TTL", ATR_SEQUENCE,
|
||||
"VERSION", ATR_SEQUENCE,
|
||||
NULL, ATR_UNKNOWN
|
||||
};
|
||||
|
||||
|
||||
static struct atr_type_by_type_name {
|
||||
char *name;
|
||||
char type;
|
||||
} atr_type_by_type_name[] = {
|
||||
"FILTER", ATR_FILTER,
|
||||
"LINK", ATR_LINK,
|
||||
"SEQUENCE", ATR_SEQUENCE,
|
||||
"ASCII", ATR_SEQUENCE, /* XXX Backwards compatability; will go away
|
||||
soon. */
|
||||
NULL, ATR_UNKNOWN
|
||||
};
|
||||
|
||||
/* used by atr_in. */
|
||||
int
|
||||
lookup_avtype_by_field_name(const char aname[])
|
||||
{
|
||||
struct atr_type_by_field_name *p;
|
||||
for (p = atr_type_by_field_name; p->name; ++p)
|
||||
if (strequal(p->name, aname))
|
||||
return p->type;
|
||||
return ATR_UNKNOWN;
|
||||
}
|
||||
|
||||
/* If you add elements to this table, you will also need to change pfs.h */
|
||||
|
||||
|
||||
int
|
||||
lookup_avtype_by_avtypename(const char t_avtype[])
|
||||
{
|
||||
struct atr_type_by_type_name *p;
|
||||
for (p = atr_type_by_type_name; p->name; ++p)
|
||||
if (strequal(p->name, t_avtype))
|
||||
return p->type;
|
||||
return ATR_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
lookup_avtypename_by_avtype(int avtype)
|
||||
{
|
||||
struct atr_type_by_type_name *p;
|
||||
for (p = atr_type_by_type_name; p->name; ++p)
|
||||
if (p->type == avtype)
|
||||
return p->name;
|
||||
return "UNKNOWN-TYPE-NAME-PLEASE-COMPLAIN-TO-THE-MAINTAINER";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* If you add elements to this table, you will also need to change pfs.h */
|
||||
|
||||
static struct aban {
|
||||
char *name;
|
||||
char precedence;
|
||||
} precedence_by_precedencename[] = {
|
||||
"OBJECT", ATR_PREC_OBJECT,
|
||||
"LINK", ATR_PREC_LINK,
|
||||
"CACHED", ATR_PREC_CACHED,
|
||||
"REPLACEMENT", ATR_PREC_REPLACE,
|
||||
"ADDITIONAL", ATR_PREC_ADD,
|
||||
NULL, ATR_PREC_UNKNOWN
|
||||
};
|
||||
|
||||
int
|
||||
lookup_precedence_by_precedencename(const char t_precedence[])
|
||||
{
|
||||
struct aban *p;
|
||||
for (p = precedence_by_precedencename; p->name; ++p)
|
||||
if (strequal(p->name, t_precedence))
|
||||
return p->precedence;
|
||||
return ATR_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
lookup_precedencename_by_precedence(int precedence)
|
||||
{
|
||||
struct aban *p;
|
||||
for (p = precedence_by_precedencename; p->name; ++p)
|
||||
if (p->precedence == precedence)
|
||||
return p->name;
|
||||
return "UNKNOWN-APPLIES-TO-VALUE-PLEASE-COMPLAIN-TO-THE-MAINTAINER";
|
||||
}
|
||||
81
prospero/lib/pfs/bindecode.c
Normal file
81
prospero/lib/pfs/bindecode.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/* bindecode.c
|
||||
Author: Steven Augart <swa@isi.edu>
|
||||
Written: 8/17/92
|
||||
I am really interested in comments on this code, suggestions for making it
|
||||
faster, and criticism of my style. Please send polite suggestions for
|
||||
improvement to swa@isi.edu.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1992 by the University of Southern California. */
|
||||
/* For copying and distribution information, see the file <usc-copyr.h> */
|
||||
#include <usc-copyr.h>
|
||||
|
||||
/*
|
||||
bindecode() takes a char* (INBUF) that represents a null-terminated string
|
||||
containing a NUL-less representation of binary data, produced by
|
||||
binencode(). bindecode() converts the contents of INBUF to a pure binary
|
||||
representation, and saves it in OUTBUF. OUTBUFSIZE is the size of OUTBUF.
|
||||
|
||||
bindecode() returns the # of characters it wrote to OUTBUF, or the # of
|
||||
characters it would have written if there had been enough room. Note that no
|
||||
terminating NUL is added to the string.
|
||||
|
||||
bindecode() will write partial strings to buffers which are not long enough.
|
||||
This seems to be reasonable behavior to me.
|
||||
To check for error returns, all is OK if bindecode's return value is less
|
||||
than OUTBUFSIZE. Otherwise, you need to either allocate a bigger outbuf, or
|
||||
give up. (This is consistent with the return values for qsprintf() and
|
||||
binencode().)
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stddef.h>
|
||||
|
||||
int
|
||||
bindecode(char *inbuf, char *outbuf, size_t outbufsize)
|
||||
#else
|
||||
int
|
||||
bindecode(inbuf, outbuf, outbufsize)
|
||||
char *inbuf, *outbuf;
|
||||
int outbufsize;
|
||||
#endif
|
||||
{
|
||||
int outcount = 0; /* how many characters did we output? */
|
||||
|
||||
#define rawput(c) do { \
|
||||
++outcount; \
|
||||
if (outbufsize > 0) { \
|
||||
--outbufsize; \
|
||||
*outbuf++ = (c); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
for (; *inbuf; ++inbuf) {
|
||||
if (*inbuf == '\\') {
|
||||
++inbuf;
|
||||
if (*inbuf == '0')
|
||||
rawput('\0');
|
||||
else if (*inbuf == '\\')
|
||||
rawput('\\');
|
||||
else if (*inbuf == 's')
|
||||
rawput(' ');
|
||||
else if (*inbuf == 't')
|
||||
rawput('\t');
|
||||
else if (*inbuf == 'v')
|
||||
rawput('\v');
|
||||
else if (*inbuf == 'f')
|
||||
rawput('\f');
|
||||
else if (*inbuf == 'r')
|
||||
rawput('\r');
|
||||
else if (*inbuf == 'n')
|
||||
rawput('\n');
|
||||
else
|
||||
return -1; /* format error */
|
||||
} else {
|
||||
rawput(*inbuf);
|
||||
}
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
91
prospero/lib/pfs/binencode.c
Normal file
91
prospero/lib/pfs/binencode.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* binencode.c
|
||||
Author: Steven Augart <swa@isi.edu>
|
||||
Written: 8/17/92
|
||||
I am really interested in comments on this code, suggestions for making it
|
||||
faster, and criticism of my style. Please send polite suggestions for
|
||||
improvement to swa@isi.edu.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 1992 by the University of Southern California. */
|
||||
/* For copying and distribution information, see the file <usc-copyr.h> */
|
||||
#include <usc-copyr.h>
|
||||
|
||||
/*
|
||||
binencode() takes a char* (INBUF) and a size count (INBUFSIZE) as its first
|
||||
two arguments. INBUF is assumed to be an array of INBUFSIZE chars containing
|
||||
binary data. binencode() converts the contents of INBUF to a
|
||||
printing-character representation, and saves it in OUTBUF. OUTBUFSIZE is the
|
||||
size of OUTBUF.
|
||||
|
||||
binencode() returns the # of characters it wrote to the string, or the # of
|
||||
characters it would have written if there had been enough room. Its return
|
||||
value INCLUDES the NUL ('\0'). Binencode() takes the SIZE of the buffer it
|
||||
writes to as an argument. This allows us to guard against buffer overflow.
|
||||
binencode() will write partial strings to buffers which are not long enough.
|
||||
This seems to be reasonable behavior to me.
|
||||
To check for error returns, all is OK if binencode's return value is less than
|
||||
OUTBUFSIZE. Otherwise, you need to either allocate a bigger outbuf, or give
|
||||
up. (This is consistent with the return values for qsprintf() and
|
||||
bindecode().)
|
||||
|
||||
This string can be converted back with bindecode().
|
||||
|
||||
This string does NOT need to be quoted using qsprintf and qsscanf; it
|
||||
escapes the NUL, backslash, newline, and horizontal whitespace.
|
||||
*/
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stddef.h>
|
||||
|
||||
int
|
||||
binencode(char *inbuf, size_t inbufsize, char *outbuf, size_t outbufsize)
|
||||
#else
|
||||
int
|
||||
binencode(inbuf, inbufsize, outbuf, outbufsize)
|
||||
char *inbuf, *outbuf;
|
||||
int inbufsize, outbufsize;
|
||||
#endif
|
||||
{
|
||||
int outcount = 0; /* how many characters did we output? */
|
||||
|
||||
#define rawput(c) do { \
|
||||
++outcount; \
|
||||
if (outbufsize > 0) { \
|
||||
--outbufsize; \
|
||||
*outbuf++ = (c); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
for (; inbufsize > 0; ++inbuf, --inbufsize) {
|
||||
if (*inbuf == '\0') {
|
||||
rawput('\\');
|
||||
rawput('0');
|
||||
} else if (*inbuf == '\\') {
|
||||
rawput('\\');
|
||||
rawput('\\');
|
||||
} else if (*inbuf == ' ') {
|
||||
rawput('\\');
|
||||
rawput('s');
|
||||
} else if (*inbuf == '\t') {
|
||||
rawput('\\');
|
||||
rawput('t');
|
||||
} else if (*inbuf == '\v') {
|
||||
rawput('\\');
|
||||
rawput('v');
|
||||
} else if (*inbuf == '\r') {
|
||||
rawput('\\');
|
||||
rawput('r');
|
||||
} else if (*inbuf == '\f') {
|
||||
rawput('\\');
|
||||
rawput('f');
|
||||
} else if (*inbuf == '\n') {
|
||||
rawput('\\');
|
||||
rawput('n');
|
||||
} else {
|
||||
rawput(*inbuf);
|
||||
}
|
||||
}
|
||||
rawput('\0');
|
||||
|
||||
return outcount;
|
||||
}
|
||||
28
prospero/lib/pfs/charset.h
Normal file
28
prospero/lib/pfs/charset.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* charset.h */
|
||||
/* Written by Steven Augart <swa@isi.edu> July, 1992 */
|
||||
/* This implements a simple character set recognizer. */
|
||||
/* It is used by qsprintf.c and qsscanf.c */
|
||||
/* must include limits.h to use this. */
|
||||
#include <limits.h>
|
||||
|
||||
/* These macros define an abstraction for a set of characters where one can add
|
||||
members, remove them, and test for membership. There are several ways in
|
||||
which this might be made more efficient, but I'm tired. */
|
||||
|
||||
#include <string.h> /* This should include a definition of
|
||||
memset(), but the one on our system doesn't
|
||||
have it, so I have to define memset below.
|
||||
*/
|
||||
extern void *memset(void *, int, size_t);
|
||||
|
||||
typedef char charset[UCHAR_MAX + 1]; /* what we'll work on */
|
||||
#define new_full_charset(cs) do { memset((cs), 1, sizeof (cs)); \
|
||||
/* cs['\0'] = 0; */} while (0)
|
||||
#define new_empty_charset(cs) memset((cs), 0, sizeof (cs))
|
||||
#define add_char(cs, c) do { \
|
||||
assert(c != EOF); \
|
||||
((cs)[(unsigned char) (c)] = 1); \
|
||||
} while (0)
|
||||
#define remove_char(cs, c) ((cs)[(unsigned char) (c)] = 0)
|
||||
#define in_charset(cs,c) (((c) != EOF) && (cs)[(unsigned char) (c)])
|
||||
|
||||
31
prospero/lib/pfs/cl_qoprintf.c
Normal file
31
prospero/lib/pfs/cl_qoprintf.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
|
||||
int
|
||||
cl_qoprintf(OUTPUT out, const char fmt[], ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
assert(! out->req && out->request);
|
||||
|
||||
return vp__add_req(out->request, fmt, ap);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
requesttoout(RREQ req, OUTPUT out)
|
||||
{
|
||||
out->request = req;
|
||||
out->req = NULL;
|
||||
out->f = NULL;
|
||||
return PSUCCESS;
|
||||
}
|
||||
79
prospero/lib/pfs/copyfile.c
Normal file
79
prospero/lib/pfs/copyfile.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <errno.h>
|
||||
#include <perrno.h>
|
||||
#include <pfs.h>
|
||||
#include <stdio.h> /* FILE, fopen etc */
|
||||
|
||||
int
|
||||
copyFile(char *source,char *destn)
|
||||
{
|
||||
/* This code is adapted from user/vget:copy_file, but errors are now
|
||||
not put on standard out, and it doesnt use "goto" */
|
||||
char buf[1024];
|
||||
int numread,numwritten;
|
||||
FILE *in, *out;
|
||||
if ((in = fopen(source, "r")) == NULL) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldn't open the file %s for reading. Copy failed.\n",
|
||||
source);
|
||||
RETURNPFAILURE;
|
||||
}
|
||||
if ((out = fopen(destn, "w")) == NULL) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldn't open the file %s for writing. Copy failed.\n",
|
||||
destn);
|
||||
fclose(in);
|
||||
RETURNPFAILURE;
|
||||
}
|
||||
while ((numread = fread(buf, 1, sizeof buf, in)) >0 ) {
|
||||
numwritten = fwrite(buf, 1, numread, out);
|
||||
if (numwritten != numread) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"tried to write %d items to %s; only wrote %d. Copying aborted.\n",
|
||||
numread, destn, numwritten);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
RETURNPFAILURE;
|
||||
}
|
||||
}
|
||||
if (ferror(in)) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Error while reading from %s; copying to %s aborted\n",
|
||||
source, destn);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
RETURNPFAILURE;
|
||||
} else {
|
||||
/* done! */
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return PSUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
renameOrCopyAndDelete(char *source, char *destn)
|
||||
{
|
||||
int retval;
|
||||
if (!(rename(source,destn)))
|
||||
return 0;
|
||||
|
||||
switch (errno) {
|
||||
case EXDEV:
|
||||
if (retval = copyFile(source,destn))
|
||||
return retval; /* Couldnt copy , p_err_string set*/
|
||||
|
||||
if(retval = unlink(source)) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldnt unlink %s: %s",source, unixerrstr());
|
||||
}
|
||||
return(retval); /* success or failure */
|
||||
default: {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldnt rename %s to %s: %s",
|
||||
source,destn, unixerrstr());
|
||||
return -1; /* Failed to rename for another reason*/
|
||||
}
|
||||
}
|
||||
}
|
||||
143
prospero/lib/pfs/del_vlink.c
Normal file
143
prospero/lib/pfs/del_vlink.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990 by the University of Washington
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*
|
||||
* Written by bcn 1989 modified 1989-1992
|
||||
* Modified by swa 1992 to use startreq
|
||||
* Modified by bcn 1/93 to use ardp library
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
#include <pparse.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
int
|
||||
del_vlink(vpath,flags)
|
||||
const char *vpath; /* Name of link to be deleted */
|
||||
int flags; /* Options for directory */
|
||||
{
|
||||
char *dirhst; /* Host of current directory */
|
||||
char *remdir; /* Dir on remote host */
|
||||
|
||||
char *cname = ""; /* Component name */
|
||||
char *pname = ""; /* Parent name */
|
||||
|
||||
char pathcpy[MAX_VPATH];
|
||||
int fwdcnt = MAX_FWD_DEPTH;
|
||||
char fwdhst[MAX_DIR_LINESIZE];
|
||||
char fwdfnm[MAX_DIR_LINESIZE];
|
||||
|
||||
RREQ req; /* Text of request to dir server */
|
||||
|
||||
VDIR_ST dir_st;
|
||||
VDIR dir = &dir_st;
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
|
||||
int tmp;
|
||||
|
||||
vdir_init(dir);
|
||||
|
||||
strcpy(pathcpy,vpath);
|
||||
cname = p_uln_rindex(pathcpy,'/');
|
||||
if(!cname) cname = pathcpy;
|
||||
else {
|
||||
*cname++ = '\0';
|
||||
pname = pathcpy;
|
||||
if(cname == (pname + 1)) pname = "/";
|
||||
}
|
||||
|
||||
/* We must first find the directory from which the link */
|
||||
/* will be deleted */
|
||||
|
||||
tmp = rd_vdir(pname,0,dir,RVD_DFILE_ONLY);
|
||||
if (tmp || (dir->links == NULL)) return(DIRSRV_NOT_DIRECTORY);
|
||||
dirhst = dir->links->host;
|
||||
remdir = dir->links->hsoname;
|
||||
|
||||
startover:
|
||||
|
||||
req = p__start_req(dirhst);
|
||||
p__add_req(req, "DIRECTORY ASCII %'s\nDELETE-LINK '' %'s\n",
|
||||
remdir, cname);
|
||||
|
||||
tmp = ardp_send(req,dirhst,0,ARDP_WAIT_TILL_TO);
|
||||
|
||||
if(pfs_debug && tmp) {
|
||||
fprintf(stderr,"ARDP_send failed: %d\n",tmp);
|
||||
}
|
||||
|
||||
if(req->rcvd == NOPKT) return(perrno);
|
||||
|
||||
/* Here we must parse reponse - While looking at each packet */
|
||||
rreqtoin(req, in);
|
||||
while(!in_eof(in)) {
|
||||
char *line;
|
||||
char *next_word;
|
||||
|
||||
if (tmp = in_line(in, &line, &next_word)) {
|
||||
ardp_rqfree(req);
|
||||
return(tmp);
|
||||
}
|
||||
switch (*line) {
|
||||
|
||||
case 'F': /* FAILURE or FORWARDED */
|
||||
/* FORWARDED */
|
||||
if(strncmp(line,"FORWARDED",9) == 0) {
|
||||
if(fwdcnt-- <= 0) {
|
||||
ardp_rqfree(req);
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
return(perrno);
|
||||
}
|
||||
/* parse and start over */
|
||||
tmp = sscanf(line,"FORWARDED %*s %s %*s %s %*d %*d",
|
||||
fwdhst,fwdfnm);
|
||||
dirhst = stcopy(fwdhst);
|
||||
remdir = stcopy(fwdfnm);
|
||||
|
||||
if(tmp < 2) {
|
||||
ardp_rqfree(req);
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
ardp_rqfree(req);
|
||||
goto startover;
|
||||
}
|
||||
/* If FAILURE or anything else scan error */
|
||||
goto scanerr;
|
||||
|
||||
case 'S': /* SUCCESS */
|
||||
if(strncmp(line,"SUCCESS",7) == 0) {
|
||||
ardp_rqfree(req);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
goto scanerr;
|
||||
|
||||
scanerr:
|
||||
default:
|
||||
if(*line && (tmp = scan_error(line, req))) {
|
||||
ardp_rqfree(req);
|
||||
return(tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
ardp_rqfree(req);
|
||||
return(perrno);
|
||||
}
|
||||
28
prospero/lib/pfs/elt.c
Normal file
28
prospero/lib/pfs/elt.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
/* Author: Steven Augart, swa@isi.edu */
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <stdio.h>
|
||||
#include <pfs.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
/* Return the NTH element of a sequence S. Indexing starts at zero. Works
|
||||
just like the Common LISP ELT function. */
|
||||
char *
|
||||
elt(TOKEN s, int nth)
|
||||
{
|
||||
if (nth < 0) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "elt() called with illegal negative index %d\n",
|
||||
nth);
|
||||
return NULL;
|
||||
}
|
||||
for (; s && nth > 0; s = s->next, --nth)
|
||||
;
|
||||
return s ? s->token : NULL;
|
||||
}
|
||||
55
prospero/lib/pfs/equal_atrs.c
Normal file
55
prospero/lib/pfs/equal_atrs.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (c) 1992, 1993 by the University of Southern California.
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
|
||||
/* This function is used by edit_link_info() and edit_object_info() in the
|
||||
server to determine whether two attributes are the same. It will eventually
|
||||
also be used for merging attributes in VLS and other clients.
|
||||
*/
|
||||
int
|
||||
equal_attributes(PATTRIB a1, PATTRIB a2)
|
||||
{
|
||||
if (a1->precedence != a2->precedence
|
||||
|| a1->nature != a2->nature
|
||||
|| a1->avtype != a2->avtype
|
||||
|| !strequal(a1->aname, a2->aname))
|
||||
return FALSE;
|
||||
switch(a1->avtype) {
|
||||
case ATR_SEQUENCE:
|
||||
return equal_sequences(a1->value.sequence,
|
||||
a2->value.sequence);
|
||||
case ATR_FILTER:
|
||||
return equal_filters(a1->value.filter, a2->value.filter);
|
||||
case ATR_LINK:
|
||||
return vl_equal(a1->value.link, a2->value.link);
|
||||
default:
|
||||
internal_error("Invalid attribute type!");
|
||||
/*NOTREACHED */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
assert(0);
|
||||
return(-1); /*Keep gcc happy*/
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
equal_filters(FILTER f1, FILTER f2)
|
||||
{
|
||||
if (f1->name && f2->name) { /* Both PREDEFINED */
|
||||
if (!strequal(f1->name, f2->name))
|
||||
return FALSE;
|
||||
} else if (f1->link && f2->link) { /* both LOADABLE */
|
||||
if (!vl_equal(f1->link, f2->link))
|
||||
return FALSE;
|
||||
} else { /* One PREDEFINED, other LOADABLE */
|
||||
return FALSE;
|
||||
}
|
||||
return (f1->type == f2->type
|
||||
&& f1->execution_location == f2->execution_location
|
||||
&& f1->pre_or_post == f2->pre_or_post
|
||||
&& equal_sequences(f1->args, f2->args));
|
||||
}
|
||||
30
prospero/lib/pfs/equal_seq.c
Normal file
30
prospero/lib/pfs/equal_seq.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
/* Written by swa@ISI.EDU, Sept. 24, 1992 */
|
||||
|
||||
/* This is used by equal_attributes(), and probably not by much else. */
|
||||
/* Compare two token lists. Return nonzero value if they match; zero if
|
||||
they don't. */
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
int
|
||||
equal_sequences(t1, t2)
|
||||
TOKEN t1, t2;
|
||||
{
|
||||
for (;;t1 = t1->next, t2 = t2->next) {
|
||||
if (t1 == t2) /* Handles the case where both are NULL */
|
||||
return TRUE;
|
||||
if (!t1 || !t2) /* handles the case where one is null and the
|
||||
other is not. */
|
||||
return FALSE;
|
||||
if (!strequal(t1->token, t2->token))
|
||||
return FALSE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
26
prospero/lib/pfs/filetoin.c
Normal file
26
prospero/lib/pfs/filetoin.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
|
||||
#ifndef FILE
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
filetoin(FILE *f, INPUT in)
|
||||
{
|
||||
in->sourcetype = IO_FILE;
|
||||
in->rreq = NULL;
|
||||
in->inpkt = NULL;
|
||||
in->ptext_ioptr = NULL;
|
||||
in->s = NULL;
|
||||
in->file = f;
|
||||
in->offset = ftell(f);
|
||||
in->flags = JUST_INITIALIZED | SERVER_DATA_FILE;
|
||||
}
|
||||
59
prospero/lib/pfs/fl_insert.c
Normal file
59
prospero/lib/pfs/fl_insert.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990 by the University of Washington
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <uw-copyright.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/*
|
||||
* fl_insert - Add a filter to a link
|
||||
*
|
||||
* FL_INSERT takes a filter, and a link that is to receive
|
||||
* the filter. The filter is then appended to the linked list
|
||||
* of filters associated with the link.
|
||||
*
|
||||
* ARGS: fil - Filter to be inserted, lin - Link to get filter
|
||||
*
|
||||
* RETURNS: PSUCCESS - always
|
||||
*/
|
||||
int
|
||||
fl_insert(fil,lin)
|
||||
#if 0
|
||||
VLINK fil; /* Filter to be inserted */
|
||||
#endif
|
||||
FILTER fil;
|
||||
VLINK lin; /* Link to receive filter */
|
||||
|
||||
{
|
||||
APPEND_ITEM(fil, lin->filters);
|
||||
#if 0
|
||||
VLINK current; /* To step through list */
|
||||
|
||||
/* If this is the first filter in the link */
|
||||
if(lin->filters == NULL) {
|
||||
lin->filters = fil;
|
||||
fil->previous = NULL;
|
||||
fil->next = NULL;
|
||||
return(PSUCCESS);
|
||||
}
|
||||
|
||||
/* Otherwise, find the last filter */
|
||||
|
||||
current = lin->filters;
|
||||
|
||||
while(current->next) current = current->next;
|
||||
|
||||
/* insert the new filter */
|
||||
current->next = fil;
|
||||
fil->next = NULL;
|
||||
fil->previous = current;
|
||||
#endif
|
||||
return(PSUCCESS);
|
||||
|
||||
}
|
||||
182
prospero/lib/pfs/flalloc.c
Normal file
182
prospero/lib/pfs/flalloc.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For malloc and free */
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
static FILTER lfree = NULL;
|
||||
/* These are global variables which will be read by dirsrv.c
|
||||
Too bad C doesn't have better methods for structuring such global data. */
|
||||
|
||||
int filter_count = 0;
|
||||
int filter_max = 0;
|
||||
|
||||
/*
|
||||
* flalloc - allocate and initialize FILTER structure
|
||||
*
|
||||
* FLALLOC returns a pointer to an initialized structure of type
|
||||
* FILTER. If it is unable to allocate such a structure, it
|
||||
* signals out_of_memory();
|
||||
*/
|
||||
FILTER
|
||||
flalloc()
|
||||
{
|
||||
|
||||
FILTER fil;
|
||||
p_th_mutex_lock(p_th_mutexFLALLOC);
|
||||
if(lfree) {
|
||||
fil = lfree;
|
||||
lfree = lfree->next;
|
||||
}
|
||||
else {
|
||||
fil = (FILTER) malloc(sizeof(FILTER_ST));
|
||||
if (!fil) out_of_memory();
|
||||
filter_max++;
|
||||
}
|
||||
|
||||
filter_count++;
|
||||
p_th_mutex_unlock(p_th_mutexFLALLOC);
|
||||
|
||||
/* Initialize and fill in default values */
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
fil->consistency = INUSE_PATTERN;
|
||||
#endif
|
||||
fil->name = NULL;
|
||||
fil->link = NULL;
|
||||
fil->type = 0; /* Illegal value */
|
||||
fil->execution_location = 0; /* Neither -- illegal value. */
|
||||
fil->pre_or_post = 0; /* Neither -- illegal value */
|
||||
fil->args = NULL;
|
||||
fil->errmesg = NULL; /* error message from filter application, if
|
||||
any. */
|
||||
fil->app.ptr = NULL; /* On every architecture I ever heard of,
|
||||
fil->app.flg is now 0 too */
|
||||
fil->previous = NULL;
|
||||
fil->next = NULL;
|
||||
return(fil);
|
||||
}
|
||||
|
||||
static void (*flappfreefunc)(FILTER) = NULL;
|
||||
|
||||
/*
|
||||
* Specify which special freeing function (if any) to be used to free the
|
||||
* app.ptr member of the FILTER structure, if set.
|
||||
*/
|
||||
void
|
||||
flappfree(void (* appfreefunc)(FILTER))
|
||||
{
|
||||
flappfreefunc = appfreefunc;
|
||||
}
|
||||
|
||||
/*
|
||||
* flfree - free a FILTER structure
|
||||
*
|
||||
* FLFREE takes a pointer to a FILTER structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
flfree(FILTER fil)
|
||||
{
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(fil->consistency == INUSE_PATTERN);
|
||||
fil->consistency = FREE_PATTERN;
|
||||
#endif
|
||||
if(fil->name) stfree(fil->name);
|
||||
if(fil->link) vlfree(fil->link);
|
||||
if(fil->args) tklfree(fil->args);
|
||||
if (fil->errmesg) stfree(fil->errmesg);
|
||||
if(flappfreefunc && fil->app.ptr) {
|
||||
(*flappfreefunc)(fil->app.ptr); fil->app.ptr = NULL;
|
||||
}
|
||||
p_th_mutex_lock(p_th_mutexFLALLOC);
|
||||
fil->next = lfree;
|
||||
fil->previous = NULL;
|
||||
lfree = fil;
|
||||
filter_count--;
|
||||
p_th_mutex_unlock(p_th_mutexFLALLOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* fllfree - free a linked list of FILTER structures.
|
||||
*
|
||||
* FLLFREE takes a pointer to a FILTER structure frees it and any linked
|
||||
* FILTER structures. It is used to free an entrie list of FILTER
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
fllfree(fil)
|
||||
FILTER fil;
|
||||
{
|
||||
FILTER nxt;
|
||||
|
||||
while((fil != NULL) /* && !fil->dontfree */) {
|
||||
nxt = fil->next;
|
||||
flfree(fil);
|
||||
fil = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* flcopy - allocates a new filter structure and
|
||||
* initializes it with a copy of another
|
||||
* filter, v.
|
||||
*
|
||||
* If r is non-zero, successive filters will be
|
||||
* iteratively copied.
|
||||
*
|
||||
* fl-previous will always be null on the first link, and
|
||||
* will be appropriately filled in for iteratively copied links.
|
||||
*
|
||||
* FLCOPY returns a pointer to the new structure of type
|
||||
* FILTER. If it is unable to allocate such a structure, it
|
||||
* returns NULL.
|
||||
*
|
||||
* FLCOPY will recursively copy the link associated with a filter and
|
||||
* its associated attributes.
|
||||
*/
|
||||
|
||||
FILTER
|
||||
flcopy(FILTER f, int r)
|
||||
{
|
||||
FILTER nf;
|
||||
FILTER snf; /* Start of the chain of new links */
|
||||
FILTER tf; /* Temporary link pointer */
|
||||
|
||||
if (!f) return NULL; /* If called with NULL return it */
|
||||
nf = flalloc();
|
||||
snf = nf;
|
||||
|
||||
copyeach:
|
||||
|
||||
/* Copy f into nf */
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(f->consistency == INUSE_PATTERN);
|
||||
#endif
|
||||
if(f->name) nf->name = stcopyr(f->name,nf->name);
|
||||
if(f->link) nf->link = vlcopy(f->link, 1);
|
||||
nf->type = f->type;
|
||||
nf->execution_location = f->execution_location;
|
||||
nf->pre_or_post = f->pre_or_post;
|
||||
nf->args = tkcopy(f->args);
|
||||
f->errmesg = stcopy(f->errmesg);
|
||||
if(r && f->next) {
|
||||
f = f->next;
|
||||
tf = nf;
|
||||
nf = flalloc();
|
||||
nf->previous = tf;
|
||||
tf->next = nf;
|
||||
goto copyeach;
|
||||
}
|
||||
|
||||
return(snf);
|
||||
}
|
||||
|
||||
25
prospero/lib/pfs/fputbst.c
Normal file
25
prospero/lib/pfs/fputbst.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern Calfornia
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <stdio.h>
|
||||
#include <pfs.h> /* for prototypes */
|
||||
|
||||
/* Return non-zero if string ends in a newline. */
|
||||
/* Like fputs, but for bstrings. */
|
||||
int
|
||||
p__fputbst(const char *bst, FILE *out)
|
||||
{
|
||||
int len = p_bstlen(bst);
|
||||
int need_newline = 0;
|
||||
|
||||
while (len-- > 0) {
|
||||
need_newline = (*bst != '\n'); /* Does the bstring end in a newline? */
|
||||
putc(*bst++, out);
|
||||
}
|
||||
return need_newline;
|
||||
}
|
||||
192
prospero/lib/pfs/get_acl.c
Normal file
192
prospero/lib/pfs/get_acl.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 1991 by the University of Washington
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the files
|
||||
* <uw-copyright.h> and <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
/* lname is specified if we want the ACL for a link within a directory.
|
||||
It is left out when requesting the ACL for the directory itself. */
|
||||
/* XXX To be done: add an ID field. */
|
||||
#define LIST_ACL_SEND_OLDSTYLE_OBJECT_AND_CONTAINER /* until Alpha.5.2 servers
|
||||
are gone. */
|
||||
#define SEND_DIRECTORY_NOT_OBJECT /* Until Alpha.5.2 and before servers all
|
||||
gone. */
|
||||
|
||||
ACL
|
||||
get_acl(VLINK dlink,
|
||||
const char *lname,
|
||||
/* Note that 'directory' and 'object' flags will soon be the same. */
|
||||
int flags /* 0 = directory, 1 = link, 2 = object, 3 = included/named,
|
||||
4 = container 5 = named*/)
|
||||
{
|
||||
RREQ req; /* Text of request to dir server */
|
||||
ACL retval = NULL; /* ACLs being returned */
|
||||
ACL ap; /* Temporary acl pointer */
|
||||
char *options = ""; /* List of options */
|
||||
|
||||
int fwdcnt = MAX_FWD_DEPTH;
|
||||
char fwdhst[MAX_DIR_LINESIZE];
|
||||
char fwdfnm[MAX_DIR_LINESIZE];
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
char *next_line;
|
||||
int tmp;
|
||||
|
||||
if(flags == 0) {
|
||||
options = "DIRECTORY";
|
||||
/* no link name should be specified with the directory option. */
|
||||
if (lname && *lname) return NULL;
|
||||
}
|
||||
/* If for a link, or an included ACL */
|
||||
else if ((flags == 1) || (flags == 3) || (flags == 5)) {
|
||||
/* link name must be specified with this option */
|
||||
if (!lname || !*lname)
|
||||
return NULL;
|
||||
if (flags == 1) options = "LINK";
|
||||
else if (flags == 3) options = "INCLUDE";
|
||||
else if (flags == 5) options = "NAMED";
|
||||
}
|
||||
else if (flags == 2) {
|
||||
options = "OBJECT";
|
||||
if (lname && *lname) return NULL;
|
||||
}
|
||||
else if (flags == 4) {
|
||||
options = "CONTAINER";
|
||||
if (lname && *lname) return NULL;
|
||||
}
|
||||
if(lname == NULL) lname = "";
|
||||
|
||||
if(strcmp(dlink->target,"NULL") == 0) return(NULL);
|
||||
if(strcmp(dlink->target,"EXTERNAL") == 0) return(NULL);
|
||||
|
||||
startover:
|
||||
|
||||
req = p__start_req(dlink->host);
|
||||
|
||||
if ((flags == 0) || (flags == 1)) {
|
||||
#ifdef SEND_DIRECTORY_NOT_OBJECT
|
||||
p__add_req(req, "DIRECTORY %'s %'s\n", dlink->hsonametype,
|
||||
dlink->hsoname);
|
||||
#else
|
||||
p__add_req(req, "OBJECT %'s %'s\n", dlink->hsonametype,
|
||||
dlink->hsoname);
|
||||
#endif
|
||||
}
|
||||
#ifdef LIST_ACL_SEND_OLDSTYLE_OBJECT_AND_CONTAINER
|
||||
if ((flags == 0) || (flags == 1) || (flags == 3) || (flags == 5)) {
|
||||
p__add_req(req, "LIST-ACL %s", options);
|
||||
if(*lname) p__add_req(req, " %'s", lname);
|
||||
p__add_req(req, "\n");
|
||||
}
|
||||
|
||||
if ((flags == 2) || (flags == 4)) {
|
||||
p__add_req(req, "LIST-ACL %s %s\n", options, dlink->hsoname);
|
||||
}
|
||||
#else
|
||||
if (flags == 2 || flags == 4) {
|
||||
p__add_req(req, "OBJECT %'s %'s\n", dlink->hsonametype,
|
||||
dlink->hsoname);
|
||||
p__add_req(req, "LIST-ACL %'s\n", options);
|
||||
}
|
||||
if ((flags == 0) || (flags == 1) || (flags == 3) || (flags == 5)) {
|
||||
p__add_req(req, "LIST-ACL %s", options);
|
||||
if(*lname) p__add_req(req, " %'s", lname);
|
||||
p__add_req(req, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
perrno = 0;
|
||||
|
||||
tmp = ardp_send(req,dlink->host,0,ARDP_WAIT_TILL_TO);
|
||||
|
||||
if(pfs_debug && tmp) {
|
||||
fprintf(stderr,"get_acl(): Dirsend failed: %d\n",tmp);
|
||||
perrno = tmp;
|
||||
}
|
||||
|
||||
/* If we don't get a response, then return error */
|
||||
if(req->rcvd == NULL) return(NULL);
|
||||
|
||||
rreqtoin(req, in);
|
||||
/* Here we must parse reponse */
|
||||
/* While looking at each packet */
|
||||
while (in_nextline(in)) {
|
||||
char *line, *next_word;
|
||||
if(tmp = in_line(in, &line, &next_word)) {
|
||||
aclfree(retval);
|
||||
perrno = tmp;
|
||||
return NULL;
|
||||
}
|
||||
switch (*line) {
|
||||
|
||||
/* Temporary variables to info */
|
||||
/* There is already a variable "tmp" in this function*/
|
||||
int tmp1;
|
||||
|
||||
case 'A': /* ACL */
|
||||
if(!strnequal(line,"ACL",3)) goto scanerr;
|
||||
if (retval) {/* if already saw ACL lines */
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
aclfree(retval);
|
||||
return NULL;
|
||||
}
|
||||
if(in_ge1_acl(in, line, next_word, &retval)) {
|
||||
aclfree(retval);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F':/* FORWARDED */
|
||||
if(strncmp(line,"FORWARDED",9) == 0) {
|
||||
if(fwdcnt-- <= 0) {
|
||||
ardp_rqfree(req);
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
return(NULL);
|
||||
}
|
||||
/* parse and start over */
|
||||
|
||||
tmp1 = qsscanf(line,"FORWARDED %'&s %'&s %'&s %'&s %ld %ld",
|
||||
&dlink->hosttype, &dlink->host,
|
||||
&dlink->hsonametype, &dlink->hsoname,
|
||||
&dlink->version, &dlink->f_magic_no);
|
||||
if(tmp1 < 2) {
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
ardp_rqfree(req);
|
||||
goto startover;
|
||||
}
|
||||
/* If FAILURE or other, then scan error */
|
||||
goto scanerr;
|
||||
|
||||
scanerr:
|
||||
default:
|
||||
if(tmp1 = scan_error(line, req)) {
|
||||
ardp_rqfree(req);
|
||||
return(NULL);
|
||||
}
|
||||
break;
|
||||
} /* switch() */
|
||||
} /* while (in_nextline(in)) */
|
||||
ardp_rqfree(req);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
129
prospero/lib/pfs/in_acl.c
Normal file
129
prospero/lib/pfs/in_acl.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
|
||||
static int
|
||||
in_acl_data(INPUT in, char *command, char *next_word, ACL value);
|
||||
|
||||
int in_ge1_acl(INPUT in, char *command, char *next_word, ACL *aclp)
|
||||
{
|
||||
ACL nacl = acalloc();
|
||||
int retval;
|
||||
|
||||
if (!nacl) out_of_memory();
|
||||
if(retval = in_acl_data(in, command, next_word, nacl)) {
|
||||
acfree(nacl);
|
||||
return perrno = retval;
|
||||
}
|
||||
if(retval = in_acl(in, &nacl->next)) {
|
||||
acfree(nacl);
|
||||
return perrno = retval;
|
||||
}
|
||||
/* now need to correct the doubly-linked list. */
|
||||
if (nacl->next) {
|
||||
nacl->previous = nacl->next->previous;
|
||||
nacl->next->previous = nacl;
|
||||
}
|
||||
*aclp = nacl;
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
/* This function is called with in_nextline() referring to the first line that
|
||||
might contain ACL data. It sets perrno and p_err_string if bad data is
|
||||
found, and ALSO returns an error code. */
|
||||
/* Reads in a string of ACL lines. */
|
||||
|
||||
int
|
||||
in_acl(INPUT in, ACL *aclp)
|
||||
{
|
||||
ACL list = NULL; /* head of a linked list of new acls. */
|
||||
char *command, *next_word;
|
||||
|
||||
while(in_nextline(in) && strnequal(in_nextline(in), "ACL", 3)) {
|
||||
ACL nacl = acalloc();
|
||||
int retval; /* return code from function calls. */
|
||||
|
||||
if (!nacl) {
|
||||
aclfree(list);
|
||||
out_of_memory();
|
||||
}
|
||||
APPEND_ITEM(nacl, list);
|
||||
if(retval = in_line(in, &command, &next_word)) {
|
||||
aclfree(list);
|
||||
return perrno = retval;
|
||||
}
|
||||
if(retval = in_acl_data(in, command, next_word, nacl)) {
|
||||
aclfree(list);
|
||||
return perrno = retval;
|
||||
}
|
||||
/* We just safely read in the rest of the line. */
|
||||
/* Read in additional lines to skip over any RESTRICTION lines. */
|
||||
while (in_nextline(in)
|
||||
&& strnequal(in_nextline(in), "RESTRICTION ", 12)) {
|
||||
extern int p__server;
|
||||
if(retval = in_line(in, &command, &next_word)) {
|
||||
aclfree(list);
|
||||
return perrno = retval;
|
||||
}
|
||||
if (p__server) {
|
||||
aclfree(list);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"UNIMPLEMENTED This server cannot handle RESTRICTIONS \
|
||||
yet: %s", command);
|
||||
return perrno = retval;
|
||||
} else {
|
||||
pwarn = PWARNING;
|
||||
p_warn_string = qsprintf_stcopyr(p_warn_string,
|
||||
"The server sent an ACL with a RESTRICTION, but we \
|
||||
don't know what it means: %s", command);
|
||||
/* just go on; it's only a warning. */
|
||||
}
|
||||
}
|
||||
}
|
||||
*aclp = list; /* safe & done. */
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
in_acl_data(INPUT in, char *command, char *next_word, ACL value)
|
||||
{
|
||||
AUTOSTAT_CHARPP(t_acetypep);
|
||||
AUTOSTAT_CHARPP(t_atypep);
|
||||
AUTOSTAT_CHARPP(t_rightsp);
|
||||
char *p_principals;
|
||||
extern char *acltypes[];
|
||||
|
||||
p_principals = NULL;
|
||||
if(qsscanf(next_word, "%'&s %'&s %'&s %r",
|
||||
&*t_acetypep, &*t_atypep, &*t_rightsp, &p_principals) < 3) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed ACL line: %'s", command);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
for(value->acetype = 0;acltypes[value->acetype];
|
||||
(value->acetype)++) {
|
||||
if(strequal(acltypes[value->acetype],*t_acetypep))
|
||||
break;
|
||||
}
|
||||
if(acltypes[value->acetype] == NULL) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown ACL type: %'s", command);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
/* We stcopy() twice; this is not necessary. */
|
||||
value->atype = stcopyr((**t_atypep ? *t_atypep : NULL), value->atype);
|
||||
value->rights = stcopyr((**t_rightsp ? *t_rightsp : NULL), value->rights);
|
||||
value->principals = (p_principals ? qtokenize(p_principals) : NULL);
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
242
prospero/lib/pfs/in_atrs.c
Normal file
242
prospero/lib/pfs/in_atrs.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <perrno.h>
|
||||
#include <pprot.h>
|
||||
|
||||
int p__server = 0; /* set to 1 by dirsrv.c. */
|
||||
|
||||
static int
|
||||
in_attribute_value(INPUT in, char *command, char *next_word, int nesting,
|
||||
char avtype, union avalue *value);
|
||||
|
||||
int in_ge1_atrs(INPUT in, char *command, char *next_word, PATTRIB *valuep)
|
||||
{
|
||||
PATTRIB at = atalloc();
|
||||
int retval;
|
||||
|
||||
CHECK_MEM();
|
||||
*valuep = NULL;
|
||||
|
||||
CHECK_PTRinBUFF(command,next_word);
|
||||
if (!at) out_of_memory();
|
||||
if (retval = in_atr_data(in, command, next_word, 0, at)) {
|
||||
atfree(at);
|
||||
return retval;
|
||||
}
|
||||
APPEND_ITEM(at, *valuep);
|
||||
if (retval = in_atrs(in, 0, &at->next)) {
|
||||
atfree(at);
|
||||
return retval;
|
||||
}
|
||||
/* now need to correct the doubly-linked list. */
|
||||
if (at->next) {
|
||||
at->previous = at->next->previous;
|
||||
at->next->previous = at;
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
/* Read in a series of protocol-style ATTRIBUTE lines. */
|
||||
/* starts with in_nextline() set to the first possible ATTRIBUTE line, and
|
||||
returns with in_nextline() set to the next line of available text. */
|
||||
/* the caller is responsible for calling palfree() on whatever in_atrs()
|
||||
delivers up. */
|
||||
int
|
||||
in_atrs(INPUT in, int nesting, PATTRIB *valuep)
|
||||
{
|
||||
char t_nesting[100];
|
||||
char *command, *next_word;
|
||||
|
||||
PATTRIB list = NULL; /* Head of a linked list of new attributes. */
|
||||
int retval;
|
||||
|
||||
while(in_nextline(in)
|
||||
&& qsscanf(in_nextline(in), "ATTRIBUTE%!!(>)", t_nesting, sizeof
|
||||
t_nesting) == 1) {
|
||||
PATTRIB at;
|
||||
|
||||
if(strlen(t_nesting) < nesting)
|
||||
break; /* we're done with reading the subats */
|
||||
at = atalloc();
|
||||
if (!at) {
|
||||
atlfree(list);
|
||||
out_of_memory();
|
||||
}
|
||||
APPEND_ITEM(at, list);
|
||||
if (strlen(t_nesting) > nesting) {
|
||||
/* OOPS! Unexpectedly deep nesting. */
|
||||
atlfree(list);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"ATTRIBUTE line sent with Nesting too deep; got %d, \
|
||||
expected %d: %s", strlen(t_nesting), nesting, command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
assert(strlen(t_nesting) == nesting);
|
||||
if(retval = in_line(in, &command, &next_word)) {
|
||||
atlfree(list);
|
||||
return perrno = retval;
|
||||
}
|
||||
CHECK_PTRinBUFF(command,next_word);
|
||||
if(retval = in_atr_data(in, command, next_word, nesting, at)) {
|
||||
atlfree(list);
|
||||
return perrno = retval;
|
||||
}
|
||||
}
|
||||
/* done! */
|
||||
*valuep = list;
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* We may need to recursively read the subattributes of a link, which means we
|
||||
may need to read multiple lines here. */
|
||||
int
|
||||
in_atr_data(INPUT in, char *command, char *next_word, int nesting, PATTRIB at)
|
||||
{
|
||||
char t_nature[sizeof "APPLICATION"];
|
||||
AUTOSTAT_CHARPP(t_anamep);
|
||||
AUTOSTAT_CHARPP(t_avtypep);
|
||||
char t_precedence[40];
|
||||
int retval;
|
||||
int tmp; /* from qsscanf() */
|
||||
char *maybe_eol; /* Need a pointer to end of line. */
|
||||
/* Used as a temporary in two separate places in the
|
||||
code. */
|
||||
|
||||
CHECK_PTRinBUFF(command,next_word);
|
||||
tmp = qsscanf(next_word, "%!!s %!!s %'&s%r %r",
|
||||
t_precedence, sizeof t_precedence,
|
||||
t_nature, sizeof t_nature, t_anamep, &maybe_eol, &next_word);
|
||||
if (tmp < 4) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed attribute line: %s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
} else if (tmp == 4) {
|
||||
/* no tokens for data given. This still might be legal -- e.g., a
|
||||
zero-length sequence. */
|
||||
next_word = maybe_eol;
|
||||
#if 0
|
||||
/* This following item won't work because in_attribute_value expects
|
||||
NEXT_WORD to be a pointer into the same string indicated by COMMAND.
|
||||
This was causing a crash whenever we had a zero-item SEQUENCE.
|
||||
--swa */
|
||||
next_word = "";
|
||||
#endif
|
||||
} /* else all is ok. */
|
||||
|
||||
at->precedence = lookup_precedence_by_precedencename(t_precedence);
|
||||
#ifndef REALLY_NEW_FIELD
|
||||
if(strequal(t_nature, "FIELD")) {
|
||||
char *cp; /* temp. ptr. */
|
||||
|
||||
at->nature = ATR_NATURE_FIELD;
|
||||
/* If the oldstyle field name field doesn't contain a valid old field
|
||||
name, try to parse it as a new style message. */
|
||||
if((at->avtype = lookup_avtype_by_field_name(*t_anamep))
|
||||
== ATR_UNKNOWN)
|
||||
goto new_field;
|
||||
/* If there's a t_avtype that matches the appropriate type for this
|
||||
field AND we have additional data following it then it's probably a
|
||||
new-style field. */
|
||||
tmp = qsscanf(next_word, "%&'s %r", t_avtypep, &cp);
|
||||
if (tmp == 2 && at->avtype == lookup_avtype_by_avtypename(*t_avtypep))
|
||||
goto new_field;
|
||||
/* Treat it as an old-style field. */
|
||||
} else /* Note the indentation below looks odd,
|
||||
but it's the most correct way I can think of
|
||||
to do it. --swa */
|
||||
#endif
|
||||
if (strnequal(t_nature, "APPLICATION", 11) ||
|
||||
#ifdef REALLY_NEW_FIELD
|
||||
strnequal(t_nature, "FIELD", 5) ||
|
||||
#endif
|
||||
strnequal(t_nature, "INTRINSIC", 9)) {
|
||||
at->nature = (t_nature[0] == 'A' ? ATR_NATURE_APPLICATION
|
||||
#ifdef REALLY_NEW_FIELD
|
||||
: t_nature[0] == 'F' ? ATR_NATURE_FIELD
|
||||
#endif
|
||||
: ATR_NATURE_INTRINSIC);
|
||||
new_field:
|
||||
/* An independent use of maybe_eol as a temporary. */
|
||||
tmp = qsscanf(next_word, "%&'s%r %r",
|
||||
t_avtypep, &maybe_eol, &next_word);
|
||||
if (tmp < 2) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed ATTRIBUTE line: %s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
} else if (tmp == 2)
|
||||
next_word = maybe_eol; /* no more data -- zero length sequence,
|
||||
etc. */
|
||||
#if 0
|
||||
/* This following item won't work because in_attribute_value expects
|
||||
NEXT_WORD to be a pointer into the same string indicated by COMMAND.
|
||||
This was causing a crash whenever we had a zero-item SEQUENCE.
|
||||
--swa */
|
||||
next_word = "";
|
||||
#endif
|
||||
if ((at->avtype = lookup_avtype_by_avtypename(*t_avtypep))
|
||||
== ATR_UNKNOWN) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown Attribute Value type: %s",
|
||||
*t_avtypep);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
CHECK_MEM();
|
||||
} else { /* Unknown t_nature */
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Only APPLICATION, INTRINSIC, and FIELD attribute value \
|
||||
types exist -- Malformed ATTRIBUTE line: %s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
CHECK_MEM();
|
||||
}
|
||||
at->aname = stcopy(*t_anamep);
|
||||
if (next_word) {
|
||||
/* Lack of next_word is not an error, just dont fill out the value */
|
||||
if(retval = in_attribute_value(in, command, next_word, nesting,
|
||||
at->avtype, &at->value)) {
|
||||
/* Error message will have been sent by in_attribute_value */
|
||||
return perrno = retval;
|
||||
}
|
||||
}
|
||||
/* The entry AT now has all of its members filled in. On to the next!
|
||||
*/
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
/* Based upon the value of the attribute, as passed in AVTYPE, parse the
|
||||
input line and store the results in VALUE. This may cause recursive calls
|
||||
to in_attributes(). Return PSUCCESS or PFAILURE.
|
||||
Command should be the head of a BSTRING and NEXT_WORD should be a pointer
|
||||
into the bstring. */
|
||||
static
|
||||
int
|
||||
in_attribute_value(INPUT in, char *command, char *next_word, int nesting,
|
||||
char avtype, union avalue *value)
|
||||
{
|
||||
|
||||
CHECK_PTRinBUFF(command,next_word);
|
||||
CHECK_MEM();
|
||||
switch(avtype) {
|
||||
case ATR_FILTER:
|
||||
return in_filter(in, command, next_word, nesting + 1,
|
||||
&value->filter);
|
||||
case ATR_LINK:
|
||||
return in_link(in, command, next_word, nesting + 1,
|
||||
&value->link, (TOKEN *) NULL);
|
||||
case ATR_SEQUENCE:
|
||||
return in_sequence(in, command, next_word, &value->sequence);
|
||||
default:
|
||||
internal_error("Invalid attribute value type!");
|
||||
/*NOTREACHED */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return -1; /* Keep gcc happy */
|
||||
}
|
||||
|
||||
107
prospero/lib/pfs/in_filter.c
Normal file
107
prospero/lib/pfs/in_filter.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
|
||||
|
||||
/* reads in a single FILTER line. */
|
||||
|
||||
int
|
||||
in_filter(INPUT in, char *command, char *next_word, int nesting,
|
||||
FILTER *valuep)
|
||||
{
|
||||
|
||||
char t_filtype[MAX_DIR_LINESIZE];
|
||||
char t_execloc[MAX_DIR_LINESIZE];
|
||||
char t_pre_or_post[MAX_DIR_LINESIZE];
|
||||
char t_predef_or_link[MAX_DIR_LINESIZE];
|
||||
char t_name[MAX_DIR_LINESIZE];
|
||||
char *p_args;
|
||||
int tmp; /* return val. from qsscanf(). */
|
||||
FILTER fil; /* The result. */
|
||||
|
||||
tmp = qsscanf(next_word, "%!!s %!!s %!!s %!!s %r",
|
||||
t_filtype, sizeof t_filtype,
|
||||
t_execloc, sizeof t_execloc,
|
||||
t_pre_or_post, sizeof t_pre_or_post,
|
||||
t_predef_or_link, sizeof t_predef_or_link, &next_word);
|
||||
/* Set them. */
|
||||
if (tmp < 5) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Filter description format error: %'s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
fil = flalloc();
|
||||
if (!fil)
|
||||
out_of_memory();
|
||||
if(strequal(t_filtype, "DIRECTORY"))
|
||||
fil->type = FIL_DIRECTORY;
|
||||
else if (strequal(t_filtype, "HIERARCHY"))
|
||||
fil->type = FIL_HIERARCHY;
|
||||
else if (strequal(t_filtype, "OBJECT"))
|
||||
fil->type = FIL_OBJECT;
|
||||
else if (strequal(t_filtype, "UPDATE"))
|
||||
fil->type = FIL_UPDATE;
|
||||
else {
|
||||
flfree(fil);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown filter type: %'s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
if (strequal(t_execloc, "CLIENT"))
|
||||
fil->execution_location = FIL_CLIENT;
|
||||
else if (strequal(t_execloc, "SERVER"))
|
||||
fil->execution_location = FIL_SERVER;
|
||||
else {
|
||||
flfree(fil);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown filter execution location: %'s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
if (strequal(t_pre_or_post, "PRE"))
|
||||
fil->pre_or_post = FIL_PRE;
|
||||
else if (strequal(t_pre_or_post, "POST"))
|
||||
fil->pre_or_post = FIL_POST;
|
||||
else {
|
||||
flfree(fil);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown filter pre-or-post specification: %'s",
|
||||
command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
if(strequal(t_predef_or_link, "PREDEFINED")) {
|
||||
tmp = qsscanf(next_word, "%'s ARGS %r", t_name, &p_args);
|
||||
if (tmp < 1) {
|
||||
flfree(fil);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed filter spec: %'s", command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
fil->name = stcopyr(t_name, fil->name);
|
||||
if (tmp == 2)
|
||||
fil->args = qtokenize(p_args);
|
||||
} else if (strequal(t_predef_or_link, "LINK")) {
|
||||
int retval; /* return from subfunction. */
|
||||
if(retval = in_link(in, command, next_word, nesting, &(fil->link),
|
||||
&(fil->args))) {
|
||||
flfree(fil);
|
||||
return retval;
|
||||
}
|
||||
} else {
|
||||
flfree(fil);
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed filter spec, neither LINK nor PREDEFINED : %'s",
|
||||
command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
*valuep = fil;
|
||||
return PSUCCESS;
|
||||
|
||||
}
|
||||
52
prospero/lib/pfs/in_forwarded.c
Normal file
52
prospero/lib/pfs/in_forwarded.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/* Assumes next_word points to the word following a FORWARDED response. */
|
||||
int
|
||||
in_forwarded_data(INPUT in, char *command, char *next_word, VLINK dlink)
|
||||
{
|
||||
int tmp;
|
||||
int moretext; /* flag we use to check if there's more text on
|
||||
the line to examine. */
|
||||
int retval = PSUCCESS; /* return value from functions */
|
||||
|
||||
tmp = qsscanf(next_word,"%~%'&s %'&s %'&s %'&s %ld %r",
|
||||
&dlink->hosttype, &dlink->host,
|
||||
&dlink->hsonametype, &dlink->hsoname,
|
||||
&dlink->version, &next_word);
|
||||
/* Log and return a better message */
|
||||
if(tmp < 5) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string, "Too few arguments: %'s",
|
||||
command, 0);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
moretext = (tmp == 6);
|
||||
/* search for DEST_EXP, if set. */
|
||||
if (moretext) {
|
||||
AUTOSTAT_CHARPP(t_destexpp);
|
||||
tmp = qsscanf(next_word, "DEST-EXP %'&s %r", t_destexpp, &next_word);
|
||||
if (tmp >= 1)
|
||||
dlink->dest_exp = asntotime(*t_destexpp);
|
||||
moretext = (tmp == 2);
|
||||
}
|
||||
if (moretext) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown tokens at end of FORWARDED specification: %'s",
|
||||
command);
|
||||
return perrno = PARSE_ERROR;
|
||||
}
|
||||
/* Look for any and all following ID lines and merge them with the link. */
|
||||
retval = in_id(in, &dlink->f_magic_no);
|
||||
if (retval) return perrno = retval;
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
57
prospero/lib/pfs/in_id.c
Normal file
57
prospero/lib/pfs/in_id.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
|
||||
/* The interface to this function will change. The long * must become a
|
||||
pointer to some more generic ID storage type. But for now, this is correct.
|
||||
We simply ignore ID types that we don't understand. I believe this is
|
||||
correct.
|
||||
*/
|
||||
int
|
||||
in_id(INPUT in, long *magic_nop)
|
||||
{
|
||||
char *command, *next_word;
|
||||
long atol();
|
||||
|
||||
while (in_nextline(in) && strnequal(in_nextline(in), "ID", 2)) {
|
||||
char t_id_type[MAX_DIR_LINESIZE];
|
||||
int retval; /* retval from subfunctions. */
|
||||
int tmp; /* # of tokens matched by qsscanf() */
|
||||
TOKEN seq = NULL;
|
||||
|
||||
if(retval = in_line(in, &command, &next_word)) {
|
||||
return retval;
|
||||
}
|
||||
tmp = qsscanf(next_word, "%!!s %r", t_id_type, sizeof t_id_type,
|
||||
&next_word);
|
||||
if (tmp < 1) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed ID line received: %s", command);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
if (strequal(t_id_type, "REMOTE")) {
|
||||
if(retval = in_sequence(in, command, next_word, &seq))
|
||||
return retval;
|
||||
if (!seq || seq->next) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Malformed REMOTE ID type received; must be a single \
|
||||
integer: %s", command);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
/* XXX should use qsscanf() for the overflow checking. */
|
||||
*magic_nop = atol(seq->token);
|
||||
}
|
||||
/* Just ignore other ID types. */
|
||||
tklfree(seq);
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
130
prospero/lib/pfs/in_line.c
Normal file
130
prospero/lib/pfs/in_line.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <ctype.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <perrno.h>
|
||||
|
||||
|
||||
|
||||
/* in_line reads quoted Prospero lines from a number of sources, up to the next
|
||||
unquoted newline. Upon return, *thislinep points to the start of a
|
||||
NUL-terminated string which contains a Prospero protocol command line.
|
||||
*next_wordp points to the first word in that string after command.
|
||||
|
||||
in_line passes through the error codes returned by its subsidiary functions.
|
||||
The only error they return is PARSE_ERROR. If pfs_debug is set, then
|
||||
explanatory detail describing the malformed line will be reported on
|
||||
stderr.
|
||||
|
||||
*thislinep and *next_wordp point to a buffer private to in_line(). This
|
||||
buffer may be rewritten after each new line is read.
|
||||
*/
|
||||
|
||||
int
|
||||
in_line(INPUT in, char **thislinep, char **next_wordp)
|
||||
{
|
||||
int tmp; /* temp return value. */
|
||||
INPUT_ST eol_st; /* temp. variable for end of line. */
|
||||
INPUT eol = &eol_st; /* temp. variable for end of line. */
|
||||
int linebuflen; /* length to copy into linebuf */
|
||||
int i; /* temporary index */
|
||||
/* A local static variable. Points to the line in progress. */
|
||||
AUTOSTAT_CHARPP(linebufp);
|
||||
char *cp; /* temp. index */
|
||||
|
||||
if (!in_nextline(in)) internal_error("in_line() called with no data");
|
||||
/* Ok, set EOL to the end of this input line. */
|
||||
tmp = qscanf(in, "%~%r%'*(^\n\r)%r", in, eol);
|
||||
if (tmp < 2) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Read Prospero message with an unterminated quote");
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
/* Make sure that linebuf points to a string with enough room to hold the
|
||||
current line. */
|
||||
if (in->sourcetype == IO_STRING) {
|
||||
linebuflen = eol->s - in->s; /* string type doesn't use offset member.
|
||||
*/
|
||||
} else {
|
||||
linebuflen = eol->offset - in->offset; /* size that strlen() would
|
||||
return */
|
||||
}
|
||||
if (!*linebufp)
|
||||
assert(*linebufp = stalloc(linebuflen + 1));
|
||||
else if (p__bstsize(*linebufp) < linebuflen + 1) {
|
||||
stfree(*linebufp);
|
||||
assert(*linebufp = stalloc(linebuflen + 1));
|
||||
}
|
||||
/* Now copy the bytes from the input stream to the linebuf. This preserves
|
||||
quoting, which is very important. */
|
||||
for(cp = *linebufp, i = 0; i < linebuflen; ++cp, ++i, in_incc(in))
|
||||
*cp = in_readc(in);
|
||||
*cp = '\0';
|
||||
assert((in->sourcetype != IO_STRING) ? in->offset == eol->offset : 1);
|
||||
/* I need to trim off trailing spaces here. Or else there might be
|
||||
trouble. Hmm. */
|
||||
while (cp > *linebufp && isspace(*--cp)) {
|
||||
*cp = '\0', --linebuflen;
|
||||
}
|
||||
p_bst_set_buffer_length_nullterm(*linebufp, linebuflen);
|
||||
/* push on the read pointer for in to the start of the next line. */
|
||||
tmp = qscanf(in, "%R", in);
|
||||
if (tmp < 1) {
|
||||
#if 0 /* gripe about unterminated lines */
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Read Prospero message with a line that was not LF \
|
||||
terminated.");
|
||||
return PARSE_ERROR;
|
||||
#else
|
||||
while (!in_eof(in)) /* Gobble up anything else that remains.
|
||||
I don't expect there to be anything. */
|
||||
in_incc(in);
|
||||
#endif
|
||||
}
|
||||
/* linebuf now points to a complete line of still quoted text. */
|
||||
*thislinep = *linebufp;
|
||||
if(p__qbstscanf(*thislinep, *thislinep, "%*'s%~%r", next_wordp) < 1
|
||||
|| *thislinep == *next_wordp) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Read Prospero message with an empty line.");
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rreqtoin(RREQ rreq, INPUT in)
|
||||
{
|
||||
in->sourcetype = IO_RREQ;
|
||||
in->offset = 0; /* on byte 0. */
|
||||
if(in->rreq = rreq) { /* might be NULL. */
|
||||
in->inpkt = rreq->rcvd;
|
||||
in->ptext_ioptr = rreq->rcvd->text;
|
||||
/* Do a loop because there might be a crazy client that sends some
|
||||
packets in a sequence with empty length fields. Skip any of them we
|
||||
encounter; go to the next packet with some content. */
|
||||
while (in->ptext_ioptr >= in->inpkt->text + in->inpkt->length) {
|
||||
in->inpkt = in->inpkt->next;
|
||||
if (in->inpkt == NULL)
|
||||
break;
|
||||
in->ptext_ioptr = in->inpkt->text;
|
||||
}
|
||||
} else {
|
||||
in->inpkt = NULL;
|
||||
in->ptext_ioptr = NULL;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
in->file = NULL;
|
||||
in->s = NULL;
|
||||
#endif
|
||||
in->flags = JUST_INITIALIZED; /* is this needed? */
|
||||
}
|
||||
|
||||
127
prospero/lib/pfs/in_link.c
Normal file
127
prospero/lib/pfs/in_link.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/* Returns PSUCCESS or PFAILURE.
|
||||
Stashes its results in *valuep, and in *argsp, if argsp is non-NULL.
|
||||
Starts reading from next_word.
|
||||
*/
|
||||
#define RETURN(rv) { retval = rv ; goto cleanup ; }
|
||||
/* This wasnt freeing clink in all cases */
|
||||
int
|
||||
in_link(INPUT in, char *command, char *next_word,
|
||||
int nesting, VLINK *valuep,
|
||||
TOKEN *argsp /* Only used by in_filter. */)
|
||||
{
|
||||
VLINK clink;
|
||||
int tmp;
|
||||
char t_linktype;
|
||||
char t_type[MAX_DIR_LINESIZE];
|
||||
char t_name[MAX_DIR_LINESIZE];
|
||||
char t_htype[MAX_DIR_LINESIZE];
|
||||
char t_host[MAX_DIR_LINESIZE];
|
||||
char t_ntype[MAX_DIR_LINESIZE];
|
||||
char t_fname[MAX_DIR_LINESIZE];
|
||||
char t_destexp[20];
|
||||
char *p_args;
|
||||
PATTRIB at;
|
||||
int moretext; /* flag we use to check if there's more text on
|
||||
the line to examine. */
|
||||
int retval = PSUCCESS; /* return value from functions */
|
||||
|
||||
CHECK_MEM();
|
||||
clink = vlalloc(); /* free-d or returned in valuep */
|
||||
|
||||
tmp = qsscanf(next_word, "%c %s %'s %s %'s %s %'s %d %r",
|
||||
&t_linktype,t_type,t_name,t_htype,t_host,
|
||||
t_ntype,t_fname,
|
||||
&(clink->version), &next_word);
|
||||
|
||||
/* Log and return a better message */
|
||||
if(tmp < 8) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string, "Too few arguments: %'s",
|
||||
command, 0);
|
||||
RETURN(perrno = PARSE_ERROR);
|
||||
}
|
||||
assert(tmp <= 9);
|
||||
moretext = (tmp == 9);
|
||||
if (t_linktype == 'U' || t_linktype == 'L' || t_linktype == 'I'
|
||||
|| in->flags == SERVER_DATA_FILE
|
||||
&& (t_linktype == 'n' || t_linktype == 'N'))
|
||||
clink->linktype = t_linktype;
|
||||
else {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Illegal link type %c specified: %'s", t_linktype, command);
|
||||
RETURN(perrno = PARSE_ERROR);
|
||||
}
|
||||
|
||||
clink->target = stcopyr(t_type, clink->target);
|
||||
clink->name = stcopyr(t_name, clink->name);
|
||||
clink->hosttype = stcopyr(t_htype,clink->hosttype);
|
||||
clink->host = stcopyr(t_host,clink->host);
|
||||
clink->hsonametype = stcopyr(t_ntype,clink->hsonametype);
|
||||
clink->hsoname = stcopyr(t_fname,clink->hsoname);
|
||||
/* search for DEST_EXP, if set. */
|
||||
if (moretext) {
|
||||
tmp = qsscanf(next_word, "DEST-EXP %!!s %r", t_destexp,
|
||||
sizeof t_destexp, &next_word);
|
||||
if (tmp >= 1)
|
||||
clink->dest_exp = asntotime(t_destexp);
|
||||
moretext = (tmp == 2);
|
||||
}
|
||||
if (argsp) { /* if args requested */
|
||||
/* if given */
|
||||
if (moretext) {
|
||||
tmp = qsscanf(next_word, "ARGS %r", &p_args);
|
||||
if (tmp == 1) {
|
||||
*argsp = qtokenize(p_args);
|
||||
moretext = 0;
|
||||
} else {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown tokens at end of LINK specification: %'s",
|
||||
command);
|
||||
RETURN(perrno = PARSE_ERROR);
|
||||
}
|
||||
} else {
|
||||
/* no more text, but args requested. */
|
||||
*argsp = NULL;
|
||||
}
|
||||
}
|
||||
/* check for leftover text. */
|
||||
if (moretext) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Unknown tokens at end of LINK specification: %'s",
|
||||
command);
|
||||
RETURN( perrno = PARSE_ERROR);
|
||||
}
|
||||
/* Look for any and all following ID lines and merge them with the link. */
|
||||
retval = in_id(in, &clink->f_magic_no);
|
||||
|
||||
/* look for ATTRIBUTE lines specifying link attributes. */
|
||||
/* errors reported in p_err_string by these subfunctions. */
|
||||
/* These subfunctions will free up memory they don't need. */
|
||||
if (!retval) retval = in_atrs(in, nesting, &at);
|
||||
if (!retval) retval = vl_add_atrs(at, clink);
|
||||
if (retval) {
|
||||
if(argsp) tklfree(*argsp);
|
||||
/* in_atrs and add_attributes free their allocated memory if they fail;
|
||||
we don't have to. */
|
||||
RETURN(retval;) /* in_atrs && add_attributes set perrno, too.
|
||||
*/
|
||||
}
|
||||
*valuep = clink;
|
||||
return PSUCCESS;
|
||||
|
||||
cleanup:
|
||||
vlfree(clink);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
55
prospero/lib/pfs/in_nextline.c
Normal file
55
prospero/lib/pfs/in_nextline.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <ctype.h> /* For isascii */
|
||||
/* isascii() is not provided in POSIX, so we just do it here. */
|
||||
#ifndef isascii
|
||||
#define isascii(c) ((unsigned)(c)<=0177)
|
||||
#endif
|
||||
|
||||
/* XXX Assumes that the longest possible word we could read in is
|
||||
ARDP_PTXT_LEN_R. This is actually a bogus assumption; one can trigger the
|
||||
assertion by sending a packet with a first word longer than that.
|
||||
We don't cache the value returned from in_nextline() so it's safe to use
|
||||
static data. Keywords (1st word in a line) are never quoted; this is safe
|
||||
then.
|
||||
*/
|
||||
/* This function returns a pointer to internal data which will be overwritten
|
||||
on the next call to in_nextline().
|
||||
This function is used for lookahead in the parsing, and could be replaced
|
||||
with other routines to do that.
|
||||
*/
|
||||
|
||||
char *
|
||||
in_nextline(INPUT oldin)
|
||||
{
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
AUTOSTAT_CHARPP(bufp);
|
||||
char *cp; /* Pointer into the buffer*/
|
||||
int c;
|
||||
|
||||
if (!*bufp) *bufp = stalloc(ARDP_PTXT_LEN_R);
|
||||
cp = *bufp;
|
||||
|
||||
input_copy(oldin, in);
|
||||
if((c = in_readc(in)) == EOF) /* test for EOF */
|
||||
return NULL;
|
||||
while ((c != EOF) && isascii(c) && !isspace(c)) {
|
||||
*(cp++) = c;
|
||||
in_incc(in);
|
||||
c = in_readc(in);
|
||||
assert(cp - *bufp < p__bstsize(*bufp));
|
||||
}
|
||||
*cp = '\0';
|
||||
return *bufp;
|
||||
}
|
||||
141
prospero/lib/pfs/in_readc.c
Normal file
141
prospero/lib/pfs/in_readc.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright(c) 1993 by the University of Southern California
|
||||
* For copying information, see the file <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
int (*stdio_fseek)();
|
||||
|
||||
/* Returns the distinguished value EOF if end of input detected.
|
||||
*/
|
||||
int
|
||||
in_readc(INPUT in)
|
||||
{
|
||||
int c;
|
||||
|
||||
switch(in->sourcetype) {
|
||||
case IO_FILE:
|
||||
if((*stdio_fseek)(in->file, in->offset, 0) == -1) {
|
||||
/* improper seek */
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "in in_readc() an improper fseek was detected.");
|
||||
return '\0';
|
||||
}
|
||||
if((c = getc(in->file)) == EOF) {
|
||||
clearerr(in->file); /* don't want this to stick around. */
|
||||
}
|
||||
return c;
|
||||
case IO_STRING:
|
||||
return *(in->s)
|
||||
? (unsigned char) *(in->s) : EOF;
|
||||
case IO_RREQ:
|
||||
return (in->inpkt)
|
||||
? (unsigned char) *in->ptext_ioptr : EOF;
|
||||
case IO_BSTRING:
|
||||
return (in->offset < in->bstring_length)
|
||||
? (unsigned char) *(in->s) : EOF;
|
||||
default:
|
||||
internal_error("invalid in->iotype");
|
||||
}
|
||||
return(-1); /* Unreached - keeps gcc happy */
|
||||
}
|
||||
|
||||
|
||||
/* this is not too efficient. Fix it one day (yeah, right.). */
|
||||
int
|
||||
in_readcahead(INPUT in, int howfar)
|
||||
{
|
||||
INPUT_ST incpy_st;
|
||||
INPUT incpy = &incpy_st;
|
||||
|
||||
assert(howfar >= 0);
|
||||
input_copy(in, incpy);
|
||||
while (howfar-- > 0)
|
||||
in_incc(incpy);
|
||||
return in_readc(incpy);
|
||||
}
|
||||
|
||||
|
||||
/* This function may legally be called on a stream which has already reached
|
||||
EOF. In that case, it's a no-op. */
|
||||
void
|
||||
in_incc(INPUT in)
|
||||
{
|
||||
/* this takes advantage of the null termination trick. */
|
||||
|
||||
int c;
|
||||
|
||||
switch(in->sourcetype) {
|
||||
case IO_FILE:
|
||||
++in->offset;
|
||||
break;
|
||||
case IO_STRING:
|
||||
if (in->s) ++(in->s); /* don't increment past end of the string. */
|
||||
break;
|
||||
case IO_RREQ:
|
||||
if (in->inpkt) {
|
||||
++in->ptext_ioptr;
|
||||
++in->offset;
|
||||
/* Do a loop because there might be a crazy client that
|
||||
sends some packets in a sequence with empty length fields.
|
||||
Skip any of them we encounter; go to the next packet with some
|
||||
content. */
|
||||
while (in->ptext_ioptr >= in->inpkt->start + in->inpkt->length) {
|
||||
in->inpkt = in->inpkt->next;
|
||||
if (in->inpkt == NULL)
|
||||
break;
|
||||
in->ptext_ioptr = in->inpkt->text;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IO_BSTRING:
|
||||
if (in->offset < in->bstring_length) {
|
||||
++in->offset;
|
||||
++in->s;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
internal_error("invalid in->iotype");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* It is not at all clear what role this plays, given that in_readc() does
|
||||
* this test for us. But it remains.
|
||||
*/
|
||||
int
|
||||
in_eof(INPUT in)
|
||||
{
|
||||
switch(in->sourcetype) {
|
||||
case IO_FILE:
|
||||
if((*stdio_fseek)(in->file, in->offset, 0) == -1) {
|
||||
/* improper seek */
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "in in_readc() an improper fseek was detected.");
|
||||
return EOF;
|
||||
}
|
||||
if(getc(in->file) == EOF) {
|
||||
clearerr(in->file); /* don't want this to stick around. */
|
||||
return EOF;
|
||||
}
|
||||
return 0;
|
||||
case IO_STRING:
|
||||
if (*(in->s)) return 0;
|
||||
else return EOF;
|
||||
case IO_RREQ:
|
||||
if (in->inpkt) return 0;
|
||||
else return EOF;
|
||||
case IO_BSTRING:
|
||||
if (in->offset < in->bstring_length) return 0;
|
||||
else return EOF;
|
||||
}
|
||||
assert(FALSE); /*Never gets here */
|
||||
return -1;
|
||||
}
|
||||
51
prospero/lib/pfs/in_select.c
Normal file
51
prospero/lib/pfs/in_select.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/* author: swa@isi.edu */
|
||||
/*
|
||||
* Copyright (c) 1992 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
|
||||
/* The interface to this function will change. The long * must become a
|
||||
pointer to a list of attributes (PATTRIB *). But for now, this is correct,
|
||||
since dsrfinfo() and the name searching code don't pay attention to such
|
||||
information. */
|
||||
/* We simply ignore ID types that we don't understand. I believe this is
|
||||
correct. */
|
||||
int
|
||||
in_select(INPUT in, long *magic_nop)
|
||||
{
|
||||
char *command, *next_word;
|
||||
long atol();
|
||||
|
||||
while (in_nextline(in) && strnequal(in_nextline(in), "SELECT", 6)) {
|
||||
char t_id_type[MAX_DIR_LINESIZE];
|
||||
int retval; /* retval from subfunctions. */
|
||||
PATTRIB at = atalloc();
|
||||
|
||||
if(retval = in_line(in, &command, &next_word)) {
|
||||
atfree(at);
|
||||
return retval;
|
||||
}
|
||||
assert(next_word >= command);
|
||||
if (retval = in_atr_data(in, command, next_word, 0, at)) {
|
||||
atfree(at);
|
||||
return retval;
|
||||
}
|
||||
if (at->avtype == ATR_SEQUENCE && at->nature == ATR_NATURE_FIELD
|
||||
&& strequal(at->aname, "ID") && length(at->value.sequence) == 2
|
||||
&& strequal(at->value.sequence->token, "REMOTE")) {
|
||||
/* XXX should use qsscanf() for the overflow checking. */
|
||||
*magic_nop = atol(at->value.sequence->next->token);
|
||||
}
|
||||
/* Just ignore other attribute and ID types. */
|
||||
atfree(at);
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
23
prospero/lib/pfs/in_sequence.c
Normal file
23
prospero/lib/pfs/in_sequence.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
|
||||
/* Command should be the head of a BSTRING and NEXT_WORD should be a pointer
|
||||
into the BSTRING. */
|
||||
/* Convert portion of command starting at *next_word to list of TOKENs */
|
||||
int
|
||||
in_sequence(INPUT in, char *command, char *next_word, TOKEN *valuep)
|
||||
{
|
||||
CHECK_PTRinBUFF(command,next_word);
|
||||
*valuep = p__qbstokenize(command, next_word);
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
45
prospero/lib/pfs/internal_err.c
Normal file
45
prospero/lib/pfs/internal_err.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1992,1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pfs.h> /* includes internal error definitions. */
|
||||
#include <stdio.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/* This is set by p__fout_of_memory(). It is looked at by the server restart
|
||||
code in server/dirsrv.c and server/restart_srv.c. */
|
||||
|
||||
int p__is_out_of_memory = 0;
|
||||
|
||||
/* A function version of internal_error(). Used by macros. */
|
||||
void
|
||||
p__finternal_error(const char file[], int line, const char msg[])
|
||||
{
|
||||
#if 0
|
||||
write(2, "Internal error in file ",
|
||||
sizeof "Internal error in file " -1);
|
||||
write(2, file, strlen(file));
|
||||
write(2, ": ", 2);
|
||||
write(2, msg, strlen(msg));
|
||||
write(2, "\n", 1);
|
||||
#endif
|
||||
fprintf(stderr, "Internal error at %s:%d: %s\n",
|
||||
file, line, msg);
|
||||
if (internal_error_handler)
|
||||
(*internal_error_handler)(file, line, msg);
|
||||
else
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
p__fout_of_memory(const char file[], int line)
|
||||
{
|
||||
p__is_out_of_memory++;
|
||||
p__finternal_error(file, line, "Out of Memory");
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user