Intial commit
This commit is contained in:
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");
|
||||
}
|
||||
|
||||
26
prospero/lib/pfs/is_file.c
Normal file
26
prospero/lib/pfs/is_file.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Is this a file? uses stat() */
|
||||
#include <pfs.h> /* for prototypes */
|
||||
|
||||
/* Is it a regular file? 1 = yes, 0 = no, -1 = failure? */
|
||||
extern int
|
||||
is_file(const char native_filename[])
|
||||
{
|
||||
struct stat st_buf;
|
||||
|
||||
if(stat(native_filename, &st_buf) == 0)
|
||||
return S_ISREG(st_buf.st_mode) ? 1 : 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
20
prospero/lib/pfs/length.c
Normal file
20
prospero/lib/pfs/length.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 <pfs.h>
|
||||
|
||||
/* Return the length of a sequence. Works like the Common Lisp LENGTH function
|
||||
on sequences. */
|
||||
int
|
||||
length(TOKEN s)
|
||||
{
|
||||
int len;
|
||||
for (len = 0; s; s = s->next, ++len)
|
||||
;
|
||||
return len;
|
||||
}
|
||||
98
prospero/lib/pfs/mapname.c
Normal file
98
prospero/lib/pfs/mapname.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <psite.h>
|
||||
#include <pcompat.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
/*
|
||||
* see pcompat.h for the meanings of the flags
|
||||
*/
|
||||
/* This function looks a heck of a lot like retrieve_link() in user/vget.c. If
|
||||
there's a bug here, there's one there too. */
|
||||
/* This can be easily changed to use the stcopyr() interface, and should be at
|
||||
some point in the future. */
|
||||
int
|
||||
mapname(vl,npath, npathlen, flags)
|
||||
VLINK vl;
|
||||
char *npath; /* local pathname for file you can work with.
|
||||
This is filled in by mapname(). */
|
||||
int npathlen;
|
||||
int flags;
|
||||
{
|
||||
|
||||
TOKEN am_args; /* filled in by pget_am */
|
||||
int am;
|
||||
int tmp;
|
||||
int methods = P_AM_LOCAL; /* local filenames always are supported.
|
||||
*/
|
||||
|
||||
#ifdef P_NFS
|
||||
methods |= P_AM_NFS;
|
||||
#endif P_NFS
|
||||
|
||||
#ifdef P_AFS
|
||||
methods |= P_AM_AFS;
|
||||
#endif P_AFS
|
||||
|
||||
|
||||
/* P_AM_FTP requires prompting for a password, which is not something
|
||||
transparent to the user. That's why the programmer must explicitly
|
||||
specify the MAP_PROMPT_OK flag. */
|
||||
if ((flags | MAP_READONLY) && (flags | MAP_PROMPT_OK)) methods |= P_AM_FTP;
|
||||
if(flags | MAP_READONLY)
|
||||
methods |= P_AM_AFTP | P_AM_GOPHER | P_AM_RCP \
|
||||
| P_AM_PROSPERO_CONTENTS | P_AM_WAIS;
|
||||
|
||||
am = pget_am(vl,&am_args,methods);
|
||||
|
||||
if(!am && perrno) {
|
||||
return(perrno);
|
||||
}
|
||||
|
||||
switch(am) {
|
||||
|
||||
#ifdef P_NFS
|
||||
case P_AM_NFS:
|
||||
/* XXX You must change pmap_nfs() to meet the needs of your site. */
|
||||
tmp = pmap_nfs(vl->host,vl->hsoname,npath, npathlen, am_args);
|
||||
return(tmp);
|
||||
#endif P_NFS
|
||||
|
||||
#ifdef P_AFS
|
||||
case P_AM_AFS:
|
||||
strcpy(npath,P_AFS);
|
||||
strcat(npath,elt(am_args,4)); /* 4th element is the hsoname. */
|
||||
return(PSUCCESS);
|
||||
#endif P_AFS
|
||||
|
||||
case P_AM_AFTP:
|
||||
case P_AM_FTP:
|
||||
case P_AM_GOPHER:
|
||||
case P_AM_WAIS:
|
||||
case P_AM_PROSPERO_CONTENTS:
|
||||
|
||||
tmp = p__map_cache(vl, npath, npathlen, am_args);
|
||||
return(tmp);
|
||||
|
||||
case P_AM_LOCAL:
|
||||
strcpy(npath, elt(am_args, 4));
|
||||
return PSUCCESS;
|
||||
|
||||
default:
|
||||
return(PFSA_AM_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
148
prospero/lib/pfs/mk_vdir.c
Normal file
148
prospero/lib/pfs/mk_vdir.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
#include <pparse.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
/*
|
||||
*/
|
||||
int
|
||||
mk_vdir(vpath,flags)
|
||||
const char *vpath; /* Name of the new directory */
|
||||
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;
|
||||
char *next_line;
|
||||
|
||||
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 into which the link */
|
||||
/* will be inserted */
|
||||
|
||||
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\n\
|
||||
CREATE-OBJECT VIRTUAL+DIRECTORY%s %'s\n",
|
||||
remdir, ((flags&MKVD_LPRIV) ? "+LPRIV" : ""), cname);
|
||||
|
||||
tmp = ardp_send(req,dirhst,0,ARDP_WAIT_TILL_TO);
|
||||
|
||||
if(tmp) {
|
||||
fprintf(stderr,"ardp_send failed: %d\n",tmp);
|
||||
perrno = tmp;
|
||||
}
|
||||
|
||||
/* If we don't get a response, then return error */
|
||||
if(req->rcvd == NULL) return(perrno);
|
||||
|
||||
rreqtoin(req, in); /* not currently used. */
|
||||
/* Here we must parse reponse - While looking at each packet */
|
||||
while(!in_eof(in)) {
|
||||
char *line;
|
||||
char *next_word; /* a dummy, here. */
|
||||
int retval;
|
||||
|
||||
/* Look at each line in packet */
|
||||
if(retval = in_line(in, &line, &next_word))
|
||||
return retval;
|
||||
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;
|
||||
return(perrno);
|
||||
}
|
||||
121
prospero/lib/pfs/mkdirs.c
Normal file
121
prospero/lib/pfs/mkdirs.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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 <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pmachine.h>
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
|
||||
/*
|
||||
* mkdirs - Make a directory and all superior directories
|
||||
*
|
||||
* MKDIRS takes a pathame for a directory, checks to see
|
||||
* whether it exists, and if not creates it. Any parent
|
||||
* directories which do not exist will be created as
|
||||
* well.
|
||||
*
|
||||
* ARGS: path - path of the directoriy to be created
|
||||
*
|
||||
* RETURNS: 0 on success
|
||||
* the contents of errno on error
|
||||
*/
|
||||
/*
|
||||
* I've mutilated this file because most calls I found where having to
|
||||
* go through the effort of making a string for the directory name
|
||||
* from a file
|
||||
*
|
||||
* The old version also had a bug (though I found it through looking at
|
||||
* the code, not from experience, and a number of non-standards etc
|
||||
* Specifically:
|
||||
* if errno was non-zero on entry, and the directory exists, then
|
||||
* the code would find stat==0, it was a directory, tmp is zero,
|
||||
* and it would return the errno (or even fail to recreate the directory)
|
||||
* it should return immediately if the directory exists
|
||||
*
|
||||
* rindex is not POSIX
|
||||
*
|
||||
* it uses MAXPATHLEN, also non-POSIX
|
||||
*
|
||||
* the headers in here, conflicted with those in pfs.h
|
||||
*/
|
||||
#define RETURN(r1) { retval=r1 ; goto cleanup; }
|
||||
/* Argument should be TRUE if one should not strip off the trailing suffix,
|
||||
* false if one does need to strip off the trailing suffix.
|
||||
*/
|
||||
int
|
||||
p__mkdirs(const char path[], int wantdir)
|
||||
{
|
||||
char *prefix = NULL;
|
||||
char *suffix; /* Pointer into prefix */
|
||||
struct stat st;
|
||||
int mode = 0777;
|
||||
int retval = 0;
|
||||
|
||||
if (stat(path, &st) == 0) { /* exists, either dir. or file */
|
||||
if (!wantdir)
|
||||
return 0; /* File exists, so directory must */
|
||||
if (wantdir && !S_ISDIR(st.st_mode))
|
||||
return (EEXIST); /* already exists and is not dir. */
|
||||
return 0; /* Directory exists */
|
||||
}
|
||||
|
||||
if (!wantdir) { /* Want file, build parent directory */
|
||||
prefix = stcopy(path);
|
||||
if (!(suffix = strrchr(prefix, '/'))) {
|
||||
RETURN(PSUCCESS); /* No directory to build - thats ok*/
|
||||
} else {
|
||||
*suffix = '\0';
|
||||
RETURN(p__mkdirs(prefix, 1)) ; /* Recurse on directory*/
|
||||
}
|
||||
} else { /*wantdir*/
|
||||
/* If want directory, but specified trailing slash*/
|
||||
if (path[strlen(path)-1] == '/') {
|
||||
prefix = stcopy(path);
|
||||
prefix[strlen(prefix)-1] = '\0';
|
||||
RETURN(p__mkdirs(prefix, 1)); /*recurse without /*/
|
||||
}
|
||||
if (!mkdir(path, mode)) {
|
||||
chmod(path, mode);
|
||||
RETURN(0);
|
||||
}
|
||||
switch (errno) {
|
||||
case ENOENT: /* Failed because no parent, recurse for it */
|
||||
prefix = stcopy(path);
|
||||
if (suffix = strrchr(prefix, '/'))
|
||||
*suffix = '\0';
|
||||
else
|
||||
*prefix = '\0';
|
||||
|
||||
assert(*prefix != '\0'); /* Is no parent, strange */
|
||||
|
||||
if (retval = p__mkdirs(prefix, TRUE))
|
||||
RETURN(retval); /* Recurse on parent */
|
||||
RETURN(p__mkdirs(path,TRUE)); /* Recurse on self */
|
||||
case EEXIST: /* Someone else created it for us */
|
||||
RETURN(PSUCCESS);
|
||||
default: /* mkdir failed for some other reason */
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldnt create %s: %s", path, unixerrstr());
|
||||
RETURN(errno);
|
||||
}
|
||||
} /*wantdir*/
|
||||
|
||||
cleanup:
|
||||
stfree(prefix);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/* back compatibility*/
|
||||
int
|
||||
mkdirs(const char *path)
|
||||
{
|
||||
return p__mkdirs(path, 1);
|
||||
}
|
||||
164
prospero/lib/pfs/modify_acl.c
Normal file
164
prospero/lib/pfs/modify_acl.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 <pprot.h>
|
||||
#include <perrno.h>
|
||||
#include <pparse.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
extern char *acltypes[];
|
||||
|
||||
/*
|
||||
*
|
||||
* Flags:
|
||||
*/
|
||||
int
|
||||
modify_acl(dlink,lname,a,flags)
|
||||
VLINK dlink; /* Directory link */
|
||||
const char *lname; /* Link name. Must be empty for DIRECTORY
|
||||
option. OBJECT option not implemented, so
|
||||
don't worry about it. */
|
||||
ACL a; /* ACL entry to add/delete/modify */
|
||||
int flags; /* Flags */
|
||||
{
|
||||
RREQ req; /* Text of request to dir server */
|
||||
char options[100]; /* List of options */
|
||||
char *optptr; /* Options minus leading + */
|
||||
int tmp;
|
||||
OUTPUT_ST out_st;
|
||||
OUTPUT out = &out_st;
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
|
||||
int fwdcnt = MAX_FWD_DEPTH;
|
||||
|
||||
*options = '\0';
|
||||
|
||||
if(flags&EACL_NOSYSTEM) strcat(options,"+NOSYSTEM");
|
||||
if(flags&EACL_NOSELF) strcat(options,"+NOSELF");
|
||||
|
||||
if((flags&EACL_OP) == EACL_DEFAULT) strcat(options,"+DEFAULT");
|
||||
else if((flags&EACL_OP) == EACL_SET) strcat(options,"+SET");
|
||||
else if((flags&EACL_OP) == EACL_INSERT) strcat(options,"+INSERT");
|
||||
else if((flags&EACL_OP) == EACL_DELETE) strcat(options,"+DELETE");
|
||||
else if((flags&EACL_OP) == EACL_ADD) strcat(options,"+ADD");
|
||||
else if((flags&EACL_OP) == EACL_CREATE) strcat(options,"+CREATE");
|
||||
else if((flags&EACL_OP) == EACL_DESTROY) strcat(options,"+DESTROY");
|
||||
else if((flags&EACL_OP) == EACL_SUBTRACT) strcat(options,"+SUBTRACT");
|
||||
else RETURNPFAILURE; /* bad operation */
|
||||
|
||||
if((flags&EACL_OTYPE) == EACL_LINK) strcat(options,"+LINK");
|
||||
else if((flags&EACL_OTYPE) == EACL_DIRECTORY) strcat(options,"+DIRECTORY");
|
||||
else if((flags&EACL_OTYPE) == EACL_OBJECT) strcat(options,"+OBJECT");
|
||||
else if((flags&EACL_OTYPE) == EACL_INCLUDE) strcat(options,"+INCLUDE");
|
||||
else if((flags&EACL_OTYPE) == EACL_NAMED) strcat(options,"+NAMED");
|
||||
else RETURNPFAILURE; /* bad target */
|
||||
|
||||
/* CREATE and DESTROY are only valid with NAMED. */
|
||||
if (((flags & EACL_OP) == EACL_CREATE || (flags & EACL_OP) == EACL_DESTROY)
|
||||
&& (flags & EACL_OTYPE) != EACL_NAMED)
|
||||
RETURNPFAILURE;
|
||||
optptr = options + 1;
|
||||
|
||||
if(lname == NULL) lname = "";
|
||||
|
||||
if(strcmp(dlink->target,"NULL") == 0) return(PFS_EXT_USED_AS_DIR);
|
||||
if(strcmp(dlink->target,"EXTERNAL") == 0) return(PFS_EXT_USED_AS_DIR);
|
||||
|
||||
startover:
|
||||
|
||||
req = p__start_req(dlink->host);
|
||||
/* XXX need to add capability for ID specification.. */
|
||||
requesttoout(req,out);
|
||||
|
||||
if(((flags&EACL_OTYPE) == EACL_DIRECTORY) ||
|
||||
((flags&EACL_OTYPE) == EACL_LINK)) {
|
||||
p__add_req(req,"DIRECTORY ASCII %'s\n", dlink->hsoname);
|
||||
}
|
||||
|
||||
if((flags&EACL_OTYPE) == EACL_OBJECT)
|
||||
p__add_req(req,"EDIT-ACL %s %'s\n",optptr, dlink->hsoname);
|
||||
else p__add_req(req,"EDIT-ACL %s %'s\n",optptr, lname);
|
||||
|
||||
out_acl(out, a);
|
||||
|
||||
perrno = 0;
|
||||
|
||||
tmp = ardp_send(req,dlink->host,0,ARDP_WAIT_TILL_TO);
|
||||
|
||||
if(tmp) {
|
||||
if (pfs_debug) fprintf(stderr,"ardp_send failed: %d\n",tmp);
|
||||
perrno = tmp;
|
||||
}
|
||||
|
||||
/* If we don't get a response, then return error */
|
||||
if(req->rcvd == NOPKT) {
|
||||
ardp_rqfree(req);
|
||||
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(qsscanf(line, "FORWARDED%~%r", &next_word) == 1) {
|
||||
if(fwdcnt-- <= 0) {
|
||||
ardp_rqfree(req);
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
return(perrno);
|
||||
}
|
||||
if (tmp = in_forwarded_data(in, line, next_word, dlink)) {
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
ardp_rqfree(req);
|
||||
break;
|
||||
}
|
||||
/* Success; scan again. */
|
||||
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);
|
||||
}
|
||||
30
prospero/lib/pfs/month_sname.c
Normal file
30
prospero/lib/pfs/month_sname.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 1989 by the University of Washington
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <uw-copyright.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
|
||||
/*
|
||||
* month_sname - Return a month name from it's number
|
||||
*
|
||||
* MONTH_SNAME takes a number in the range 0
|
||||
* to 12 and returns a pointer to a string
|
||||
* representing the three letter abbreviation
|
||||
* for that month. If the argument is out of
|
||||
* range, MONTH_SNAME returns a pointer to "Unk".
|
||||
*
|
||||
* ARGS: n - Number of the month
|
||||
* RETURNS: Abbreviation for selected month
|
||||
*/
|
||||
char *month_sname(n)
|
||||
int n; /* Month number */
|
||||
{
|
||||
static char *name[] = {"Unk",
|
||||
"Jan","Feb","Mar","Apr","May","Jun",
|
||||
"Jul","Aug","Sep","Oct","Nov","Dec"
|
||||
};
|
||||
return((n < 1 || n > 12) ? name[0] : name[n]);
|
||||
}
|
||||
117
prospero/lib/pfs/myhost.c
Normal file
117
prospero/lib/pfs/myhost.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1993,1994 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*
|
||||
* Original author: BCN (washington) (1989, 1991).
|
||||
* Hacked by SWA.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <pcompat.h> /* for DISABLE_PFS() */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netdb.h>
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 255 /* limit in 4.2BSD manual pages. */
|
||||
#endif
|
||||
#include <pfs.h> /* for definitions of myhostname and myaddress.*/
|
||||
|
||||
/* These are mutexed below. */
|
||||
static char myhname[MAXHOSTNAMELEN + 1];
|
||||
static long myhaddr = 0L;
|
||||
|
||||
char *myhostname();
|
||||
|
||||
/* The auto-initialization mutexing here works, but is not used. */
|
||||
/* If you turn it on, you'll have to change lib/pfs/pfs_mutexes.c and
|
||||
include/pfs.h to add p_th_mutexPFS_MYHOSTNAME. */
|
||||
#undef P__MYHOST_MUTEX_AUTOINITIALIZATION
|
||||
|
||||
long
|
||||
myaddress(void)
|
||||
{
|
||||
/* First time called, make sure myhostname has been run */
|
||||
if(!myhaddr) {
|
||||
#ifndef P__MYHOST_MUTEX_AUTOINITIALIZATION
|
||||
/* myaddress() should be called as part of any general
|
||||
library initialization when running multi-threaded. */
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
#endif
|
||||
myhostname();
|
||||
}
|
||||
return(myhaddr);
|
||||
}
|
||||
|
||||
/* myhostname() always returns the official name of the host (see comment below
|
||||
for an exception to this claim; do not rely on it.
|
||||
This might be different from the version returned by gethostname(), and
|
||||
might well be different from the version stored in the 'hstname' environment
|
||||
variable defined in dirsrv.c */
|
||||
|
||||
/* This is normally called by dirsrv in p_init_mutexes() so that it
|
||||
will not fail in a multi-threaded environment. */
|
||||
|
||||
|
||||
/*
|
||||
* Implementation and Specification Comments:
|
||||
* From the SunOS 4.1.3 manual page for "gethostbyname(3)":
|
||||
* "The members of this structure are:
|
||||
h_name Official name of the host. [ ... ]"
|
||||
*
|
||||
* Under Solaris 2.3, Mitra reports that a short name that is not the fully
|
||||
* qualified domain name is being returned in the h_name member. This makes
|
||||
* myhostname() return a name that is not the official name of the host.
|
||||
*
|
||||
*
|
||||
* Problems if we don't get the fully qualified domain name (swa went through
|
||||
* all the existing code calling this function to check and make sure no
|
||||
* problems would arise):
|
||||
* dirsrv.c: no problem; envar overrides #define overrides myhostname()
|
||||
* ftp.c (in vcache): used to contstruct password for anonymous FTP.
|
||||
* So: no problem.
|
||||
* Not used elsewhere in the existing code; future code will be aware of the
|
||||
* potential problem.
|
||||
*/
|
||||
|
||||
|
||||
char *
|
||||
myhostname()
|
||||
{
|
||||
static int initialized = 0;
|
||||
|
||||
/* First time called, find out hostname and remember it */
|
||||
if(!initialized) {
|
||||
struct hostent *current_host;
|
||||
|
||||
#ifdef P__MYHOST_MUTEX_AUTOINITIALIZATION
|
||||
#ifdef PFS_THREADS
|
||||
p_th_mutex_lock(p_th_mutexPFS_MYHOSTNAME);
|
||||
if (!initialized) { /* check again */
|
||||
#endif
|
||||
#else
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* autoinitializing */
|
||||
#endif
|
||||
gethostname(myhname,sizeof(myhname));
|
||||
/* gethostbyname reads files, so we must disable pfs */
|
||||
p_th_mutex_lock(p_th_mutexGETHOSTBYNAME);
|
||||
DISABLE_PFS(current_host = gethostbyname(myhname));
|
||||
strcpy(myhname,current_host->h_name);
|
||||
/* Save the address too */
|
||||
/* Length of the address is h_length; in practice, is always 4. */
|
||||
bcopy(current_host->h_addr,&myhaddr, current_host->h_length);
|
||||
/* We're now done copying data out of the current_host structure,
|
||||
so we can safely unlock the mutex around GETHOSTBYNAME */
|
||||
p_th_mutex_unlock(p_th_mutexGETHOSTBYNAME);
|
||||
ucase(myhname);
|
||||
++initialized;
|
||||
#ifdef P__MYHOST_MUTEX_AUTOINITIALIZATION
|
||||
#ifdef PFS_THREADS
|
||||
p_th_mutex_unlock(p_th_mutexPFS_MYHOSTNAME);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return(myhname);
|
||||
}
|
||||
139
prospero/lib/pfs/oballoc.c
Normal file
139
prospero/lib/pfs/oballoc.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h> /* For malloc and free */
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
static P_OBJECT lfree = NULL;
|
||||
int p_object_count = 0;
|
||||
int p_object_max = 0;
|
||||
|
||||
/*
|
||||
* oballoc - allocate and initialize p_object structure
|
||||
*
|
||||
* OBALLOC returns a pointer to an initialized structure of type
|
||||
* P_OBJECT. If it is unable to allocate such a structure, it
|
||||
* signals out_of_memory();
|
||||
*/
|
||||
P_OBJECT
|
||||
oballoc(void)
|
||||
{
|
||||
P_OBJECT ob;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexOBALLOC);
|
||||
if(lfree) {
|
||||
ob = lfree;
|
||||
lfree = lfree->next;
|
||||
}
|
||||
else {
|
||||
ob = (P_OBJECT) malloc(sizeof(P_OBJECT_ST));
|
||||
if (!ob) out_of_memory();
|
||||
p_object_max++;
|
||||
}
|
||||
|
||||
p_object_count++;
|
||||
p_th_mutex_unlock(p_th_mutexOBALLOC);
|
||||
|
||||
/* Initialize and fill in default values */
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
ob->consistency = INUSE_PATTERN;
|
||||
#endif
|
||||
ob->version = 0; /* version is always zero. */
|
||||
ob->flags = 0; /* no flags set */
|
||||
ob->inc_native = VDIN_UNINITIALIZED; /* don't write out object until this
|
||||
is reset. Used only on server. */
|
||||
ob->magic_no = 0L; /* zero means unset */
|
||||
ob->acl = NULL; /* */
|
||||
ob->exp = 0;
|
||||
ob->ttl = 0;
|
||||
ob->last_ref = 0;
|
||||
ob->forward = NULL;
|
||||
ob->backlinks = NULL;
|
||||
ob->attributes = NULL;
|
||||
ob->links = NULL;
|
||||
ob->ulinks = NULL;
|
||||
ob->native_mtime = 0;
|
||||
ob->shadow_file = NULL; /* used only on server.*/
|
||||
ob->status = DQ_INACTIVE; /* used only in client mode. */
|
||||
ob->dqs = NULL; /* ditto */
|
||||
ob->statbuf = NULL; /* Used only on server */
|
||||
ob->app.ptr = NULL; /* On every architecture I ever heard of, ob->
|
||||
app.flg is now 0 too */
|
||||
ob->previous = NULL;
|
||||
ob->next = NULL;
|
||||
return(ob);
|
||||
}
|
||||
|
||||
static void (*obappfreefunc)(P_OBJECT) = NULL;
|
||||
|
||||
/*
|
||||
* Specify which special freeing function (if any) to be used to free the
|
||||
* app.ptr member of the P_OBJECT structure, if set.
|
||||
*/
|
||||
void
|
||||
obappfree(void (* appfreefunc)(P_OBJECT))
|
||||
{
|
||||
obappfreefunc = appfreefunc;
|
||||
}
|
||||
|
||||
/*
|
||||
* obfree - free a P_OBJECT structure
|
||||
*
|
||||
* OBFREE takes a pointer to a P_OBJECT structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
obfree(P_OBJECT ob)
|
||||
{
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(ob->consistency == INUSE_PATTERN);
|
||||
ob->consistency = FREE_PATTERN;
|
||||
#endif
|
||||
if(ob->acl) aclfree(ob->acl); ob->acl = NULL;
|
||||
if(ob->forward) { vllfree(ob->forward); ob->forward = NULL;}
|
||||
if(ob->backlinks) { vllfree(ob->backlinks); ob->backlinks = NULL;}
|
||||
if(ob->attributes) { atlfree(ob->attributes); ob->attributes = NULL;}
|
||||
if(ob->links) { vllfree(ob->links); ob->links = NULL; }
|
||||
if(ob->ulinks) { vllfree(ob->ulinks); ob->ulinks = NULL; }
|
||||
if(ob->shadow_file) {stfree(ob->shadow_file); ob->shadow_file = NULL;}
|
||||
if(ob->statbuf) {stfree(ob->statbuf); ob->statbuf = NULL;}
|
||||
/* If ob->dqs signal a memory leak. */
|
||||
if(obappfreefunc && ob->app.ptr) {
|
||||
(*obappfreefunc)(ob->app.ptr);
|
||||
ob->app.ptr = NULL;
|
||||
}
|
||||
|
||||
p_th_mutex_lock(p_th_mutexOBALLOC);
|
||||
ob->next = lfree;
|
||||
ob->previous = NULL;
|
||||
lfree = ob;
|
||||
p_object_count--;
|
||||
p_th_mutex_unlock(p_th_mutexOBALLOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* oblfree - free a P_OBJECT structure list
|
||||
*
|
||||
* OBLFREE takes a pointer to a P_OBJECT structure frees it and any linked
|
||||
* P_OBJECT structures. It is used to free an entire list of P_OBJECT
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
oblfree(P_OBJECT ob)
|
||||
{
|
||||
P_OBJECT nxt;
|
||||
|
||||
while(ob != NULL) {
|
||||
nxt = ob->next;
|
||||
obfree(ob);
|
||||
ob = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
21
prospero/lib/pfs/obother.c
Normal file
21
prospero/lib/pfs/obother.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Other routines - written by Mitra - that deal with P_OBJECT's
|
||||
*
|
||||
* Steve - feel free to move anywhere you want
|
||||
*/
|
||||
#include <pfs.h>
|
||||
|
||||
/* Syntactically same as atput in goph_gw_dsdb.c */
|
||||
/* Note caller must pass last arg as (char *)0 */
|
||||
/* Note an arg of *char *)1 will force next arg to be pointed at rather
|
||||
than copied */
|
||||
void ob_atput(P_OBJECT po, char *name, ...)
|
||||
{
|
||||
va_list ap;
|
||||
PATTRIB at;
|
||||
|
||||
va_start(ap, name);
|
||||
at = vatbuild(name, ap);
|
||||
APPEND_ITEM(at, po->attributes);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
203
prospero/lib/pfs/opentcp.c
Normal file
203
prospero/lib/pfs/opentcp.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h> /* for fcntl() */
|
||||
#include <fcntl.h> /* for fcntl() */
|
||||
#include <errno.h> /* for EINPROGRESS. etc.*/
|
||||
#ifdef AIX /* lucb */
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <pfs_threads.h>
|
||||
#include <ardp.h>
|
||||
#include <perrno.h>
|
||||
#include <pfs.h>
|
||||
#include <sys/time.h> /* For gettimeofday */
|
||||
#include <sockettime.h> /* for xxx_APPROACH */
|
||||
|
||||
/* Open a TCP stream from here to the HOST at the PORT. */
|
||||
/* Return socket descriptor on success, or -1 on failure. */
|
||||
/* This is mostly swiped from user/vcache/gopherget.c */
|
||||
/* It is part of the Prospero library. It includes special goodies to keep
|
||||
the connect() operation from blocking in a multi-threaded environment.
|
||||
Non-blocking or briefly-blocking TCP opens are important here. */
|
||||
|
||||
/* Uses hostname2addr() in the ARDP library. */
|
||||
|
||||
/* Like close, but try again if EINTR */
|
||||
static int
|
||||
sure_close(int s)
|
||||
{
|
||||
int retval;
|
||||
while ((((retval = close(s)) == -1) && (errno == EINTR)));
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/* Wait till the file descriptor is writable or times out */
|
||||
/* Returns: 1 success, 0, timeout, -1 (& errno) error */
|
||||
static int
|
||||
wait_till_writable(int s,int timeout)
|
||||
{
|
||||
struct timeval time_out;
|
||||
fd_set writefds;
|
||||
int retval;
|
||||
int soerror;
|
||||
int lensoerrors = sizeof(soerror);
|
||||
|
||||
time_out.tv_sec = timeout;
|
||||
time_out.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&writefds);
|
||||
FD_SET(s,&writefds);
|
||||
|
||||
switch (retval = select(FD_SETSIZE, NULL, &writefds, NULL, &time_out)) {
|
||||
case 1:
|
||||
retval = getsockopt(s, SOL_SOCKET, SO_ERROR,
|
||||
(char *)&soerror, &lensoerrors);
|
||||
/* While we'd like the error back in soerror,
|
||||
it fails when there is an error*/
|
||||
if (retval) return -1;
|
||||
return 1;
|
||||
|
||||
case 0:
|
||||
case -1:
|
||||
default:
|
||||
return(retval);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait till the file descriptor is readable or times out */
|
||||
/* Returns: 1 success, 0, timeout, -1 (& errno) error */
|
||||
int
|
||||
wait_till_readable(int s,int timeout)
|
||||
{
|
||||
struct timeval time_out;
|
||||
fd_set readfds;
|
||||
|
||||
time_out.tv_sec = timeout;
|
||||
time_out.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(s,&readfds);
|
||||
return(select(FD_SETSIZE, &readfds, NULL, NULL, &time_out));
|
||||
}
|
||||
|
||||
int
|
||||
quick_open_tcp_stream(const char host[], int port, int timeout)
|
||||
{
|
||||
extern int ardp_hostname2addr(const char *hostname, struct sockaddr_in *hostaddr);
|
||||
struct sockaddr_in server; /* server side socket. */
|
||||
int s; /* the socket */
|
||||
int tmp; /* return from subfunctions. */
|
||||
|
||||
if(ardp_hostname2addr(host, &server)) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"%s: unknown host\n", host);
|
||||
return -1; /* p_err_string not set in callee */
|
||||
}
|
||||
server.sin_port = htons(port);
|
||||
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldn't reach host %s: Call to socket(AF_INET, SOCK_STREAM,\
|
||||
0) failed: errno %d: %s", host, errno, unixerrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SETSOCKOPTS
|
||||
/* Actually, these may be generally usefull. */
|
||||
#define M_SETSOCKOPT(f,sol,p1,p2,p3) \
|
||||
if (setsockopt(f,sol,p1,p2,p3)) { \
|
||||
p_err_string = qsprintf_stcopyr(p_err_string, \
|
||||
"INTERNAL: setsockopt failure: %s %s", "##p1##",unixerrstr()); \
|
||||
sure_close(f); \
|
||||
return -1; \
|
||||
}
|
||||
#ifndef UCX
|
||||
M_SETSOCKOPT(s, SOL_SOCKET, ~SO_LINGER, 0, 0);
|
||||
#endif
|
||||
/* Allow address reuse, I forget exactly why, but its something to do
|
||||
with a time delay before address:port pairs can be reused otherwise */
|
||||
M_SETSOCKOPT(s, SOL_SOCKET, SO_REUSEADDR, 0, 0);
|
||||
/* Attempt to keep a silent connection alive, and so fail if it goes down */
|
||||
M_SETSOCKOPT(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
|
||||
#endif /*SETSOCKOPTS*/
|
||||
|
||||
#if defined(NONBLOCKING_APPROACH) || defined(SELECT_APPROACH)
|
||||
/* This is one approach to multi-threading. The problem with it is
|
||||
that we seem to get 'address in use' errors. */
|
||||
/* Set the socket non-blocking if we're running multithreaded. The main
|
||||
downside of this approach is that we're not going to be able to get a
|
||||
great error message if the call to connect() fails, which is why we
|
||||
don't normally enable this in the non-threaded case. */
|
||||
/* This code has not been fully tested. If the FNDELAY operation is
|
||||
unavailable on your version of unix, you will need an alternative
|
||||
approach. Mitra has one in his TCPTIME patch. */
|
||||
/* This may be FDELAY on some systems -
|
||||
its O_NODELAY or O_NONBLOCK on Solaris2.3 & POSIX*/
|
||||
if(fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"call to fcntl(s, F_SETFL, \
|
||||
FNDELAY) failed: errno %d: %s", errno, unixerrstr());
|
||||
/* Close the socket so we don't have trash data hanging around. */
|
||||
sure_close(s);
|
||||
return -1;
|
||||
}
|
||||
#endif /*NONBLOCKING_APPROACH||SELECT_APPROACH*/
|
||||
|
||||
/* Connect will do the bind for us! Hooray! That's a relief. */
|
||||
/* connect() will return -1 if the connection is already in progress. */
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
if ((quick_connect(s, (struct sockaddr *) &server, sizeof server, timeout))
|
||||
==-1) {
|
||||
#else /*!TIMEOUT_APPROACH*/
|
||||
redo_connect:
|
||||
tmp = connect(s, (struct sockaddr *) &server, sizeof server);
|
||||
if (tmp == -1) {
|
||||
/* Ick - doing an fprintf, meant that in the non-debugging mode,
|
||||
where there is no stderr, this will fail and CHANGE errno to "Bad
|
||||
FileNo */
|
||||
|
||||
switch (errno) {
|
||||
case EINPROGRESS:
|
||||
#ifdef SELECT_APPROACH
|
||||
switch (wait_till_writable(s,timeout)) {
|
||||
case -1: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"unable to connect to: %s(%d)", host, port);
|
||||
/* "call to select failed: %s", unixerrstr()); */
|
||||
sure_close(s);
|
||||
return -1;
|
||||
case 0:
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"took more than %d secs to connect to: %s(%d)",
|
||||
timeout, host, port);
|
||||
sure_close(s);
|
||||
return -1;
|
||||
}
|
||||
/* Default is going to be 1 - which is success */
|
||||
|
||||
#endif /*SELECT_APPROACH*/
|
||||
return s; /* Non-blocking*/
|
||||
case EINTR: goto redo_connect; /* Interrupted*/
|
||||
}
|
||||
#endif /*!TIMEOUT_APPROACH*/
|
||||
/* I've changed this cos users will see it all the time, lets make
|
||||
it friendly - this has all the relevant info! - Mitra */
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldn't connect to host %s: %s", host, unixerrstr());
|
||||
/* Now close it so we don't have the descriptor and associated data
|
||||
hanging around. */
|
||||
sure_close(s);
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
45
prospero/lib/pfs/out_acl.c
Normal file
45
prospero/lib/pfs/out_acl.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
|
||||
static int out_ac(OUTPUT out, ACL ac);
|
||||
|
||||
int
|
||||
out_acl(OUTPUT out, ACL acl)
|
||||
{
|
||||
int retval = PSUCCESS;
|
||||
/* This check helps us track down a possible bug involving occasional loops
|
||||
as a result of subtraction of ACL rights. */
|
||||
int num_times = 0; /* # of times through loop */
|
||||
ACL sentinel_acl = NULL; /* mark a sentinel after we've been
|
||||
through too many times */
|
||||
for (; acl; acl = acl->next) {
|
||||
if (acl == sentinel_acl)
|
||||
internal_error("Found an ACL with a cycle in it");
|
||||
if(++num_times == 100) sentinel_acl = acl;
|
||||
if (!retval) retval = out_ac(out, acl);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* Spits out an ACL line describing the ACL entry "ac". */
|
||||
static int
|
||||
out_ac(OUTPUT out, ACL ac)
|
||||
{
|
||||
extern char *acltypes[]; /* defined in lib/pfs/acltypes.c */
|
||||
|
||||
qoprintf(out, "ACL %'s %'s %'s", acltypes[ac->acetype],
|
||||
(ac->atype ? ac->atype : ""),
|
||||
(ac->rights ? ac->rights : ""), 0);
|
||||
return out_sequence(out, ac->principals);
|
||||
}
|
||||
|
||||
71
prospero/lib/pfs/out_atr.c
Normal file
71
prospero/lib/pfs/out_atr.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
|
||||
extern int p__server; /* set if server is calilng this code. */
|
||||
|
||||
/* This function sends a protocol reply line in appropriate format describing
|
||||
the attribute AT. It only outputs for a single attribute, not for a list
|
||||
of them. */
|
||||
|
||||
int
|
||||
out_atr(OUTPUT out, PATTRIB at, int nesting)
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(at);
|
||||
qoprintf(out, "ATTRIBUTE");
|
||||
for (i = nesting; i; --i) {
|
||||
qoprintf(out, ">");
|
||||
}
|
||||
if (at->nature == ATR_NATURE_FIELD) {
|
||||
qoprintf(out, " %'s FIELD %'s",
|
||||
lookup_precedencename_by_precedence(at->precedence),
|
||||
at->aname);
|
||||
#ifndef REALLY_NEW_FIELD
|
||||
/* Databases (files) get the new format right away. */
|
||||
if (!p__server || out->f ||
|
||||
lookup_avtype_by_field_name(at->aname) == ATR_UNKNOWN) {
|
||||
#endif
|
||||
qoprintf(out, " %'s", lookup_avtypename_by_avtype(at->avtype));
|
||||
#ifndef REALLY_NEW_FIELD
|
||||
}
|
||||
#endif
|
||||
|
||||
} else if (at->nature == ATR_NATURE_INTRINSIC) {
|
||||
qoprintf(out, " %'s INTRINSIC %'s %'s",
|
||||
lookup_precedencename_by_precedence(at->precedence),
|
||||
at->aname, lookup_avtypename_by_avtype(at->avtype));
|
||||
} else {
|
||||
assert(at->nature == ATR_NATURE_APPLICATION);
|
||||
qoprintf(out, " %'s APPLICATION %'s %'s",
|
||||
lookup_precedencename_by_precedence(at->precedence),
|
||||
at->aname, lookup_avtypename_by_avtype(at->avtype));
|
||||
}
|
||||
switch(at->avtype) {
|
||||
case ATR_SEQUENCE:
|
||||
return out_sequence(out, at->value.sequence);
|
||||
break;
|
||||
case ATR_FILTER:
|
||||
return out_filter(out, at->value.filter, nesting + 1);
|
||||
break;
|
||||
case ATR_LINK:
|
||||
return out_link(out, at->value.link, nesting + 1, (TOKEN) NULL);
|
||||
break;
|
||||
default:
|
||||
internal_error("Unimplemented or Invalid attribute type!");
|
||||
/*NOTREACHED */
|
||||
}
|
||||
assert(0); /* NOTREACHED */
|
||||
return(-1); /* To keep GCC happy */
|
||||
}
|
||||
|
||||
|
||||
20
prospero/lib/pfs/out_atrs.c
Normal file
20
prospero/lib/pfs/out_atrs.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
|
||||
int
|
||||
out_atrs(OUTPUT out, PATTRIB at, int nesting)
|
||||
{
|
||||
int retval = PSUCCESS;
|
||||
for (; at; at = at->next)
|
||||
if (!retval) retval = out_atr(out, at, nesting);
|
||||
return retval;
|
||||
}
|
||||
67
prospero/lib/pfs/out_filter.c
Normal file
67
prospero/lib/pfs/out_filter.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
|
||||
/* This sends out the data for a filter, but does not prefix it with the words
|
||||
ATTRIBUTE FILTER, or anything like that. */
|
||||
int
|
||||
out_filter(OUTPUT out, FILTER fil, int nesting)
|
||||
{
|
||||
assert(fil); /* sanity checks */
|
||||
switch(fil->type) {
|
||||
case FIL_DIRECTORY:
|
||||
qoprintf(out, " DIRECTORY");
|
||||
break;
|
||||
case FIL_HIERARCHY:
|
||||
qoprintf(out, " HIERARCHY");
|
||||
break;
|
||||
case FIL_OBJECT:
|
||||
qoprintf(out, " OBJECT");
|
||||
break;
|
||||
case FIL_UPDATE:
|
||||
qoprintf(out, " UPDATE");
|
||||
break;
|
||||
default:
|
||||
internal_error("unknown fil->type value.");
|
||||
}
|
||||
switch(fil->execution_location) {
|
||||
case FIL_SERVER:
|
||||
qoprintf(out, " SERVER");
|
||||
break;
|
||||
case FIL_CLIENT:
|
||||
qoprintf(out, " CLIENT");
|
||||
break;
|
||||
default:
|
||||
internal_error("unknown fil->execution_location");
|
||||
}
|
||||
switch(fil->pre_or_post) {
|
||||
case FIL_PRE:
|
||||
qoprintf(out, " PRE");
|
||||
break;
|
||||
case FIL_POST:
|
||||
qoprintf(out, " POST");
|
||||
break;
|
||||
default:
|
||||
internal_error("unknown fil->pre_or_post");
|
||||
}
|
||||
if (fil->name) {
|
||||
qoprintf(out, " PREDEFINED %'s", fil->name);
|
||||
qoprintf(out, " ARGS");
|
||||
return out_sequence(out, fil->args); /* sequence_reply() terminates
|
||||
with a \n for us. */
|
||||
} else {
|
||||
assert(fil->link);
|
||||
qoprintf(out, " LINK ");
|
||||
out_link(out, fil->link, nesting, fil->args);
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
64
prospero/lib/pfs/out_link.c
Normal file
64
prospero/lib/pfs/out_link.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/* This just sends out the data for a link, but does not prefix it with the
|
||||
word LINK. It will suffix it with arguments, if needed. */
|
||||
#define chknl(s) ((s) ? (s) : "")
|
||||
int
|
||||
out_link(OUTPUT out, VLINK vl, int nesting, TOKEN args)
|
||||
{
|
||||
int retval;
|
||||
assert(vl);
|
||||
qoprintf(out, " %c %s %'s %s %'s %s %'s %ld", vl->linktype,
|
||||
chknl(vl->target), chknl(vl->name), chknl(vl->hosttype),
|
||||
chknl(vl->host), chknl(vl->hsonametype), chknl(vl->hsoname),
|
||||
vl->version, 0);
|
||||
if (vl->dest_exp) {
|
||||
char * cp = NULL;
|
||||
qoprintf(out, " DEST-EXP %s",
|
||||
cp = p_timetoasn_stcopyr(vl->dest_exp, cp));
|
||||
stfree(cp);
|
||||
}
|
||||
if (args) {
|
||||
qoprintf(out, " ARGS");
|
||||
retval = out_sequence(out, args); /* out_sequence() terminates
|
||||
with a \n for us. */
|
||||
} else {
|
||||
retval = qoprintf(out, "\n");
|
||||
}
|
||||
#if 0
|
||||
if (vl->f_magic_no)
|
||||
qoprintf(out, "ID REMOTE %ld\n", vl->f_magic_no, 0);
|
||||
#else /* There has been a minor format change; ID is now preferably sent as an
|
||||
ID line, not as an attribute line. */
|
||||
if(vl->f_magic_no) {
|
||||
int i;
|
||||
|
||||
qoprintf(out, "ATTRIBUTE", 0);
|
||||
for (i = nesting; i; --i) {
|
||||
qoprintf(out, ">", 0);
|
||||
}
|
||||
qoprintf(out, " LINK FIELD ID SEQUENCE REMOTE %ld\n", vl->f_magic_no);
|
||||
retval = qoprintf(out, "\n");
|
||||
}
|
||||
#endif
|
||||
/* Send recursive sub-attributes if we're already nested. But, if we're at
|
||||
the top-level (nesting == 0), we could only have gotten here by being
|
||||
called by list_name(), which makes its own decisions about which
|
||||
attributes to send. Well, we might have also been called by dswdir(),
|
||||
but that's OK. */
|
||||
if (nesting) {
|
||||
PATTRIB at;
|
||||
for (at = vl->lattrib; at; at = at->next)
|
||||
out_atr(out, at, nesting);
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
20
prospero/lib/pfs/out_sequence.c
Normal file
20
prospero/lib/pfs/out_sequence.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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 <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
|
||||
int
|
||||
out_sequence(OUTPUT out, TOKEN tk)
|
||||
{
|
||||
for(; tk; tk = tk->next)
|
||||
qoprintf(out, " %'b", tk->token);
|
||||
return qoprintf(out, "\n");
|
||||
}
|
||||
|
||||
52
prospero/lib/pfs/p__qbstokenize.c
Normal file
52
prospero/lib/pfs/p__qbstokenize.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-license.h>
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
/* Written, 9/18/92, swa@isi.edu */
|
||||
/* Made use 'previous' member 6/14/93, swa@isi.edu */
|
||||
/* Turned into qbstokenize 19 Nov 1993, swa@isi.edu */
|
||||
|
||||
/* Break up a string into space-separated tokens and recognize Prospero
|
||||
quoting. This strips off the quoting in the process. This function could
|
||||
also be called p__tokenize_newstyle_mcomp(), and it serves that function.
|
||||
It assumes the input string is correctly quoted.
|
||||
*/
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
/* loc is a pointer into the string pointed to by header, where we
|
||||
should start tokenizing, it is NOT const, but used within the loop,
|
||||
however since not passed as &loc, it wont be returned as NULL
|
||||
*/
|
||||
TOKEN
|
||||
#ifdef OLDSWA
|
||||
p__qbstokenize(const char * head, const char *loc)
|
||||
#else
|
||||
p__qbstokenize(const char * head, char *loc)
|
||||
#endif
|
||||
{
|
||||
TOKEN retval;
|
||||
int tmp;
|
||||
|
||||
CHECK_MEM();
|
||||
CHECK_PTRinBUFF(head,loc);
|
||||
if (!head || !loc) return NULL;
|
||||
retval = NULL;
|
||||
for (;;) {
|
||||
TOKEN tk;
|
||||
char *buf = NULL;
|
||||
tmp = p__qbstscanf(head, loc, "%'&b %r", &buf, &loc);
|
||||
assert(tmp >= 0); /* no possible error, I hope! */
|
||||
if (tmp == 0)
|
||||
return retval;
|
||||
tk = tkalloc(NULL);
|
||||
tk->token = buf; buf = NULL;
|
||||
APPEND_ITEM(tk, retval);
|
||||
if (tmp == 1) return retval; /* no more to tokenize. */
|
||||
}
|
||||
}
|
||||
50
prospero/lib/pfs/p__qbstscanf.c
Normal file
50
prospero/lib/pfs/p__qbstscanf.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* p__qbstscanf.c
|
||||
Author: Steven Augart (swa@isi.edu)
|
||||
Designed, Documented, and Written: 7/18/92 -- 7/27/92
|
||||
Ported from Gnu C to full ANSI C & traditional C, 10/5/92
|
||||
& modifier added, detraditionalized: 2/16/93.
|
||||
Made a wrapper around qscanf(), 3/2/93
|
||||
Turned into p__qbstscanf(), 19 Nov 1993
|
||||
*/
|
||||
/* This file is not a final interface; use it for internal purposes only. */
|
||||
/* Copyright (c) 1992, 1993 by the University of Southern California. */
|
||||
/* For copying and distribution information, see the file <usc-license.h> */
|
||||
|
||||
#include <usc-license.h>
|
||||
#include <stdarg.h> /* ANSI variable arguments facility. */
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
|
||||
int
|
||||
p__qbstscanf(const char *sthead, /* Start of the string stpos is in */
|
||||
const char *stpos, /* position for the read ptr. */
|
||||
const char *format, /* What to scan for. */
|
||||
...) /* remaining args: pointers to places to store
|
||||
the data we read, or integers (field widths).
|
||||
*/
|
||||
{
|
||||
va_list ap; /* for varargs */
|
||||
int retval;
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
|
||||
#ifdef P_ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(p__bst_consistency_fld(sthead) == P__INUSE_PATTERN);
|
||||
#endif
|
||||
CHECK_PTRinBUFF(sthead,stpos);
|
||||
in->sourcetype = IO_BSTRING;
|
||||
in->rreq = NULL;
|
||||
in->s = stpos;
|
||||
in->file = NULL;
|
||||
in->bstring_length = p_bstlen(sthead);
|
||||
assert(sthead <= stpos);
|
||||
in->offset = stpos - sthead;
|
||||
assert(in->offset <= in->bstring_length); /* make sure consistent. */
|
||||
in->flags = PERCENT_R_TARGET_IS_STRING;
|
||||
|
||||
va_start(ap, format);
|
||||
|
||||
retval = vqscanf(in, format, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
718
prospero/lib/pfs/p__req.c
Normal file
718
prospero/lib/pfs/p__req.c
Normal file
@@ -0,0 +1,718 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>
|
||||
*
|
||||
* Written by swa 1992 to provide common code for starting request
|
||||
* Modified by prasad 1992 to add Kerberos support
|
||||
* Modified by bcn 1/93 to use new ardp library and rreq structure
|
||||
* Modified by swa 6/93 to construct multiple-packet messages.
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
extern int h_errno;
|
||||
|
||||
/* For compatability between GCC-2.3.1 running under SunOS 4.1 and the sunOS
|
||||
* standard include files (they define size_t and others differently), we MUST
|
||||
* include stddef and stdarg after anything that might include the sun include
|
||||
* file <sys/stdtypes.h> (in this case, <pwd.h> includes <sys/stdtypes.h>).
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <psite.h> /* must precede pfs.h for defs. of P_KERBEROS, */
|
||||
/* P_P_PASSWORD */
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
#include <pcompat.h>
|
||||
|
||||
#ifdef P_KERBEROS
|
||||
#include <krb5/krb5.h>
|
||||
#endif /* P_KERBEROS */
|
||||
|
||||
/* gives us a name for this buffer, which we need so we
|
||||
can keep the reference around. */
|
||||
|
||||
/* Ok that this is static, since it's read-only. */
|
||||
static char pfs_sw_id_buf[] = PFS_SW_ID;
|
||||
static char *pfs_sw_id = pfs_sw_id_buf;
|
||||
|
||||
/* Oops - I dont think a "char p__username" is very usefull! - Mitra*/
|
||||
char *p__username = NULL;
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
static PAUTH p__get_pauth(int type, const char *hostname);
|
||||
#ifdef P_P_PASSWORD
|
||||
char *ppw_encode();
|
||||
#endif /* P_P_PASSWORD */
|
||||
char *get_psession_filename();
|
||||
static char *uid_to_name();
|
||||
#ifdef P_ACCOUNT
|
||||
static void p__add_acc_req();
|
||||
#endif
|
||||
|
||||
/* This code handles possible multiple resettings of the software ID
|
||||
without any memory leaks.
|
||||
It is internal; should only be called through p_initialize(). Nothing will
|
||||
break if you ignore this admonition, but it keeps the library interface
|
||||
smaller. */
|
||||
void
|
||||
p__set_sw_id(char *app_sw_id)
|
||||
{
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
if (app_sw_id && *app_sw_id) {
|
||||
if (pfs_sw_id == pfs_sw_id_buf)
|
||||
pfs_sw_id = qsprintf_stcopyr(NULL,"%s(%s)",app_sw_id,PFS_SW_ID);
|
||||
else
|
||||
pfs_sw_id = qsprintf_stcopyr(pfs_sw_id,"%s(%s)",app_sw_id,
|
||||
PFS_SW_ID);
|
||||
} else {
|
||||
/* Resetting software ID to normal values. */
|
||||
if (pfs_sw_id == pfs_sw_id_buf)
|
||||
; /* Same as before; leave set to default. */
|
||||
else {
|
||||
stfree(pfs_sw_id); /* must be set to some allocated memory. */
|
||||
pfs_sw_id = pfs_sw_id_buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* p__start_req - start a prospero request
|
||||
*
|
||||
* p__start_req takes the name of the server (used by Kerberos to
|
||||
* determine what credentials are needed), it allocates a request
|
||||
* structure, and it fills in the start, including the Prospero
|
||||
* version and software ID, and authentication information. The
|
||||
* function returns a request of type RREQ, which can be used
|
||||
* in subsequent calls to p__addreq, and passed to ardp_send.
|
||||
*/
|
||||
RREQ
|
||||
p__start_req(const char server_hostname[])
|
||||
{
|
||||
RREQ req = ardp_rqalloc(); /* The request to fill in */
|
||||
PAUTH authinfo; /* Structure containing authentication info */
|
||||
PAUTH authp; /* To iterate through authinfo list */
|
||||
TOKEN prin; /* To Iterate through principal names */
|
||||
|
||||
#ifdef CLIENTS_REQUEST_VERSION_FROM_SERVER
|
||||
p__add_req(req, "VERSION\n");
|
||||
#endif
|
||||
p__add_req(req, "VERSION %d %s", VFPROT_VNO, pfs_sw_id);
|
||||
|
||||
authinfo = p__get_pauth(PFSA_UNAUTHENTICATED, server_hostname);
|
||||
if (authinfo) {
|
||||
p__add_req(req, "\nAUTHENTICATE '' UNAUTHENTICATED %'s",
|
||||
authinfo->authenticator);
|
||||
/* For the UNAUTHENTICATED and KERBEROS authentication types, */
|
||||
/* the principals are optional additional information for */
|
||||
/* debugging use. We don't worry about them here. */
|
||||
for(prin = authinfo->principals; prin; prin = prin->next)
|
||||
p__add_req(req, " %'s", prin->token);
|
||||
pafree(authinfo);
|
||||
}
|
||||
|
||||
#ifdef P_KERBEROS
|
||||
authinfo = p__get_pauth(PFSA_KERBEROS, server_hostname);
|
||||
for (authp = authinfo; authp; authp = authp->next) {
|
||||
p__add_req(req, "\nAUTHENTICATE '' KERBEROS %'s",
|
||||
authp->authenticator);
|
||||
/* For the UNAUTHENTICATED and KERBEROS authentication types, the
|
||||
principals are optional additional information for debugging use.
|
||||
We don't worry about them here. */
|
||||
for (prin = authp->principals; prin; prin = prin->next)
|
||||
p__add_req(req, " %'s", prin->token);
|
||||
}
|
||||
if (authinfo)
|
||||
palfree(authinfo);
|
||||
#endif
|
||||
#ifdef P_P_PASSWORD
|
||||
authinfo = p__get_pauth(PFSA_P_PASSWORD, server_hostname);
|
||||
for (authp = authinfo; authp; authp = authp->next) {
|
||||
p__add_req(req, "\nAUTHENTICATE OPTIONAL P_PASSWORD %'s",
|
||||
authp->authenticator);
|
||||
/* Principal NOT optional here! */
|
||||
for (prin = authp->principals; prin; prin = prin->next)
|
||||
p__add_req(req, " %'s", prin->token);
|
||||
}
|
||||
if (authinfo)
|
||||
palfree(authinfo);
|
||||
#endif
|
||||
p__add_req(req, "\n");
|
||||
#ifdef P_ACCOUNT
|
||||
p__add_acc_req(req, server_hostname);
|
||||
#endif
|
||||
return(req);
|
||||
}
|
||||
|
||||
/* Adds stuff to a Prospero request. */
|
||||
int
|
||||
p__add_req(RREQ req, const char fmt[], ...)
|
||||
{
|
||||
int retval;
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
retval = vp__add_req(req, fmt, ap);
|
||||
va_end(ap);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
int
|
||||
vp__add_req(RREQ req, const char fmt[], va_list ap)
|
||||
{
|
||||
PTEXT ptmp; /* packet being written to. */
|
||||
int mesglen; /* # of characters in this message, NOT
|
||||
including trailing NUL which doesn't need to
|
||||
be sent. */
|
||||
AUTOSTAT_CHARPP(bufp); /* buffer for long packets */
|
||||
int numsent; /* How many chars. out of buf have been sent so
|
||||
far? */
|
||||
|
||||
if(!req->outpkt) {
|
||||
ptmp = ardp_ptalloc();
|
||||
if(!ptmp) RETURNPFAILURE;
|
||||
APPEND_ITEM(ptmp,req->outpkt);
|
||||
} else {
|
||||
ptmp = req->outpkt->previous; /* last member of list. */
|
||||
}
|
||||
|
||||
/* Subtract 1: Trailing NUL character isn't sent,
|
||||
since the length of the message is encoded into the message. Recipient
|
||||
will automatically append the NUL byte for convenience of the users. */
|
||||
/* Add one to buffer space available, since it includes an MBZ byte to
|
||||
catch runaway strings. vqsprintf() will always null-terminate the
|
||||
strings it writes. */
|
||||
mesglen =
|
||||
vqsprintf(ptmp->ioptr, ARDP_PTXT_LEN + 1 - ptmp->length, fmt, ap) - 1;
|
||||
if (ptmp->length + mesglen <= ARDP_PTXT_LEN) {
|
||||
ptmp->length += mesglen;
|
||||
ptmp->ioptr = ptmp->start + ptmp->length;
|
||||
return(PSUCCESS);
|
||||
}
|
||||
/* Ran out of room. Have to write it to a temporary buffer, then copy. */
|
||||
/* Four-line Optimization: we already know we're going to need mesglen + 1
|
||||
of buffer space. By doing this, we save a possible double calling of
|
||||
vqsprintf() in p__vqbstprintf_stcopyr(). */
|
||||
if (p__bstsize(*bufp) < mesglen + 1) {
|
||||
stfree(*bufp);
|
||||
*bufp = stalloc(mesglen + 1);
|
||||
}
|
||||
/* There used to be a lot of code here that did this in a slightly more
|
||||
efficient way, but I am willing to suffer a performance penalty
|
||||
in order to make this work more transparently. */
|
||||
*bufp = p__vqbstprintf_stcopyr(*bufp, fmt, ap);
|
||||
assert(mesglen == p_bstlen(*bufp));
|
||||
|
||||
/* Record what we already sent. */
|
||||
numsent = ARDP_PTXT_LEN - ptmp->length;
|
||||
ptmp->length = ARDP_PTXT_LEN;
|
||||
/* Start this loop with the current ptmp full of as much data as it can
|
||||
hold. */
|
||||
while (numsent < mesglen) {
|
||||
ptmp = ardp_ptalloc();
|
||||
if(!ptmp) RETURNPFAILURE;
|
||||
APPEND_ITEM(ptmp,req->outpkt);
|
||||
ptmp->length = ( mesglen - numsent > ARDP_PTXT_LEN
|
||||
? ARDP_PTXT_LEN : mesglen - numsent);
|
||||
strncpy(ptmp->start, *bufp + numsent, ptmp->length);
|
||||
ptmp->ioptr = ptmp->start + ptmp->length;
|
||||
numsent += ptmp->length;
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
p__set_username(char *un)
|
||||
{
|
||||
p__username = stcopyr(un, p__username);
|
||||
}
|
||||
|
||||
static
|
||||
PAUTH p__get_pauth(int type, const char server_hostname[])
|
||||
{
|
||||
#ifdef P_KERBEROS
|
||||
krb5_data buf;
|
||||
krb5_checksum send_cksum;
|
||||
krb5_ccache ccdef;
|
||||
krb5_principal server;
|
||||
static char *tkt_file = NULL;
|
||||
int retval = 0;
|
||||
#endif
|
||||
#ifdef P_P_PASSWORD
|
||||
PAUTH curr_auth = NULL;
|
||||
static char *password = NULL;
|
||||
typedef struct _p_passwd {
|
||||
char *hostname;
|
||||
char *princ_name;
|
||||
char *password;
|
||||
struct _p_passwd *next;
|
||||
} p_passwd;
|
||||
p_passwd *p_list = NULL, *p_ptr;
|
||||
#endif
|
||||
PAUTH auth = paalloc();
|
||||
int ruid, euid;
|
||||
FILE *psession_fp;
|
||||
char *psession_filename = get_psession_filename();
|
||||
char line[255];
|
||||
AUTOSTAT_CHARPP(hostnamep);
|
||||
AUTOSTAT_CHARPP(princ_namep);
|
||||
int num, entry_exists = 0;
|
||||
char full_hname[255];
|
||||
struct hostent *host;
|
||||
char *cp;
|
||||
char *hostaddr = NULL;
|
||||
struct in_addr haddr;
|
||||
|
||||
#if defined(P_KERBEROS) || defined(P_P_PASSWORD)
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
#endif
|
||||
CHECK_MEM();
|
||||
auth->principals = NULL; /* not really needed. Let's be paranoid. */
|
||||
|
||||
/* Convert hostname into canonical form */
|
||||
qsprintf(full_hname, sizeof full_hname, "%s", server_hostname);
|
||||
|
||||
/* Strip off the trailing (portnum), if any */
|
||||
for (cp = full_hname; *cp; ++cp)
|
||||
;
|
||||
if (cp > full_hname && *--cp == ')') {
|
||||
while (*--cp && cp >= full_hname) {
|
||||
if (*cp == '(') {
|
||||
*cp = '\0';
|
||||
break;
|
||||
}
|
||||
if (!isdigit(*cp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up server host */
|
||||
/* Not multi-threaded yet because clients not done yet. */
|
||||
CHECK_MEM();
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
if ((host = gethostbyname(full_hname)) == (struct hostent *) 0) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__get_pauth(): unknown host %s\n",
|
||||
full_hname);
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
qsprintf(full_hname, sizeof full_hname, "%s", host->h_name);
|
||||
bcopy(host->h_addr,&haddr,sizeof(haddr));
|
||||
hostaddr = stcopy(inet_ntoa(haddr));
|
||||
|
||||
switch(auth->ainfo_type = type) {
|
||||
case PFSA_UNAUTHENTICATED:
|
||||
if (p__username) {
|
||||
auth->authenticator = stcopy(p__username);
|
||||
return auth;
|
||||
}
|
||||
/* Upper-case to use in search of password file */
|
||||
for (cp = full_hname; *cp; cp++)
|
||||
if (islower(*cp))
|
||||
*cp = toupper(*cp);
|
||||
|
||||
/* Get the real and effective user ids */
|
||||
ruid = getuid();
|
||||
euid = geteuid();
|
||||
|
||||
/* check if the psession file exists */
|
||||
if (!(psession_fp = fopen(psession_filename, "r")))
|
||||
/* No file; send real uid across */
|
||||
auth->authenticator = uid_to_name(ruid);
|
||||
else {
|
||||
while (fgets(line, sizeof(line), psession_fp)) {
|
||||
num = qsscanf(line,
|
||||
"AUTHENTICATE %'&s UNAUTHENTICATED %'&s\n",
|
||||
&(*hostnamep), &(*princ_namep));
|
||||
if (num < 2)
|
||||
continue;
|
||||
if (wcmatch(full_hname, (*hostnamep)) ||
|
||||
strequal(hostaddr, (*hostnamep))) {
|
||||
entry_exists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(psession_fp);
|
||||
/* No entry in file; */
|
||||
/* no UNAUTHENTICATED authentication sent */
|
||||
if (!entry_exists) {
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
if ((*princ_namep)[0] && (!ruid || euid))
|
||||
#ifdef OVERRIDE_DEFAULT_USERNAME
|
||||
auth->authenticator = stcopy((*princ_namep));
|
||||
#else
|
||||
auth->authenticator = uid_to_name(ruid);
|
||||
#endif
|
||||
else
|
||||
auth->authenticator = uid_to_name(ruid);
|
||||
}
|
||||
|
||||
return(auth);
|
||||
break;
|
||||
|
||||
#ifdef P_KERBEROS /* 4/5/93 Made error handling pass errors
|
||||
to higher layers. */
|
||||
case PFSA_KERBEROS:
|
||||
if (!(psession_fp = fopen(psession_filename, "r"))) {
|
||||
/* No file; do not send KERBEROS authentication */
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), psession_fp)) {
|
||||
num = qsscanf(line, "AUTHENTICATE %'&s KERBEROS %'&s %'&s\n",
|
||||
&(*hostnamep), &(*princ_namep), &tkt_file);
|
||||
if (num < 3)
|
||||
continue;
|
||||
if (wcmatch(full_hname, (*hostnamep)) ||
|
||||
strequal(hostaddr, (*hostnamep))) {
|
||||
entry_exists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(psession_fp);
|
||||
|
||||
if (!entry_exists) {
|
||||
/* No entry; do not send KERBEROS authentication */
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If ticket-file name not empty, tell KRB5 routines to look */
|
||||
/* at it. */
|
||||
if (tkt_file[0])
|
||||
setenv("KRB5CCNAME", tkt_file, 1);
|
||||
|
||||
/* PREPARE KRB_AP_REQ MESSAGE */
|
||||
|
||||
/* compute checksum, using CRC-32 */
|
||||
if (!(send_cksum.contents = (krb5_octet *)
|
||||
stalloc(krb5_checksum_size(CKSUMTYPE_CRC32)))) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__get_pauth(): Cannot allocate Kerberos checksum\n");
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* choose some random stuff to compute checksum from */
|
||||
if (retval = krb5_calculate_checksum(CKSUMTYPE_CRC32,
|
||||
(char *) server_hostname,
|
||||
strlen(server_hostname),
|
||||
0,
|
||||
0, /* if length is 0, */
|
||||
/* crc-32 doesn't use */
|
||||
/* the seed */
|
||||
&send_cksum)) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__get_pauth(): Error while computing Kerberos checksum\n");
|
||||
stfree(send_cksum.contents);
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get credentials for server, create krb_mk_req message */
|
||||
|
||||
if (retval = krb5_cc_default(&ccdef)) {
|
||||
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__get_pauth(): Error while getting default \
|
||||
Kerberos cache\n");
|
||||
stfree(send_cksum.contents);
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Format service name into a principal structure and */
|
||||
/* canonicalizes host name. */
|
||||
if (retval = krb5_sname_to_principal(full_hname,
|
||||
KERBEROS_SERVICE,
|
||||
1, /* Canonicalize */
|
||||
&server)) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__get_pauth(): Error while setting up \
|
||||
Kerberos server principal\n");
|
||||
stfree(send_cksum.contents);
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retval = krb5_mk_req(server, 0 /* default options */, &send_cksum,
|
||||
ccdef, &buf)) {
|
||||
if (pfs_debug) fprintf(stderr, "p__get_pauth(): Error while \
|
||||
preparing Kerberos AP_REQ\n");
|
||||
pafree(auth);
|
||||
stfree(send_cksum.contents);
|
||||
return NULL;
|
||||
}
|
||||
stfree(send_cksum.contents);
|
||||
auth->authenticator = stalloc(AUTHENTICATOR_SZ);
|
||||
retval = binencode(buf.data, buf.length,
|
||||
auth->authenticator,
|
||||
AUTHENTICATOR_SZ);
|
||||
if (retval >= AUTHENTICATOR_SZ) {
|
||||
internal_error("binencode: Buffer too small");
|
||||
}
|
||||
|
||||
return(auth);
|
||||
break;
|
||||
#endif /* P_KERBEROS */
|
||||
#ifdef P_P_PASSWORD
|
||||
case PFSA_P_PASSWORD:
|
||||
/* Upper-case to use in search of password file */
|
||||
for (cp = full_hname; *cp; cp++)
|
||||
if (islower(*cp))
|
||||
*cp = toupper(*cp);
|
||||
|
||||
if (!(psession_fp = fopen(psession_filename, "r"))) {
|
||||
#if 0 /* This is annoying. It's NOT AN ERROR for
|
||||
somebody not to have set up a session file, at
|
||||
least not right now. --swa, 9 May 1994 */
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__get_pauth(): Error in P_PASSWORD \
|
||||
authentication: Cannot open psession file %s\n", psession_filename);
|
||||
#endif
|
||||
pafree(auth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), psession_fp)) {
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
num = qsscanf(line, "AUTHENTICATE %'&s P_PASSWORD %'&s %'&s\n",
|
||||
&(*hostnamep), &(*princ_namep), &password);
|
||||
|
||||
if (num < 3) /* Ignore if no password */
|
||||
continue;
|
||||
|
||||
if (wcmatch(full_hname, (*hostnamep)) ||
|
||||
strequal(hostaddr, (*hostnamep))) {
|
||||
p_passwd *last = NULL;
|
||||
|
||||
for (p_ptr = p_list; p_ptr; last = p_ptr, p_ptr = p_ptr->next)
|
||||
if (!strcmp((*princ_namep), p_ptr->princ_name)) {
|
||||
if (isdigit(p_ptr->hostname[0]))
|
||||
break; /* Already have most specific */
|
||||
/* address */
|
||||
|
||||
if (isdigit((*hostnamep)[0]) ||
|
||||
strlen((*hostnamep)) > strlen(p_ptr->hostname)) {
|
||||
p_ptr->hostname = stcopyr((*hostnamep), p_ptr->hostname);
|
||||
p_ptr->password = stcopyr(password, p_ptr->password);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!p_ptr) {
|
||||
if (!last) {
|
||||
p_list = (p_passwd *) stalloc(sizeof(p_passwd));
|
||||
last = p_list;
|
||||
}
|
||||
else {
|
||||
last->next = (p_passwd *) stalloc(sizeof(p_passwd));
|
||||
last = last->next;
|
||||
}
|
||||
last->hostname = stcopy((*hostnamep));
|
||||
last->princ_name = stcopy((*princ_namep));
|
||||
last->password = stcopy(password);
|
||||
last->next = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void) fclose(psession_fp);
|
||||
|
||||
pafree(auth);
|
||||
auth = NULL;
|
||||
|
||||
for (p_ptr = p_list; p_ptr; p_ptr = p_ptr->next) {
|
||||
if (!auth)
|
||||
auth = curr_auth = paalloc();
|
||||
else {
|
||||
curr_auth->next = paalloc();
|
||||
curr_auth = curr_auth->next;
|
||||
}
|
||||
curr_auth->ainfo_type = type;
|
||||
curr_auth->authenticator = stcopy(ppw_encode(p_ptr->password));
|
||||
curr_auth->principals = tkalloc(p_ptr->princ_name);
|
||||
curr_auth->next = NULL;
|
||||
}
|
||||
|
||||
return(auth);
|
||||
break;
|
||||
#endif /* P_P_PASSWORD */
|
||||
default:
|
||||
fprintf(stderr, "p__get_pauth(): Unknown authenticator type: %d\n", type);
|
||||
internal_error("Unknown authenticator type!");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
assert(FALSE); /*Unreached*/
|
||||
return(NULL); /* To keep GCC happy*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef P_ACCOUNT
|
||||
static void
|
||||
p__add_acc_req(RREQ req, char *server_hostname)
|
||||
{
|
||||
FILE *psession_fp;
|
||||
char *psession_filename = get_psession_filename();
|
||||
char line[255];
|
||||
static char *hostname = NULL, *acc_method = NULL;
|
||||
static char *acc_server = NULL, *acc_name = NULL;
|
||||
static char *acc_verifier = NULL, *int_bill_ref = NULL;
|
||||
static char *currency = NULL, *prompt_amt = NULL, *max_amt = NULL;
|
||||
struct hostent *host;
|
||||
char *cp;
|
||||
char *hostaddr = NULL;
|
||||
struct in_addr haddr;
|
||||
int num, entry_exists = 0;
|
||||
char full_hname[255];
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
/* Convert hostname into canonical form */
|
||||
qsprintf(full_hname, sizeof full_hname, "%s", server_hostname);
|
||||
|
||||
/* Strip off the trailing (portnum), if any */
|
||||
for (cp = full_hname; *cp; ++cp)
|
||||
;
|
||||
if (cp > full_hname && *--cp == ')') {
|
||||
while (*--cp && cp >= full_hname) {
|
||||
if (*cp == '(') {
|
||||
*cp = '\0';
|
||||
break;
|
||||
}
|
||||
if (!isdigit(*cp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look up server host */
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
if ((host = gethostbyname(full_hname)) == (struct hostent *) 0) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p__add_acc_req(): unknown host %s\n",
|
||||
full_hname);
|
||||
return;
|
||||
}
|
||||
qsprintf(full_hname, sizeof full_hname, "%s", host->h_name);
|
||||
bcopy(host->h_addr,&haddr,sizeof(haddr));
|
||||
hostaddr = stcopy(inet_ntoa(haddr));
|
||||
|
||||
/* Upper-case to use in search of password file */
|
||||
for (cp = full_hname; *cp; cp++)
|
||||
if (islower(*cp))
|
||||
*cp = toupper(*cp);
|
||||
|
||||
if (!(psession_fp = fopen(psession_filename, "r")))
|
||||
return;
|
||||
|
||||
while (fgets(line, sizeof(line), psession_fp)) {
|
||||
num = qsscanf(line, "ACCOUNT %'&s %'&s %'&s %'&s %'&s %'&s\n",
|
||||
&hostname, &acc_method, &acc_server, &acc_name,
|
||||
&acc_verifier, &int_bill_ref);
|
||||
|
||||
if (num < 6)
|
||||
continue;
|
||||
if (wcmatch(full_hname, hostname) ||
|
||||
strequal(hostaddr, hostname)) {
|
||||
p__add_req(req, "ACCOUNT MANDATORY %'s %'s %'s %'s %'s",
|
||||
acc_method, acc_server, acc_name,
|
||||
ppw_encode(acc_verifier), int_bill_ref);
|
||||
while(fgets(line, sizeof(line), psession_fp) &&
|
||||
strnequal(line, "CURRENCY", strlen("CURRENCY"))) {
|
||||
num = qsscanf(line, "CURRENCY %'&s %'&s %'&s\n",
|
||||
¤cy, &prompt_amt, &max_amt);
|
||||
if (num < 2)
|
||||
continue;
|
||||
p__add_req(req, " %'s %'s", currency, prompt_amt);
|
||||
}
|
||||
p__add_req(req, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(psession_fp);
|
||||
}
|
||||
#endif /* P_ACCOUNT */
|
||||
|
||||
|
||||
/* returns name of user's psession file. */
|
||||
char *get_psession_filename()
|
||||
{
|
||||
int uid;
|
||||
char *home;
|
||||
static char *psession_filename = NULL;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if (!(psession_filename = stcopy(getenv("PSESSION")))) {
|
||||
uid = getuid();
|
||||
if (!(home = getenv("HOME"))) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr,
|
||||
"ERROR: Could not get value of HOME!\n");
|
||||
return NULL;
|
||||
}
|
||||
psession_filename = qsprintf_stcopyr(psession_filename,
|
||||
"%s/.psession_%d",
|
||||
home, uid);
|
||||
}
|
||||
|
||||
return psession_filename;
|
||||
}
|
||||
|
||||
|
||||
/* Converts a uid into a username. If unknown uid, returns a string of */
|
||||
/* the form "uid#<uid>" */
|
||||
static char *uid_to_name(int uid)
|
||||
{
|
||||
struct passwd *whoiampw;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*getpwuid MT-Unsafe*/
|
||||
DISABLE_PFS(whoiampw = getpwuid(uid));
|
||||
if (whoiampw == 0) {
|
||||
char tmp_uid_str[100];
|
||||
qsprintf(tmp_uid_str, sizeof tmp_uid_str, "uid#%d", uid);
|
||||
return stcopy(tmp_uid_str);
|
||||
}
|
||||
else {
|
||||
return stcopy(whoiampw->pw_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Two-way function to encode string.*/
|
||||
char *ppw_encode(char *str)
|
||||
{
|
||||
static char *retstr = NULL;
|
||||
int i;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
retstr = stcopyr(str, retstr);
|
||||
|
||||
for (i = 0; retstr[i]; i++)
|
||||
if (retstr[i] > 31 && retstr[i] < 127)
|
||||
retstr[i] = 126 - retstr[i] + 32;
|
||||
|
||||
return retstr;
|
||||
}
|
||||
|
||||
654
prospero/lib/pfs/p_get_dir.c
Normal file
654
prospero/lib/pfs/p_get_dir.c
Normal file
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
* 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 1989 modified 1989-1992
|
||||
* Modified by swa 1992 to use qsscanf()
|
||||
* Modified by bcn 1/93 to use ardp library
|
||||
* bug fix by cheang 11/93 pre server filters.
|
||||
*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pprot.h>
|
||||
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pparse.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
extern TOKEN p__tokenize_midstyle_mcomp(char *nextname);
|
||||
|
||||
static void build_out(VDIR dir, OUTPUT out, char *options, FILTER *ptr_filters) {
|
||||
/* Build dir->dqs->preq and out */
|
||||
/* Note side effect, filters updated to point to first client filter */
|
||||
struct dqstate *dqs = dir->dqs;
|
||||
FILTER filters = *ptr_filters;
|
||||
|
||||
dir->status = DQ_ACTIVE;
|
||||
dqs->preq = p__start_req(dqs->dl->host);
|
||||
requesttoout(dqs->preq,out); /* two ways to output to this. */
|
||||
if(dqs->flags & GVD_MOTD) p__add_req(dqs->preq, "PARAMETER GET MOTD\n");
|
||||
if(dqs->flags & GVD_MOTD_O) return; /* Skip over query */
|
||||
|
||||
/* The Server FILTER option should be applied only once before */
|
||||
/* union link expansion. */
|
||||
if(filters && filters->execution_location == FIL_SERVER) {
|
||||
static char * fil_option = NULL;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
fil_option = qsprintf_stcopyr(fil_option, "%s+FILTER", options);
|
||||
|
||||
p__add_req(dqs->preq, "DIRECTORY ASCII %'s\nLIST %s COMPONENTS",
|
||||
dqs->dl->hsoname, fil_option + 1);
|
||||
}
|
||||
else
|
||||
p__add_req(dqs->preq, "DIRECTORY ASCII %'s\nLIST %s COMPONENTS",
|
||||
dqs->dl->hsoname,
|
||||
(*options) ? options+1 : "''" );
|
||||
if(dqs->comp) {
|
||||
p__add_req(dqs->preq, " %'s", dqs->comp);
|
||||
|
||||
if (dqs->mcomp) {
|
||||
#ifdef CLIENT_SEND_NEW_MCOMP
|
||||
out_sequence(out, *dqs->acomp); /* terminates with a \n. */
|
||||
#else
|
||||
TOKEN acp;
|
||||
|
||||
for (acp = *dqs->acomp; acp; acp = acp->next) {
|
||||
if(!(acp->token) || (!*(acp->token)))
|
||||
p__add_req(dqs->preq, "/*", acp->token);
|
||||
else p__add_req(dqs->preq, "/%'s", acp->token);
|
||||
}
|
||||
p__add_req(dqs->preq, "\n");
|
||||
#endif
|
||||
} else {
|
||||
p__add_req(dqs->preq, "\n");
|
||||
}
|
||||
} else {
|
||||
p__add_req(dqs->preq, "\n");
|
||||
}
|
||||
/* Append any appropriate filters to the request. */
|
||||
while (filters && filters->execution_location == FIL_SERVER
|
||||
&& (filters->type == FIL_DIRECTORY
|
||||
|| filters->type == FIL_HIERARCHY)) {
|
||||
qoprintf(out, "FILTER");
|
||||
out_filter(out, filters, 0);
|
||||
filters = filters->next;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
retrieve_and_parse( VDIR dir)
|
||||
{
|
||||
/* Retrieve and parse a ardp response, */
|
||||
INPUT_ST in_st; /* Input pointer for response contents */
|
||||
INPUT in = &in_st;
|
||||
|
||||
struct dqstate *dqs = dir->dqs;
|
||||
|
||||
CHECK_MEM();
|
||||
rreqtoin(dqs->preq, in);
|
||||
while(!in_eof(in)) {
|
||||
int tmp;
|
||||
char *line;
|
||||
char *next_word;
|
||||
|
||||
CHECK_MEM();
|
||||
if (tmp = in_line(in, &line, &next_word))
|
||||
return(tmp);
|
||||
|
||||
switch (*line) {
|
||||
|
||||
char l_htype[MAX_DIR_LINESIZE];
|
||||
char l_host[MAX_DIR_LINESIZE];
|
||||
char l_ntype[MAX_DIR_LINESIZE];
|
||||
char l_fname[MAX_DIR_LINESIZE];
|
||||
int l_version;
|
||||
int l_magic;
|
||||
char t_unresolved[MAX_DIR_LINESIZE];
|
||||
|
||||
case 'A': /* ATTRIBUTE lines that apply to this
|
||||
directory. */
|
||||
if (!strnequal(line, "ATTRIBUTE", sizeof "ATTRIBUTE" - 1))
|
||||
goto scanerr;
|
||||
if (tmp = in_ge1_atrs(in, line, next_word, &dir->attributes)) {
|
||||
if (pfs_debug)
|
||||
perrmesg("p_get_dir()", 0, NULL);
|
||||
return(tmp);
|
||||
}
|
||||
case 'L': /* LINK or LINK-INFO */
|
||||
if(!strnequal(line,"LINK",4))
|
||||
goto scanerr;
|
||||
|
||||
/* If only verifying, don't want to change dir */
|
||||
if(dqs->flags & GVD_VERIFY) {
|
||||
break;
|
||||
}
|
||||
/* If first link and some links in dir, free them */
|
||||
if(!dqs->newlinks++) {
|
||||
if(dir->links) vllfree(dir->links); dir->links=NULL;
|
||||
if(dir->ulinks) vllfree(dir->ulinks); dir->ulinks=NULL;
|
||||
}
|
||||
CHECK_MEM();
|
||||
if (tmp = in_link(in,line,next_word,0,&(dqs->clnk),
|
||||
(TOKEN *) NULL)) {
|
||||
if (pfs_debug)
|
||||
perrmesg("p_get_dir()", 0, NULL);
|
||||
return(DIRSRV_BAD_FORMAT);
|
||||
}
|
||||
|
||||
/* Double check to make sure we don't get */
|
||||
/* back unwanted components */
|
||||
/* OK to keep if special (URP) links */
|
||||
/* or if dqs->mcomp specified */
|
||||
if(!dqs->mcomp &&
|
||||
((dqs->clnk->linktype == 'L') ||
|
||||
(dqs->clnk->linktype == 'I')) && dqs->comp
|
||||
&& (!wcmatch(dqs->clnk->name,dqs->comp))) {
|
||||
vlfree(dqs->clnk); dqs->clnk = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If other optional info was sent back, it must */
|
||||
/* also be parsed before inserting link *** */
|
||||
|
||||
|
||||
if(dqs->clnk->linktype == 'L' || dqs->clnk->linktype == 'I')
|
||||
vl_insert(dqs->clnk,dir,
|
||||
(dqs->flags & GVD_NOSORT) ? VLI_NOSORT : VLI_ALLOW_CONF
|
||||
);
|
||||
else {
|
||||
tmp = ul_insert(dqs->clnk,dir,dqs->pulnk);
|
||||
|
||||
/* If inserted after dqs->pulnk, next one after dqs->clnk*/
|
||||
if(dqs->pulnk && (!tmp || (tmp == UL_INSERT_SUPERSEDING)))
|
||||
dqs->pulnk = dqs->clnk;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'F': /* FAILURE or FORWARDED */
|
||||
/* FORWARDED */
|
||||
if(strncmp(line,"FORWARDED",9) == 0) {
|
||||
if((dqs->fwdcnt)-- <= 0) {
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
if (pfs_debug)
|
||||
perrmesg("p_get_dir()", 0, NULL);
|
||||
return(perrno);
|
||||
}
|
||||
/* parse and start over */
|
||||
tmp = qsscanf(line,"FORWARDED %s %'s %s %'s %d %d",
|
||||
l_htype,l_host,l_ntype,l_fname,
|
||||
&l_version, &l_magic);
|
||||
|
||||
dqs->dl->host = stcopyr(l_host, dqs->dl->host);
|
||||
dqs->dl->hsoname = stcopyr(l_fname, dqs->dl->hsoname);
|
||||
|
||||
if(tmp < 4) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr,
|
||||
"p_get_dir(): Malformed FORWARDED line: %s",
|
||||
line);
|
||||
return(DIRSRV_BAD_FORMAT);
|
||||
}
|
||||
|
||||
ardp_rqfree(dqs->preq);
|
||||
dqs->preq = NOREQ;
|
||||
dir->status = DQ_INACTIVE;
|
||||
return(DSRFINFO_FORWARDED);
|
||||
}
|
||||
goto scanerr;
|
||||
break;
|
||||
|
||||
|
||||
case 'N': /* NONE-FOUND */
|
||||
/* NONE-FOUND, we just have no links to insert */
|
||||
/* It is not an error, but we must clear any */
|
||||
/* old links in the directory arg */
|
||||
if(strncmp(line,"NONE-FOUND",10) == 0) {
|
||||
/* If only verifying, don't want to change dir */
|
||||
if(dqs->flags & GVD_VERIFY) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* If first link and some links in dir, free them */
|
||||
if(!dqs->newlinks++) {
|
||||
if(dir->links) vllfree(dir->links);
|
||||
if(dir->ulinks) vllfree(dir->ulinks);
|
||||
dir->links = NULL;
|
||||
dir->ulinks = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* If anything else, scan error */
|
||||
goto scanerr;
|
||||
|
||||
case 'U': /* UNRESOLVED */ {
|
||||
char *p_unresolved;
|
||||
TOKEN new_acomp;
|
||||
int newlen, oldlen;
|
||||
|
||||
tmp = qsscanf(line,"UNRESOLVED %r", &p_unresolved);
|
||||
if(tmp < 1) goto scanerr;
|
||||
#ifndef DONT_ACCEPT_OLD_MCOMP
|
||||
new_acomp = p__tokenize_midstyle_mcomp(p_unresolved);
|
||||
#else /* guaranteed a new reply from server */
|
||||
new_acomp = qtokenize(p_unresolved);
|
||||
#endif
|
||||
newlen = length(new_acomp);
|
||||
oldlen = length(*dqs->acomp);
|
||||
/* If multiple components were resolved */
|
||||
/* Must be a proper suffix. */
|
||||
if (newlen != oldlen) {
|
||||
if (oldlen <= newlen) goto badunresolved;
|
||||
/* Comp gets the last component resolved. (NB: Indexing
|
||||
for elt() starts at 0.) */
|
||||
dqs->comp = stcopy(elt(*dqs->acomp, oldlen - newlen - 1));
|
||||
dqs->stfree_comp = 1;
|
||||
/* Let rd_vdir know what remains */
|
||||
tklfree(*dqs->acomp);
|
||||
*dqs->acomp = new_acomp;
|
||||
}
|
||||
dqs->unresp = 1;
|
||||
break;
|
||||
badunresolved:
|
||||
if (pfs_debug)
|
||||
fprintf(stderr, "p_get_dir(): Received an UNRESOLVED \
|
||||
response not a proper suffix of the acomp sent. This is not legal: %s\n",
|
||||
line);
|
||||
#if 0 /* mitra commented these out; unclear why */
|
||||
ardp_rqfree(dir->dqs->preq);
|
||||
if (dir->dqs->stfree_comp) stfree(dir->dqs->comp);
|
||||
stfree(dir->dqs); dir->dqs = NULL;
|
||||
#endif
|
||||
return perrno = dir->status = DIRSRV_BAD_FORMAT;
|
||||
} /* case 'U' (unresolved) */
|
||||
|
||||
scanerr:
|
||||
default:
|
||||
if(tmp = scan_error(line, dqs->preq)) {
|
||||
/* XXX memory leak? check this mitracode. */
|
||||
|
||||
/* change 1 follows */
|
||||
return(tmp);
|
||||
}
|
||||
break;
|
||||
} /* switch */
|
||||
} /*while*/
|
||||
return PSUCCESS;
|
||||
} /* bad_p_get_dir( */
|
||||
/*
|
||||
* p_get_dir - Get contents of a directory given its location
|
||||
*
|
||||
* P_GET_DIR takes a directory location, a list of desired
|
||||
* components, a pointer to a directory structure to be
|
||||
* filled in, and flags. It then queries the appropriate
|
||||
* directory server and retrieves the desired information.
|
||||
*
|
||||
* ARGS: dlink - Host and host specific object name for directory
|
||||
* plus any filters to be applied (->filters)
|
||||
* components - The first component of the name we want to
|
||||
* resolve in that directory. Wildcards are
|
||||
* allowed if there are no additional components.
|
||||
* NULL or the empty string means 'all'.
|
||||
* dir - Structure to be filled in (or possibly in the
|
||||
* process of being filled in, if GVD_ASYNC)
|
||||
* flags - Options. See FLAGS
|
||||
* acomp - Pointer to a token list consisting of the
|
||||
* remaining components of the name we
|
||||
* want to resolve in that directory. This
|
||||
* argument might get modified. If it is, acomp
|
||||
* will be left pointing to a suffix (not
|
||||
* necessarily a proper suffix) of the token list or
|
||||
* NULL, and the extra tokens will be freed by
|
||||
* p_get_dir().
|
||||
*
|
||||
* FLAGS: GVD_UNION - Do not expand union links
|
||||
* GVD_EXPAND - Expand union links locally
|
||||
* GVD_REMEXP - Request remote expansion (& local if refused)
|
||||
* GVD_LREMEXP - Request remote expansion of local union links
|
||||
* GVD_VERIFY - Only verify that args are for a directory
|
||||
* GVD_FIND - Stop expanding when a match is found
|
||||
* GVD_ATTRIB - Request attributes from directory server
|
||||
* GVD_NOSORT - Do not sort links when adding to directory
|
||||
* GVD_MOTD - Request MOTD string from server
|
||||
* GVD_MOTD_O - Request MOTD and nothing else
|
||||
* GVD_ASYNC - Process request asynchronously
|
||||
*
|
||||
* RETURNS: PSUCCESS (0) or error code on completion.
|
||||
* On some codes addition information in p_err_string.
|
||||
* DQ_ACTIVE if request if GVD_ASYNC specified and
|
||||
* request is still active.
|
||||
*
|
||||
* NOTES: If acomp is non-null the string it points to might be modified
|
||||
*
|
||||
* If the directory passed as an argument already has
|
||||
* links or union links, then those lists will be freed
|
||||
* before the new contents are filled in.
|
||||
*
|
||||
* If a filter is passed to the procedure, and application of
|
||||
* the filter results in additional union link, then those links
|
||||
* will (or will not) be expanded as specified in the FLAGS field.
|
||||
*
|
||||
* If the list of components in NULL, or the null string, then
|
||||
* p_get_dir will return all links in the requested directory.
|
||||
*/
|
||||
|
||||
/* XXX
|
||||
* See bug report in /nfs/pfs/bugs/p_get_dir_modifies_argument for
|
||||
* an explanation of what needs to be done to make this code
|
||||
* more aesthetic and maintainable. this is a quick fix to get it working.
|
||||
*/
|
||||
|
||||
#define RETURN(rv) { retval = (rv); goto cleanup ; }
|
||||
|
||||
static int
|
||||
bad_p_get_dir(VLINK dlink, /* Directory to examine */
|
||||
const char *components,/* Component name (wildcards allowed). */
|
||||
VDIR dir, /* Structure to be filled in */
|
||||
long flags, /* Flags */
|
||||
TOKEN *acomp) /* Components left to be resolved */
|
||||
{
|
||||
struct dqstate *dqs; /* State of current query */
|
||||
|
||||
OUTPUT_ST out_st; /* Output pointer for packet contents */
|
||||
OUTPUT out = &out_st;
|
||||
|
||||
int ardptime; /* Time to wait for ardp_send */
|
||||
|
||||
int tmp; /* To check return values */
|
||||
VLINK tl = NULL; /* Temp link used for apply_filter() */
|
||||
/* Setting it to NULL shuts up GCC; never used
|
||||
before set. */
|
||||
VLINK l; /* Temp link pointer */
|
||||
FILTER filters; /* Filters to apply this time through */
|
||||
|
||||
char options[40]; /* LIST option */
|
||||
char *tchar; /* Temporary chatacter pointer */
|
||||
int retval; /* Hold return value */
|
||||
|
||||
perrno = 0;
|
||||
|
||||
if((dir->status == DQ_ACTIVE) && dir->dqs) {
|
||||
dqs = dir->dqs;
|
||||
/* Turn off this query's GVD_ASYNC flag if it was set on a previous
|
||||
call to P_GET_DIR. */
|
||||
if(!(flags & GVD_ASYNC)) dqs->flags &= (~GVD_ASYNC);
|
||||
}
|
||||
else {
|
||||
/* Initialize a new dqstate structure. */
|
||||
dqs = (struct dqstate *) stalloc(sizeof(struct dqstate));
|
||||
if(!dqs) RETURN(PFAILURE);
|
||||
dir->dqs = dqs;
|
||||
dqs->dl = dlink;
|
||||
|
||||
if (!components || (*components == '\0')) dqs->comp = NULL;
|
||||
else dqs->comp = (char *) components; /* strip off CONST. */
|
||||
dqs->stfree_comp = 0;
|
||||
dqs->acomp = acomp;
|
||||
|
||||
dqs->flags = flags;
|
||||
dqs->fwdcnt = MAX_FWD_DEPTH;
|
||||
dqs->newlinks = 0;
|
||||
dqs->clnk = NULL;
|
||||
dqs->cexp = NULL;
|
||||
dqs->pulnk = NULL;
|
||||
|
||||
/* If filters, don't do remote expansion of union links! */
|
||||
#ifdef NEVERDEFINED
|
||||
/* I cant see why not! */
|
||||
if(dqs->dl->filters) {
|
||||
dqs->flags &= (~(GVD_REMEXP&(~GVD_EXPAND)));
|
||||
dqs->comp = NULL;
|
||||
}
|
||||
#endif
|
||||
if(acomp && *acomp && !dlink->filters) dqs->mcomp = 1;
|
||||
else dqs->mcomp = 0;
|
||||
}
|
||||
|
||||
*options = '\0';
|
||||
if(dqs->flags & GVD_ATTRIB) strcat(options,"+ATTRIBUTES");
|
||||
if((dqs->flags & GVD_EXPMASK) == GVD_REMEXP) strcat(options,"+EXPAND");
|
||||
if((dqs->flags & GVD_EXPMASK) == GVD_LREMEXP) strcat(options,"+LEXPAND");
|
||||
|
||||
/* If all we are doing is verifying a directory */
|
||||
/* we do not want a big response from the directory */
|
||||
/* server. A NOT-FOUND is sufficient. */
|
||||
if(dqs->flags & GVD_VERIFY) strcat(options,"+VERIFY");
|
||||
|
||||
|
||||
if((dir->status == DQ_ACTIVE) && dir->dqs) goto cont_async;
|
||||
|
||||
startover:
|
||||
filters = dqs->dl->filters;
|
||||
|
||||
if(filters) {
|
||||
if(tl) vlfree(tl); /* Loop with filter leaked old copy */
|
||||
tl = vlalloc(); /* Pased to apply_filters */
|
||||
tl->name = stcopy("UNNEEDED");
|
||||
tl->host = stcopy(dqs->dl->host);
|
||||
tl->hsoname = stcopy(dqs->dl->hsoname);
|
||||
tl->filters = flcopy(filters,1); /* otherwise gets freed twice*/
|
||||
}
|
||||
|
||||
get_contents:
|
||||
|
||||
/* Build dir->dqs->preq and out */
|
||||
/* Side effect, filters now points to first client-side filter */
|
||||
build_out(dir, out, options, &filters);
|
||||
|
||||
cont_async:
|
||||
|
||||
if(dqs->flags & GVD_ASYNC) ardptime = 0;
|
||||
else ardptime = ARDP_WAIT_TILL_TO;
|
||||
|
||||
if(dqs->preq->status == ARDP_STATUS_NOSTART)
|
||||
tmp = ardp_send(dqs->preq,dqs->dl->host,0,ardptime);
|
||||
else tmp = ardp_retrieve(dqs->preq,ardptime);
|
||||
|
||||
if((dqs->flags & GVD_ASYNC) && (tmp == ARDP_PENDING)) RETURN(DQ_ACTIVE);
|
||||
|
||||
/* If we don't get a response, then if the requested */
|
||||
/* directory, return error, if a ulink, mark it unexpanded */
|
||||
if(tmp != PSUCCESS) {
|
||||
if (pfs_debug)
|
||||
fprintf(stderr,"ardp_send failed: %d\n",tmp);
|
||||
if(dqs->cexp) dqs->cexp->expanded = FAILED;
|
||||
else {
|
||||
ardp_rqfree(dir->dqs->preq);
|
||||
/* change 1 done*/
|
||||
if (dir->dqs->stfree_comp) stfree(dir->dqs->comp);
|
||||
|
||||
stfree(dir->dqs); dir->dqs = NULL;
|
||||
RETURN(perrno = dir->status = tmp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Claim that we don't have any more unresolved components to process. If
|
||||
we get an UNRESOLVED response, we'll set this back on. */
|
||||
dqs->unresp = 0;
|
||||
|
||||
if (tmp == PSUCCESS) {
|
||||
/* Here we must parse reponse and put in directory */
|
||||
/* While looking at each packet */
|
||||
switch (tmp = retrieve_and_parse(dir)) {
|
||||
case PSUCCESS: break;
|
||||
case DSRFINFO_FORWARDED: goto startover;
|
||||
default:
|
||||
if (dqs->cexp) dqs->cexp->expanded = FAILED;
|
||||
else {
|
||||
ardp_rqfree(dqs->preq);
|
||||
if (dqs->stfree_comp) stfree(dqs->comp);
|
||||
stfree(dqs); dqs = NULL;
|
||||
RETURN(perrno = dir->status = tmp);
|
||||
}
|
||||
} /*switch*/
|
||||
}
|
||||
|
||||
/* We sent multiple components and weren't told any */
|
||||
/* were unresolved */
|
||||
if(dqs->mcomp && !dqs->unresp) {
|
||||
TOKEN acp;
|
||||
for (acp = *dqs->acomp; acp->next; acp = acp->next)
|
||||
;
|
||||
/* acp now points to the last additional component */
|
||||
dqs->comp = acp->token;
|
||||
acp->token = NULL;
|
||||
/* Free the entries. */
|
||||
tklfree(*dqs->acomp);
|
||||
/* Let rd_vdir know what remains */
|
||||
*(dqs->acomp) = NULL;
|
||||
/* If we have union links to resolve, only one component remains */
|
||||
dqs->mcomp = 0;
|
||||
}
|
||||
|
||||
/* If only verifying, we already know it is a directory */
|
||||
if(dqs->flags & GVD_VERIFY) {
|
||||
ardp_rqfree(dqs->preq);
|
||||
if (dir->dqs->stfree_comp) stfree(dir->dqs->comp);
|
||||
stfree(dir->dqs); dir->dqs = NULL;
|
||||
dir->status = DQ_COMPLETE;
|
||||
RETURN(PSUCCESS);
|
||||
}
|
||||
|
||||
/* Don't return if matching was delayed by the need to filter */
|
||||
/* if FIND specified, and dir->links is non null, then we have */
|
||||
/* found a match, and should return. */
|
||||
if((dqs->flags & GVD_FIND) && dir->links && (!filters)) {
|
||||
ardp_rqfree(dqs->preq);
|
||||
if (dir->dqs->stfree_comp) stfree(dir->dqs->comp);
|
||||
stfree(dir->dqs); dir->dqs = NULL;
|
||||
dir->status = DQ_COMPLETE;
|
||||
RETURN(PSUCCESS);
|
||||
}
|
||||
|
||||
/* If expand specified, and ulinks must be expanded, making sure */
|
||||
/* that the order of the links is maintained properly */
|
||||
|
||||
expand_ulinks:
|
||||
|
||||
if ((dqs->flags & GVD_FIND) ||
|
||||
(((dqs->flags & GVD_EXPMASK) != GVD_UNION) &&
|
||||
!(dqs->flags & GVD_VERIFY))) {
|
||||
|
||||
l = dir->ulinks;
|
||||
|
||||
/* Find first unexpanded ulink */
|
||||
while(l && l->expanded && (l->linktype == 'U')) l = l->next;
|
||||
|
||||
/* Only expand if a FILE or DIRECTORY - Mark as */
|
||||
/* failed otherwise */
|
||||
/* We must still add support for symbolic ulinks */
|
||||
if(l) {
|
||||
if ((strcmp(l->target,"DIRECTORY") == 0) ||
|
||||
(strcmp(l->target,"FILE") == 0)) {
|
||||
l->expanded = TRUE;
|
||||
dqs->cexp = l;
|
||||
dqs->pulnk = l;
|
||||
dqs->dl->host = stcopyr(l->host, dqs->dl->host);
|
||||
dqs->dl->hsoname = stcopyr(l->hsoname, dqs->dl->hsoname);
|
||||
/* When we're expanding union links, we need to turn off
|
||||
support for multiple components. Otherwise, p_get_dir() is
|
||||
confused by a NONE-FOUND response during the expansion
|
||||
process and zeroes out the dqs->acomp. */
|
||||
dqs->mcomp = 0;
|
||||
goto get_contents;
|
||||
}
|
||||
else l->expanded = FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Right now, give off no error messages if inappropriate filters are
|
||||
encountered (e.g., a SERVER filter following a CLIENT filter).
|
||||
We just don't worry about it right now. Maybe we should do error
|
||||
reporting. Presumably, only client filters are left right now. XXX */
|
||||
if(filters && filters->execution_location == FIL_CLIENT &&
|
||||
(filters->type == FIL_DIRECTORY || filters->type == FIL_HIERARCHY)) {
|
||||
apply_filters(dir,filters,tl,0); /* Apply a single filter */
|
||||
filters = filters->next;
|
||||
goto expand_ulinks;
|
||||
}
|
||||
|
||||
/* Double check to make sure we don't get */
|
||||
/* back unwanted components */
|
||||
/* OK to keep if special (URP) links */
|
||||
if(dqs->comp && *(dqs->comp)) {
|
||||
l = dir->links;
|
||||
while(l) {
|
||||
VLINK ol;
|
||||
if((l->linktype == 'L' || l->linktype == 'I')
|
||||
&& (!wcmatch(l->name,dqs->comp))) {
|
||||
if(l == dir->links)
|
||||
dir->links = l->next;
|
||||
else l->previous->next = l->next;
|
||||
if(l->next) l->next->previous = l->previous;
|
||||
ol = l;
|
||||
l = l->next;
|
||||
vlfree(ol);
|
||||
}
|
||||
else l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
ardp_rqfree(dqs->preq);
|
||||
if (dir->dqs->stfree_comp) stfree(dir->dqs->comp);
|
||||
stfree(dir->dqs); dir->dqs = NULL;
|
||||
dir->status = DQ_COMPLETE;
|
||||
RETURN(PSUCCESS);
|
||||
cleanup:
|
||||
if (tl) vlfree(tl);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
int
|
||||
p_get_dir(VLINK dlink, const char *components, VDIR dir,
|
||||
long flags, TOKEN *acomp)
|
||||
{
|
||||
VLINK vl;
|
||||
int retval;
|
||||
|
||||
/* the distributed p_get_dir hacks dlink if the resulting directory contains
|
||||
any union links, or is forwarded, fix this behaviour */
|
||||
|
||||
vl = vlcopy(dlink,FALSE);
|
||||
retval = bad_p_get_dir(vl, components, dir, flags, acomp);
|
||||
vlfree(vl);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* Older interfaces (backwards compatability) */
|
||||
|
||||
int
|
||||
p_get_vdir(VLINK dlink, /* Directory to examine */
|
||||
const char *components,/* Component name (wildcards allowed). */
|
||||
VDIR dir, /* Structure to be filled in */
|
||||
long flags, /* Flags */
|
||||
TOKEN *acomp) /* Components left to be resolved */
|
||||
{
|
||||
return p_get_dir(dlink, components, dir, flags, acomp);
|
||||
}
|
||||
|
||||
int
|
||||
get_vdir(VLINK dlink, /* Directory to examine */
|
||||
const char *components,/* Component name (wildcards allowed). */
|
||||
VDIR dir, /* Structure to be filled in */
|
||||
long flags, /* Flags */
|
||||
TOKEN *acomp) /* Components left to be resolved */
|
||||
{
|
||||
return p_get_dir(dlink, components, dir, flags, acomp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
69
prospero/lib/pfs/p_initialize.c
Normal file
69
prospero/lib/pfs/p_initialize.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 <pfs_threads.h>
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pfs_threads.h>
|
||||
#include <pcompat.h> /* For PMAP_ATSIGN*/
|
||||
|
||||
static void
|
||||
p_thread_initialize_master_and_daughters()
|
||||
{
|
||||
pfs_enable = PMAP_ATSIGN;
|
||||
if (!p_err_string) p_err_string = stcopy("");
|
||||
if (!p_warn_string) p_warn_string = stcopy("");
|
||||
p_clear_errors();
|
||||
}
|
||||
void
|
||||
p_thread_initialize()
|
||||
{
|
||||
#ifdef PFS_THREADS
|
||||
#ifndef MASTER_IS_ONLY_SUBTHREAD
|
||||
/* This should probably be a general purpose initialization fnctn*/
|
||||
p_th_allocate_self_num();
|
||||
#endif
|
||||
#endif
|
||||
p_thread_initialize_master_and_daughters();
|
||||
}
|
||||
|
||||
/* p_initialize(), written by swa@isi.edu, 6 Nov 1993 */
|
||||
void
|
||||
p_initialize(char *software_id, int flags, struct p_initialize_st * arg_st)
|
||||
{
|
||||
if (pfs_debug == 0) { /* if specified in a command line flag or
|
||||
otherwise by the program itself, this
|
||||
overrides the environment variable. */
|
||||
char *pfs_debug_string; /* temporary */
|
||||
if(pfs_debug_string = getenv("PFS_DEBUG"))
|
||||
sscanf(pfs_debug_string, "%d", &pfs_debug);
|
||||
}
|
||||
/* Carefull not to put anything in here specific to the server */
|
||||
/* No flags currently defined. */
|
||||
/* Currently no options to set in the p_initialize_st */
|
||||
#ifdef PFS_THREADS
|
||||
p__th_set_self_master(); /* must be called first. */
|
||||
#endif
|
||||
p__set_sw_id(software_id);
|
||||
/* Initialize error messages to null string, if they're currently set to
|
||||
NULL ptr. This means that it will never be wrong to dereference
|
||||
p_err_string. */
|
||||
p_thread_initialize_master_and_daughters();
|
||||
ardp_init_mutexes(); /* need not be called if not running threaded.
|
||||
Won't hurt though. */
|
||||
p__init_mutexes(); /* ditto */
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void
|
||||
p_diagnose(void)
|
||||
{
|
||||
ardp_diagnose_mutexes();
|
||||
p__diagnose_mutexes();
|
||||
}
|
||||
#endif /*NDEBUG*/
|
||||
64
prospero/lib/pfs/p_uln_index.c
Normal file
64
prospero/lib/pfs/p_uln_index.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 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>
|
||||
|
||||
char *
|
||||
p_uln_rindex(const char *s, char c)
|
||||
{
|
||||
const char *lastmatch = NULL;
|
||||
|
||||
for (; *s; ++s) {
|
||||
if (*s == '\\') {
|
||||
if (*++s == '\0') /* special case this error condition */
|
||||
return (char *) lastmatch; /* done. Flush the CONST.*/
|
||||
else
|
||||
continue; /* don't match a quoted symbol */
|
||||
}
|
||||
if (*s == c) lastmatch = s;
|
||||
}
|
||||
return (char *) lastmatch; /* done. flush the CONST. */
|
||||
}
|
||||
|
||||
char *
|
||||
p_uln_index(const char *s, char c)
|
||||
{
|
||||
for (; *s; ++s) {
|
||||
if (*s == '\\') {
|
||||
if (*++s == '\0') /* special case this error condition */
|
||||
return NULL; /* done */
|
||||
else
|
||||
continue; /* don't match a quoted symbol */
|
||||
}
|
||||
if (*s == c) return (char *) s; /* done. flush the CONST. */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a linkname from the last component of a user level name.
|
||||
Returns memory that will be freed on the next call. */
|
||||
char *
|
||||
p_uln_lastcomp_to_linkname(const char *s)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
char *outp;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if (p__bstsize(buf) < strlen(s) + 1) {
|
||||
stfree(buf);
|
||||
buf = stalloc(strlen(s) + 1);
|
||||
}
|
||||
outp = buf;
|
||||
while (*s) {
|
||||
if (*s == '\\')
|
||||
++s;
|
||||
*outp++ = *s++;
|
||||
}
|
||||
*outp = '\0';
|
||||
return buf;
|
||||
}
|
||||
120
prospero/lib/pfs/paalloc.c
Normal file
120
prospero/lib/pfs/paalloc.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 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>.
|
||||
*/
|
||||
/* Munged by swa to handle multiple principals. */
|
||||
|
||||
#include <uw-copyright.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For malloc and free */
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
static PAUTH pauthflist = NULL;
|
||||
int pauth_count = 0;
|
||||
int pauth_max = 0;
|
||||
|
||||
/*
|
||||
* paalloc - allocate and initialize pacess control list structure
|
||||
*
|
||||
* PAALLOC returns a pointer to an initialized structure of type
|
||||
* PAUTH. If it is unable to allocate such a structure, it
|
||||
* signals out_of_memory();
|
||||
*/
|
||||
/* We dynamically allocate these because the server end may have several of
|
||||
them hanging out. */
|
||||
PAUTH
|
||||
paalloc()
|
||||
{
|
||||
PAUTH pauth_ent;
|
||||
p_th_mutex_lock(p_th_mutexPAALLOC);
|
||||
if(pauthflist) {
|
||||
pauth_ent = pauthflist;
|
||||
pauthflist = pauthflist->next;
|
||||
}
|
||||
else {
|
||||
pauth_ent = (PAUTH) malloc(sizeof(PAUTH_ST));
|
||||
if (!pauth_ent) out_of_memory();
|
||||
pauth_max++;
|
||||
}
|
||||
|
||||
pauth_count++;
|
||||
p_th_mutex_unlock(p_th_mutexPAALLOC);
|
||||
|
||||
/* Initialize and fill in default values */
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
pauth_ent->consistency = INUSE_PATTERN;
|
||||
#endif
|
||||
pauth_ent->ainfo_type = 0;
|
||||
pauth_ent->authenticator = NULL;
|
||||
pauth_ent->principals = NULL;
|
||||
pauth_ent->app.ptr = NULL; /* On every architecture I ever heard
|
||||
of, pauth_ent->app.flg is now 0 too
|
||||
*/
|
||||
pauth_ent->next = NULL;
|
||||
return(pauth_ent);
|
||||
}
|
||||
|
||||
static void (*paappfreefunc)(PAUTH) = NULL;
|
||||
|
||||
/*
|
||||
* Specify which special freeing function (if any) to be used to free the
|
||||
* app.ptr member of the PAUTH structure, if set.
|
||||
*/
|
||||
void
|
||||
paappfree(void (* appfreefunc)(PAUTH))
|
||||
{
|
||||
paappfreefunc = appfreefunc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* pafree - free an PAUTH structure
|
||||
*
|
||||
* PAFREE takes a pointer to an PAUTH structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
pafree(PAUTH pauth_ent)
|
||||
{
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(pauth_ent->consistency == INUSE_PATTERN);
|
||||
pauth_ent->consistency = FREE_PATTERN;
|
||||
#endif
|
||||
pauth_ent->ainfo_type = 0;
|
||||
if(pauth_ent->authenticator) stfree(pauth_ent->authenticator);
|
||||
if(pauth_ent->principals) tklfree(pauth_ent->principals);
|
||||
if(paappfreefunc && pauth_ent->app.ptr) {
|
||||
(*paappfreefunc)(pauth_ent->app.ptr); pauth_ent->app.ptr = NULL;
|
||||
}
|
||||
|
||||
p_th_mutex_lock(p_th_mutexPAALLOC);
|
||||
pauth_ent->next = pauthflist;
|
||||
pauthflist = pauth_ent;
|
||||
pauth_count--;
|
||||
p_th_mutex_unlock(p_th_mutexPAALLOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* palfree - free a PAUTH structure
|
||||
*
|
||||
* PALFREE takes a pointer to an PAUTH structure frees it and any linked
|
||||
* PAUTH structures. It is used to free an entrie list of PAUTH
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
palfree(PAUTH pauth_ent)
|
||||
{
|
||||
PAUTH nxt;
|
||||
|
||||
while(pauth_ent != NULL) {
|
||||
nxt = pauth_ent->next;
|
||||
pafree(pauth_ent);
|
||||
pauth_ent = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
486
prospero/lib/pfs/penviron.c
Normal file
486
prospero/lib/pfs/penviron.c
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
* Copyright (c) 1991, 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 <pcompat.h>
|
||||
#include <pfs.h>
|
||||
#include <psite.h>
|
||||
#include <pmachine.h>
|
||||
#include <perrno.h>
|
||||
#ifdef SOLARIS
|
||||
/* #include "p_solaris_stdlib.h" \* Special tricks to prototype setenv() */
|
||||
#else
|
||||
#include <stdlib.h> /* For malloc and free, getenv etc */
|
||||
#endif
|
||||
|
||||
static char vsroot_host[MAX_VPATH] = "";
|
||||
static char vsroot_file[MAX_VPATH] = "";
|
||||
|
||||
static char vswork_host[MAX_VPATH] = "";
|
||||
static char vswork_file[MAX_VPATH] = "";
|
||||
static char vswork[MAX_VPATH] = "";
|
||||
|
||||
static char vshome_host[MAX_VPATH] = "";
|
||||
static char vshome_file[MAX_VPATH] = "";
|
||||
static char vshome[MAX_VPATH] = "";
|
||||
|
||||
static char vsdesc_host[MAX_VPATH] = "";
|
||||
static char vsdesc_file[MAX_VPATH] = "";
|
||||
static char vsname[MAX_VPATH] = "";
|
||||
|
||||
|
||||
/*
|
||||
* Note that there is one more environment variable used, PFS_DEFAULT,
|
||||
* but that environment variable is per process and is handled in the
|
||||
* pcompat library.
|
||||
*/
|
||||
|
||||
#ifdef PUTENV /* If we don't have the lib. function */
|
||||
static setenv();
|
||||
#endif
|
||||
|
||||
void
|
||||
pset_wd(wdhost,wdfile,wdname)
|
||||
char *wdhost;
|
||||
char *wdfile;
|
||||
char *wdname;
|
||||
{
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(wdhost) {
|
||||
strcpy(vswork_host,wdhost);
|
||||
setenv("VSWORK_HOST",wdhost,1);
|
||||
}
|
||||
if(wdfile) {
|
||||
strcpy(vswork_file,wdfile);
|
||||
setenv("VSWORK_FILE",wdfile,1);
|
||||
}
|
||||
if(wdname) {
|
||||
strcpy(vswork,wdname);
|
||||
setenv("VSWORK",wdname,1);
|
||||
}
|
||||
}
|
||||
|
||||
char * pget_wdhost()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vswork_host && (env_st = getenv("VSWORK_HOST")))
|
||||
strcpy(vswork_host,env_st);
|
||||
if(*vswork_host) return(vswork_host);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_wdfile()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vswork_file && (env_st = getenv("VSWORK_FILE")))
|
||||
strcpy(vswork_file,env_st);
|
||||
if(*vswork_file) return(vswork_file);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_wd()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vswork && (env_st = getenv("VSWORK")))
|
||||
strcpy(vswork,env_st);
|
||||
if(*vswork) return(vswork);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
pset_hd(hdhost,hdfile,hdname)
|
||||
char *hdhost;
|
||||
char *hdfile;
|
||||
char *hdname;
|
||||
{
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(hdhost) {
|
||||
strcpy(vshome_host,hdhost);
|
||||
setenv("VSHOME_HOST",hdhost,1);
|
||||
}
|
||||
if(hdfile) {
|
||||
strcpy(vshome_file,hdfile);
|
||||
setenv("VSHOME_FILE",hdfile,1);
|
||||
}
|
||||
if(hdname) {
|
||||
strcpy(vshome,hdname);
|
||||
setenv("VSHOME",hdname,1);
|
||||
}
|
||||
}
|
||||
|
||||
char * pget_hdhost()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vshome_host && (env_st = getenv("VSHOME_HOST")))
|
||||
strcpy(vshome_host,env_st);
|
||||
if(*vshome_host) return(vshome_host);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_hdfile()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vshome_file && (env_st = getenv("VSHOME_FILE")))
|
||||
strcpy(vshome_file,env_st);
|
||||
if(*vshome_file) return(vshome_file);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_hd()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vshome && (env_st = getenv("VSHOME")))
|
||||
strcpy(vshome,env_st);
|
||||
if(*vshome) return(vshome);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
pset_rd(rdhost,rdfile)
|
||||
char *rdhost;
|
||||
char *rdfile;
|
||||
{
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(rdhost) {
|
||||
strcpy(vsroot_host,rdhost);
|
||||
setenv("VSROOT_HOST",rdhost,1);
|
||||
}
|
||||
if(rdfile) {
|
||||
strcpy(vsroot_file,rdfile);
|
||||
setenv("VSROOT_FILE",rdfile,1);
|
||||
}
|
||||
}
|
||||
|
||||
char * pget_rdhost()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vsroot_host && (env_st = getenv("VSROOT_HOST")))
|
||||
strcpy(vsroot_host,env_st);
|
||||
if(*vsroot_host) return(vsroot_host);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_rdfile()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vsroot_file && (env_st = getenv("VSROOT_FILE")))
|
||||
strcpy(vsroot_file,env_st);
|
||||
if(*vsroot_file) return(vsroot_file);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
pset_desc(dhost,dfile,vsnm)
|
||||
char *dhost;
|
||||
char *dfile;
|
||||
char *vsnm;
|
||||
{
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(dhost) {
|
||||
strcpy(vsdesc_host,dhost);
|
||||
setenv("VSDESC_HOST",dhost,1);
|
||||
}
|
||||
if(dfile) {
|
||||
strcpy(vsdesc_file,dfile);
|
||||
setenv("VSDESC_FILE",dfile,1);
|
||||
}
|
||||
if(vsnm) {
|
||||
strcpy(vsname,vsnm);
|
||||
setenv("VSNAME",vsnm,1);
|
||||
}
|
||||
}
|
||||
|
||||
char * pget_dhost()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vsdesc_host && (env_st = getenv("VSDESC_HOST")))
|
||||
strcpy(vsdesc_host,env_st);
|
||||
if(*vsdesc_host) return(vsdesc_host);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_dfile()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vsdesc_file && (env_st = getenv("VSDESC_FILE")))
|
||||
strcpy(vsdesc_file,env_st);
|
||||
if(*vsdesc_file) return(vsdesc_file);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
char * pget_vsname()
|
||||
{
|
||||
char *env_st;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if(!*vsname && (env_st = getenv("VSNAME")))
|
||||
strcpy(vsname,env_st);
|
||||
if(*vsname) return(vsname);
|
||||
else return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pprint shell string prints command on the standard output which when
|
||||
* interpreted by the shell will set environment variable and define
|
||||
* aliases needed to pass the prospero environment from program to
|
||||
* program. This routine is called by vfsetup and vcd.
|
||||
*
|
||||
* The argument is a bit vector indicating which variable should be set.
|
||||
* The low order bit is (0x0):
|
||||
*
|
||||
* 0x001 Print aliases
|
||||
* 0x002 Print virtual system description
|
||||
* 0x004 Print working directory
|
||||
* 0x008 Print home directory
|
||||
* 0x010 Print root directory
|
||||
* 0x1e0 Mask indicating which shell to print strings for. We leave room
|
||||
* for 16 possibilities for when more shells with their own weird
|
||||
* syntaxes show up.
|
||||
*/
|
||||
#define SHELL_MASK 0x1e0
|
||||
#define SHELL_ERROR 0x0 /* 0 is undefined */
|
||||
#define SHELL_SH 0x020
|
||||
#define SHELL_CSH 0x040
|
||||
|
||||
void
|
||||
p__print_shellstring(int which)
|
||||
{
|
||||
int shell = which & SHELL_MASK;
|
||||
|
||||
if((which & 0x1)&&(shell == SHELL_CSH)) {
|
||||
printf("alias vwd 'echo $VSWORK';\n");
|
||||
printf("alias vwp 'echo $VSWORK_HOST $VSWORK_FILE';\n");
|
||||
printf("alias vwho 'echo $VSNAME';\n");
|
||||
printf("alias vcd 'p__vcd -s csh \\!* >! /tmp/vfs$$;source /tmp/vfs$$;\
|
||||
/bin/rm /tmp/vfs$$'\n");
|
||||
|
||||
#ifndef P_NO_PCOMPAT
|
||||
printf("alias venable 'setenv PFS_DEFAULT %d;if($?Poldcd == 0) set Poldcd = `alias cd`;alias pwd vwd;alias cd vcd';\n",PMAP_ATSIGN_NF);
|
||||
printf("set Presetcd = 'unalias cd;alias cd $Poldcd;unset Poldcd';\n");
|
||||
printf("alias vdisable 'unsetenv PFS_DEFAULT;unalias pwd;if($?Poldcd) eval $Presetcd';\n");
|
||||
#endif P_NO_PCOMPAT
|
||||
} else if((which & 0x1)&&(shell == SHELL_SH)) {
|
||||
printf("vwd () { echo $VSWORK \n}\n");
|
||||
printf("vwp () { echo $VSWORK_HOST $VSWORK_FILE \n}\n");
|
||||
printf("vwho () { echo $VSNAME \n}\n");
|
||||
printf("vcd () { p__vcd -s sh $* > /tmp/vfs$$ ;. /tmp/vfs$$; /bin/rm /tmp/vfs$$ \n}\n");
|
||||
|
||||
#ifndef P_NO_PCOMPAT
|
||||
/* Note that this will bash any existing cd alias */
|
||||
printf("venable () { PFS_DEFAULT=%d;export PFS_DEFAULT;alias cd=vcd;alias pwd=vwd \n}\n",PMAP_ATSIGN_NF);
|
||||
printf("vdisable () { unset PFS_DEFAULT;unalias cd; unalias pwd\n}\n");
|
||||
#endif P_NO_PCOMPAT
|
||||
}
|
||||
if((which & 0x2)&&(shell == SHELL_CSH)) {
|
||||
printf("setenv VSDESC_HOST \"%s\";\n",pget_dhost());
|
||||
printf("setenv VSDESC_FILE \"%s\";\n",pget_dfile());
|
||||
printf("setenv VSNAME \"%s\";\n",pget_vsname());
|
||||
}
|
||||
else if((which & 0x2)&&(shell == SHELL_SH)) {
|
||||
printf("VSDESC_HOST=\"%s\";export VSDESC_HOST\n",pget_dhost());
|
||||
printf("VSDESC_FILE=\"%s\";export VSDESC_FILE\n",pget_dfile());
|
||||
printf("VSNAME=\"%s\";export VSNAME\n",pget_vsname());
|
||||
}
|
||||
|
||||
if((which & 0x4)&&(shell == SHELL_CSH)) {
|
||||
printf("setenv VSWORK_HOST \"%s\";\n",pget_wdhost());
|
||||
printf("setenv VSWORK_FILE \"%s\";\n",pget_wdfile());
|
||||
printf("setenv VSWORK \"%s\";\n",pget_wd());
|
||||
}
|
||||
else if((which & 0x4)&&(shell == SHELL_SH)) {
|
||||
printf("VSWORK_HOST=\"%s\";export VSWORK_HOST\n",pget_wdhost());
|
||||
printf("VSWORK_FILE=\"%s\";export VSWORK_FILE\n",pget_wdfile());
|
||||
printf("VSWORK=\"%s\";export VSWORK\n",pget_wd());
|
||||
}
|
||||
|
||||
if((which & 0x8)&&(shell == SHELL_CSH)) {
|
||||
printf("setenv VSHOME_HOST \"%s\";\n",pget_hdhost());
|
||||
printf("setenv VSHOME_FILE \"%s\";\n",pget_hdfile());
|
||||
printf("setenv VSHOME \"%s\";\n",pget_hd());
|
||||
}
|
||||
else if((which & 0x8)&&(shell == SHELL_SH)) {
|
||||
printf("VSHOME_HOST=\"%s\";export VSHOME_HOST\n",pget_hdhost());
|
||||
printf("VSHOME_FILE=\"%s\";export VSHOME_FILE\n",pget_hdfile());
|
||||
printf("VSHOME=\"%s\";export VSHOME\n",pget_hd());
|
||||
}
|
||||
|
||||
if((which & 0x10)&&(shell == SHELL_CSH)) {
|
||||
printf("setenv VSROOT_HOST \"%s\";\n",pget_rdhost());
|
||||
printf("setenv VSROOT_FILE \"%s\";\n",pget_rdfile());
|
||||
}
|
||||
else if((which & 0x10)&&(shell == SHELL_SH)) {
|
||||
printf("VSROOT_HOST=\"%s\";export VSROOT_HOST\n",pget_rdhost());
|
||||
printf("VSROOT_FILE=\"%s\";export VSROOT_FILE\n",pget_rdfile());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* return a flag value for the shell that can be given to
|
||||
p__print_shellstring(). If no shell defined, return 0 and set
|
||||
p_err_string. This functions is only called by the VCD and VFSETUP
|
||||
commands at this time. */
|
||||
int
|
||||
p__get_shellflag(const char *shellname)
|
||||
{
|
||||
char *shellenvar;
|
||||
int shellenvarlen;
|
||||
if (shellname) {
|
||||
if (strequal(shellname, "sh")) return SHELL_SH;
|
||||
if (strequal(shellname, "csh")) return SHELL_CSH;
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"The system doesn't know about shells of type \"%s\". \
|
||||
Please see the person who maintains Prospero at your site.", shellname);
|
||||
perrno = PFAILURE;
|
||||
return SHELL_ERROR;
|
||||
}
|
||||
/* this part is going to go away eventually. The -s flag to p__vfsetup and
|
||||
p__vcd has effectively obsoleted it. It's still around for a while, (a)
|
||||
in case people are using old versions of vfsetup.source or
|
||||
vfsetup.profil. and (b) because I'm too sentimental to flush it yet :).
|
||||
*/
|
||||
shellenvar = getenv("SHELL");
|
||||
if (!shellenvar) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Couldn't find SHELL environment variable; \
|
||||
I don't know what kind of SHELL you're using. Please see your maintainer.");
|
||||
perrno = PFAILURE;
|
||||
return SHELL_ERROR; /* undefined */
|
||||
}
|
||||
shellenvarlen = strlen(shellenvar);
|
||||
if (shellenvarlen >= 3 && strequal(shellenvar + shellenvarlen - 3, "csh"))
|
||||
return SHELL_CSH;
|
||||
else
|
||||
return SHELL_SH;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef PUTENV
|
||||
static int
|
||||
setenv(char *n,char *v, int o)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/* Allocate space for environment variable */
|
||||
char *template = (char *) stalloc(strlen(n)+strlen(v)+2);
|
||||
|
||||
sprintf(template,"%s=%s",n,v);
|
||||
tmp = putenv(template);
|
||||
return(tmp);
|
||||
|
||||
/* Potential memory leak - it is not clear whether putenv */
|
||||
/* deallocates the string with the old value of the */
|
||||
/* envorinment variable. If not, then we should do so here. */
|
||||
/* This concern is not valid (swa, 5/27/93):
|
||||
From the SUN OS 4.1.3 manual page for 'putenv()':
|
||||
|
||||
int putenv(string)
|
||||
char *string;
|
||||
"the string pointed to by string becomes part of the environment, so
|
||||
altering the string will change the environment. "
|
||||
|
||||
The HP-UX 8.05 manual page is similarly worded.
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
#endif PUTENV
|
||||
|
||||
#ifdef BADSETENV
|
||||
/*
|
||||
* Copyright (c) 1987 Regents of the University of California.
|
||||
* This file may be freely redistributed provided that this
|
||||
* notice remains attached.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)setenv.c 1.2 (Berkeley) 3/13/87";
|
||||
#endif LIBC_SCCS and not lint
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* setenv(name,value,rewrite)
|
||||
* Set the value of the environmental variable "name" to be
|
||||
* "value". If rewrite is set, replace any current value.
|
||||
*/
|
||||
setenv(name,value,rewrite)
|
||||
register char *name,
|
||||
*value;
|
||||
int rewrite;
|
||||
{
|
||||
extern char **environ;
|
||||
static int alloced; /* if allocated space before */
|
||||
register char *C;
|
||||
int l_value,
|
||||
offset;
|
||||
char *_findenv();
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
if (*value == '=') /* no `=' in value */
|
||||
++value;
|
||||
l_value = strlen(value);
|
||||
if ((C = _findenv(name,&offset))) { /* find if already exists */
|
||||
if (!rewrite)
|
||||
return(0);
|
||||
#if BUG
|
||||
if (strlen(C) <= l_value) { /* smaller; copy over */
|
||||
while (*C++ = *value++);
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
if (l_value <= strlen(C)) { /* smaller; copy over */
|
||||
while (*C++ = *value++);
|
||||
return(0);
|
||||
}
|
||||
#endif BUG
|
||||
}
|
||||
else { /* create new slot */
|
||||
register int cnt;
|
||||
register char **P;
|
||||
|
||||
for (P = environ,cnt = 0;*P;++P,++cnt);
|
||||
if (alloced) { /* just increase size */
|
||||
environ = (char **)realloc((char *)environ,
|
||||
(u_int)(sizeof(char *) * (cnt + 2)));
|
||||
if (!environ)
|
||||
return(-1);
|
||||
}
|
||||
else { /* get new space */
|
||||
alloced = 1; /* copy old entries into it */
|
||||
P = (char **)malloc((u_int)(sizeof(char *) *
|
||||
(cnt + 2)));
|
||||
if (!P)
|
||||
return(-1);
|
||||
bcopy(environ,P,cnt * sizeof(char *));
|
||||
environ = P;
|
||||
}
|
||||
environ[cnt + 1] = NULL;
|
||||
offset = cnt;
|
||||
}
|
||||
for (C = name;*C && *C != '=';++C); /* no `=' in name */
|
||||
if (!(environ[offset] = /* name + `=' + value */
|
||||
malloc((u_int)((int)(C - name) + l_value + 2))))
|
||||
return(-1);
|
||||
for (C = environ[offset];(*C = *name++) && *C != '=';++C);
|
||||
for (*C++ = '=';*C++ = *value++;);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif BADSETENV
|
||||
383
prospero/lib/pfs/perrmesg.c
Normal file
383
prospero/lib/pfs/perrmesg.c
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* 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 <perrno.h>
|
||||
#include <stdio.h>
|
||||
#include <pfs_threads.h>
|
||||
|
||||
/* This file and perrno.h should always be updated simultaneously */
|
||||
|
||||
/* Don't declare perrno here
|
||||
because some Prospero applications declare it themselves, internally,
|
||||
and the two can conflict.
|
||||
There is a version of perrno provided in lib/ardp/ardp_perrno.c
|
||||
which will be linked in in case of a problem.
|
||||
|
||||
int perrno = 0;
|
||||
*/
|
||||
|
||||
/* These need to be per-thread in case of two simultaneous errors*/
|
||||
#ifdef NEVERDEFINED
|
||||
int pwarn = 0;
|
||||
char *p_err_string = NULL;
|
||||
char *p_warn_string = NULL;
|
||||
#endif
|
||||
|
||||
EXTERN_INT_DEF(pwarn);
|
||||
EXTERN_CHARP_DEF(p_err_string);
|
||||
EXTERN_CHARP_DEF(p_warn_string);
|
||||
|
||||
/* These are initialized in p_initialize(). */
|
||||
|
||||
/* This depends upon the internals of lib/ardp/ardp_error.c */
|
||||
|
||||
char *ardp___please_do_not_optimize_me_out_of_existence;
|
||||
/* See lib/ardp/usc_lic_str.c */
|
||||
extern char *usc_license_string;
|
||||
|
||||
|
||||
/* This function definition is shadowed in lib/ardp/ardp_error.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 = PSUCCESS; if (p_err_string) p_err_string[0] = '\0';
|
||||
pwarn = PNOWARN; if (p_warn_string) p_warn_string[0] = '\0';
|
||||
}
|
||||
|
||||
char *p_err_text[256] = {
|
||||
/* 0 */ "Success (prospero)",
|
||||
/* 1 */ "Port unknown (ardp)",
|
||||
/* 2 */ "Can't open local UDP port (ardp)",
|
||||
/* 3 */ "Can't resolve hostname (ardp)",
|
||||
/* 4 */ "Attempt to send message failed (ardp)",
|
||||
/* 5 */ "Select failed (ardp)",
|
||||
/* 6 */ "Recvfrom failed (ardp)",
|
||||
/* 7 */ "Unknown protocol version number (ardp)",
|
||||
/* 8 */ "Inconsistent or unexpected form for request structure (ardp)",
|
||||
/* 9 */ "Timed out (ardp)",
|
||||
/* 10 */ "Connection refused by server (ardp)",
|
||||
/* 11 */ "Generic failure sending or receiving message (ardp)",
|
||||
/* 12 */ "Undefined error 12 (prospero)",
|
||||
/* 13 */ "Undefined error 13 (prospero)",
|
||||
/* 14 */ "Undefined error 14 (prospero)",
|
||||
/* 15 */ "Undefined error 15 (prospero)",
|
||||
/* 16 */ "Undefined error 16 (prospero)",
|
||||
/* 17 */ "Undefined error 17 (prospero)",
|
||||
/* 18 */ "Undefined error 18 (prospero)",
|
||||
/* 19 */ "Undefined error 19 (prospero)",
|
||||
/* 20 */ "Undefined error 20 (prospero)",
|
||||
/* 21 */ "Link already exists (vl_insert)",
|
||||
/* 22 */ "Link with same name already exists (vl_insert)",
|
||||
/* 23 */ "Undefined error 23 (prospero)",
|
||||
/* 24 */ "Undefined error 24 (prospero)",
|
||||
/* 25 */ "Link already exists (ul_insert)",
|
||||
/* 26 */ "Replacing existing link (ul_insert)",
|
||||
/* 27 */ "Previous entry not found in dir->ulinks (ul_insert)",
|
||||
/* 28 */ "Undefined error 28 (prospero)",
|
||||
/* 29 */ "Undefined error 29 (prospero)",
|
||||
/* 30 */ "Undefined error 30 (prospero)",
|
||||
/* 31 */ "Undefined error 31 (prospero)",
|
||||
/* 32 */ "Undefined error 32 (prospero)",
|
||||
/* 33 */ "Undefined error 33 (prospero)",
|
||||
/* 34 */ "Undefined error 34 (prospero)",
|
||||
/* 35 */ "Undefined error 35 (prospero)",
|
||||
/* 36 */ "Undefined error 36 (prospero)",
|
||||
/* 37 */ "Undefined error 37 (prospero)",
|
||||
/* 38 */ "Undefined error 38 (prospero)",
|
||||
/* 39 */ "Undefined error 39 (prospero)",
|
||||
/* 40 */ "Undefined error 40 (prospero)",
|
||||
/* 41 */ "Temporary not found (rd_vdir)",
|
||||
/* 42 */ "Namespace not closed with object (rd_vdir)",
|
||||
/* 43 */ "Alias for namespace not defined (rd_vdir)",
|
||||
/* 44 */ "Specified namespace not found (rd_vdir)",
|
||||
/* 45 */ "Undefined error 45 (prospero)",
|
||||
/* 46 */ "Undefined error 46 (prospero)",
|
||||
/* 47 */ "Undefined error 47 (prospero)",
|
||||
/* 48 */ "Undefined error 48 (prospero)",
|
||||
/* 49 */ "Undefined error 49 (prospero)",
|
||||
/* 50 */ "Undefined error 50 (prospero)",
|
||||
/* 51 */ "File access method not supported (pfs_access)",
|
||||
/* 52 */ "Undefined error 52 (prospero)",
|
||||
/* 53 */ "Undefined error 53 (prospero)",
|
||||
/* 54 */ "Undefined error 54 (prospero)",
|
||||
/* 55 */ "Pointer to cached copy - delete on close (p__map_cache)",
|
||||
/* 56 */ "Unable to retrieve file (p__map_cache)",
|
||||
/* 57 */ "Undefined error 57 (prospero)",
|
||||
/* 58 */ "Undefined error 58 (prospero)",
|
||||
/* 59 */ "Undefined error 59 (prospero)",
|
||||
/* 60 */ "Undefined error 60 (prospero)",
|
||||
/* 61 */ "Directory already exists (mk_vdir)",
|
||||
/* 62 */ "Link with same name already exists (mk_vdir)",
|
||||
/* 63 */ "Undefined error 63 (prospero)",
|
||||
/* 64 */ "Undefined error 64 (prospero)",
|
||||
/* 65 */ "Not a virtual system (vfsetenv)",
|
||||
/* 66 */ "Can't find directory (vfsetenv)",
|
||||
/* 67 */ "Undefined error 67 (prospero)",
|
||||
/* 68 */ "Undefined error 68 (prospero)",
|
||||
/* 69 */ "Undefined error 69 (prospero)",
|
||||
/* 70 */ "Undefined error 70 (prospero)",
|
||||
/* 71 */ "Link already exists (add_vlink)",
|
||||
/* 72 */ "Link with same name already exists (add_vlink)",
|
||||
/* 73 */ "Undefined error 73 (prospero)",
|
||||
/* 74 */ "Undefined error 74 (prospero)",
|
||||
/* 75 */ "Undefined error 75 (prospero)",
|
||||
/* 76 */ "Undefined error 76 (prospero)",
|
||||
/* 77 */ "Undefined error 77 (prospero)",
|
||||
/* 78 */ "Undefined error 78 (prospero)",
|
||||
/* 79 */ "Undefined error 79 (prospero)",
|
||||
/* 80 */ "Undefined error 80 (prospero)",
|
||||
/* 81 */ "This link does not refer to an object; can't set an OBJECT \
|
||||
attribute on it (pset_at)",
|
||||
/* 82 */ "Undefined error 82 (prospero)",
|
||||
/* 83 */ "Undefined error 83 (prospero)",
|
||||
/* 84 */ "Undefined error 84 (prospero)",
|
||||
/* 85 */ "Undefined error 85 (prospero)",
|
||||
/* 86 */ "Undefined error 86 (prospero)",
|
||||
/* 87 */ "Undefined error 87 (prospero)",
|
||||
/* 88 */ "Undefined error 88 (prospero)",
|
||||
/* 89 */ "Undefined error 89 (prospero)",
|
||||
/* 90 */ "Undefined error 90 (prospero)",
|
||||
/* 91 */ "Undefined error 91 (prospero)",
|
||||
/* 92 */ "Undefined error 92 (prospero)",
|
||||
/* 93 */ "Undefined error 93 (prospero)",
|
||||
/* 94 */ "Undefined error 94 (prospero)",
|
||||
/* 95 */ "Undefined error 95 (prospero)",
|
||||
/* 96 */ "Undefined error 96 (prospero)",
|
||||
/* 97 */ "Undefined error 97 (prospero)",
|
||||
/* 98 */ "Undefined error 98 (prospero)",
|
||||
/* 99 */ "Undefined error 99 (prospero)",
|
||||
/* 100 */ "Undefined error 100 (prospero)",
|
||||
/* 101 */ "Error parsing Prospero Protocol Input",
|
||||
/* 102 */ "Undefined error 102 (prospero)",
|
||||
/* 103 */ "Undefined error 103 (prospero)",
|
||||
/* 104 */ "Undefined error 104 (prospero)",
|
||||
/* 105 */ "Undefined error 105 (prospero)",
|
||||
/* 106 */ "Undefined error 106 (prospero)",
|
||||
/* 107 */ "Undefined error 107 (prospero)",
|
||||
/* 108 */ "Undefined error 108 (prospero)",
|
||||
/* 109 */ "Undefined error 109 (prospero)",
|
||||
/* 110 */ "Undefined error 110 (prospero)",
|
||||
/* 111 */ "Undefined error 111 (prospero)",
|
||||
/* 112 */ "Undefined error 112 (prospero)",
|
||||
/* 113 */ "Undefined error 113 (prospero)",
|
||||
/* 114 */ "Undefined error 114 (prospero)",
|
||||
/* 115 */ "Undefined error 115 (prospero)",
|
||||
/* 116 */ "Undefined error 116 (prospero)",
|
||||
/* 117 */ "Undefined error 117 (prospero)",
|
||||
/* 118 */ "Undefined error 118 (prospero)",
|
||||
/* 119 */ "Undefined error 119 (prospero)",
|
||||
/* 120 */ "Undefined error 120 (prospero)",
|
||||
/* 121 */ "Undefined error 121 (prospero)",
|
||||
/* 122 */ "Undefined error 122 (prospero)",
|
||||
/* 123 */ "Undefined error 123 (prospero)",
|
||||
/* 124 */ "Undefined error 124 (prospero)",
|
||||
/* 125 */ "Undefined error 125 (prospero)",
|
||||
/* 126 */ "Undefined error 126 (prospero)",
|
||||
/* 127 */ "Undefined error 127 (prospero)",
|
||||
/* 128 */ "Undefined error 128 (prospero)",
|
||||
/* 129 */ "Undefined error 129 (prospero)",
|
||||
/* 130 */ "Undefined error 130 (prospero)",
|
||||
/* 131 */ "Undefined error 131 (prospero)",
|
||||
/* 132 */ "Undefined error 132 (prospero)",
|
||||
/* 133 */ "Undefined error 133 (prospero)",
|
||||
/* 134 */ "Undefined error 134 (prospero)",
|
||||
/* 135 */ "Undefined error 135 (prospero)",
|
||||
/* 136 */ "Undefined error 136 (prospero)",
|
||||
/* 137 */ "Undefined error 137 (prospero)",
|
||||
/* 138 */ "Undefined error 138 (prospero)",
|
||||
/* 139 */ "Undefined error 139 (prospero)",
|
||||
/* 140 */ "Undefined error 140 (prospero)",
|
||||
/* 141 */ "Undefined error 141 (prospero)",
|
||||
/* 142 */ "Undefined error 142 (prospero)",
|
||||
/* 143 */ "Undefined error 143 (prospero)",
|
||||
/* 144 */ "Undefined error 144 (prospero)",
|
||||
/* 145 */ "Undefined error 145 (prospero)",
|
||||
/* 146 */ "Undefined error 146 (prospero)",
|
||||
/* 147 */ "Undefined error 147 (prospero)",
|
||||
/* 148 */ "Undefined error 148 (prospero)",
|
||||
/* 149 */ "Undefined error 149 (prospero)",
|
||||
/* 150 */ "Undefined error 150 (prospero)",
|
||||
/* 151 */ "Undefined error 151 (prospero)",
|
||||
/* 152 */ "Undefined error 152 (prospero)",
|
||||
/* 153 */ "Undefined error 153 (prospero)",
|
||||
/* 154 */ "Undefined error 154 (prospero)",
|
||||
/* 155 */ "Undefined error 155 (prospero)",
|
||||
/* 156 */ "Undefined error 156 (prospero)",
|
||||
/* 157 */ "Undefined error 157 (prospero)",
|
||||
/* 158 */ "Undefined error 158 (prospero)",
|
||||
/* 159 */ "Undefined error 159 (prospero)",
|
||||
/* 160 */ "Undefined error 160 (prospero)",
|
||||
/* 161 */ "Undefined error 161 (prospero)",
|
||||
/* 162 */ "Undefined error 162 (prospero)",
|
||||
/* 163 */ "Undefined error 163 (prospero)",
|
||||
/* 164 */ "Undefined error 164 (prospero)",
|
||||
/* 165 */ "Undefined error 165 (prospero)",
|
||||
/* 166 */ "Undefined error 166 (prospero)",
|
||||
/* 167 */ "Undefined error 167 (prospero)",
|
||||
/* 168 */ "Undefined error 168 (prospero)",
|
||||
/* 169 */ "Undefined error 169 (prospero)",
|
||||
/* 170 */ "Undefined error 170 (prospero)",
|
||||
/* 171 */ "Undefined error 171 (prospero)",
|
||||
/* 172 */ "Undefined error 172 (prospero)",
|
||||
/* 173 */ "Undefined error 173 (prospero)",
|
||||
/* 174 */ "Undefined error 174 (prospero)",
|
||||
/* 175 */ "Undefined error 175 (prospero)",
|
||||
/* 176 */ "Undefined error 176 (prospero)",
|
||||
/* 177 */ "Undefined error 177 (prospero)",
|
||||
/* 178 */ "Undefined error 178 (prospero)",
|
||||
/* 179 */ "Undefined error 179 (prospero)",
|
||||
/* 180 */ "Undefined error 180 (prospero)",
|
||||
/* 181 */ "Undefined error 181 (prospero)",
|
||||
/* 182 */ "Undefined error 182 (prospero)",
|
||||
/* 183 */ "Undefined error 183 (prospero)",
|
||||
/* 184 */ "Undefined error 184 (prospero)",
|
||||
/* 185 */ "Undefined error 185 (prospero)",
|
||||
/* 186 */ "Undefined error 186 (prospero)",
|
||||
/* 187 */ "Undefined error 187 (prospero)",
|
||||
/* 188 */ "Undefined error 188 (prospero)",
|
||||
/* 189 */ "Undefined error 189 (prospero)",
|
||||
/* 190 */ "Undefined error 190 (prospero)",
|
||||
/* 191 */ "Undefined error 191 (prospero)",
|
||||
/* 192 */ "Undefined error 192 (prospero)",
|
||||
/* 193 */ "Undefined error 193 (prospero)",
|
||||
/* 194 */ "Undefined error 194 (prospero)",
|
||||
/* 195 */ "Undefined error 195 (prospero)",
|
||||
/* 196 */ "Undefined error 196 (prospero)",
|
||||
/* 197 */ "Undefined error 197 (prospero)",
|
||||
/* 198 */ "Undefined error 198 (prospero)",
|
||||
/* 199 */ "Undefined error 199 (prospero)",
|
||||
/* 200 */ "Undefined error 200 (prospero)",
|
||||
/* 201 */ "Undefined error 201 (prospero)",
|
||||
/* 202 */ "Undefined error 202 (prospero)",
|
||||
/* 203 */ "Undefined error 203 (prospero)",
|
||||
/* 204 */ "Undefined error 204 (prospero)",
|
||||
/* 205 */ "Undefined error 205 (prospero)",
|
||||
/* 206 */ "Undefined error 206 (prospero)",
|
||||
/* 207 */ "Undefined error 207 (prospero)",
|
||||
/* 208 */ "Undefined error 208 (prospero)",
|
||||
/* 209 */ "Undefined error 209 (prospero)",
|
||||
/* 210 */ "Undefined error 210 (prospero)",
|
||||
/* 211 */ "Undefined error 211 (prospero)",
|
||||
/* 212 */ "Undefined error 212 (prospero)",
|
||||
/* 213 */ "Undefined error 213 (prospero)",
|
||||
/* 214 */ "Undefined error 214 (prospero)",
|
||||
/* 215 */ "Undefined error 215 (prospero)",
|
||||
/* 216 */ "Undefined error 216 (prospero)",
|
||||
/* 217 */ "Undefined error 217 (prospero)",
|
||||
/* 218 */ "Undefined error 218 (prospero)",
|
||||
/* 219 */ "Undefined error 219 (prospero)",
|
||||
/* 220 */ "Undefined error 220 (prospero)",
|
||||
/* 221 */ "Undefined error 221 (prospero)",
|
||||
/* 222 */ "Undefined error 222 (prospero)",
|
||||
/* 223 */ "Undefined error 223 (prospero)",
|
||||
/* 224 */ "Undefined error 224 (prospero)",
|
||||
/* 225 */ "Undefined error 225 (prospero)",
|
||||
/* 226 */ "Undefined error 226 (prospero)",
|
||||
/* 227 */ "Undefined error 227 (prospero)",
|
||||
/* 228 */ "Undefined error 228 (prospero)",
|
||||
/* 229 */ "Undefined error 229 (prospero)",
|
||||
/* 230 */ "File not found (prospero)",
|
||||
/* 231 */ "Directory not found (prospero)",
|
||||
/* 232 */ "Symbolic links nested too deep (prospero)",
|
||||
/* 233 */ "Environment not initialized - source vfsetup.source then run vfsetup",
|
||||
/* 234 */ "Can't traverse an external file (prospero)",
|
||||
/* 235 */ "Forwarding chain is too long (prospero)",
|
||||
/* 236 */ "Undefined error 236 (prospero)",
|
||||
/* 237 */ "Undefined error 237 (prospero)",
|
||||
/* 238 */ "Undefined error 238 (prospero)",
|
||||
/* 239 */ "Undefined error 239 (prospero)",
|
||||
/* 240 */ "WAIS gateway",
|
||||
/* 241 */ "Gopher gateway",
|
||||
/* 242 */ "Authentication required (prospero server)",
|
||||
/* 243 */ "Not authorized (prospero server)",
|
||||
/* 244 */ "Not found (prospero server)",
|
||||
/* 245 */ "Bad version number (prospero server)",
|
||||
/* 246 */ "Not a directory (prospero server)",
|
||||
/* 247 */ "Already exists (prospero server)",
|
||||
/* 248 */ "Link with same name already exists (prospero server)",
|
||||
/* 249 */ "Too many items to return (prospero server)",
|
||||
/* 250 */ "Undefined error 250 (prospero)",
|
||||
/* 251 */ "Command not implemented on server (dirsrv)",
|
||||
/* 252 */ "Bad format for response (dirsrv)",
|
||||
/* 253 */ "Protocol error (prospero server)",
|
||||
/* 254 */ "Unspecified server failure (prospero server)",
|
||||
/* 255 */ "Generic Failure (prospero)"};
|
||||
|
||||
char *p_warn_text[256] = {
|
||||
/* 0 */ "No warning",
|
||||
/* 1 */ "You are using an old version of this program",
|
||||
/* 2 */ "From server",
|
||||
/* 3 */ "Unrecognized line in response from server",
|
||||
/* 4-254 */ "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
/* 255 */ ""};
|
||||
|
||||
void
|
||||
perrmesg(char *prefix, int no, char *text)
|
||||
{
|
||||
fprintf(stderr,"%s%s%s%s\n", (prefix ? prefix : ""),
|
||||
(no ? p_err_text[no] : p_err_text[perrno]),
|
||||
((text ? (*text ? " - " : "") :
|
||||
(!no && *p_err_string ? " - " : ""))),
|
||||
(text ? text : (no ? "" : p_err_string)));
|
||||
}
|
||||
|
||||
void
|
||||
sperrmesg(char *buf, const char *prefix, int no, const char *text)
|
||||
{
|
||||
sprintf(buf,"%s%s%s%s\n", (prefix ? prefix : ""),
|
||||
(no ? p_err_text[no] : p_err_text[perrno]),
|
||||
((text ? (*text ? " - " : "") :
|
||||
(!no && *p_err_string ? " - " : ""))),
|
||||
(text ? text : (no ? "" : p_err_string)));
|
||||
}
|
||||
|
||||
void
|
||||
pwarnmesg(char *prefix, int no, char *text)
|
||||
{
|
||||
fprintf(stderr,"%s%s%s%s\n", (prefix ? prefix : ""),
|
||||
(no ? p_warn_text[no] : p_warn_text[pwarn]),
|
||||
((text ? (*text ? " - " : "") :
|
||||
(!no && *p_warn_string ? " - " : ""))),
|
||||
(text ? text : (no ? "" : p_warn_string)));
|
||||
}
|
||||
|
||||
void
|
||||
spwarnmesg(char *buf, char *prefix, int no, char *text)
|
||||
{
|
||||
sprintf(buf,"%s%s%s%s\n", (prefix ? prefix : ""),
|
||||
(no ? p_warn_text[no] : p_warn_text[pwarn]),
|
||||
((text ? (*text ? " - " : "") :
|
||||
(!no && *p_warn_string ? " - " : ""))),
|
||||
(text ? text : (no ? "" : p_warn_string)));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PFAILURE
|
||||
void
|
||||
it_failed()
|
||||
{
|
||||
static int itfailed = 0;
|
||||
itfailed++; /* So not optimized out of existence */
|
||||
}
|
||||
#endif
|
||||
108
prospero/lib/pfs/pfalloc.c
Normal file
108
prospero/lib/pfs/pfalloc.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h> /* For malloc and free */
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
static PFILE lfree = NULL;
|
||||
int pfile_count = 0;
|
||||
int pfile_max = 0;
|
||||
|
||||
/*
|
||||
* fialloc - allocate and initialize pfile structure
|
||||
*
|
||||
* PFALLOC returns a pointer to an initialized structure of type
|
||||
* PFILE. If it is unable to allocate such a structure, it
|
||||
* signals out_of_memory();
|
||||
*/
|
||||
PFILE
|
||||
pfalloc(void)
|
||||
{
|
||||
PFILE pf;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexPFALLOC);
|
||||
if(lfree) {
|
||||
pf = lfree;
|
||||
lfree = lfree->next;
|
||||
}
|
||||
else {
|
||||
pf = (PFILE) malloc(sizeof(PFILE_ST));
|
||||
if (!pf) out_of_memory();
|
||||
pfile_max++;
|
||||
}
|
||||
|
||||
pfile_count++;
|
||||
p_th_mutex_unlock(p_th_mutexPFALLOC);
|
||||
|
||||
/* Initialize and fill in default values */
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
pf->consistency = INUSE_PATTERN;
|
||||
#endif
|
||||
pf->version = 0;
|
||||
pf->f_magic_no = 0;
|
||||
pf->oacl = NULL;
|
||||
pf->exp = 0;
|
||||
pf->ttl = 0;
|
||||
pf->last_ref = 0;
|
||||
pf->forward = NULL;
|
||||
pf->backlinks = NULL;
|
||||
pf->attributes = NULL;
|
||||
pf->previous = NULL;
|
||||
pf->next = NULL;
|
||||
return(pf);
|
||||
}
|
||||
|
||||
/*
|
||||
* pffree - free a PFILE structure
|
||||
*
|
||||
* PFFREE takes a pointer to a PFILE structure and adds it to
|
||||
* the free list for later reuse.
|
||||
*/
|
||||
void
|
||||
pffree(PFILE pf)
|
||||
{
|
||||
if (!pf) return;
|
||||
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
assert(pf->consistency == INUSE_PATTERN);
|
||||
pf->consistency = FREE_PATTERN;
|
||||
#endif
|
||||
if(pf->oacl) aclfree(pf->oacl); pf->oacl = NULL;
|
||||
if(pf->forward) vllfree(pf->forward); pf->forward = NULL;
|
||||
if(pf->backlinks) vllfree(pf->backlinks); pf->backlinks = NULL;
|
||||
if(pf->attributes) atlfree(pf->attributes); pf->attributes = NULL;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexPFALLOC);
|
||||
pf->next = lfree;
|
||||
pf->previous = NULL;
|
||||
lfree = pf;
|
||||
pfile_count--;
|
||||
p_th_mutex_unlock(p_th_mutexPFALLOC);
|
||||
}
|
||||
|
||||
/*
|
||||
* pflfree - free a PFILE structure list
|
||||
*
|
||||
* PFLFREE takes a pointer to a PFILE structure frees it and any linked
|
||||
* PFILE structures. It is used to free an entire list of PFILE
|
||||
* structures.
|
||||
*/
|
||||
void
|
||||
pflfree(PFILE pf)
|
||||
{
|
||||
PFILE nxt;
|
||||
|
||||
while(pf != NULL) {
|
||||
nxt = pf->next;
|
||||
pffree(pf);
|
||||
pf = nxt;
|
||||
}
|
||||
}
|
||||
|
||||
16
prospero/lib/pfs/pfs_debug.c
Normal file
16
prospero/lib/pfs/pfs_debug.c
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 1989 by the University of Washington
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <uw-copyright.h>.
|
||||
*/
|
||||
|
||||
#include <uw-copyright.h>
|
||||
|
||||
/*
|
||||
* pfs_debug - a global variable containing debugging flag
|
||||
*
|
||||
* Included in the library in case users forget to
|
||||
* include it themselves.
|
||||
*/
|
||||
int pfs_debug = 0;
|
||||
26
prospero/lib/pfs/pfs_enable.c
Normal file
26
prospero/lib/pfs/pfs_enable.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
/*
|
||||
* 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>
|
||||
/*
|
||||
* pfs_enable - Disable Virtual File System interpetation of filenames to
|
||||
* syscalls
|
||||
*
|
||||
* Included in the library in case users forget to
|
||||
* include it themselves and initialize.
|
||||
*
|
||||
* This is initialized in p_initialize() (in libpfs) to PMAP_DISABLE.
|
||||
* By default,
|
||||
* which means that file names will be
|
||||
*/
|
||||
|
||||
#include <pcompat.h>
|
||||
|
||||
int pfs_enable;
|
||||
|
||||
|
||||
45
prospero/lib/pfs/pfs_fopen.c
Normal file
45
prospero/lib/pfs/pfs_fopen.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1991-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 <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
/*SEE: pfs_open if you want a fd instead of a file returned */
|
||||
|
||||
FILE *pfs_fopen(VLINK vl, const char *type)
|
||||
{
|
||||
char npath[MAXPATHLEN];
|
||||
int tmp;
|
||||
int mapflags;
|
||||
FILE *fopen_return;
|
||||
|
||||
if(strcmp(type,"r") == 0) mapflags = MAP_READONLY;
|
||||
else mapflags = MAP_READWRITE;
|
||||
|
||||
tmp = mapname(vl, npath, sizeof npath, mapflags);
|
||||
|
||||
if(tmp && (tmp != PMC_DELETE_ON_CLOSE)) {
|
||||
errno = ENOENT;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
DISABLE_PFS(fopen_return = fopen(npath,type));
|
||||
if(tmp == PMC_DELETE_ON_CLOSE) unlink(npath);
|
||||
|
||||
return(fopen_return);
|
||||
}
|
||||
|
||||
71
prospero/lib/pfs/pfs_mutexes.c
Normal file
71
prospero/lib/pfs/pfs_mutexes.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <pfs.h>
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
p_th_mutex p_th_mutexATALLOC;
|
||||
p_th_mutex p_th_mutexACALLOC;
|
||||
p_th_mutex p_th_mutexFLALLOC;
|
||||
p_th_mutex p_th_mutexOBALLOC;
|
||||
p_th_mutex p_th_mutexPAALLOC;
|
||||
p_th_mutex p_th_mutexPFALLOC;
|
||||
p_th_mutex p_th_mutexPFS_VQSCANF_NW_CS;
|
||||
p_th_mutex p_th_mutexPFS_VQSPRINTF_NQ_CS;
|
||||
p_th_mutex p_th_mutexPFS_TIMETOASN;
|
||||
p_th_mutex p_th_mutexTOKEN;
|
||||
p_th_mutex p_th_mutexVLINK;
|
||||
p_th_mutex p_th_mutexREGEX;
|
||||
#endif
|
||||
|
||||
void
|
||||
p__init_mutexes(void)
|
||||
{
|
||||
#ifdef PFS_THREADS
|
||||
myaddress(); /* Calling myaddress() will initialize this
|
||||
function, which is good, since it's not
|
||||
inherently multithreaded when called for the
|
||||
1st time. */
|
||||
p_th_mutex_init(p_th_mutexATALLOC);
|
||||
p_th_mutex_init(p_th_mutexACALLOC);
|
||||
p_th_mutex_init(p_th_mutexFLALLOC);
|
||||
p_th_mutex_init(p_th_mutexOBALLOC);
|
||||
p_th_mutex_init(p_th_mutexPAALLOC);
|
||||
p_th_mutex_init(p_th_mutexPFALLOC);
|
||||
p_th_mutex_init(p_th_mutexPFS_TIMETOASN); /* does calls to gmtimes */
|
||||
p_th_mutex_init(p_th_mutexPFS_VQSCANF_NW_CS);
|
||||
p_th_mutex_init(p_th_mutexPFS_VQSPRINTF_NQ_CS);
|
||||
p_th_mutex_init(p_th_mutexTOKEN);
|
||||
p_th_mutex_init(p_th_mutexVLINK);
|
||||
p_th_mutex_init(p_th_mutexREGEX);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void
|
||||
p__diagnose_mutexes(void)
|
||||
{
|
||||
#ifdef PFS_THREADS
|
||||
DIAGMUTEX(ATALLOC,"ATALLOC");
|
||||
DIAGMUTEX(ACALLOC,"ACALLOC");
|
||||
DIAGMUTEX(FLALLOC,"FLALLOC");
|
||||
DIAGMUTEX(OBALLOC,"OBALLOC");
|
||||
DIAGMUTEX(PAALLOC,"PAALLOC");
|
||||
DIAGMUTEX(PFALLOC,"PFALLOC");
|
||||
DIAGMUTEX(PFS_TIMETOASN,"PFS_TIMETOASN"); /* does calls to gmtimes */
|
||||
DIAGMUTEX(PFS_VQSCANF_NW_CS,"PFS_VQSCANF_NW_CS");
|
||||
DIAGMUTEX(PFS_VQSPRINTF_NQ_CS,"PFS_VQSPRINTF_NQ_CS");
|
||||
DIAGMUTEX(TOKEN,"TOKEN");
|
||||
DIAGMUTEX(VLINK,"VLINK");
|
||||
DIAGMUTEX(REGEX,"REGEX");
|
||||
#endif
|
||||
}
|
||||
#endif /*NDEBUG*/
|
||||
57
prospero/lib/pfs/pfs_open.c
Normal file
57
prospero/lib/pfs/pfs_open.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* needed for SCO Unix*/
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
/*SEE: pfs_fopen if you want a FILE rather than fd returned */
|
||||
|
||||
int
|
||||
pfs_open(VLINK vl,int flags)
|
||||
{
|
||||
char npath[MAXPATHLEN];
|
||||
int tmp;
|
||||
int mapflags;
|
||||
int open_return;
|
||||
|
||||
/* Test flags for validity. */
|
||||
if (flags & (O_EXCL | O_SYNC)) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Bad flags specified to pfs_open().");
|
||||
return -1;
|
||||
}
|
||||
if((flags & (O_ACCMODE)) == O_RDONLY) mapflags = MAP_READONLY;
|
||||
else mapflags = MAP_READWRITE;
|
||||
|
||||
tmp = mapname(vl, npath, sizeof npath, mapflags);
|
||||
|
||||
if(tmp && (tmp != PMC_DELETE_ON_CLOSE)) {
|
||||
errno = ENOENT;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
DISABLE_PFS(open_return = open(npath, flags));
|
||||
if(tmp == PMC_DELETE_ON_CLOSE) unlink(npath);
|
||||
|
||||
return(open_return);
|
||||
}
|
||||
|
||||
262
prospero/lib/pfs/pget_am.c
Normal file
262
prospero/lib/pfs/pget_am.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 1991 by the University of Washington
|
||||
* Copyright (c) 1991, 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 <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
static PATTRIB expand_amat(PATTRIB ca, VLINK vl);
|
||||
static int match_am(PATTRIB list, TOKEN *ainfop, int methods);
|
||||
|
||||
/* Returns the chosen access method, or zero if failure.
|
||||
We do NOT modify link, unless the object that is the target oflink was
|
||||
forwarded, in which case vl may be returned updated. */
|
||||
/* This interface is suboptimal, since it doesn't allow for retries in case
|
||||
one of the access methods fails. */
|
||||
int
|
||||
pget_am(vl,ainfop,methods)
|
||||
VLINK vl;
|
||||
TOKEN *ainfop; /* This will be filled in with access info
|
||||
data. */
|
||||
int methods; /* Methods this client supports */
|
||||
{
|
||||
PATTRIB hits = NULL; /* list of the hits. */
|
||||
PATTRIB ats; /* attributes returned by pget_at() */
|
||||
PATTRIB ca; /* index variable */
|
||||
int retval;
|
||||
|
||||
perrno = PSUCCESS;
|
||||
if(strcmp(vl->target,"NULL") == 0)
|
||||
return(0);
|
||||
*ainfop = (TOKEN) NULL;
|
||||
|
||||
/* For an EXTERNAL link, the access method should be somewhere on
|
||||
the lattrib member. This is guaranteed in the protocol. Look on the
|
||||
lattrib member in any case, so that we avoid going over the network for
|
||||
the ACCESS-METHOD attribute if it was already cached or otherwise
|
||||
available (perhaps it was returned as an OBJECT attribute). */
|
||||
for (ca = vl->lattrib; ca; ca = ca->next) {
|
||||
if (strequal(ca->aname, "ACCESS-METHOD")) {
|
||||
PATTRIB amat = expand_amat(ca, vl);
|
||||
if (amat) /* if the amat was correctly formed */
|
||||
APPEND_ITEM(amat, hits);
|
||||
}
|
||||
}
|
||||
retval = match_am(hits, ainfop, methods);
|
||||
if (retval) return retval; /* found a match. */
|
||||
|
||||
/* If no match found on the link's attribute list try to retrieve the
|
||||
ACCESS-METHOD attribute directly from the object.
|
||||
pget_at() will always return NULL for EXTERNAL links; we take advantage
|
||||
of this. */
|
||||
hits = NULL; /* no hits for this try. */
|
||||
ats = pget_at(vl, "ACCESS-METHOD");
|
||||
for (ca = ats; ca; ca = ca->next)
|
||||
if (strequal(ca->aname, "ACCESS-METHOD")) {
|
||||
PATTRIB amat = expand_amat(ca, vl);
|
||||
if (amat) /* if the amat was correctly formed */
|
||||
APPEND_ITEM(amat, hits);
|
||||
}
|
||||
atlfree(ats);
|
||||
if (!hits)
|
||||
p_err_string = qsprintf_stcopyr(p_err_string, "No ACCESS-METHOD");
|
||||
return match_am(hits, ainfop, methods);
|
||||
}
|
||||
|
||||
static void wrong_length(PATTRIB ca);
|
||||
|
||||
/* Takes responsibility for freeing the list of attributes passed to it. */
|
||||
/* Returns a matching access method found on the list, or zero if failure. */
|
||||
static int
|
||||
match_am(PATTRIB hits, TOKEN *ainfop, int methods)
|
||||
{
|
||||
PATTRIB ca;
|
||||
/* Now, go through each of the hits, if any. */
|
||||
for (ca = hits; ca; ca = ca->next) {
|
||||
/* First element of the sequence is the name of the access method. */
|
||||
|
||||
if (!ca->value.sequence) {
|
||||
wrong_length(ca); /* Record that it was malformed */
|
||||
continue;
|
||||
}
|
||||
if((methods & P_AM_LOCAL)
|
||||
&& (strequal(ca->value.sequence->token,"LOCAL"))) {
|
||||
if (length(ca->value.sequence) != 5) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_LOCAL);
|
||||
}
|
||||
if((methods & P_AM_NFS)
|
||||
&& (strequal(ca->value.sequence->token,"NFS"))) {
|
||||
if (length(ca->value.sequence) != 6) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_NFS);
|
||||
}
|
||||
if((methods & P_AM_PROSPERO_CONTENTS)
|
||||
&& (strequal(ca->value.sequence->token,"PROSPERO-CONTENTS"))) {
|
||||
if (length(ca->value.sequence) != 5) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_PROSPERO_CONTENTS);
|
||||
}
|
||||
if((methods & P_AM_WAIS)
|
||||
&& (strequal(ca->value.sequence->token,"WAIS"))) {
|
||||
if (length(ca->value.sequence) != 5) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_WAIS);
|
||||
}
|
||||
if((methods & P_AM_TELNET)
|
||||
&& (strequal(ca->value.sequence->token,"TELNET"))) {
|
||||
if (length(ca->value.sequence) < 5) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_TELNET);
|
||||
}
|
||||
if((methods & P_AM_AFS)
|
||||
&& (strequal(ca->value.sequence->token,"AFS"))) {
|
||||
if (length(ca->value.sequence) != 5) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_AFS);
|
||||
}
|
||||
if((methods & P_AM_AFTP)
|
||||
&& (strequal(ca->value.sequence->token,"AFTP"))) {
|
||||
if (length(ca->value.sequence) != 6) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_AFTP);
|
||||
}
|
||||
if((methods & P_AM_GOPHER)
|
||||
&& (strequal(ca->value.sequence->token,"GOPHER"))) {
|
||||
int len = length(ca->value.sequence);
|
||||
if (len != 5 && len != 6) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
if (len == 5) {
|
||||
/* Canonicalize 5-token format to six-token format internally.
|
||||
*/
|
||||
TOKEN tmp = tkalloc(" ");
|
||||
*(tmp->token) = *elt(*ainfop, 4);
|
||||
APPEND_ITEM(tmp, *ainfop);
|
||||
}
|
||||
atlfree(hits);
|
||||
return(P_AM_GOPHER);
|
||||
}
|
||||
if((methods & P_AM_RCP)
|
||||
&& (strequal(ca->value.sequence->token,"RCP"))) {
|
||||
if (length(ca->value.sequence) != 5) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_RCP);
|
||||
}
|
||||
/* The FTP method requires prompting for a password, which is not
|
||||
transparent to the user. Thus, it is the least desirable method,
|
||||
from our point of view. */
|
||||
if((methods & P_AM_FTP)
|
||||
&& (strequal(ca->value.sequence->token,"FTP"))) {
|
||||
if (length(ca->value.sequence) != 6) {
|
||||
wrong_length(ca);
|
||||
continue;
|
||||
}
|
||||
*ainfop = ca->value.sequence;
|
||||
ca->value.sequence = (TOKEN) NULL;
|
||||
atlfree(hits);
|
||||
return(P_AM_FTP);
|
||||
}
|
||||
}
|
||||
atlfree(hits);
|
||||
*ainfop = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Inform the user of a problem if pfs_debug is set. */
|
||||
static void
|
||||
wrong_length(PATTRIB ca)
|
||||
{
|
||||
p_warn_string = qsprintf_stcopyr(p_warn_string,
|
||||
"Parse error: the server returned ACCESS-METHOD %s%swith %d \
|
||||
elements; not what was expected by pget_am()!",
|
||||
length(ca->value.sequence) > 0 ? ca->value.sequence->token : "",
|
||||
length(ca->value.sequence) > 0 ? " " : "",
|
||||
length(ca->value.sequence));
|
||||
if (pfs_debug) {
|
||||
fputs(p_warn_string, stderr);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
pwarn = PWARNING;
|
||||
}
|
||||
|
||||
|
||||
/* Copy an attribute and expand it. */
|
||||
static PATTRIB
|
||||
expand_amat(PATTRIB ca, VLINK vl)
|
||||
{
|
||||
TOKEN tk;
|
||||
|
||||
if (length(ca->value.sequence) < 5) return NULL; /* malformed. */
|
||||
ca = atcopy(ca); /* don't modify the original. */
|
||||
/* atcopy has been fixed to do this properly! - Mitra*/
|
||||
#ifdef NEVERDEFINED
|
||||
ca->value.sequence = tkcopy(ca->value.sequence); /* copy the data too! */
|
||||
#endif
|
||||
tk = ca->value.sequence;
|
||||
|
||||
tk = tk->next; /* skip access method name */
|
||||
if(*tk->token == '\0') tk->token = stcopyr(vl->hosttype, tk->token);
|
||||
tk = tk->next; /* go on */
|
||||
if(*tk->token == '\0') tk->token = stcopyr(vl->host, tk->token);
|
||||
tk = tk->next; /* go on */
|
||||
if(*tk->token == '\0') tk->token = stcopyr(vl->hsonametype, tk->token);
|
||||
tk = tk->next; /* go on */
|
||||
if(*tk->token == '\0') tk->token = stcopyr(vl->hsoname, tk->token);
|
||||
return ca;
|
||||
}
|
||||
130
prospero/lib/pfs/pget_at.c
Normal file
130
prospero/lib/pfs/pget_at.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990, 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 <pprot.h>
|
||||
#include <perrno.h>
|
||||
#include <pparse.h>
|
||||
|
||||
extern int pfs_debug;
|
||||
|
||||
/* Obtain object attributes from a remote host.. */
|
||||
/* Use pget_linkat() to obtain link attributes. */
|
||||
PATTRIB pget_at(vl,atname)
|
||||
VLINK vl;
|
||||
const char *atname;
|
||||
{
|
||||
RREQ req; /* Text of request to dir server */
|
||||
PATTRIB retval = NULL; /* Start of list of attributes */
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
int tmp; /* return value from subfunctions. Value is
|
||||
only used for a couple of lines after it's
|
||||
set each time. */
|
||||
|
||||
int fwdcnt = MAX_FWD_DEPTH;
|
||||
|
||||
perrno = PSUCCESS; /* must set perrno, since that's how we report
|
||||
success or failure. */
|
||||
|
||||
/* It's not an error to ask; However, we already know that there won't be
|
||||
any object attributes, so we just report that fact and don't waste the
|
||||
time for the request to time out. */
|
||||
if (vl->target && !strequal(vl->target, "OBJECT")
|
||||
&& !strequal(vl->target, "FILE")
|
||||
&& !strequal(vl->target, "DIRECTORY")
|
||||
&& !strequal(vl->target, "DIRECTORY+FILE"))
|
||||
return NULL;
|
||||
startover:
|
||||
CHECK_MEM();
|
||||
req = p__start_req(vl->host);
|
||||
p__add_req(req, "GET-OBJECT-INFO %'s ASCII %'s 0\n",
|
||||
atname, vl->hsoname);
|
||||
if (vl->f_magic_no)
|
||||
p__add_req(req, "SELECT OBJECT FIELD ID REMOTE %ld\n",
|
||||
vl->f_magic_no);
|
||||
|
||||
tmp = ardp_send(req,vl->host,0,ARDP_WAIT_TILL_TO);
|
||||
|
||||
/* If the request fails or if we don't get a response, then return error */
|
||||
if(tmp || req->rcvd == NULL) return(NULL);
|
||||
|
||||
rreqtoin(req, in);
|
||||
|
||||
while (!in_eof(in)) {
|
||||
char *line;
|
||||
char *next_word;
|
||||
|
||||
if (in_line(in, &line, &next_word)) {
|
||||
ardp_rqfree(req);
|
||||
return(NULL);
|
||||
}
|
||||
switch (*line) {
|
||||
case 'A': /* ATTRIBUTE */
|
||||
/* If anything but ATTRIBUTE scan error */
|
||||
if(!strnequal(line,"ATTRIBUTE", 9))
|
||||
goto scanerr;
|
||||
|
||||
if (in_ge1_atrs(in, line, next_word, &retval)) {
|
||||
ardp_rqfree(req);
|
||||
return NULL; /* perrno will be set. */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N': /* NONE-FOUND */
|
||||
/* NONE-FOUND, we just have no attributes to insert. No error;
|
||||
just don't do anything. */
|
||||
if(strncmp(line,"NONE-FOUND",10) == 0)
|
||||
break;
|
||||
goto scanerr;
|
||||
|
||||
case 'F':/* FORWARDED, FAILURE */
|
||||
if(strncmp(line,"FORWARDED",9) == 0) {
|
||||
if(fwdcnt-- <= 0) {
|
||||
ardp_rqfree(req);
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
return(NULL);
|
||||
}
|
||||
/* parse and start over */
|
||||
tmp = qsscanf(line,"FORWARDED %&'s %&'s %&'s %&'s %ld %ld",
|
||||
&vl->hosttype, &vl->host, &vl->hsonametype,
|
||||
&vl->hsoname,
|
||||
&(vl->version), &(vl->f_magic_no));
|
||||
|
||||
if(tmp < 2) {
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
ardp_rqfree(req);
|
||||
goto startover;
|
||||
}
|
||||
/* If FAILURE or anything but FORWARDED, scan error */
|
||||
goto scanerr;
|
||||
|
||||
scanerr:
|
||||
default:
|
||||
if(*line && (tmp = scan_error(line, req))) {
|
||||
ardp_rqfree(req);
|
||||
perrno = tmp;
|
||||
return(NULL);
|
||||
}
|
||||
break;
|
||||
} /* end of moby switch */
|
||||
} /* while in_nextline(in) */
|
||||
ardp_rqfree(req);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
293
prospero/lib/pfs/pmap_cache.c
Normal file
293
prospero/lib/pfs/pmap_cache.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#if 0 /* This code should be deleted if this
|
||||
clean-compiles. */
|
||||
/* For SCO which doesn't define MAXPATHLEN */
|
||||
#ifndef MAXPATHLEN
|
||||
#define MAXPATHLEN 1024
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <psite.h>
|
||||
#include <perrno.h>
|
||||
#include <mitra_macros.h> /* For L2 */
|
||||
#include <pmachine.h> /* for INCLUDE_FILES_LACK_TEMPNAM_PROTOTYPE */
|
||||
|
||||
static int pmap_getcache(char *npath, TOKEN am_args);
|
||||
|
||||
#define SECONDSPERDAY (60*60*24)
|
||||
|
||||
/* This defines our caching policy -- a simple cut-off. A more sophisticated
|
||||
* policy could be used but doesn't seem necessary.
|
||||
*
|
||||
* This policy does not take into account the issues of swiftly-changing data.
|
||||
*/
|
||||
|
||||
#define MAXFILECACHEAGE (1*SECONDSPERDAY)
|
||||
|
||||
/* p__map_cache(): Retrieve a file and cache it.
|
||||
*
|
||||
* The interface should be changed to be char **npath and use stcopy for name.
|
||||
*/
|
||||
|
||||
/* Note returns 0 or PMC_DELETE_ON_CLOSE for success */
|
||||
|
||||
#ifndef P_CACHE_ENABLED
|
||||
/* Retrieve file caching it in /tmp/pfs_cache */
|
||||
int
|
||||
p__map_cache(VLINK vl, /* link to object - NOT USED at this time. */
|
||||
char *npath, /* Buffer to write filename into */
|
||||
int npathlen, /* length of buffer */
|
||||
TOKEN am_args) /* Access mode args
|
||||
access_method,INTERNET-D,host,ASCII,remote*/
|
||||
{
|
||||
qsprintf(npath, npathlen, "/tmp/pfs_cache/%s/%s%s%s", elt(am_args,2),
|
||||
elt(am_args, 0), ((*elt(am_args,4) == '/') ? "" : "/"),
|
||||
elt(am_args, 4));
|
||||
return pmap_getcache(npath,am_args);
|
||||
|
||||
}
|
||||
#else
|
||||
/* Retrieve file caching it in P_CACHE_VC */
|
||||
int
|
||||
p__map_cache(VLINK vl, /* link to object - NOT USED at this time. */
|
||||
char *npath, /* Buffer to write filename into */
|
||||
int npathlen, /* length of buffer */
|
||||
TOKEN am_args) /* Access mode args
|
||||
access_method,INTERNET-D,host,ASCII,remote*/
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
char *cachename = NULL;
|
||||
char *tempfile = NULL;
|
||||
|
||||
/* Name of cached version is -- P_CACHE_VC/host/method/remote */
|
||||
|
||||
cachename = qsprintf_stcopyr(cachename, "%s/%s/%s%s%s",
|
||||
P_CACHE_VC, elt(am_args,2),
|
||||
elt(am_args, 0), ((*elt(am_args,4) == '/') ? "" : "/"),
|
||||
elt(am_args, 4));
|
||||
|
||||
if ((strlen(cachename) > 250 )
|
||||
&& (strncmp(elt(am_args, 4), "WAIS-GW",7) == 0) ) {
|
||||
/* Horrible Kludge alert, make component length smaller for
|
||||
WAIS docid's */
|
||||
char *cp;
|
||||
for (cp=cachename; *cp; cp++)
|
||||
if (*cp == '%')
|
||||
*cp = '/';
|
||||
}
|
||||
/* Determine whether a cached copy already exists */
|
||||
if (!file_incache(cachename) || (stat_age(cachename) > MAXFILECACHEAGE) ) {
|
||||
switch (retval = pmap_getcache(cachename,am_args)) {
|
||||
case PMC_DELETE_ON_CLOSE:
|
||||
case PSUCCESS:
|
||||
break;
|
||||
/*PMC_RETRIEVE_FAILED:*/
|
||||
default:
|
||||
if (file_incache(cachename)) {
|
||||
/* Old copy stil available */
|
||||
break;
|
||||
} else {
|
||||
/* Failed */
|
||||
stfree(cachename);
|
||||
return(retval);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Either succeeded in fetching, or already had it */
|
||||
/* Assuming caller opens this file, then it will touch access time*/
|
||||
tempfile = tempnam(P_CACHE_P,NULL);
|
||||
if (link(cachename, tempfile)) {
|
||||
retval=errno;
|
||||
} else {
|
||||
qsprintf(npath,npathlen,tempfile);
|
||||
}
|
||||
stfree(cachename);
|
||||
free(tempfile);
|
||||
return(retval);
|
||||
}
|
||||
#endif /* P_CACHE_ENABLED */
|
||||
|
||||
/*
|
||||
* Retrieves a file with access method am_args into the file
|
||||
* named NPATH. This breakout is attributable to mitra (thanks).
|
||||
*
|
||||
* Return codes:
|
||||
* 0 or PMC_DELETE_ON_CLOSE is success.
|
||||
* All other return codes indicate a failure. Currently always returns
|
||||
* PMC_DELETE_ON_CLOSE.
|
||||
*/
|
||||
static
|
||||
int
|
||||
pmap_getcache(char *npath, TOKEN am_args)
|
||||
{
|
||||
static char *vcachebin;
|
||||
int pid;
|
||||
#ifdef BSD_UNION_WAIT
|
||||
union wait status;
|
||||
#else
|
||||
int status;
|
||||
#endif
|
||||
int tmp;
|
||||
char *vcargv[12]; /* vcache's ARGV. Enough to hold any known
|
||||
access method arguments. */
|
||||
char **vcargvp = vcargv; /* pointer to vcache's argv. */
|
||||
#ifndef INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE
|
||||
char *p_binaries;
|
||||
#else /*INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE*/
|
||||
char *host, *method, *remote;
|
||||
#endif /*INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE*/
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* Not thread safe yet */
|
||||
#ifndef INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE
|
||||
/* should really do this on our own without */
|
||||
/* calling system, but... */
|
||||
/* Set args first. This makes it easier to debug on debuggers that don't
|
||||
take kindly to subprocesses forking. */
|
||||
p_binaries = getenv("P_BINARIES");
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
#ifdef P_BINARIES
|
||||
if (!p_binaries)
|
||||
p_binaries = P_BINARIES;
|
||||
#endif
|
||||
|
||||
*vcargvp++ = "vcache";
|
||||
#ifdef P_CACHE_ENABLED
|
||||
*vcargvp++ = "-m"; /* manage the cache argument */
|
||||
#endif
|
||||
*vcargvp++ = npath;
|
||||
#else /*INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE*/
|
||||
if (!am_args) return PMC_RETRIEVE_FAILED;
|
||||
method = am_args->token ; am_args = am_args->next;
|
||||
if (!am_args) return PMC_RETRIEVE_FAILED;
|
||||
if (strcmp(am_args->token,"INTERNET-D")) return PMC_RETRIEVE_FAILED;
|
||||
am_args = am_args->next;
|
||||
if (!am_args) return PMC_RETRIEVE_FAILED;
|
||||
host = am_args->token ; am_args = am_args->next;
|
||||
if (!am_args) return PMC_RETRIEVE_FAILED;
|
||||
if (strcmp(am_args->token,"ASCII")) return PMC_RETRIEVE_FAILED;
|
||||
am_args = am_args->next;
|
||||
if (!am_args) return PMC_RETRIEVE_FAILED;
|
||||
remote = am_args->token ; am_args = am_args->next;
|
||||
#endif /*INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE*/
|
||||
for (;am_args; am_args = am_args->next) {
|
||||
*vcargvp++ = am_args->token;
|
||||
}
|
||||
*vcargvp = NULL;
|
||||
|
||||
#ifndef INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
if (pfs_debug) {
|
||||
perror("p__map_cache(): failed to fork().");
|
||||
}
|
||||
return PMC_RETRIEVE_FAILED;
|
||||
}
|
||||
#if 0
|
||||
#define atline() if(pfs_debug > 10) fprintf(stderr, "%s:%d\n", __FILE__, __LINE__)
|
||||
#else
|
||||
#define atline() do ; while (0)
|
||||
#endif
|
||||
if (pid == 0) {
|
||||
if (pfs_debug > 10)
|
||||
fprintf(stderr, "p__map_cache(): just forked.\n");
|
||||
atline();
|
||||
if (!p_binaries || !*p_binaries) {
|
||||
atline();
|
||||
/* In execl, add the "-m" option if cache to be managed */
|
||||
/* Add the "-r" option if existing item is out of date */
|
||||
DISABLE_PFS(execvp("vcache",vcargv));
|
||||
atline();
|
||||
if (!vcachebin) vcachebin = stcopy("vcache");
|
||||
strcpy(vcachebin, "vcache"); /* for error reporting */
|
||||
atline();
|
||||
} else {
|
||||
atline();
|
||||
if (!vcachebin)
|
||||
vcachebin = qsprintf_stcopyr(vcachebin,
|
||||
"%s/vcache",p_binaries);
|
||||
atline();
|
||||
/* In execl, add the "-m" option if cache to be managed */
|
||||
/* Add the "-r" option if existing item is out of date */
|
||||
DISABLE_PFS(execv(vcachebin,vcargv));
|
||||
atline();
|
||||
}
|
||||
atline();
|
||||
if (pfs_debug) {
|
||||
fprintf(stderr,
|
||||
"p__map_cache(): exec failed for %s (errno=%d): ",
|
||||
vcachebin,errno);
|
||||
perror(NULL);
|
||||
}
|
||||
atline();
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
wait(&status);
|
||||
}
|
||||
#ifdef BSD_UNION_WAIT
|
||||
tmp = status.w_T.w_Retcode;
|
||||
#else
|
||||
tmp = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
|
||||
#endif
|
||||
|
||||
#else /*INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE*/
|
||||
/* This is an experiment in calling vcache directly */
|
||||
DISABLE_PFS(tmp=vcache2a(host, remote, npath, method, vcargv,
|
||||
#ifdef P_CACHE_ENABLED
|
||||
TRUE /* argument to manage the cache */
|
||||
#else
|
||||
FALSE
|
||||
#endif
|
||||
));
|
||||
#endif /*INCREASE_CLIENT_EXECUTABLE_SIZE_DO_NOT_EXEC_VCACHE*/
|
||||
if(tmp) return(PMC_RETRIEVE_FAILED);
|
||||
|
||||
/* Return PMC_DELETE_ON_CLOSE if cache is not being managed */
|
||||
/* I left this, because we are making a copy, that the caller
|
||||
needs to delete -- Mitra */
|
||||
return(PMC_DELETE_ON_CLOSE);
|
||||
|
||||
/* return(PSUCCESS);*/
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
file_incache(char *local)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
/* This is probably lazy bad code, stat fails if and only if the
|
||||
file doesn't exist in the cache*/
|
||||
return (stat(local,&buf) == 0);
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* not used; different test up above. */
|
||||
int
|
||||
file_incache_and_uptodate(char *local)
|
||||
{
|
||||
/* For now, everything is up to date, need to be much cleverer !!*/
|
||||
return (file_incache(local));
|
||||
}
|
||||
#endif
|
||||
133
prospero/lib/pfs/pmap_nfs.c
Normal file
133
prospero/lib/pfs/pmap_nfs.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 <psite.h>
|
||||
|
||||
#ifdef P_NFS
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pcompat.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef ULTRIX
|
||||
#include <sys/fs_types.h>
|
||||
#else
|
||||
#include <mntent.h>
|
||||
#endif
|
||||
|
||||
pmap_nfs(host,rpath,npath, npathlen, am_args)
|
||||
char *host;
|
||||
char *rpath;
|
||||
char *npath;
|
||||
int npathlen;
|
||||
TOKEN am_args;
|
||||
{
|
||||
char rfile[MAXPATHLEN];
|
||||
char lmpt[MAXPATHLEN];
|
||||
char *rmpt; /* remote mount point */
|
||||
char rmparg[MAXPATHLEN];
|
||||
char *suffix; /* path from remote mount point. */
|
||||
char *rf = rfile;
|
||||
char *a;
|
||||
int devnl;
|
||||
int tmp;
|
||||
int pid;
|
||||
#ifdef BSD_UNION_WAIT
|
||||
union wait status;
|
||||
#else
|
||||
int status;
|
||||
#endif
|
||||
int start = 0;
|
||||
#ifdef ULTRIX
|
||||
struct fs_data buffer;
|
||||
struct fs_data *buf = &buffer;
|
||||
#else
|
||||
struct mntent *mtentry;
|
||||
FILE *mtab;
|
||||
#endif
|
||||
|
||||
rmpt = elt(am_args, 5); /* mount point on remote host. */
|
||||
suffix = elt(am_args, 4); /* object handle used by NFS on remote host */
|
||||
|
||||
sprintf(rf,"%s:%s/%s",host,rmpt,suffix);
|
||||
|
||||
#ifdef ULTRIX
|
||||
while(getmountent(&start, buf, 1) > 0) {
|
||||
devnl = strlen(buf->fd_devname);
|
||||
if(!strncmp(rfile,buf->fd_devname,devnl)) {
|
||||
qsprintf(npath, npathlen, "%s%s",buf->fd_path,rfile+devnl);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
}
|
||||
#else
|
||||
DISABLE_PFS(mtab = setmntent("/etc/mtab","r"));
|
||||
|
||||
while(mtentry = getmntent(mtab)) {
|
||||
devnl = strlen(mtentry->mnt_fsname);
|
||||
if(!strncmp(rfile,mtentry->mnt_fsname,devnl)) {
|
||||
qsprintf(npath, npathlen, "%s%s",mtentry->mnt_dir,rfile+devnl);
|
||||
endmntent(mtab);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
}
|
||||
endmntent(mtab);
|
||||
#endif
|
||||
|
||||
sprintf(lmpt,"/tmp/pfs_mount/%s%s",host,rmpt);
|
||||
|
||||
a = lmpt + strlen(lmpt) - strlen(rmpt);
|
||||
while(*a) {
|
||||
if(*a == '/') *a = '-';
|
||||
a++;
|
||||
}
|
||||
|
||||
mkdir("/tmp/pfs_mount",0777);
|
||||
chmod("/tmp/pfs_mount",0777);
|
||||
mkdir(lmpt,0777);
|
||||
chmod(lmpt,0777);
|
||||
|
||||
sprintf(rmparg,"%s:%s",host,rmpt);
|
||||
|
||||
/* should really do this on our own without */
|
||||
/* calling system, but... */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
#ifdef ULTRIX
|
||||
DISABLE_PFS(execl("/etc/mount","mount", "-t", "nfs",
|
||||
"-o", "rw,hard,intr,retry=20",
|
||||
rmparg, lmpt, 0));
|
||||
#else
|
||||
DISABLE_PFS(execl("/etc/mount","mount", rmparg, lmpt, 0));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
wait(&status);
|
||||
}
|
||||
#ifdef BSD_UNION_WAIT
|
||||
tmp = status.w_T.w_Retcode;
|
||||
#else
|
||||
tmp = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
|
||||
#endif
|
||||
|
||||
if(tmp) RETURNPFAILURE;
|
||||
|
||||
qsprintf(npath, npathlen, "%s/%s",lmpt,suffix);
|
||||
|
||||
return(PSUCCESS);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif P_NFS
|
||||
116
prospero/lib/pfs/pset_at.c
Normal file
116
prospero/lib/pfs/pset_at.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file <usc-license.h>
|
||||
*/
|
||||
/* Author: Steven Augart, swa@isi.edu */
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <pprot.h>
|
||||
#include <perrno.h>
|
||||
|
||||
static int eoi_parse_resp(RREQ resp);
|
||||
extern int pfs_debug;
|
||||
|
||||
/* Sets OBJECT attributes appropriately. */
|
||||
/* Returns PSUCCESS upon successful execution, failure code otherwise. */
|
||||
int
|
||||
pset_at(VLINK vl, int flags, PATTRIB attributes)
|
||||
{
|
||||
RREQ req;
|
||||
OUTPUT_ST out_st;
|
||||
OUTPUT out = &out_st;
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
int fwdcnt = MAX_FWD_DEPTH;
|
||||
|
||||
int tmp; /* error return code from functions. Value only
|
||||
used a few lines after set, each time. */
|
||||
|
||||
if (vl->target && !strequal(vl->target, "OBJECT")
|
||||
&& !strequal(vl->target, "FILE")
|
||||
&& !strequal(vl->target, "DIRECTORY")
|
||||
&& !strequal(vl->target, "DIRECTORY+FILE")) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"pset_at(): Asked to munge the attributes of the object \
|
||||
pointed to by a link with a target of %s. Cannot do this.\n", vl->target);
|
||||
return perrno = PSET_AT_TARGET_NOT_AN_OBJECT;
|
||||
}
|
||||
startover:
|
||||
req = p__start_req(vl->host);
|
||||
p__add_req(req, "EDIT-OBJECT-INFO ");
|
||||
switch(flags) {
|
||||
case EOI_ADD:
|
||||
p__add_req(req, "ADD");
|
||||
break;
|
||||
case EOI_DELETE:
|
||||
p__add_req(req, "DELETE");
|
||||
break;
|
||||
case EOI_DELETE_ALL:
|
||||
p__add_req(req, "DELETE-ALL");
|
||||
break;
|
||||
case EOI_REPLACE:
|
||||
p__add_req(req, "REPLACE");
|
||||
break;
|
||||
default:
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"edit_object_info(): Illegal flag value: %d", flags);
|
||||
break;
|
||||
return perrno = PFAILURE;
|
||||
}
|
||||
p__add_req(req, " %'s %'s\n", vl->hsonametype, vl->hsoname);
|
||||
requesttoout(req,out);
|
||||
out_atrs(out, attributes, 0);
|
||||
tmp = ardp_send(req, vl->host, 0, ARDP_WAIT_TILL_TO);
|
||||
if(tmp) {
|
||||
if (pfs_debug) fprintf(stderr,"ardp_send failed: %d\n",perrno);
|
||||
return perrno = tmp;
|
||||
}
|
||||
if(req->rcvd == NULL) return(perrno);
|
||||
|
||||
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);
|
||||
}
|
||||
if(strncmp(line,"FORWARDED",9) == 0) {
|
||||
if(fwdcnt-- <= 0) {
|
||||
ardp_rqfree(req);
|
||||
perrno = PFS_MAX_FWD_DEPTH;
|
||||
return(perrno);
|
||||
}
|
||||
/* parse and start over */
|
||||
tmp = qsscanf(line,"FORWARDED %&'s %&'s %&s %&'s",
|
||||
&vl->hosttype, &vl->host,
|
||||
&vl->hsonametype,&vl->hsoname);
|
||||
if(tmp < 2) {
|
||||
ardp_rqfree(req);
|
||||
perrno = DIRSRV_BAD_FORMAT;
|
||||
break;
|
||||
}
|
||||
ardp_rqfree(req);
|
||||
goto startover;
|
||||
}
|
||||
if(strncmp(line,"SUCCESS",7) == 0) {
|
||||
ardp_rqfree(req);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
/* If FAILURE or anything else scan error */
|
||||
if (tmp = scan_error(line, req)) {
|
||||
ardp_rqfree(req);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
ardp_rqfree(req);
|
||||
return PSUCCESS;
|
||||
}
|
||||
|
||||
89
prospero/lib/pfs/pset_linkat.c
Normal file
89
prospero/lib/pfs/pset_linkat.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 <ardp.h>
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
#include <perrno.h>
|
||||
|
||||
static int eoi_parse_resp(RREQ resp);
|
||||
extern int pfs_debug;
|
||||
|
||||
/* Returns PSUCCESS upon successful execution, PFAILURE for whatever failure
|
||||
reason. */
|
||||
int
|
||||
pset_linkat(VLINK dlink, char lname[], int flags, PATTRIB attributes)
|
||||
{
|
||||
RREQ req;
|
||||
OUTPUT_ST out_st;
|
||||
OUTPUT out = &out_st;
|
||||
int tmp;
|
||||
|
||||
req = p__start_req(dlink->host);
|
||||
p__add_req(req, "DIRECTORY ASCII %'s 0\nEDIT-LINK-INFO ", dlink->hsoname);
|
||||
switch(flags) {
|
||||
case EOI_ADD:
|
||||
p__add_req(req, "ADD");
|
||||
break;
|
||||
case EOI_DELETE:
|
||||
p__add_req(req, "DELETE");
|
||||
break;
|
||||
case EOI_DELETE_ALL:
|
||||
p__add_req(req, "DELETE-ALL");
|
||||
break;
|
||||
case EOI_REPLACE:
|
||||
p__add_req(req, "REPLACE");
|
||||
break;
|
||||
default:
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"edit_object_info(): Illegal flag value: %d", flags);
|
||||
break;
|
||||
RETURNPFAILURE;
|
||||
}
|
||||
p__add_req(req, " %'s\n", lname);
|
||||
requesttoout(req,out);
|
||||
out_atrs(out, attributes, 0);
|
||||
tmp = ardp_send(req, dlink->host, 0, ARDP_WAIT_TILL_TO);
|
||||
if(tmp) {
|
||||
fprintf(stderr,"Dirsend failed: %d\n",perrno);
|
||||
perrno = tmp;
|
||||
}
|
||||
|
||||
if(req->rcvd == NULL) return(perrno);
|
||||
|
||||
return eoi_parse_resp(req);
|
||||
}
|
||||
|
||||
static int
|
||||
eoi_parse_resp(RREQ resp)
|
||||
{
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
|
||||
rreqtoin(resp, in);
|
||||
|
||||
while(!in_eof(in)) {
|
||||
char *line;
|
||||
char *next_word;
|
||||
int tmp; /* error return code from functions */
|
||||
|
||||
if (tmp = in_line(in, &line, &next_word)) {
|
||||
ardp_rqfree(resp);
|
||||
return(tmp);
|
||||
}
|
||||
/* Scanerr() will handle SUCCESS or FAILURE or any other error return
|
||||
codes. It parses it all for us! */
|
||||
if (tmp = scan_error(line, resp)) {
|
||||
ardp_rqfree(resp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
return PSUCCESS;
|
||||
}
|
||||
40
prospero/lib/pfs/qbstp_stcopyr.c
Normal file
40
prospero/lib/pfs/qbstp_stcopyr.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 <pfs.h>
|
||||
|
||||
char *
|
||||
p__qbstprintf_stcopyr(char *buf, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buf = p__vqbstprintf_stcopyr(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
p__vqbstprintf_stcopyr(char *buf, const char *fmt, va_list ap)
|
||||
{
|
||||
int tmp;
|
||||
assert(p__bst_consistent(buf));
|
||||
again:
|
||||
tmp = qsprintf(buf, p__bstsize(buf), fmt, ap);
|
||||
if (tmp > p__bstsize(buf)) {
|
||||
stfree(buf);
|
||||
buf = stalloc(tmp);
|
||||
goto again;
|
||||
}
|
||||
/* Tmp is now the size of the total output area, including a trailing null.
|
||||
Need to set the size to tmp -1, since trailing null is not included. */
|
||||
p_bst_set_buffer_length_nullterm(buf, tmp - 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
22
prospero/lib/pfs/qfprintf.c
Normal file
22
prospero/lib/pfs/qfprintf.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Copyright (c) 1992 by the University of Southern California. */
|
||||
/* For copying and distribution information, see the file <usc-copyr.h> */
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
|
||||
/* See vqsprintf() for documentation.
|
||||
This is slightly inefficient, since it wastes a function call. Oh well.
|
||||
Return PFAILURE or PSUCCESS.
|
||||
*/
|
||||
int
|
||||
qfprintf(FILE *outf, const char fmt[], ...)
|
||||
{
|
||||
va_list ap;
|
||||
int retval;
|
||||
|
||||
va_start(ap,fmt);
|
||||
retval = vqfprintf(outf, fmt, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
55
prospero/lib/pfs/qindex.c
Normal file
55
prospero/lib/pfs/qindex.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/* qindex.c
|
||||
This program works just like "index()", but it recognizes Prospero quoting.
|
||||
Looks for first unquoted instance of "c" in string s.
|
||||
Returns NULL if none found.
|
||||
If it finds a mis-quoted string, returns NULL and sets perrno to
|
||||
PARSE_ERROR.
|
||||
Author: swa@isi.edu, 8/17/92
|
||||
*/
|
||||
#include <pfs.h> /* to make sure we match definition. */
|
||||
#include <perrno.h>
|
||||
|
||||
char *
|
||||
qindex(const char *s, char c)
|
||||
{
|
||||
enum { OUTSIDE_QUOTATION, IN_QUOTATION,
|
||||
SEEN_POSSIBLE_CLOSING_QUOTE } state;
|
||||
const char *start = s;
|
||||
|
||||
state = OUTSIDE_QUOTATION;
|
||||
|
||||
for (; *s; ++s) {
|
||||
switch (state) {
|
||||
case OUTSIDE_QUOTATION:
|
||||
if (*s == '\'')
|
||||
state = IN_QUOTATION;
|
||||
else if (*s == c)
|
||||
return (char *) s; /* flush CONST */
|
||||
break;
|
||||
case IN_QUOTATION:
|
||||
if (*s == '\'')
|
||||
state = SEEN_POSSIBLE_CLOSING_QUOTE;
|
||||
break;
|
||||
case SEEN_POSSIBLE_CLOSING_QUOTE:
|
||||
if (*s == '\'') {
|
||||
if (c == '\'')
|
||||
return (char *) s; /* flush CONST */
|
||||
state = IN_QUOTATION;
|
||||
} else {
|
||||
state = OUTSIDE_QUOTATION;
|
||||
if (*s == c)
|
||||
return (char *) s; /* flush CONST */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
internal_error("qindex(): impossible state!");
|
||||
}
|
||||
}
|
||||
if (state == IN_QUOTATION) {
|
||||
perrno = PARSE_ERROR;
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"qindex(): encountered text with unbalanced quoting: %'s", start);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
23
prospero/lib/pfs/qoprintf.c
Normal file
23
prospero/lib/pfs/qoprintf.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/* This function will be reset by the server to srv_qoprintf.c, which is found
|
||||
in libpsrv. This hack lets us avoid linking the client with
|
||||
srv_qoprintf.c, and thereby cuts down on the client code size. */
|
||||
|
||||
/* This function, in its client and server incarnations, qprintfs to an OUTPUT
|
||||
structure. */
|
||||
|
||||
#ifdef __STDC__
|
||||
int (*qoprintf)(OUTPUT out, const char format[], ...) = cl_qoprintf;
|
||||
#else
|
||||
int (*qoprintf)() = cl_qoprintf;
|
||||
#endif
|
||||
|
||||
23
prospero/lib/pfs/qrindex.c
Normal file
23
prospero/lib/pfs/qrindex.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Copyright (c) 1992, 1993 by the University of Southern California. */
|
||||
/* For copying and distribution information, see the file <usc-copyr.h> */
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
/* Like rindex(), but respecting Prospero quoting. */
|
||||
|
||||
char *
|
||||
qrindex(const char *s, char c)
|
||||
{
|
||||
char *thisc;
|
||||
char *lastc = NULL;
|
||||
|
||||
assert(c); /* it'll blow up otherwise, cause we might
|
||||
shoot off the end of the string. */
|
||||
for(thisc = qindex(s, c); thisc;
|
||||
lastc = thisc, thisc = qindex(thisc + 1, c))
|
||||
;
|
||||
return lastc;
|
||||
}
|
||||
|
||||
18
prospero/lib/pfs/qscanf.c
Normal file
18
prospero/lib/pfs/qscanf.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Copyright (c) 1993 by the University of Southern California.
|
||||
* For copying information, see the file <usc-copyr.h>
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
|
||||
#include <pparse.h>
|
||||
|
||||
extern int
|
||||
qscanf(INPUT in, const char fmt[], ...)
|
||||
{
|
||||
int retval;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
retval = vqscanf(in, fmt, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
40
prospero/lib/pfs/qsp_stcopyr.c
Normal file
40
prospero/lib/pfs/qsp_stcopyr.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 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>
|
||||
|
||||
char *
|
||||
qsprintf_stcopyr(char *buf, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buf = vqsprintf_stcopyr(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
vqsprintf_stcopyr(char *buf, const char *fmt, va_list ap)
|
||||
{
|
||||
int tmp;
|
||||
again:
|
||||
tmp = vqsprintf(buf, p__bstsize(buf), fmt, ap);
|
||||
if (tmp > p__bstsize(buf)) {
|
||||
stfree(buf);
|
||||
buf = stalloc(tmp);
|
||||
goto again;
|
||||
}
|
||||
/* The count returned by vqsprintf includes a trailing null. */
|
||||
/* Mark this so that vqsprintf_stcopyr() returns a properly sized bstring.
|
||||
*/
|
||||
p_bst_set_buffer_length_nullterm(buf, tmp - 1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
30
prospero/lib/pfs/qsprintf.c
Normal file
30
prospero/lib/pfs/qsprintf.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* vqsprintf.c
|
||||
Author: Steven Augart <swa@isi.edu>
|
||||
Written: 7/18/92 -- 7/24/92
|
||||
Long support added, 10/2/92
|
||||
vqsprintf() added, 10/6/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>
|
||||
#include <pfs.h>
|
||||
|
||||
/* See vqsprintf() for documentation.
|
||||
This is slightly inefficient, since it wastes a function call. Oh well.
|
||||
*/
|
||||
size_t
|
||||
qsprintf(char *buf, size_t buflen, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t retval;
|
||||
|
||||
va_start(ap,fmt);
|
||||
retval = vqsprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
|
||||
}
|
||||
43
prospero/lib/pfs/qsscanf.c
Normal file
43
prospero/lib/pfs/qsscanf.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* qsscanf.c
|
||||
Author: Steven Augart (swa@isi.edu)
|
||||
Designed, Documented, and Written: 7/18/92 -- 7/27/92
|
||||
Ported from Gnu C to full ANSI C & traditional C, 10/5/92
|
||||
& modifier added, detraditionalized: 2/16/93.
|
||||
Made a wrapper around qscanf(), 3/2/93
|
||||
*/
|
||||
/* Copyright (c) 1992, 1993 by the University of Southern California. */
|
||||
/* For copying and distribution information, see the file <usc-copyr.h> */
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <stdarg.h> /* ANSI variable arguments facility. */
|
||||
#include <pfs.h>
|
||||
#include <pparse.h>
|
||||
|
||||
int
|
||||
qsscanf(const char *s, const char *fmt, ...)
|
||||
/* s: source string
|
||||
fmt: format describing what to scan for.
|
||||
remaining args: pointers to places to store the data we read, or
|
||||
integers (field widths).
|
||||
*/
|
||||
{
|
||||
va_list ap; /* for varargs */
|
||||
int retval;
|
||||
INPUT_ST in_st;
|
||||
INPUT in = &in_st;
|
||||
|
||||
/* Otherwise vqscanf will fail an assertion*/
|
||||
if (!s || s[0] == '\0') return 0;
|
||||
|
||||
in->sourcetype = IO_STRING;
|
||||
in->rreq = NULL;
|
||||
in->s = s;
|
||||
in->file = NULL;
|
||||
in->flags = PERCENT_R_TARGET_IS_STRING;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
retval = vqscanf(in, fmt, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
64
prospero/lib/pfs/qtokenize.c
Normal file
64
prospero/lib/pfs/qtokenize.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/* Written, 9/18/92, swa@isi.edu */
|
||||
/* Made use 'previous' member 6/14/93, swa@isi.edu */
|
||||
/* Got rid of double invocation of stcopy() for efficiency,. 5/15/94,
|
||||
swa@ISI.EDU */
|
||||
|
||||
/* Break up a string into space-separated tokens and recognize Prospero
|
||||
quoting. This strips off the quoting in the process. This function could
|
||||
also be called p__tokenize_newstyle_mcomp(), and it serves that function.
|
||||
It assumes the input string is correctly quoted.
|
||||
*/
|
||||
|
||||
#include <pfs.h>
|
||||
#include <pprot.h>
|
||||
|
||||
TOKEN
|
||||
qtokenize(const char *s)
|
||||
{
|
||||
TOKEN retval;
|
||||
int tmp;
|
||||
|
||||
AUTOSTAT_CHARPP(bufp);
|
||||
|
||||
/* We need a new interface to tkalloc() so we can avoid doing two stcopy()
|
||||
operations on the same data. */
|
||||
/* swa, 5/15/94: I decided to just make the code a bit longer, but used the
|
||||
existing TKALLOC interface instead. This seems like less hassle than a
|
||||
new interface, since it is not used very frequently. */
|
||||
|
||||
if (!s) return NULL;
|
||||
retval = NULL;
|
||||
for (;;) {
|
||||
#if 1 /* 5/15/94 change --swa */
|
||||
TOKEN tmptok;
|
||||
#endif
|
||||
tmp = qsscanf(s, "%'&s %r", bufp, &s);
|
||||
assert(tmp >= 0); /* no possible error, I hope! */
|
||||
if (tmp == 0)
|
||||
return retval;
|
||||
#if 1
|
||||
tmptok = tkalloc((char *) NULL);
|
||||
tmptok->token = *bufp;
|
||||
|
||||
*bufp = NULL; /* Leaving out this step cost almost a day's
|
||||
work. Since *bufp sticks around, we should
|
||||
mark it as free so that it is not reused
|
||||
inappropriately. I now understand what
|
||||
broke and why. --swa, 5/16/94 */
|
||||
APPEND_ITEM(/* new */ tmptok, /* head */ retval);
|
||||
/* This version just avoided the stcopy(). */
|
||||
#else
|
||||
/* This is the old less efficient version: --swa, 5/15/94 */
|
||||
retval = tkappend(*bufp, retval);
|
||||
#endif
|
||||
if (tmp == 1) return retval; /* no more to tokenize. */
|
||||
}
|
||||
}
|
||||
640
prospero/lib/pfs/rd_vdir.c
Normal file
640
prospero/lib/pfs/rd_vdir.c
Normal file
@@ -0,0 +1,640 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
static TOKEN p__rvdslashpath2tkl(char *nextcomp);
|
||||
static void p__tkl_back_2rvdslashpath(TOKEN nextcomp_tkl, char *nextcomp);
|
||||
|
||||
/*
|
||||
*/
|
||||
int
|
||||
rd_vdir(dirarg,comparg,dir,flags)
|
||||
const char *dirarg; /* Virtual name for the directory */
|
||||
const char *comparg; /* Component name (wildcards allowed) */
|
||||
VDIR dir; /* Structure to be filled in */
|
||||
long flags; /* Flags */
|
||||
{
|
||||
/* Note: We use a working copy of dirarg because we want to */
|
||||
/* modify the working copy, and we would prefer not to */
|
||||
/* modify the directory name passed to this procedure. */
|
||||
/* dirnm is required because we need a character pointer */
|
||||
/* later on (dirname), but the compiler only allows */
|
||||
/* automatic allocation for a character array. */
|
||||
/* components is a working copy of comparg which might be */
|
||||
/* modified if a magic number has been specified. */
|
||||
char dirnm[MAX_VPATH]; /* Working copy of dirarg */
|
||||
char *dirname = dirnm; /* Pointer to dirnm */
|
||||
char components[MAX_VPATH];/* Working copy of comparg */
|
||||
|
||||
char *dirhst; /* Host of current directory */
|
||||
char *remdir; /* Dir on remote host */
|
||||
char *homedir; /* Name of home directory */
|
||||
char *workdir; /* Name of working directory */
|
||||
int hdlen; /* Length of homedir name */
|
||||
int wdlen; /* Length of workdir name */
|
||||
char relativeto; /* 0 = name relative to root */
|
||||
FILTER filters = NULL; /* Filters to be applied */
|
||||
char *ndname; /* Next component of dirname */
|
||||
char *magic_str; /* Magic number part of ndname */
|
||||
int magic_no; /* Magic number from magic_str */
|
||||
int poundsign; /* Flag, nextcomp contains # */
|
||||
char wdname[MAX_VPATH]; /* Working directory name */
|
||||
VLINK ltmp; /* To look for unexpanded links */
|
||||
PATTRIB closure; /* Namespace from closed object */
|
||||
int retval; /* Return value */
|
||||
int depth; /* Depth for sym-link expansion */
|
||||
char stmp[MAX_VPATH]; /* Temporary string */
|
||||
char *colon; /* Pointer to colon in path */
|
||||
char *nsname; /* Possible name of new ns */
|
||||
int beyondcolon; /* Length of text after colon */
|
||||
char *nextcomp; /* 4 steppng through components */
|
||||
long intflags; /* Flags for intermediate query */
|
||||
|
||||
depth = SYMLINK_NESTING;
|
||||
|
||||
strcpy(dirname,dirarg);
|
||||
strcpy(components,(comparg ? comparg : ""));
|
||||
|
||||
nsname = dirname;
|
||||
|
||||
colon = p_uln_index(dirname,':');
|
||||
if(colon) {
|
||||
/* Name can not start with a ":" */
|
||||
if(colon == nsname) return(RVD_NS_NOT_FOUND);
|
||||
|
||||
/* Don't support name space aliases yet, so return an error */
|
||||
/* if the colon is preceded by a "#". */
|
||||
if(*(colon-1) == '#') return(RVD_NO_NS_ALIAS);
|
||||
|
||||
}
|
||||
|
||||
/* In most cases, we start from a specific directory */
|
||||
/* and don't care about the full pathname from root */
|
||||
/* We only want to deal with the pathname for the root */
|
||||
/* directory if the name starts with ../'s or ~/../'s */
|
||||
*wdname = '\0';
|
||||
|
||||
if(*dirname == '\0') {
|
||||
relativeto = 2;
|
||||
dirhst = pget_wdhost();
|
||||
remdir = pget_wdfile();
|
||||
}
|
||||
else if(*dirname == '/') {
|
||||
relativeto = 0;
|
||||
dirhst = pget_rdhost();
|
||||
remdir = pget_rdfile();
|
||||
dirname++;
|
||||
}
|
||||
else if((strncmp(dirname,"~/",2) == 0)||(strcmp(dirname,"~") == 0)) {
|
||||
/* Set wdname to homedir and later check for ../'s */
|
||||
relativeto = 1;
|
||||
strcpy(wdname,pget_hd());
|
||||
dirhst = pget_hdhost();
|
||||
remdir = pget_hdfile();
|
||||
dirname++;
|
||||
/* We only want to step over the next byte if it is not the */
|
||||
/* end of the string. It will be if string was ~ */
|
||||
if(*dirname) dirname++;
|
||||
}
|
||||
else {
|
||||
/* Set wdname and later check for ../'s */
|
||||
relativeto = 2;
|
||||
workdir = pget_wd();
|
||||
if(workdir) strcpy(wdname,workdir);
|
||||
else return(PFS_ENV_NOT_INITIALIZED);
|
||||
dirhst = pget_wdhost();
|
||||
remdir = pget_wdfile();
|
||||
}
|
||||
|
||||
/* If Prospero environment has not been initialized return error */
|
||||
if((dirhst == NULL) || (*dirhst == '\0'))
|
||||
return(PFS_ENV_NOT_INITIALIZED);
|
||||
|
||||
/* If we still allow ../'s and the dirname starts */
|
||||
/* as such, determine the correct name for the new */
|
||||
/* file relative to VSROOT, and use that instead */
|
||||
if(*wdname && (strncmp(dirname,"..",2) == 0)) {
|
||||
char *slash;
|
||||
|
||||
relativeto = 0;
|
||||
dirhst = pget_rdhost();
|
||||
remdir = pget_rdfile();
|
||||
while((strncmp(dirname,"../",3) == 0) ||
|
||||
(strcmp(dirname,"..") == 0)) {
|
||||
|
||||
dirname += 2;
|
||||
if(*dirname == '/') dirname++;
|
||||
|
||||
slash = p_uln_rindex(wdname,'/');
|
||||
colon = p_uln_rindex(wdname,':');
|
||||
|
||||
if(slash && (!colon || (slash > colon))) *slash = '\0';
|
||||
else if(colon) *(colon+1) = '\0';
|
||||
else *wdname = '\0';
|
||||
if(!*wdname) strcpy(wdname,"/");
|
||||
}
|
||||
|
||||
/* Remove a ./ if it caused termination of ../s */
|
||||
if(strncmp(dirname,"./",2) == 0) {
|
||||
dirname++;
|
||||
dirname++;
|
||||
}
|
||||
|
||||
if(*dirname && (*(wdname + strlen(wdname)-1) != '/'))
|
||||
strcat(wdname,"/");
|
||||
strcat(wdname,dirname);
|
||||
dirname = wdname;
|
||||
}
|
||||
|
||||
/* Special case "." if appears by itself */
|
||||
if(strcmp(dirname,".") == 0) {
|
||||
dirname++;
|
||||
}
|
||||
|
||||
/* And finally, remove a ./ if it appears at start */
|
||||
else if(strncmp(dirname,"./",2) == 0) {
|
||||
dirname++;
|
||||
dirname++;
|
||||
}
|
||||
|
||||
/* Check to see if working or home directory is a */
|
||||
/* prefix of the directory to be listed */
|
||||
if(! (flags & RVD_NOCACHE) ) {
|
||||
workdir = pget_wd();
|
||||
homedir = pget_hd();
|
||||
if((relativeto == 0) && (*dirname != '/')) {
|
||||
workdir++;
|
||||
homedir++;
|
||||
}
|
||||
wdlen = strlen(workdir);
|
||||
hdlen = strlen(homedir);
|
||||
/* Do not cache if remaining part of name has any */
|
||||
/* single colons. Right now the check disables caching */
|
||||
/* if it finds any colons. It should allow it if it is */
|
||||
/* a double colon. */
|
||||
if((strncmp(dirname,workdir,wdlen) == 0) &&
|
||||
((hdlen <= wdlen) || (strncmp(dirname,homedir,hdlen) != 0)) &&
|
||||
((*(dirname+wdlen) == '/') || (*(dirname+wdlen) == '\0'))&&
|
||||
(p_uln_index(dirname+wdlen,':') == 0)) {
|
||||
dirname = dirname + wdlen;
|
||||
if(*dirname == '/') dirname++;
|
||||
relativeto = 2;
|
||||
dirhst = pget_wdhost();
|
||||
remdir = pget_wdfile();
|
||||
}
|
||||
else if((strncmp(dirname,homedir,hdlen) == 0) &&
|
||||
((*(dirname+hdlen) == '/') || (*(dirname+hdlen) == '\0'))&&
|
||||
(p_uln_index(dirname+hdlen,':') == 0)) {
|
||||
dirname = dirname + hdlen;
|
||||
if(*dirname == '/') dirname++;
|
||||
relativeto = 1;
|
||||
dirhst = pget_hdhost();
|
||||
remdir = pget_hdfile();
|
||||
}
|
||||
}
|
||||
else flags &= (~ RVD_NOCACHE);
|
||||
|
||||
startover:
|
||||
|
||||
/* The target of a symbolic link must be an absolute path */
|
||||
/* from the root of the specified virtual system. Thus */
|
||||
/* if chasing a link, we skip the code above that checks */
|
||||
/* for ../s, and ~/s. */
|
||||
|
||||
nsname = dirname;
|
||||
|
||||
/* If the directory includes :s, find correct namespace */
|
||||
while(colon = p_uln_index(dirname,':')) {
|
||||
|
||||
/* If the vs name is null, return an error */
|
||||
if(colon == nsname) return(RVD_NS_NOT_FOUND);
|
||||
|
||||
/* If an alias, return error. Aliases are only allowed for */
|
||||
/* the first : and if an alias, it was resolved previously */
|
||||
if(*(colon-1) == '#') return(RVD_NO_NS_ALIAS);
|
||||
|
||||
/* object closure */
|
||||
if(*(colon+1) == ':') {
|
||||
*(colon++) = '\0';
|
||||
colon++;
|
||||
ltmp = rd_vlink(dirname);
|
||||
if(!ltmp) return(RVD_NO_CLOSED_NS);
|
||||
closure = pget_at(ltmp,"CLOSURE");
|
||||
vllfree(ltmp);
|
||||
if(!closure) return(RVD_NO_CLOSED_NS);
|
||||
/* XXX This must change! */
|
||||
if (closure->avtype != ATR_SEQUENCE) {
|
||||
atlfree(closure);
|
||||
return(RVD_NO_CLOSED_NS);
|
||||
}
|
||||
if (qsprintf(stmp,sizeof stmp,
|
||||
"%s:%s",closure->value.sequence->token,colon) >
|
||||
sizeof stmp)
|
||||
internal_error("stmp too small!");
|
||||
atlfree(closure);
|
||||
strcpy(dirnm,stmp);
|
||||
dirname = dirnm;
|
||||
nsname = dirname;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* text between nsname and colon is name space */
|
||||
*(colon++) = '\0';
|
||||
if (sizeof stmp <
|
||||
qsprintf(stmp, sizeof stmp,
|
||||
"/VIRTUAL-SYSTEMS/%s/ROOT%s%s",nsname,
|
||||
((!*colon || (*colon == '/')) ? "" : "/"),colon))
|
||||
internal_error("stmp too small!");
|
||||
|
||||
/* Remember how much text after colon before we overwite dirname */
|
||||
beyondcolon = strlen(colon);
|
||||
|
||||
/* Keep part of dirname that defines root of old namespace */
|
||||
if((nsname > dirname) && (*(nsname-1) == '/')) *(nsname-1) = '\0';
|
||||
else *nsname = '\0';
|
||||
|
||||
/* And append path to root of new one */
|
||||
strcat(dirname,stmp);
|
||||
|
||||
/* Keep track of the root of the new name space */
|
||||
nsname = dirname + strlen(dirname) - beyondcolon;
|
||||
|
||||
/* Start search from root of active name space */
|
||||
relativeto = 0;
|
||||
dirhst = pget_rdhost();
|
||||
remdir = pget_rdfile();
|
||||
}
|
||||
|
||||
ndname = dirname;
|
||||
while(*ndname == '/') ndname++; /* multiple slashes treated as one slash */
|
||||
nextcomp = p_uln_index(ndname,'/');
|
||||
if(nextcomp) {
|
||||
*(nextcomp++) = '\0';
|
||||
if(!*nextcomp) nextcomp = NULL; /* trailing slash ignored. */
|
||||
}
|
||||
if(!*ndname) ndname = NULL;
|
||||
|
||||
/* If we only want the directory file, and we have a null */
|
||||
/* dirname (ndname is first component), then we must create */
|
||||
/* a fictitious directory entry from dirhst and remdir */
|
||||
if(!ndname && (flags & RVD_DFILE_ONLY)) {
|
||||
VLINK vl;
|
||||
char *tmp_wdname = pget_wd(); /* working directory. */
|
||||
char *s; /* link name */
|
||||
/* If links remain in dir, free them */
|
||||
vdir_freelinks(dir);
|
||||
|
||||
/* Allocate the pseudo link */
|
||||
dir->links = vl = vlalloc();
|
||||
if (!vl) out_of_memory();
|
||||
|
||||
/* and fill it in */
|
||||
vl->host = stcopy(dirhst);
|
||||
vl->hsoname = stcopy(remdir);
|
||||
vl->target = stcopyr("DIRECTORY", vl->target);
|
||||
/* Set a NAME field of some sort. */
|
||||
if (tmp_wdname && *tmp_wdname) {
|
||||
char *sp = p_uln_rindex(tmp_wdname, '/'); /* slashptr */
|
||||
char *cp = p_uln_rindex(tmp_wdname, ':'); /* colonptr */
|
||||
char *lastwdcomp; /* last comp in tmp_wdname */
|
||||
s = ((cp < sp) ? sp : cp) + 1;
|
||||
if (s && *s) vl->name = stcopyr(s, vl->name);
|
||||
else vl->name = stcopyr(tmp_wdname, vl->name);
|
||||
} else if (s = strrchr(remdir, '/')) {
|
||||
vl->name = stcopyr(s, vl->name);
|
||||
} else {
|
||||
vl->name = stcopyr(remdir, vl->name);
|
||||
}
|
||||
}
|
||||
|
||||
while(ndname) {
|
||||
TOKEN nextcomp_tkl; /* Token list form of nextcomp variable;
|
||||
a temporary var. */
|
||||
TOKEN thiscomp_tkl; /* used to convert quoted component strings to
|
||||
normal format. */
|
||||
|
||||
VLINK dlink = vlalloc();
|
||||
|
||||
dlink->host = stcopyr(dirhst, dlink->host);
|
||||
dlink->hsoname = stcopyr(remdir, dlink->hsoname);
|
||||
dlink->filters = flcopy(filters, 1);
|
||||
|
||||
/* Check for magic number */
|
||||
magic_no = 0;
|
||||
magic_str = p_uln_rindex(ndname,'#');
|
||||
/* Make sure that the rest of magic str is digits */
|
||||
if(magic_str && *(magic_str + 1) &&
|
||||
(strspn(magic_str+1,"-0123456789") == strlen(magic_str+1))) {
|
||||
*(magic_str++) = '\0';
|
||||
sscanf(magic_str,"%d",&magic_no);
|
||||
}
|
||||
|
||||
/* Find out if there is a # in any remaining components */
|
||||
/* and if so, don't reolve multiple components */
|
||||
if(nextcomp && p_uln_index(nextcomp,'#')) poundsign = 1;
|
||||
else poundsign = 0;
|
||||
|
||||
intflags = (magic_no ? GVD_LREMEXP : GVD_FIND);
|
||||
if((*ndname == '#')&&(*(ndname+1))) {
|
||||
intflags = GVD_UNION;
|
||||
poundsign = 1;
|
||||
}
|
||||
/* if((flags & RVD_DFILE_ONLY) && (flags & RVD_ATTRIB)) */
|
||||
/* intflags |= GVD_ATTRIB; */
|
||||
/* It might not be a directory in which case we want the */
|
||||
/* attributes */
|
||||
if(flags & RVD_ATTRIB) intflags |= GVD_ATTRIB;
|
||||
|
||||
if ((*ndname != '#') || (!*(ndname + 1))) {
|
||||
thiscomp_tkl = p__rvdslashpath2tkl(ndname);
|
||||
assert(thiscomp_tkl && !thiscomp_tkl->next);
|
||||
} else
|
||||
thiscomp_tkl = NULL;
|
||||
if (!magic_no && !poundsign) {
|
||||
nextcomp_tkl = p__rvdslashpath2tkl(nextcomp);
|
||||
retval = p_get_dir(dlink,
|
||||
thiscomp_tkl? thiscomp_tkl->token : (char *)NULL,
|
||||
dir, intflags, &nextcomp_tkl);
|
||||
p__tkl_back_2rvdslashpath(nextcomp_tkl, nextcomp);
|
||||
tklfree(nextcomp_tkl);
|
||||
} else {
|
||||
retval = p_get_dir(dlink,
|
||||
thiscomp_tkl? thiscomp_tkl->token : (char *)NULL,
|
||||
dir, intflags, NULL);
|
||||
}
|
||||
if (thiscomp_tkl) tklfree(thiscomp_tkl);
|
||||
|
||||
if(retval) {
|
||||
vlfree(dlink);
|
||||
if (retval == DIRSRV_NOT_DIRECTORY) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Directory %s not found.",ndname);
|
||||
return(PFS_DIR_NOT_FOUND);
|
||||
}
|
||||
else return(retval);
|
||||
}
|
||||
|
||||
if(*ndname == '#' && *(ndname+1)) {
|
||||
vllfree(dir->links);
|
||||
dir->links = dir->ulinks;
|
||||
dir->ulinks = NULL;
|
||||
while(dir->links && (strcmp(dir->links->name,ndname+1) != 0)) {
|
||||
ltmp = dir->links;
|
||||
dir->links = dir->links->next;
|
||||
vlfree(ltmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the one with the correct magic number. */
|
||||
/* We can get rid of those that don't match */
|
||||
if(dir->links && magic_no && (magic_no != dir->links->f_magic_no)){
|
||||
ltmp = dir->links->replicas;
|
||||
while(ltmp && (ltmp->f_magic_no != magic_no)) {
|
||||
dir->links->replicas = ltmp->next;
|
||||
vlfree(ltmp);
|
||||
ltmp = dir->links->replicas;
|
||||
}
|
||||
/* found it, replace primary link */
|
||||
if(ltmp) {
|
||||
ltmp->replicas = ltmp->next;
|
||||
if(ltmp->replicas) ltmp->replicas->previous = NULL;
|
||||
ltmp->next = dir->links->next;
|
||||
ltmp->previous = dir->links->previous;
|
||||
dir->links->replicas = NULL;
|
||||
vlfree(dir->links);
|
||||
dir->links = ltmp;
|
||||
}
|
||||
/* Otherwise get rid of primary link */
|
||||
else {
|
||||
ltmp = dir->links;
|
||||
dir->links = ltmp->next;
|
||||
vlfree(ltmp);
|
||||
dir->links->previous = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Can't find next directory link */
|
||||
if(dir->links == NULL) {
|
||||
p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Directory %s not found.",ndname);
|
||||
|
||||
/* If unexpanded ulinks, return temporary error */
|
||||
ltmp = dir->ulinks;
|
||||
while(ltmp) {
|
||||
if(ltmp->expanded != TRUE) {
|
||||
vlfree(dlink);
|
||||
return(RVD_DIR_NOT_THERE);
|
||||
}
|
||||
ltmp = ltmp->next;
|
||||
}
|
||||
vlfree(dlink);
|
||||
return(PFS_DIR_NOT_FOUND);
|
||||
}
|
||||
|
||||
/* If a symbolic link, expand it */
|
||||
if((strncmp(dir->links->target,"SYMBOLIC",8) == 0) &&
|
||||
(strncmp(dir->links->hosttype,"VIRTUAL-SYSTEM",14) == 0)) {
|
||||
if(depth-- > 0) {
|
||||
sprintf(stmp,"%s:%s",dir->links->host,
|
||||
dir->links->hsoname);
|
||||
if(nextcomp && !*nextcomp) nextcomp = NULL;
|
||||
while(ndname = nextcomp) {
|
||||
nextcomp = p_uln_index(ndname,'/');
|
||||
if(nextcomp) {
|
||||
*(nextcomp++) = '\0';
|
||||
if(*nextcomp == '\0') nextcomp = NULL;
|
||||
}
|
||||
strcat(stmp,"/");
|
||||
strcat(stmp,ndname);
|
||||
}
|
||||
strcpy(dirnm,stmp);
|
||||
dirname = dirnm;
|
||||
vlfree(dlink); /* Goto's considered harmfull! */
|
||||
goto startover;
|
||||
}
|
||||
else {
|
||||
vlfree(dlink);
|
||||
return(PFS_SYMLINK_DEPTH);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
assert(0); /* should never get here. */
|
||||
}
|
||||
|
||||
/* found next directory - update dirhost and remdir - continue */
|
||||
dirhst = dir->links->host;
|
||||
remdir = dir->links->hsoname;
|
||||
filters = dir->links->filters;
|
||||
/* remove the next line */
|
||||
dir->links->filters = NULL;
|
||||
|
||||
/* Find the next component of the path name */
|
||||
if(nextcomp && !*nextcomp) nextcomp = NULL;
|
||||
ndname = nextcomp;
|
||||
if(ndname) {
|
||||
nextcomp = p_uln_index(ndname,'/');
|
||||
if(nextcomp) {
|
||||
*(nextcomp++) = '\0';
|
||||
if(*nextcomp == '\0') nextcomp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If more components, and not a real link, then */
|
||||
/* return an error */
|
||||
if (ndname && (strcmp(dir->links->target,"DIRECTORY") != 0) &&
|
||||
(strcmp(dir->links->target,"FILE") != 0)) {
|
||||
/* Ooops - Release does vlfree but not return, good
|
||||
reason to bracket EVERY if - Mitra */
|
||||
vlfree(dlink);
|
||||
return (PFS_EXT_USED_AS_DIR);
|
||||
}
|
||||
vlfree(dlink); /* For drop-thru or loop */
|
||||
} /*while */
|
||||
|
||||
/* if magic number specified, chop it off before making request */
|
||||
magic_no = 0;
|
||||
magic_str = p_uln_rindex(components,'#');
|
||||
/* Make sure that the rest of magic str is digits */
|
||||
if(magic_str && *(magic_str + 1) &&
|
||||
(strspn(magic_str+1,"-0123456789") == strlen(magic_str+1))) {
|
||||
*(magic_str++) = '\0';
|
||||
sscanf(magic_str,"%d",&magic_no);
|
||||
/* If alternate version specified, don't stop looking */
|
||||
if(flags & GVD_FIND) flags = (flags & (~GVD_FIND)) | GVD_LREMEXP;
|
||||
}
|
||||
|
||||
/* If a normal link, then we do a listing of the */
|
||||
/* directory. If not a directory, then get_vidr */
|
||||
/* will fail We will pass through the error code */
|
||||
/* Dir will contain the single directory link */
|
||||
/* corresponding to the file */
|
||||
if(!dir->links || (strcmp(dir->links->target,"DIRECTORY") == 0) ||
|
||||
(strcmp(dir->links->target,"FILE") == 0)) {
|
||||
VLINK dlink = vlalloc();
|
||||
|
||||
dlink->host = stcopyr(dirhst, dlink->host);
|
||||
dlink->hsoname = stcopyr(remdir, dlink->hsoname);
|
||||
dlink->filters = flcopy(filters, 1);
|
||||
retval = p_get_dir(dlink,components,dir,flags, NULL);
|
||||
|
||||
/* Find the one with the correct magic number. */
|
||||
/* We can get rid of those that don't match */
|
||||
/* This code is not applicable for all flags combos */
|
||||
if(dir->links && magic_no && (magic_no != dir->links->f_magic_no)){
|
||||
ltmp = dir->links->replicas;
|
||||
while(ltmp && (ltmp->f_magic_no != magic_no)) {
|
||||
dir->links->replicas = ltmp->next;
|
||||
vlfree(ltmp);
|
||||
ltmp = dir->links->replicas;
|
||||
}
|
||||
/* found it, replace primary link */
|
||||
if(ltmp) {
|
||||
ltmp->replicas = ltmp->next;
|
||||
if(ltmp->replicas) ltmp->replicas->previous = NULL;
|
||||
ltmp->next = dir->links->next;
|
||||
ltmp->previous = dir->links->previous;
|
||||
dir->links->replicas = NULL;
|
||||
vlfree(dir->links);
|
||||
dir->links = ltmp;
|
||||
}
|
||||
/* Otherwise get rid of primary link */
|
||||
else {
|
||||
ltmp = dir->links;
|
||||
dir->links = ltmp->next;
|
||||
vlfree(ltmp);
|
||||
dir->links->previous = NULL;
|
||||
}
|
||||
}
|
||||
vlfree(dlink);
|
||||
return(retval);
|
||||
}
|
||||
else return(DIRSRV_NOT_DIRECTORY);
|
||||
|
||||
}
|
||||
|
||||
/* These are not thread safe */
|
||||
static int oldpathlen;
|
||||
#ifndef NDEBUG /* for assertions */
|
||||
static char *oldnextcomp;
|
||||
#endif
|
||||
|
||||
static
|
||||
TOKEN
|
||||
p__rvdslashpath2tkl(char *nextcomp)
|
||||
{
|
||||
TOKEN retval = NULL;
|
||||
char *cp;
|
||||
char thiscomp[MAX_VPATH]; /* buffer for current comp. strip backslashes.
|
||||
*/
|
||||
char *thisp = thiscomp;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
oldpathlen = 0;
|
||||
#ifndef NDEBUG
|
||||
oldnextcomp = nextcomp;
|
||||
#endif
|
||||
if (!nextcomp) return NULL;
|
||||
for (cp = nextcomp; *cp; cp++) {
|
||||
if (*cp == '/') {
|
||||
*thisp = '\0';
|
||||
/* Skip multiple slashes (as rd_vdir() does.) */
|
||||
if (thisp > thiscomp) {
|
||||
++oldpathlen;
|
||||
retval = tkappend(thiscomp, retval);
|
||||
thisp = thiscomp; /* set for next */
|
||||
}
|
||||
continue;
|
||||
} else if (*cp == '\\') {
|
||||
++cp;
|
||||
if (*cp == '\0') --cp; /* special case trailing \; treat it as a
|
||||
literal backslash. */
|
||||
}
|
||||
*thisp++ = *cp; /* process quoted and literal characters */
|
||||
}
|
||||
/* Handle the last component. Skip trailing slashes. (as rd_vdir does). */
|
||||
*thisp = '\0';
|
||||
if (thisp > thiscomp) {
|
||||
++oldpathlen;
|
||||
retval = tkappend(thiscomp, retval);
|
||||
}
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Should only be called when p__rvdslashpath2tkl was called. */
|
||||
static
|
||||
void
|
||||
p__tkl_back_2rvdslashpath(TOKEN nextcomp_tkl, char *nextcomp)
|
||||
{
|
||||
char buf[MAX_VPATH];
|
||||
|
||||
/* Make sure the functions were called in the proper order. This assertion
|
||||
helps make sure we don't write too much back into the old nextcomp
|
||||
buffer. */
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
assert(oldnextcomp == nextcomp);
|
||||
*buf = '\0';
|
||||
/* Optimize common case (no change). */
|
||||
if (oldpathlen == length(nextcomp_tkl))
|
||||
return;
|
||||
assert(oldpathlen > length(nextcomp_tkl)); /* sanity */
|
||||
for(; nextcomp_tkl; nextcomp_tkl = nextcomp_tkl->next) {
|
||||
strcat(buf, nextcomp_tkl->token);
|
||||
strcat(buf, "/");
|
||||
}
|
||||
assert(strlen(buf) <= strlen(nextcomp));
|
||||
strcpy(nextcomp, buf);
|
||||
}
|
||||
|
||||
129
prospero/lib/pfs/rd_vlink.c
Normal file
129
prospero/lib/pfs/rd_vlink.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1990 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>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
static VLINK rd_vslink();
|
||||
|
||||
/*
|
||||
* rd_vlink will read the named link, expanding any symbolic links
|
||||
* along the way. Call rd_slink if you do not want to expand the
|
||||
* final sym_link.
|
||||
*/
|
||||
VLINK
|
||||
rd_vlink(const char *path)
|
||||
{
|
||||
return(rd_vslink(path,SYMLINK_NESTING));
|
||||
}
|
||||
|
||||
/*
|
||||
* rd_slink will read the named link, returing the result without
|
||||
* expansion, even if the result is a symbolic link.
|
||||
*/
|
||||
VLINK
|
||||
rd_slink(const char *path)
|
||||
{
|
||||
return(rd_vslink(path,-1));
|
||||
}
|
||||
|
||||
extern char *p_uln_lastcomp_to_linkname(const char *s);
|
||||
|
||||
|
||||
static VLINK
|
||||
rd_vslink(path,depth)
|
||||
const char *path; /* Pathname for links to be returned */
|
||||
int depth; /* How many levels of sym links to expand */
|
||||
{
|
||||
char pth[MAX_VPATH]; /* Working copy of pathname */
|
||||
char *p = pth; /* So we can use it as a pointer */
|
||||
|
||||
char *c; /* Component part of name */
|
||||
char *d; /* Directory part of name */
|
||||
char *slash; /* Position of slash */
|
||||
char *colon; /* Position of colon */
|
||||
|
||||
int flags;
|
||||
|
||||
VDIR_ST dir_st;
|
||||
VDIR dir = &dir_st;
|
||||
VLINK v;
|
||||
|
||||
vdir_init(dir);
|
||||
|
||||
/* special case just a . as a name for the current working directory,
|
||||
by mapping it onto the empty string. . */
|
||||
if (strequal(path, ".")) ++path;
|
||||
strcpy(p,path);
|
||||
|
||||
d = p;
|
||||
slash = p_uln_rindex(p,'/');
|
||||
colon = p_uln_rindex(p,':');
|
||||
|
||||
if(colon && (!slash || (colon > slash))) {
|
||||
*(colon + 1) = '\0';
|
||||
c = p_uln_lastcomp_to_linkname(p_uln_rindex(path,':') + 1);
|
||||
}
|
||||
else if(slash) {
|
||||
if(slash == p) d = "/";
|
||||
*slash = '\0';
|
||||
c = p_uln_lastcomp_to_linkname(slash + 1);
|
||||
}
|
||||
else if (strequal(path, "..")) {
|
||||
/* Special case just .. as a name for the superior directory. */
|
||||
d = "..";
|
||||
c = NULL;
|
||||
} else {
|
||||
d = "";
|
||||
c = p_uln_lastcomp_to_linkname(p);
|
||||
}
|
||||
|
||||
if(c && *c) flags = RVD_FIND;
|
||||
else flags = RVD_DFILE_ONLY;
|
||||
|
||||
perrno = rd_vdir(d,c,dir,flags);
|
||||
|
||||
if(perrno || !dir->links) {
|
||||
if (!perrno) perrno = PFAILURE;
|
||||
vllfree(dir->links);
|
||||
vllfree(dir->ulinks);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
vllfree(dir->ulinks);
|
||||
|
||||
if((strncmp(dir->links->target,"SYMBOLIC",8) == 0) &&
|
||||
(strncmp(dir->links->hosttype,"VIRTUAL-SYSTEM",14) == 0)) {
|
||||
if(depth > 0) {
|
||||
if (sizeof pth <
|
||||
qsprintf(pth, sizeof pth,
|
||||
"/VIRTUAL-SYSTEMS/%s/ROOT%s%s",dir->links->host,
|
||||
((*(dir->links->hsoname) == '/') ? "" : "/"),
|
||||
dir->links->hsoname))
|
||||
internal_error("pth too small!");
|
||||
v = rd_vslink(pth,depth-1);
|
||||
vllfree(dir->links);
|
||||
if (!perrno) perrno = PFAILURE;
|
||||
return(v);
|
||||
}
|
||||
else if(depth == 0) {
|
||||
vllfree(dir->links);
|
||||
perrno = PFS_SYMLINK_DEPTH;
|
||||
return(NULL);
|
||||
} /* depth < 0 means don't expand symlink. */
|
||||
}
|
||||
return(dir->links);
|
||||
}
|
||||
|
||||
51
prospero/lib/pfs/re_comp_exec.c
Normal file
51
prospero/lib/pfs/re_comp_exec.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#ifdef PFS_THREADS
|
||||
extern p_th_mutex p_th_mutexREGEX;
|
||||
#endif
|
||||
|
||||
/* This routine combines RE_COMP and RE_EXEC in an appropriate thread-safe
|
||||
interface. It currently operates by mutexing the use of the regex package.
|
||||
It will later be revised to take advantage of thread-safe library calls,
|
||||
as they become available in standard system libraries. If you need
|
||||
to do multithreaded matches right now, then you could do so by using the
|
||||
routine in misc/regex.c.
|
||||
This can also be linked with the versions of re_comp() and re_exec() that
|
||||
your system library provides; Prospero will do this by default.
|
||||
*/
|
||||
/*
|
||||
* Returns zero if successfully compiled and matched.
|
||||
* Returns 1 if not.
|
||||
* This is probably inefficient, since we always compile, even in the common
|
||||
* case where the pattern string has not changed. Need to rethink this at
|
||||
* a later date. (but not right now.)
|
||||
*/
|
||||
int
|
||||
p__re_comp_exec(char *temp, char *s)
|
||||
{
|
||||
int retval;
|
||||
|
||||
p_th_mutex_lock(p_th_mutexREGEX);
|
||||
if(re_comp(temp)) {
|
||||
/* There should be a way to pass this error information up to the
|
||||
caller,but we don't have one right now. Need to look at this again
|
||||
later. */
|
||||
retval= 0;
|
||||
} else {
|
||||
/* -1 is internal error for re_exec(). 1 is match. 0 is failure to
|
||||
match. */
|
||||
retval = (re_exec(s) > 0);
|
||||
}
|
||||
p_th_mutex_unlock(p_th_mutexREGEX);
|
||||
|
||||
return(retval);
|
||||
}
|
||||
52
prospero/lib/pfs/readheader.c
Normal file
52
prospero/lib/pfs/readheader.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 <pmachine.h>
|
||||
|
||||
/*
|
||||
* readheader will read the f until it comes across a line with
|
||||
* header whose name ends in h. It will then return the next token
|
||||
* on the same line.
|
||||
*
|
||||
* IMPORTANT: The returned value is static. It must be copied if it is
|
||||
* to be used after the next call to readheader.
|
||||
*
|
||||
* BUGS: The present implementation only looks for the first occurance of the
|
||||
* last character in h. This may cause problems if the character is not
|
||||
* unique. Ideally it should be something like a ":".
|
||||
*/
|
||||
char *readheader(f,h)
|
||||
FILE *f;
|
||||
char *h;
|
||||
{
|
||||
static char hv[MAX_VPATH];
|
||||
|
||||
char temp[MAX_VPATH+40];
|
||||
char *p;
|
||||
|
||||
int hl = strlen(h); /* Length of h */
|
||||
char *he = h + hl - 1; /* Last char in h */
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
while(fgets(temp,sizeof(temp),f)) {
|
||||
/* Note, for now, we only check the first occurance of */
|
||||
/* the last character. It had better be a uniqe one */
|
||||
/* such as a ":". */
|
||||
if(p = strchr(temp + hl - 1, *he)) {
|
||||
if(strcncmp(p-hl+1,h,hl) == 0) {
|
||||
sscanf(++p,"%s",hv);
|
||||
return(hv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
137
prospero/lib/pfs/scan_error.c
Normal file
137
prospero/lib/pfs/scan_error.c
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pfs.h>
|
||||
#include <perrno.h>
|
||||
|
||||
char *p_motd = NULL; /* motd is read here. */
|
||||
|
||||
static void fix_server_might_append_null_to_packet(RREQ req);
|
||||
|
||||
int
|
||||
scan_error(char *erst, RREQ req)
|
||||
{
|
||||
p_clear_errors();
|
||||
|
||||
if (strequal(erst, "SUCCESS"))
|
||||
return PSUCCESS;
|
||||
|
||||
#ifdef CLIENTS_REQUEST_VERSION_FROM_SERVER
|
||||
if (qsscanf(erst, "VERSION %*d %&s", &req->peer_sw_id) == 1) {
|
||||
#ifdef SERVER_MIGHT_APPEND_NULL_TO_PACKET
|
||||
if (req->peer_sw_id && (strnequal(req->peer_sw_id, "A50", 3) ||
|
||||
strnequal(req->peer_sw_id, "A51", 3) ||
|
||||
strnequal(req->peer_sw_id, "B51", 3) ||
|
||||
strnequal(req->peer_sw_id, "A52", 3)))
|
||||
fix_server_might_append_null_to_packet(req);
|
||||
#endif
|
||||
return PSUCCESS;
|
||||
}
|
||||
#endif
|
||||
if(strncmp(erst,"VERSION-NOT-SUPPORTED",21) == 0) {
|
||||
qsscanf(erst,"%'&[^\n]",&p_err_string);
|
||||
return perrno = DIRSRV_BAD_VERS;
|
||||
}
|
||||
|
||||
if(strncmp(erst,"WARNING ",8) == 0) {
|
||||
erst += 8;
|
||||
*p_warn_string = '\0';
|
||||
qsscanf(erst,"%~%*[^\n \t\r]%~%'&[^\n\r]",
|
||||
&p_warn_string);
|
||||
/* Return values for warnings are negative */
|
||||
if(strncmp(erst,"OUT-OF-DATE",11) == 0) {
|
||||
pwarn = PWARN_OUT_OF_DATE;
|
||||
return(PSUCCESS);
|
||||
}
|
||||
if(strncmp(erst,"MESSAGE",7) == 0) {
|
||||
pwarn = PWARN_MSG_FROM_SERVER;
|
||||
return(PSUCCESS);
|
||||
}
|
||||
pwarn = PWARNING;
|
||||
qsscanf(erst,"%'&[^\n]",&p_warn_string);
|
||||
return(PSUCCESS);
|
||||
}
|
||||
else if(strncmp(erst,"ERROR",5) == 0) {
|
||||
if(*(erst+5))
|
||||
qsscanf(erst+6,"%'&[^\n\r]",&p_err_string);
|
||||
perrno = DIRSRV_ERROR;
|
||||
return(perrno);
|
||||
}
|
||||
else if (strnequal(erst, "PARAMETER", 9)) {
|
||||
qsscanf(erst, "PARAMETER%~VALUE%*( \t)MOTD%*( \t)%'&s",
|
||||
&p_motd);
|
||||
/* It doesn't matter whether we successfully read in a value
|
||||
for p_motd, since we return SUCCESS anyway, and since
|
||||
p_motd is initialized to the empty string. */
|
||||
return PSUCCESS;
|
||||
}
|
||||
/* FAILURE on a line by itself. */
|
||||
else if (strequal(erst, "FAILURE")) return perrno = PFAILURE;
|
||||
/* The rest start with "FAILURE " */
|
||||
else if(!strnequal(erst,"FAILURE ", 8)) {
|
||||
/* Unrecognized Protocol message - Give warning, but return PSUCCESS */
|
||||
if(pwarn == 0) {
|
||||
*p_warn_string = '\0';
|
||||
pwarn = PWARN_UNRECOGNIZED_RESP;
|
||||
qsscanf(erst,"%'&[^\n\r]", &p_warn_string);
|
||||
}
|
||||
return(PSUCCESS);
|
||||
}
|
||||
erst += 8;
|
||||
|
||||
qsscanf(erst,"%*[^\n \t\r]%*[ \t]%&'[^\n\r]", &p_err_string);
|
||||
|
||||
/* Still to add */
|
||||
/* DIRSRV_AUTHENT_REQ 242 */
|
||||
/* DIRSRV_BAD_VERS 245 */
|
||||
|
||||
if(strncmp(erst,"NOT-FOUND",9) == 0)
|
||||
perrno = DIRSRV_NOT_FOUND;
|
||||
else if(strncmp(erst,"NOT-FOUND",9) == 0)
|
||||
perrno = DIRSRV_NOT_FOUND;
|
||||
else if(strncmp(erst,"NOT-AUTHORIZED",13) == 0)
|
||||
perrno = DIRSRV_NOT_AUTHORIZED;
|
||||
else if(strncmp(erst,"ALREADY-EXISTS",14) == 0)
|
||||
perrno = DIRSRV_ALREADY_EXISTS;
|
||||
else if(strncmp(erst,"NAME-CONFLICT",13) == 0)
|
||||
perrno = DIRSRV_NAME_CONFLICT;
|
||||
else if(strncmp(erst,"TOO-MANY",8) == 0)
|
||||
perrno = DIRSRV_TOO_MANY;
|
||||
else if(strncmp(erst,"SERVER-FAILED",13) == 0)
|
||||
perrno = DIRSRV_SERVER_FAILED;
|
||||
else if(strncmp(erst,"UNIMPLEMENTED",13) == 0) {
|
||||
perrno = DIRSRV_UNIMPLEMENTED;
|
||||
} else if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0)
|
||||
perrno = DIRSRV_NOT_DIRECTORY;
|
||||
else perrno = PFAILURE;
|
||||
|
||||
return perrno;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SERVER_MIGHT_APPEND_NULL_TO_PACKET
|
||||
/* This allows clients to fix output they get from the 5.0, 5.1, and 5.2
|
||||
servers. */
|
||||
static
|
||||
void
|
||||
fix_server_might_append_null_to_packet(RREQ req)
|
||||
{
|
||||
PTEXT pt = req->rcvd;
|
||||
for ( ; pt; pt = pt->next) {
|
||||
/* If the packet has a text area with at least one character in it */
|
||||
if ((pt->start + pt->length - pt->text > 0)
|
||||
/* and that character is ASCII NUL */
|
||||
&& (pt->start[pt->length - 1] == '\0')) {
|
||||
--pt->length; /* get rid of it (shorten the packet by 1) */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
45
prospero/lib/pfs/sindex.c
Normal file
45
prospero/lib/pfs/sindex.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <pmachine.h>
|
||||
|
||||
#include <pfs.h>
|
||||
|
||||
/*
|
||||
* sindex - Find first instance of string 2 in string 1
|
||||
*
|
||||
* SINDEX scans string 1 for the first instance of string
|
||||
* 2. If found, SINDEX returns a pointer to the first
|
||||
* character of that instance. If no instance is found,
|
||||
* SINDEX returns NULL (0).
|
||||
*
|
||||
* ARGS: s1 - string to be searched
|
||||
* s2 - string to be found
|
||||
* RETURNS: First instance of s2 in s1, or NULL (0) if not found
|
||||
*/
|
||||
const char *
|
||||
sindex(const char *s1 /* String to be searched */,
|
||||
const char *s2 /* String to be found */)
|
||||
{
|
||||
const char *s = s1; /* Temp pointer to string */
|
||||
|
||||
/* Check for first character of s2 */
|
||||
while((s = strchr(s,*s2)) != NULL) {
|
||||
if(strncmp(s,s2,strlen(s2)) == 0)
|
||||
return(s);
|
||||
s++;
|
||||
}
|
||||
|
||||
/* We didn't find it */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
72
prospero/lib/pfs/slashpath.c
Normal file
72
prospero/lib/pfs/slashpath.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 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>
|
||||
|
||||
static int oldpathlen;
|
||||
#ifndef NDEBUG /* for assertions */
|
||||
static char *oldnextcomp;
|
||||
#endif
|
||||
|
||||
TOKEN
|
||||
p__slashpath2tkl(char *nextcomp)
|
||||
{
|
||||
TOKEN retval = NULL;
|
||||
char *cp;
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
oldpathlen = 0;
|
||||
#ifndef NDEBUG
|
||||
oldnextcomp = nextcomp;
|
||||
#endif
|
||||
if (!nextcomp) return NULL;
|
||||
for (cp = nextcomp; *cp; cp++) {
|
||||
if (*cp == '/') {
|
||||
if (cp == nextcomp)
|
||||
/* eliminate double-slashes */
|
||||
++nextcomp;
|
||||
else {
|
||||
*cp = '\0';
|
||||
++oldpathlen;
|
||||
retval = tkappend(nextcomp, retval);
|
||||
*cp = '/'; /* restore it */
|
||||
nextcomp = cp + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Handle the last component. */
|
||||
if (cp > nextcomp)/* More components. (Path didn't end in a slash). */
|
||||
tkappend(nextcomp, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* Should only be called when p__slashpath2tkl was called. */
|
||||
void
|
||||
p__tkl_back_2slashpath(TOKEN nextcomp_tkl, char *nextcomp)
|
||||
{
|
||||
char buf[MAX_VPATH];
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER());
|
||||
/* Make sure the functions were called in the proper order. This assertion
|
||||
helps make sure we don't write too much back into the old nextcomp
|
||||
buffer. */
|
||||
assert(oldnextcomp == nextcomp);
|
||||
*buf = '\0';
|
||||
/* Optimize common case (no change). */
|
||||
if (oldpathlen == length(nextcomp_tkl))
|
||||
return;
|
||||
assert(oldpathlen > length(nextcomp_tkl)); /* sanity */
|
||||
for(; nextcomp_tkl; nextcomp_tkl = nextcomp_tkl->next) {
|
||||
strcat(buf, nextcomp_tkl->token);
|
||||
strcat(buf, "/");
|
||||
}
|
||||
assert(strlen(buf) <= strlen(nextcomp));
|
||||
strcpy(nextcomp, buf);
|
||||
}
|
||||
|
||||
28
prospero/lib/pfs/slashpath2.c
Normal file
28
prospero/lib/pfs/slashpath2.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 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>
|
||||
|
||||
/* Used by ARCHIE database code to convert slashpath to token lists.
|
||||
We can use the same regular p__slashpath2tkl to convert back. */
|
||||
/* Jan 10, 1994: I believe this code is now vestigial. If it isn't, it must
|
||||
be rewritten. */
|
||||
|
||||
char *
|
||||
p__tkl_2slashpath(TOKEN nextcomp_tkl)
|
||||
{
|
||||
char buf[MAX_VPATH];
|
||||
|
||||
assert("p__tkl_2slashpath() must be rewritten.");
|
||||
*buf = '\0';
|
||||
for(; nextcomp_tkl; nextcomp_tkl = nextcomp_tkl->next) {
|
||||
strcat(buf, nextcomp_tkl->token);
|
||||
strcat(buf, "/");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
223
prospero/lib/pfs/socket.c
Normal file
223
prospero/lib/pfs/socket.c
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (c) 1993 by the University of Southern California
|
||||
*
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-license.h>.
|
||||
*/
|
||||
|
||||
/* These routines are pulled from lib/psrv/gopher_gw/goph_gw_dsdb.c
|
||||
and user/vcache/gopherget.c since they are common to both*/
|
||||
|
||||
#include <usc-license.h>
|
||||
|
||||
#include <netdb.h> /* Must be before pmachine.h */
|
||||
#include <pfs.h>
|
||||
#include <pmachine.h>
|
||||
#include <errno.h>
|
||||
#include <perrno.h>
|
||||
#include <posix_signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <pfs_threads.h>
|
||||
#include <sockettime.h>
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
EXTERN_TYPEP_DEF(jmp_buf, Jmpenv);
|
||||
#define Jmpenv p_th_arJmpenv[p__th_self_num()]
|
||||
|
||||
static void
|
||||
reprimeAlarm(int oldalarm, SIGNAL_RET_TYPE(*oldintr)())
|
||||
{
|
||||
if (signal(SIGALRM, oldintr) == SIG_ERR)
|
||||
perror("signal died:"), exit(-1);
|
||||
alarm(oldalarm);
|
||||
}
|
||||
/* These are probably not used, can remove if usefull for threading */
|
||||
EXTERN_INT_DEF(syscall_oldalarmtime); /* Save old alarm time */
|
||||
#define syscall_oldalarmtime p_th_arsyscall_oldalarmtime[p__th_self_num()]
|
||||
/* SIGNAL_RET_TYPE (*syscall_oldintr)();*/ /* Old signal */
|
||||
EXTERN_TYPEP_DEF(void *,syscall_oldintr); /* Old signal */
|
||||
#define syscall_oldintr p_th_arsyscall_oldintr[p__th_self_num()]
|
||||
|
||||
static SIGNAL_RET_TYPE
|
||||
alarmJmp(int sig)
|
||||
{
|
||||
reprimeAlarm(syscall_oldalarmtime,syscall_oldintr);
|
||||
longjmp(Jmpenv,1);
|
||||
}
|
||||
|
||||
#endif /*TIMEOUT_APPROACH*/
|
||||
|
||||
#ifdef SELECT_APPROACH
|
||||
int
|
||||
wait_till_stream_readable(FILE *str, int timeout)
|
||||
{
|
||||
if (str->_cnt > 0) return 1;
|
||||
return (wait_till_readable(fileno(str),timeout));
|
||||
}
|
||||
|
||||
#endif /*SELECT_APPROACH*/
|
||||
|
||||
/* This is adapted from interruptable_connect in gopher */
|
||||
int
|
||||
quick_connect(int s, struct sockaddr *name, int namelen, int timeout)
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
syscall_oldalarmtime = alarm(timeout);
|
||||
if ((syscall_oldintr = signal(SIGALRM, alarmJmp)) == SIG_ERR)
|
||||
perror("signal died:\n"), exit(-1);
|
||||
if (setjmp(Jmpenv)) {
|
||||
/* Note alarmJmp will reprime alarm*/
|
||||
errno = ETIMEDOUT;
|
||||
return(-1);
|
||||
}
|
||||
#endif
|
||||
while ( (((retval = connect(s, name, namelen)) == -1)
|
||||
&& (errno == EINTR)));
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
reprimeAlarm(syscall_oldalarmtime,syscall_oldintr);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
quick_read(int fd, char *nptr, int nbytes, int timeout)
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
syscall_oldalarmtime = alarm(timeout);
|
||||
if ((syscall_oldintr = signal(SIGALRM, alarmJmp)) == SIG_ERR)
|
||||
perror("signal died:\n"), exit(-1);
|
||||
if (setjmp(Jmpenv)) {
|
||||
/* Note alarmJmp will reprime alarm*/
|
||||
errno = ETIMEDOUT;
|
||||
return(-1);
|
||||
}
|
||||
#endif /*TIMEOUT_APPROACH*/
|
||||
#ifdef SELECT_APPROACH
|
||||
switch (wait_till_readable(fd,timeout)) {
|
||||
case -1: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"INTERNAL: read select failed: %s", unixerrstr());
|
||||
return NULL;
|
||||
case 0: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"Waited more than %d secs for response", timeout);
|
||||
return NULL;
|
||||
}
|
||||
/* Default is going to be 1 - which is success */
|
||||
|
||||
#endif /*SELECT_APPROACH*/
|
||||
retval = read(fd, nptr, nbytes); /* socket or -1 */
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
reprimeAlarm(syscall_oldalarmtime,syscall_oldintr);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *
|
||||
quick_fgets(char *s, int n, FILE *stream, int timeout)
|
||||
/* Do a fgets, with opportunity for timeout handling, depending on system
|
||||
same return code as fgets, but can return NULL (and not set error)
|
||||
in some circumstances */
|
||||
{
|
||||
char *retval;
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
syscall_oldalarmtime = alarm(timeout);
|
||||
if ((syscall_oldintr = signal(SIGALRM, alarmJmp)) == SIG_ERR)
|
||||
perror("signal died:\n"), exit(-1);
|
||||
if (setjmp(Jmpenv)) {
|
||||
/* Note alarmJmp will reprime alarm*/
|
||||
errno = ETIMEDOUT;
|
||||
return(NULL);
|
||||
}
|
||||
#endif
|
||||
#ifdef SELECT_APPROACH
|
||||
switch (wait_till_stream_readable(stream,timeout)) {
|
||||
case -1: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"INTERNAL: read select failed: %s", unixerrstr());
|
||||
return NULL;
|
||||
case 0: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"waited more than %d secs for a response", timeout);
|
||||
errno = ETIMEDOUT;
|
||||
return NULL;
|
||||
}
|
||||
/* Default is going to be 1 - which is success */
|
||||
|
||||
#endif /*SELECT_APPROACH*/
|
||||
retval = fgets(s, n, stream);
|
||||
#ifdef SELECT_APPROACH
|
||||
/* fgets can retunr an incomplete line, since it is non-blocking */
|
||||
if (retval) {
|
||||
int buflen = strlen(s);
|
||||
if ((s[buflen -1 ] != '\n') && (n-1 > buflen)) {
|
||||
retval = quick_fgets(s+buflen, n-buflen, stream, timeout);
|
||||
}
|
||||
}
|
||||
#endif /*SELECT_APPROACH*/
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
reprimeAlarm(syscall_oldalarmtime,syscall_oldintr);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int
|
||||
quick_fgetc(FILE *stream, int timeout)
|
||||
{
|
||||
int retval;
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
syscall_oldalarmtime = alarm(timeout);
|
||||
if ((syscall_oldintr = signal(SIGALRM, alarmJmp)) == SIG_ERR)
|
||||
perror("signal died:\n"), exit(-1);
|
||||
if (setjmp(Jmpenv)) {
|
||||
/* Note alarmJmp will reprime alarm*/
|
||||
errno = ETIMEDOUT;
|
||||
return(EOF);
|
||||
}
|
||||
#endif
|
||||
#ifdef SELECT_APPROACH
|
||||
switch (wait_till_stream_readable(stream,timeout)) {
|
||||
case -1: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"INTERNAL: quick_fgetc: select failed: %s", unixerrstr());
|
||||
return EOF;
|
||||
case 0: p_err_string = qsprintf_stcopyr(p_err_string,
|
||||
"waited more than %d secs for a response", timeout);
|
||||
errno = ETIMEDOUT;
|
||||
return EOF;
|
||||
}
|
||||
/* Default is going to be 1 - which is success */
|
||||
|
||||
#endif /*SELECT_APPROACH*/
|
||||
retval = getc(stream);
|
||||
|
||||
#ifdef TIMEOUT_APPROACH
|
||||
reprimeAlarm(syscall_oldalarmtime,syscall_oldintr);
|
||||
#endif
|
||||
return retval;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int quick_fgetc (FILE *stream, int timeout)
|
||||
{
|
||||
char c[2];
|
||||
char *retval;
|
||||
|
||||
if (!(retval = quick_fgets(c, 2, stream, timeout))) {
|
||||
/* errno set in quick_fgets */
|
||||
return EOF;
|
||||
}
|
||||
return c[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
49
prospero/lib/pfs/stat.c
Normal file
49
prospero/lib/pfs/stat.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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>
|
||||
/* Stuff that handles stat, scrounged from other places */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <pfs.h> /* for prototypes for these functions */
|
||||
|
||||
/* Stat and get a modification time. Returns 0 upon failure. */
|
||||
extern time_t
|
||||
mtime(const char native_dirname[])
|
||||
{
|
||||
struct stat st_buf;
|
||||
|
||||
if(stat(native_dirname, &st_buf) == 0)
|
||||
return st_buf.st_mtime;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Is it a directory? 1 = yes, 0 = no, -1 = failure? */
|
||||
extern int
|
||||
is_dir(const char native_filename[])
|
||||
{
|
||||
struct stat st_buf;
|
||||
|
||||
if(stat(native_filename, &st_buf) == 0)
|
||||
return S_ISDIR(st_buf.st_mode) ? 1 : 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return age of file in seconds -1 on failure*/
|
||||
int
|
||||
stat_age(const char *path) {
|
||||
time_t then;
|
||||
|
||||
return ((then = mtime(path)) ? time((time_t *) 0)-then : -1);
|
||||
|
||||
}
|
||||
211
prospero/lib/pfs/stcopy.c
Normal file
211
prospero/lib/pfs/stcopy.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <ardp.h> /* For ALLOCATOR_CONSISTENCY_CHECK */
|
||||
#include <pfs.h> /* for defs. of functions in this file. */
|
||||
#include <stdlib.h> /*SOLARIS: for malloc, free etc*/
|
||||
|
||||
/* #define DREADFUL_TEMPORARY_HACK_TO_FIX_URGENT_CRASH_5_16_94 *//* my fault --swa */
|
||||
|
||||
/* See pfs.h for discussion of the string format we use and for macros that
|
||||
manipulate it. . */
|
||||
|
||||
int string_count = 0;
|
||||
int string_max = 0;
|
||||
|
||||
/*
|
||||
* stcopy - allocate space for and copy a string
|
||||
*
|
||||
* STCOPY takes a string as an argument, allocates space for
|
||||
* a copy of the string, copies the string to the allocated space,
|
||||
* and returns a pointer to the copy.
|
||||
* Cannot fail - calls out_of_memory
|
||||
*/
|
||||
|
||||
char *
|
||||
stcopy(const char *st)
|
||||
{
|
||||
return(stcopyr(st,(char *)0));
|
||||
}
|
||||
|
||||
/*
|
||||
* stcopyr - copy a string allocating space if necessary
|
||||
*
|
||||
* STCOPYR takes a conventional string, S, as an argument, and a pointer to
|
||||
* a second string, R, which is to be replaced by S. If R is long enough
|
||||
* to hold S, S is copied. Otherwise, new space is allocated, and R is
|
||||
* freed. S is then copied to the newly allocated space. If S is
|
||||
* NULL, then R is freed and NULL is returned.
|
||||
*
|
||||
* In any event, STCOPYR returns a pointer to the new copy of S,
|
||||
* or a NULL pointer.
|
||||
*/
|
||||
char *
|
||||
stcopyr(const char *s, char *r)
|
||||
{
|
||||
int sl;
|
||||
int rl;
|
||||
|
||||
CHECK_MEM();
|
||||
assert(p__bst_consistent(r));
|
||||
if(!s && r) {
|
||||
stfree(r);
|
||||
return(NULL);
|
||||
}
|
||||
else if (!s) return(NULL);
|
||||
|
||||
sl = strlen(s) + 1;
|
||||
|
||||
if(r) {
|
||||
rl = p__bstsize(r);
|
||||
if(rl < sl) {
|
||||
stfree(r);
|
||||
r = (char *) malloc(sl + p__bst_header_sz);
|
||||
/* Check for out of memory. not too cool, but better than segfaulting. */
|
||||
if (!r) out_of_memory();
|
||||
string_count++;
|
||||
r += p__bst_header_sz;
|
||||
p__bst_size_fld(r) = sl;
|
||||
p__bst_length_fld(r) = P__BST_LENGTH_NULLTERMINATED;
|
||||
#ifdef P_ALLOCATOR_CONSISTENCY_CHECK
|
||||
p__bst_consistency_fld(r) = P__INUSE_PATTERN;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
r = (char *) malloc(sl + p__bst_header_sz);
|
||||
if (!r) out_of_memory();
|
||||
string_count++;
|
||||
r += p__bst_header_sz;
|
||||
p__bst_size_fld(r) = sl;
|
||||
p__bst_length_fld(r) = P__BST_LENGTH_NULLTERMINATED;
|
||||
#ifdef P_ALLOCATOR_CONSISTENCY_CHECK
|
||||
p__bst_consistency_fld(r) = P__INUSE_PATTERN;
|
||||
#endif
|
||||
if(string_max < string_count) string_max = string_count;
|
||||
}
|
||||
strcpy(r,s);
|
||||
return(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* stalloc - Allocate space for a string
|
||||
*
|
||||
* STALLOC allocates space for a string by calling malloc.
|
||||
* STALLOC guarantees never to honor requests for zero or fewer bytes of
|
||||
* memory.
|
||||
*/
|
||||
char *
|
||||
stalloc(int size)
|
||||
{
|
||||
void *st;
|
||||
|
||||
if (size <= 0) return NULL;
|
||||
st = (void *) malloc(size + p__bst_header_sz);
|
||||
if(!st) out_of_memory();
|
||||
string_count++;
|
||||
st += p__bst_header_sz;
|
||||
p__bst_size_fld(st) = size;
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
p__bst_consistency_fld(st) = INUSE_PATTERN;
|
||||
#endif
|
||||
p__bst_length_fld(st) = P__BST_LENGTH_NULLTERMINATED;
|
||||
if(string_max < string_count) string_max = string_count;
|
||||
return(st);
|
||||
}
|
||||
|
||||
/*
|
||||
* stfree - free space allocated by stcopy or stalloc
|
||||
*
|
||||
* STFREE takes a string that was returned by stcopy or stalloc
|
||||
* and frees the space that was allocated for the string.
|
||||
*/
|
||||
void
|
||||
stfree(void *st)
|
||||
{
|
||||
#ifndef DREADFUL_TEMPORARY_HACK_TO_FIX_URGENT_CRASH_5_16_94 /* my fault --swa */
|
||||
assert(p__bst_consistent(st));
|
||||
#else
|
||||
if (!p__bst_consistent(st))
|
||||
return;
|
||||
#endif
|
||||
if(st) {
|
||||
#ifdef ALLOCATOR_CONSISTENCY_CHECK
|
||||
p__bst_consistency_fld(st) = FREE_PATTERN;
|
||||
#endif
|
||||
free(st - p__bst_header_sz);
|
||||
string_count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Take the length of a Prospero bstring. Must be allocated by Prospero. */
|
||||
int
|
||||
p_bstlen(const char *s)
|
||||
{
|
||||
assert(p__bst_consistent(s));
|
||||
if (!s) return 0;
|
||||
else if (p__bst_length_fld(s) == P__BST_LENGTH_NULLTERMINATED)
|
||||
return strlen(s);
|
||||
else
|
||||
return p__bst_length_fld(s);
|
||||
}
|
||||
|
||||
|
||||
/* Mark the length field of a buffer appropriately, when BUFLEN amount of data
|
||||
has been read into it. Give preference to using a raw length. */
|
||||
/* This is what you do after allocating a buffer with stalloc(), and it might
|
||||
be seen as part of the interface. */
|
||||
void
|
||||
p_bst_set_buffer_length_nullterm(char *buf, int buflen)
|
||||
{
|
||||
register int i;
|
||||
|
||||
assert(p__bst_consistent(buf));
|
||||
assert(p__bstsize(buf) >= buflen + 1);
|
||||
for (i = 0; i < buflen; ++i) {
|
||||
if (buf[i] == '\0') {
|
||||
/* If a null is present in the data, have to set an explicit
|
||||
count. */
|
||||
p__bst_length_fld(buf) = buflen;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
p__bst_length_fld(buf) = P__BST_LENGTH_NULLTERMINATED;
|
||||
|
||||
done:
|
||||
buf[buflen] = '\0';
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
p_bst_set_buffer_length_explicit(char *buf, int buflen)
|
||||
{
|
||||
assert(p__bst_consistent(buf));
|
||||
assert(p__bst_size_fld(buf) < buflen + 1);
|
||||
p__bst_length_fld(buf) = buflen;
|
||||
buf[buflen] = '\0';
|
||||
}
|
||||
|
||||
|
||||
/* This is called through the CHECK_MEM macro */
|
||||
void
|
||||
check_mem()
|
||||
{
|
||||
static int check_mem_val = 2000 ; /* Not thread safe, but not a prob */
|
||||
void *t1;
|
||||
|
||||
if (++check_mem_val > 20000)
|
||||
check_mem_val = 2000;
|
||||
|
||||
t1 = malloc(check_mem_val++);
|
||||
assert(t1);
|
||||
free(t1);
|
||||
}
|
||||
23
prospero/lib/pfs/stequal.c
Normal file
23
prospero/lib/pfs/stequal.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Copyright (c) 1992 -- 1993by the University of Southern California.
|
||||
* For copying and distribution information, please see the file
|
||||
* <usc-copyr.h>.
|
||||
*/
|
||||
|
||||
#include <usc-copyr.h>
|
||||
#include <pfs.h>
|
||||
|
||||
/* Equality tester for strings. This is used because there are a number of
|
||||
places in the Prospero code where string pointersare left set to NULL.
|
||||
Rather than paranoically guard against all such places, we can just use this
|
||||
function to test string equality, where appropriate.
|
||||
*/
|
||||
|
||||
int
|
||||
stequal(const char *s1, const char *s2)
|
||||
{
|
||||
if (s1 == s2) /* test for case when both NULL*/
|
||||
return TRUE;
|
||||
if (!s1 || !s2) /* Test for case where one is NULL; other is not */
|
||||
return FALSE;
|
||||
return strequal(s1, s2);
|
||||
}
|
||||
75
prospero/lib/pfs/strccmp.c
Normal file
75
prospero/lib/pfs/strccmp.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 <ctype.h>
|
||||
|
||||
#define toupper(x) (islower(x) ? (x & 0xdf) : x)
|
||||
|
||||
/*
|
||||
* strccmp - Compare two strings ignoring case
|
||||
*
|
||||
* STRCCMP compare two strings ignoring case. It
|
||||
* returns 0 if the strings are equal, negative is
|
||||
* string 1 is less than string 2, and positive
|
||||
* if string 1 is greater than string 2.
|
||||
* ARGS: s1 - first string
|
||||
* s2 - second string
|
||||
*
|
||||
* RETURNS: +,- or 0 depending on comparison
|
||||
*/
|
||||
int
|
||||
strccmp(s1,s2)
|
||||
char *s1; /* First String */
|
||||
char *s2; /* Second String */
|
||||
{
|
||||
int tmp;
|
||||
|
||||
while ((*s1 != '\0') && (*s2 != '\0')) {
|
||||
tmp = toupper(*s1) - toupper(*s2);
|
||||
if(tmp) return (tmp);
|
||||
s1++; s2++;
|
||||
}
|
||||
return(toupper(*s1) - toupper(*s2));
|
||||
}
|
||||
|
||||
/*
|
||||
* strcncmp - Compare two strings ignoring case and stoping after n chars
|
||||
*
|
||||
* STRCCMP compare two strings ignoring case. It
|
||||
* returns 0 if the strings are equal, negative is
|
||||
* string 1 is less than string 2, and positive
|
||||
* if string 1 is greater than string 2.
|
||||
* ARGS: s1 - first string
|
||||
* s2 - second string
|
||||
* n - number of characters to check
|
||||
*
|
||||
* RETURNS: +,- or 0 depending on comparison
|
||||
*/
|
||||
int
|
||||
strcncmp(s1,s2,n)
|
||||
char *s1; /* First String */
|
||||
char *s2; /* Second String */
|
||||
int n; /* Number of chars */
|
||||
{
|
||||
int tmp;
|
||||
|
||||
while ((n-- > 0) && (*s1 != '\0') && (*s2 != '\0')) {
|
||||
tmp = toupper(*s1) - toupper(*s2);
|
||||
if(tmp) return (tmp);
|
||||
s1++; s2++;
|
||||
}
|
||||
|
||||
if(n >= 0) return(toupper(*s1) - toupper(*s2));
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
39
prospero/lib/pfs/strpbrk.c
Normal file
39
prospero/lib/pfs/strpbrk.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* strpbrk - Find first instance of character from chrs in s
|
||||
*
|
||||
* SINDEX scans a string for the first instance of a character
|
||||
* from chrs. If found, STRPBRK returns a pointer to the
|
||||
* character in s. If no instance is found STRPBRK returns
|
||||
* NULL (0).
|
||||
*
|
||||
* ARGS: s - string to be searched
|
||||
* chrs - string of characters we are looking for
|
||||
* RETURNS: First instance of chrs in s, or NULL (0) if not found
|
||||
*/
|
||||
char *
|
||||
strpbrk(s,chrs)
|
||||
char *s; /* String to search */
|
||||
char *chrs; /* String of characters we are looking for */
|
||||
{
|
||||
char *cp; /* Pointer to the current character in chrs */
|
||||
|
||||
while(*s) {
|
||||
for(cp = chrs;*cp;cp++)
|
||||
if(*cp == *s) return(s);
|
||||
s++;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
44
prospero/lib/pfs/strspn.c
Normal file
44
prospero/lib/pfs/strspn.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
/*
|
||||
* strspn - Count initial characters from chrs in s
|
||||
*
|
||||
* STRSPN counts the occurances of chacters from chrs
|
||||
* in the string s preceeding the first occurance of
|
||||
* a character not in s.
|
||||
*
|
||||
* ARGS: s - string to be checked
|
||||
* chrs - string of characters we are looking for
|
||||
*
|
||||
* RETURNS: Count of initial characters from chrs in s
|
||||
*/
|
||||
int
|
||||
strspn(s,chrs)
|
||||
char *s; /* String to search */
|
||||
char *chrs; /* String of characters we are looking for */
|
||||
{
|
||||
char *cp; /* Pointer to the current character in chrs */
|
||||
int count; /* Count of characters seen so far */
|
||||
|
||||
count = 0;
|
||||
|
||||
while(*s) {
|
||||
for(cp = chrs;*cp;cp++)
|
||||
if(*cp == *s) {
|
||||
s++;
|
||||
count++;
|
||||
goto done;
|
||||
}
|
||||
return(count);
|
||||
done:
|
||||
;
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
38
prospero/lib/pfs/timetoasn.c
Normal file
38
prospero/lib/pfs/timetoasn.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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>
|
||||
/* Written by swa@ISI.EDU, October 2, 1992 */
|
||||
/* Mutexed, swa@ISI.EDU, November 1993. */
|
||||
/* Interface changed: swa@ISI.EDU, Feb. 16, 1994 */
|
||||
/* got rid of appearance of number 22 anywhere here; converted back to
|
||||
qsprintf: swa, April 20, 1994. */
|
||||
|
||||
#include <time.h>
|
||||
#include <pfs.h>
|
||||
#include <pfs_threads.h>
|
||||
|
||||
|
||||
/*
|
||||
* Writes timetoasn() stamp into target.
|
||||
*/
|
||||
char *
|
||||
p_timetoasn_stcopyr(time_t ourtime, char *target)
|
||||
{
|
||||
/* This mutexes GMTIME and sprintf. These are the only
|
||||
problematic cases. */
|
||||
p_th_mutex_lock(p_th_mutexPFS_TIMETOASN);
|
||||
{
|
||||
struct tm *mt = gmtime(&ourtime);
|
||||
target = qsprintf_stcopyr(target, "%04d%02d%02d%02d%02d%02dZ",
|
||||
mt->tm_year+1900,mt->tm_mon+1,mt->tm_mday,
|
||||
mt->tm_hour, mt->tm_min,mt->tm_sec);
|
||||
}
|
||||
p_th_mutex_unlock(p_th_mutexPFS_TIMETOASN);
|
||||
return target;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user