From 11492ebf389bb0d7bf1e60c34492aea20a0360d3 Mon Sep 17 00:00:00 2001 From: CSRG Date: Thu, 21 Feb 1991 18:32:49 -0800 Subject: [PATCH] BSD 4_3_Net_2 development Work on file usr/src/contrib/isode/others/listen/Makefile Work on file usr/src/contrib/isode/others/listen/READ-ME Work on file usr/src/contrib/isode/others/listen/initiate.c Work on file usr/src/contrib/isode/others/listen/listen.c Work on file usr/src/contrib/isode/others/listen/listen.h Work on file usr/src/contrib/isode/others/listen/make Work on file usr/src/contrib/isode/others/lookup/Makefile Work on file usr/src/contrib/isode/others/lookup/READ-ME Work on file usr/src/contrib/isode/others/lookup/lookup.1c Work on file usr/src/contrib/isode/others/lookup/lookup.c Work on file usr/src/contrib/isode/others/lookup/lookup.ry Work on file usr/src/contrib/isode/others/lookup/lookupd.8c Work on file usr/src/contrib/isode/others/lookup/lookupd.c Work on file usr/src/contrib/isode/others/lookup/make Work on file usr/src/contrib/isode/others/lookup/ryinitiator.c Work on file usr/src/contrib/isode/others/lookup/ryinitiator.h Work on file usr/src/contrib/isode/others/lookup/ryresponder.c Work on file usr/src/contrib/isode/others/lookup/ryresponder.h Work on file usr/src/contrib/isode/others/rfa/Makefile Work on file usr/src/contrib/isode/others/rfa/READ-ME Work on file usr/src/contrib/isode/others/rfa/advise.c Work on file usr/src/contrib/isode/others/rfa/config.h Work on file usr/src/contrib/isode/others/rfa/dirname.c Work on file usr/src/contrib/isode/others/rfa/error.c Work on file usr/src/contrib/isode/others/rfa/filedata.c Work on file usr/src/contrib/isode/others/rfa/fileinfo.c Work on file usr/src/contrib/isode/others/rfa/filemode.c Work on file usr/src/contrib/isode/others/rfa/getfile.c Work on file usr/src/contrib/isode/others/rfa/llock.c Work on file usr/src/contrib/isode/others/rfa/ls.c Work on file usr/src/contrib/isode/others/rfa/make Work on file usr/src/contrib/isode/others/rfa/printerr.c Work on file usr/src/contrib/isode/others/rfa/reqmaster.c Work on file usr/src/contrib/isode/others/rfa/rfa.1c Work on file usr/src/contrib/isode/others/rfa/rfa.c Work on file usr/src/contrib/isode/others/rfa/rfa.h Work on file usr/src/contrib/isode/others/rfa/rfa.ry Work on file usr/src/contrib/isode/others/rfa/rfa.tr Work on file usr/src/contrib/isode/others/rfa/rfa2fi.c Work on file usr/src/contrib/isode/others/rfa/rfad.8c Work on file usr/src/contrib/isode/others/rfa/rfad.c Work on file usr/src/contrib/isode/others/rfa/rfainfo.c Work on file usr/src/contrib/isode/others/rfa/rfainfo.h Work on file usr/src/contrib/isode/others/rfa/rfatailor Work on file usr/src/contrib/isode/others/rfa/rfatime.c Work on file usr/src/contrib/isode/others/rfa/ryinitiator.c Work on file usr/src/contrib/isode/others/rfa/ryresponder.c Work on file usr/src/contrib/isode/others/rfa/ryresponder.h Work on file usr/src/contrib/isode/others/rfa/sync.c Work on file usr/src/contrib/isode/others/rfa/synctime.c Work on file usr/src/contrib/isode/others/rfa/tailor.c Work on file usr/src/contrib/isode/others/mosy/Makefile Work on file usr/src/contrib/isode/others/mosy/make Work on file usr/src/contrib/isode/others/mosy/mosy.1 Work on file usr/src/contrib/isode/others/osilookup/Makefile Work on file usr/src/contrib/isode/others/osilookup/READ-ME Work on file usr/src/contrib/isode/others/osilookup/make Work on file usr/src/contrib/isode/others/osilookup/osilookup.c Work on file usr/src/contrib/isode/others/pingpong/Makefile Work on file usr/src/contrib/isode/others/pingpong/READ-ME Work on file usr/src/contrib/isode/others/pingpong/make Work on file usr/src/contrib/isode/others/pingpong/pingpong.c Work on file usr/src/contrib/isode/others/quipu/make Work on file usr/src/contrib/isode/others/quipu/photo/Makefile Work on file usr/src/contrib/isode/others/quipu/photo/READ-ME Work on file usr/src/contrib/isode/others/quipu/photo/build_trees.c Work on file usr/src/contrib/isode/others/quipu/photo/code_word.c Work on file usr/src/contrib/isode/others/quipu/photo/d_main.c Work on file usr/src/contrib/isode/others/quipu/photo/decode.c Work on file usr/src/contrib/isode/others/quipu/photo/e_main.c Work on file usr/src/contrib/isode/others/quipu/photo/encode.c Work on file usr/src/contrib/isode/others/quipu/photo/faxtopbm.c Work on file usr/src/contrib/isode/others/quipu/photo/faxx.c Work on file usr/src/contrib/isode/others/quipu/photo/hexphoto.c Work on file usr/src/contrib/isode/others/quipu/photo/interface.c Work on file usr/src/contrib/isode/others/quipu/photo/make Work on file usr/src/contrib/isode/others/quipu/photo/pbmtofax.c Work on file usr/src/contrib/isode/others/quipu/photo/ps.c Work on file usr/src/contrib/isode/others/quipu/photo/sunview.c Work on file usr/src/contrib/isode/others/quipu/photo/t4014.c Work on file usr/src/contrib/isode/others/quipu/photo/template.c Work on file usr/src/contrib/isode/others/quipu/photo/tty.c Work on file usr/src/contrib/isode/others/quipu/photo/winx.c Work on file usr/src/contrib/isode/others/quipu/tools/Makefile Work on file usr/src/contrib/isode/others/quipu/tools/make Work on file usr/src/contrib/isode/others/quipu/tools/dsaconfig/Makefile Work on file usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaconfig.8 Work on file usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaptailor Work on file usr/src/contrib/isode/others/quipu/tools/dsaconfig/make Work on file usr/src/contrib/isode/others/quipu/tools/scripts/Makefile Work on file usr/src/contrib/isode/others/quipu/tools/scripts/READ-ME Work on file usr/src/contrib/isode/others/quipu/tools/scripts/aei2dsa Work on file usr/src/contrib/isode/others/quipu/tools/scripts/dsa2aei Work on file usr/src/contrib/isode/others/quipu/tools/scripts/ent2aei Work on file usr/src/contrib/isode/others/quipu/tools/scripts/make Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/Makefile Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/READ-ME Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/dsastats.dist Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/make Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/quipulocaladds Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/quipulocaladds.example Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/quipulocaladds.ucl Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/quiputechusers Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/quiputechusers.example Work on file usr/src/contrib/isode/others/quipu/tools/dsastats/quiputechusers.ucl Work on file usr/src/contrib/isode/others/quipu/uips/READ-ME Work on file usr/src/contrib/isode/others/quipu/uips/make Work on file usr/src/contrib/isode/others/quipu/uips/dish/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/dish/READ-ME Work on file usr/src/contrib/isode/others/quipu/uips/dish/clist Work on file usr/src/contrib/isode/others/quipu/uips/dish/dishinit Work on file usr/src/contrib/isode/others/quipu/uips/dish/dlist Work on file usr/src/contrib/isode/others/quipu/uips/dish/dsalist Work on file usr/src/contrib/isode/others/quipu/uips/dish/dsaping Work on file usr/src/contrib/isode/others/quipu/uips/dish/make Work on file usr/src/contrib/isode/others/quipu/uips/dish/osearch Work on file usr/src/contrib/isode/others/quipu/uips/dish/ousearch Work on file usr/src/contrib/isode/others/quipu/uips/dish/pipe.c Work on file usr/src/contrib/isode/others/quipu/uips/dish/psearch Work on file usr/src/contrib/isode/others/quipu/uips/dish/quipurc.c Work on file usr/src/contrib/isode/others/quipu/uips/dish/socket.c Work on file usr/src/contrib/isode/others/quipu/uips/dish/unbind.c Work on file usr/src/contrib/isode/others/quipu/uips/fred/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/fred/dad.8c Work on file usr/src/contrib/isode/others/quipu/uips/fred/fred.1c Work on file usr/src/contrib/isode/others/quipu/uips/fred/fred.c Work on file usr/src/contrib/isode/others/quipu/uips/fred/fredrc Work on file usr/src/contrib/isode/others/quipu/uips/fred/fredsh.sh Work on file usr/src/contrib/isode/others/quipu/uips/fred/make Work on file usr/src/contrib/isode/others/quipu/uips/fred/mh-patches Work on file usr/src/contrib/isode/others/quipu/uips/fred/miscellany.c Work on file usr/src/contrib/isode/others/quipu/uips/fred/ufnrc Work on file usr/src/contrib/isode/others/quipu/uips/fred/whitepages.sh Work on file usr/src/contrib/isode/others/quipu/uips/fred/whois.c Work on file usr/src/contrib/isode/others/quipu/uips/dsc/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/dsc/READ-ME Work on file usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist1 Work on file usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist2 Work on file usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist3 Work on file usr/src/contrib/isode/others/quipu/uips/dsc/localmess Work on file usr/src/contrib/isode/others/quipu/uips/dsc/host Work on file usr/src/contrib/isode/others/quipu/uips/dsc/localmess.dist Work on file usr/src/contrib/isode/others/quipu/uips/dsc/localmess.ucl Work on file usr/src/contrib/isode/others/quipu/uips/dsc/localphone Work on file usr/src/contrib/isode/others/quipu/uips/dsc/localphone.dist Work on file usr/src/contrib/isode/others/quipu/uips/dsc/localphone.ucl Work on file usr/src/contrib/isode/others/quipu/uips/dsc/make Work on file usr/src/contrib/isode/others/quipu/uips/dsc/paa Work on file usr/src/contrib/isode/others/quipu/uips/pod/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/pod/Pod.ad Work on file usr/src/contrib/isode/others/quipu/uips/pod/READ-ME Work on file usr/src/contrib/isode/others/quipu/uips/pod/bitmap Work on file usr/src/contrib/isode/others/quipu/uips/pod/calls.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/conf_read.y Work on file usr/src/contrib/isode/others/quipu/uips/pod/cpr Work on file usr/src/contrib/isode/others/quipu/uips/pod/defs.h Work on file usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.h Work on file usr/src/contrib/isode/others/quipu/uips/pod/filt.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/filt.h Work on file usr/src/contrib/isode/others/quipu/uips/pod/list.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/main.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/make Work on file usr/src/contrib/isode/others/quipu/uips/pod/modify.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/photo.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/pod.1c Work on file usr/src/contrib/isode/others/quipu/uips/pod/pod.5 Work on file usr/src/contrib/isode/others/quipu/uips/pod/pod.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/pod.h Work on file usr/src/contrib/isode/others/quipu/uips/pod/search.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/sequence.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/sequence.h Work on file usr/src/contrib/isode/others/quipu/uips/pod/util.c Work on file usr/src/contrib/isode/others/quipu/uips/pod/util.h Work on file usr/src/contrib/isode/others/quipu/uips/manage/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/manage/add_alias.1c Work on file usr/src/contrib/isode/others/quipu/uips/manage/add_alias.c Work on file usr/src/contrib/isode/others/quipu/uips/manage/alias_chk.c Work on file usr/src/contrib/isode/others/quipu/uips/manage/del_alias.c Work on file usr/src/contrib/isode/others/quipu/uips/manage/make Work on file usr/src/contrib/isode/others/quipu/uips/sd/READ-ME Work on file usr/src/contrib/isode/others/quipu/uips/sd/calls.c Work on file usr/src/contrib/isode/others/quipu/uips/sd/conf_read.y Work on file usr/src/contrib/isode/others/quipu/uips/sd/filt.h Work on file usr/src/contrib/isode/others/quipu/uips/sd/help.c Work on file usr/src/contrib/isode/others/quipu/uips/sd/main.c Work on file usr/src/contrib/isode/others/quipu/uips/sd/make Work on file usr/src/contrib/isode/others/quipu/uips/sd/sd.1c Work on file usr/src/contrib/isode/others/quipu/uips/sd/sd.5 Work on file usr/src/contrib/isode/others/quipu/uips/sd/sequence.c Work on file usr/src/contrib/isode/others/quipu/uips/sd/sequence.h Work on file usr/src/contrib/isode/others/quipu/uips/sd/symtab.c Work on file usr/src/contrib/isode/others/quipu/uips/sd/symtab.h Work on file usr/src/contrib/isode/others/quipu/uips/sd/wdgtdefs.h Work on file usr/src/contrib/isode/others/quipu/uips/sd/widget.c Work on file usr/src/contrib/isode/others/quipu/uips/sd/widget.h Work on file usr/src/contrib/isode/others/quipu/uips/xd/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/xd/READ-ME Work on file usr/src/contrib/isode/others/quipu/uips/xd/Xd.1c Work on file usr/src/contrib/isode/others/quipu/uips/xd/Xd.ad Work on file usr/src/contrib/isode/others/quipu/uips/xd/Xd.c Work on file usr/src/contrib/isode/others/quipu/uips/xd/calls.c Work on file usr/src/contrib/isode/others/quipu/uips/xd/conf_read.y Work on file usr/src/contrib/isode/others/quipu/uips/xd/dirtitle.h Work on file usr/src/contrib/isode/others/quipu/uips/xd/filt.c Work on file usr/src/contrib/isode/others/quipu/uips/xd/filt.h Synthesized-from: CSRG/cd2/net.2 --- usr/src/contrib/isode/others/listen/Makefile | 108 + usr/src/contrib/isode/others/listen/READ-ME | 7 + .../contrib/isode/others/listen/initiate.c | 142 + usr/src/contrib/isode/others/listen/listen.c | 168 + usr/src/contrib/isode/others/listen/listen.h | 51 + usr/src/contrib/isode/others/listen/make | 7 + usr/src/contrib/isode/others/lookup/Makefile | 193 + usr/src/contrib/isode/others/lookup/READ-ME | 5 + usr/src/contrib/isode/others/lookup/lookup.1c | 59 + usr/src/contrib/isode/others/lookup/lookup.c | 253 ++ usr/src/contrib/isode/others/lookup/lookup.ry | 109 + .../contrib/isode/others/lookup/lookupd.8c | 58 + usr/src/contrib/isode/others/lookup/lookupd.c | 227 ++ usr/src/contrib/isode/others/lookup/make | 7 + .../contrib/isode/others/lookup/ryinitiator.c | 429 ++ .../contrib/isode/others/lookup/ryinitiator.h | 52 + .../contrib/isode/others/lookup/ryresponder.c | 443 +++ .../contrib/isode/others/lookup/ryresponder.h | 53 + usr/src/contrib/isode/others/mosy/Makefile | 165 + usr/src/contrib/isode/others/mosy/make | 7 + usr/src/contrib/isode/others/mosy/mosy.1 | 55 + .../contrib/isode/others/osilookup/Makefile | 98 + .../contrib/isode/others/osilookup/READ-ME | 8 + usr/src/contrib/isode/others/osilookup/make | 7 + .../isode/others/osilookup/osilookup.c | 126 + .../contrib/isode/others/pingpong/Makefile | 52 + usr/src/contrib/isode/others/pingpong/READ-ME | 18 + usr/src/contrib/isode/others/pingpong/make | 7 + .../contrib/isode/others/pingpong/pingpong.c | 304 ++ usr/src/contrib/isode/others/quipu/make | 7 + .../contrib/isode/others/quipu/photo/Makefile | 174 + .../contrib/isode/others/quipu/photo/READ-ME | 49 + .../isode/others/quipu/photo/build_trees.c | 425 ++ .../isode/others/quipu/photo/code_word.c | 293 ++ .../contrib/isode/others/quipu/photo/d_main.c | 148 + .../contrib/isode/others/quipu/photo/decode.c | 984 +++++ .../contrib/isode/others/quipu/photo/e_main.c | 119 + .../contrib/isode/others/quipu/photo/encode.c | 699 ++++ .../isode/others/quipu/photo/faxtopbm.c | 377 ++ .../contrib/isode/others/quipu/photo/faxx.c | 240 ++ .../isode/others/quipu/photo/hexphoto.c | 72 + .../isode/others/quipu/photo/interface.c | 131 + usr/src/contrib/isode/others/quipu/photo/make | 7 + .../isode/others/quipu/photo/pbmtofax.c | 222 ++ usr/src/contrib/isode/others/quipu/photo/ps.c | 93 + .../isode/others/quipu/photo/sunview.c | 128 + .../contrib/isode/others/quipu/photo/t4014.c | 101 + .../isode/others/quipu/photo/template.c | 78 + .../contrib/isode/others/quipu/photo/tty.c | 279 ++ .../contrib/isode/others/quipu/photo/winx.c | 225 ++ .../contrib/isode/others/quipu/tools/Makefile | 76 + .../others/quipu/tools/dsaconfig/Makefile | 137 + .../others/quipu/tools/dsaconfig/dsaconfig.8 | 41 + .../others/quipu/tools/dsaconfig/dsaptailor | 67 + .../isode/others/quipu/tools/dsaconfig/make | 7 + .../others/quipu/tools/dsastats/Makefile | 50 + .../isode/others/quipu/tools/dsastats/READ-ME | 99 + .../others/quipu/tools/dsastats/dsastats.dist | 687 ++++ .../isode/others/quipu/tools/dsastats/make | 7 + .../quipu/tools/dsastats/quipulocaladds | 3 + .../tools/dsastats/quipulocaladds.example | 3 + .../quipu/tools/dsastats/quipulocaladds.ucl | 9 + .../quipu/tools/dsastats/quiputechusers | 3 + .../tools/dsastats/quiputechusers.example | 3 + .../quipu/tools/dsastats/quiputechusers.ucl | 3 + usr/src/contrib/isode/others/quipu/tools/make | 7 + .../isode/others/quipu/tools/scripts/Makefile | 48 + .../isode/others/quipu/tools/scripts/READ-ME | 42 + .../isode/others/quipu/tools/scripts/aei2dsa | 58 + .../isode/others/quipu/tools/scripts/dsa2aei | 73 + .../isode/others/quipu/tools/scripts/ent2aei | 47 + .../isode/others/quipu/tools/scripts/make | 7 + .../contrib/isode/others/quipu/uips/READ-ME | 20 + .../isode/others/quipu/uips/dish/Makefile | 296 ++ .../isode/others/quipu/uips/dish/READ-ME | 22 + .../isode/others/quipu/uips/dish/clist | 3 + .../isode/others/quipu/uips/dish/dishinit | 15 + .../isode/others/quipu/uips/dish/dlist | 5 + .../isode/others/quipu/uips/dish/dsalist | 41 + .../isode/others/quipu/uips/dish/dsaping | 51 + .../contrib/isode/others/quipu/uips/dish/make | 7 + .../isode/others/quipu/uips/dish/osearch | 23 + .../isode/others/quipu/uips/dish/ousearch | 5 + .../isode/others/quipu/uips/dish/pipe.c | 413 ++ .../isode/others/quipu/uips/dish/psearch | 5 + .../isode/others/quipu/uips/dish/quipurc.c | 700 ++++ .../isode/others/quipu/uips/dish/socket.c | 118 + .../isode/others/quipu/uips/dish/unbind.c | 222 ++ .../isode/others/quipu/uips/dsc/Makefile | 65 + .../isode/others/quipu/uips/dsc/READ-ME | 91 + .../isode/others/quipu/uips/dsc/dsc.dist1 | 237 ++ .../isode/others/quipu/uips/dsc/dsc.dist2 | 336 ++ .../isode/others/quipu/uips/dsc/dsc.dist3 | 37 + .../contrib/isode/others/quipu/uips/dsc/host | 3 + .../isode/others/quipu/uips/dsc/localmess | 3 + .../others/quipu/uips/dsc/localmess.dist | 1 + .../isode/others/quipu/uips/dsc/localmess.ucl | 3 + .../isode/others/quipu/uips/dsc/localphone | 18 + .../others/quipu/uips/dsc/localphone.dist | 6 + .../others/quipu/uips/dsc/localphone.ucl | 18 + .../contrib/isode/others/quipu/uips/dsc/make | 7 + .../contrib/isode/others/quipu/uips/dsc/paa | 3 + .../isode/others/quipu/uips/fred/Makefile | 273 ++ .../isode/others/quipu/uips/fred/dad.8c | 56 + .../isode/others/quipu/uips/fred/fred.1c | 459 +++ .../isode/others/quipu/uips/fred/fred.c | 1036 +++++ .../isode/others/quipu/uips/fred/fredrc | 29 + .../isode/others/quipu/uips/fred/fredsh.sh | 79 + .../contrib/isode/others/quipu/uips/fred/make | 7 + .../isode/others/quipu/uips/fred/mh-patches | 1157 ++++++ .../isode/others/quipu/uips/fred/miscellany.c | 454 +++ .../isode/others/quipu/uips/fred/ufnrc | 28 + .../others/quipu/uips/fred/whitepages.sh | 3 + .../isode/others/quipu/uips/fred/whois.c | 1091 ++++++ usr/src/contrib/isode/others/quipu/uips/make | 7 + .../isode/others/quipu/uips/manage/Makefile | 235 ++ .../others/quipu/uips/manage/add_alias.1c | 82 + .../others/quipu/uips/manage/add_alias.c | 522 +++ .../others/quipu/uips/manage/alias_chk.c | 528 +++ .../others/quipu/uips/manage/del_alias.c | 425 ++ .../isode/others/quipu/uips/manage/make | 7 + .../isode/others/quipu/uips/pod/Makefile | 405 ++ .../isode/others/quipu/uips/pod/Pod.ad | 415 ++ .../isode/others/quipu/uips/pod/READ-ME | 75 + .../isode/others/quipu/uips/pod/bitmap | 24 + .../isode/others/quipu/uips/pod/calls.c | 877 +++++ .../isode/others/quipu/uips/pod/conf_read.y | 225 ++ .../contrib/isode/others/quipu/uips/pod/cpr | 92 + .../isode/others/quipu/uips/pod/defs.h | 43 + .../isode/others/quipu/uips/pod/dir_entry.c | 33 + .../isode/others/quipu/uips/pod/dir_entry.h | 46 + .../isode/others/quipu/uips/pod/filt.c | 500 +++ .../isode/others/quipu/uips/pod/filt.h | 24 + .../isode/others/quipu/uips/pod/list.c | 163 + .../isode/others/quipu/uips/pod/main.c | 146 + .../contrib/isode/others/quipu/uips/pod/make | 8 + .../isode/others/quipu/uips/pod/modify.c | 742 ++++ .../isode/others/quipu/uips/pod/photo.c | 128 + .../isode/others/quipu/uips/pod/pod.1c | 109 + .../contrib/isode/others/quipu/uips/pod/pod.5 | 174 + .../contrib/isode/others/quipu/uips/pod/pod.c | 3456 +++++++++++++++++ .../contrib/isode/others/quipu/uips/pod/pod.h | 45 + .../isode/others/quipu/uips/pod/search.c | 167 + .../isode/others/quipu/uips/pod/sequence.c | 60 + .../isode/others/quipu/uips/pod/sequence.h | 29 + .../isode/others/quipu/uips/pod/util.c | 54 + .../isode/others/quipu/uips/pod/util.h | 4 + .../isode/others/quipu/uips/sd/READ-ME | 27 + .../isode/others/quipu/uips/sd/calls.c | 1627 ++++++++ .../isode/others/quipu/uips/sd/conf_read.y | 220 ++ .../contrib/isode/others/quipu/uips/sd/filt.h | 33 + .../contrib/isode/others/quipu/uips/sd/help.c | 112 + .../contrib/isode/others/quipu/uips/sd/main.c | 150 + .../contrib/isode/others/quipu/uips/sd/make | 2 + .../contrib/isode/others/quipu/uips/sd/sd.1c | 115 + .../contrib/isode/others/quipu/uips/sd/sd.5 | 172 + .../isode/others/quipu/uips/sd/sequence.c | 72 + .../isode/others/quipu/uips/sd/sequence.h | 48 + .../isode/others/quipu/uips/sd/symtab.c | 114 + .../isode/others/quipu/uips/sd/symtab.h | 56 + .../isode/others/quipu/uips/sd/wdgtdefs.h | 51 + .../isode/others/quipu/uips/sd/widget.c | 909 +++++ .../isode/others/quipu/uips/sd/widget.h | 127 + .../isode/others/quipu/uips/xd/Makefile | 288 ++ .../isode/others/quipu/uips/xd/READ-ME | 140 + .../contrib/isode/others/quipu/uips/xd/Xd.1c | 215 + .../contrib/isode/others/quipu/uips/xd/Xd.ad | 126 + .../contrib/isode/others/quipu/uips/xd/Xd.c | 882 +++++ .../isode/others/quipu/uips/xd/calls.c | 1109 ++++++ .../isode/others/quipu/uips/xd/conf_read.y | 313 ++ .../isode/others/quipu/uips/xd/dirtitle.h | 227 ++ .../contrib/isode/others/quipu/uips/xd/filt.c | 278 ++ .../contrib/isode/others/quipu/uips/xd/filt.h | 65 + usr/src/contrib/isode/others/rfa/Makefile | 268 ++ usr/src/contrib/isode/others/rfa/READ-ME | 26 + usr/src/contrib/isode/others/rfa/advise.c | 150 + usr/src/contrib/isode/others/rfa/config.h | 72 + usr/src/contrib/isode/others/rfa/dirname.c | 232 ++ usr/src/contrib/isode/others/rfa/error.c | 151 + usr/src/contrib/isode/others/rfa/filedata.c | 252 ++ usr/src/contrib/isode/others/rfa/fileinfo.c | 103 + usr/src/contrib/isode/others/rfa/filemode.c | 231 ++ usr/src/contrib/isode/others/rfa/getfile.c | 246 ++ usr/src/contrib/isode/others/rfa/llock.c | 271 ++ usr/src/contrib/isode/others/rfa/ls.c | 144 + usr/src/contrib/isode/others/rfa/make | 7 + usr/src/contrib/isode/others/rfa/printerr.c | 113 + usr/src/contrib/isode/others/rfa/reqmaster.c | 196 + usr/src/contrib/isode/others/rfa/rfa.1c | 96 + usr/src/contrib/isode/others/rfa/rfa.c | 1206 ++++++ usr/src/contrib/isode/others/rfa/rfa.h | 86 + usr/src/contrib/isode/others/rfa/rfa.ry | 168 + usr/src/contrib/isode/others/rfa/rfa.tr | 862 ++++ usr/src/contrib/isode/others/rfa/rfa2fi.c | 165 + usr/src/contrib/isode/others/rfa/rfad.8c | 50 + usr/src/contrib/isode/others/rfa/rfad.c | 220 ++ usr/src/contrib/isode/others/rfa/rfainfo.c | 604 +++ usr/src/contrib/isode/others/rfa/rfainfo.h | 90 + usr/src/contrib/isode/others/rfa/rfatailor | 48 + usr/src/contrib/isode/others/rfa/rfatime.c | 86 + .../contrib/isode/others/rfa/ryinitiator.c | 377 ++ .../contrib/isode/others/rfa/ryresponder.c | 298 ++ .../contrib/isode/others/rfa/ryresponder.h | 47 + usr/src/contrib/isode/others/rfa/sync.c | 660 ++++ usr/src/contrib/isode/others/rfa/synctime.c | 192 + usr/src/contrib/isode/others/rfa/tailor.c | 280 ++ 206 files changed, 42317 insertions(+) create mode 100644 usr/src/contrib/isode/others/listen/Makefile create mode 100644 usr/src/contrib/isode/others/listen/READ-ME create mode 100644 usr/src/contrib/isode/others/listen/initiate.c create mode 100644 usr/src/contrib/isode/others/listen/listen.c create mode 100644 usr/src/contrib/isode/others/listen/listen.h create mode 100644 usr/src/contrib/isode/others/listen/make create mode 100644 usr/src/contrib/isode/others/lookup/Makefile create mode 100644 usr/src/contrib/isode/others/lookup/READ-ME create mode 100644 usr/src/contrib/isode/others/lookup/lookup.1c create mode 100644 usr/src/contrib/isode/others/lookup/lookup.c create mode 100644 usr/src/contrib/isode/others/lookup/lookup.ry create mode 100644 usr/src/contrib/isode/others/lookup/lookupd.8c create mode 100644 usr/src/contrib/isode/others/lookup/lookupd.c create mode 100644 usr/src/contrib/isode/others/lookup/make create mode 100644 usr/src/contrib/isode/others/lookup/ryinitiator.c create mode 100644 usr/src/contrib/isode/others/lookup/ryinitiator.h create mode 100644 usr/src/contrib/isode/others/lookup/ryresponder.c create mode 100644 usr/src/contrib/isode/others/lookup/ryresponder.h create mode 100644 usr/src/contrib/isode/others/mosy/Makefile create mode 100644 usr/src/contrib/isode/others/mosy/make create mode 100644 usr/src/contrib/isode/others/mosy/mosy.1 create mode 100644 usr/src/contrib/isode/others/osilookup/Makefile create mode 100644 usr/src/contrib/isode/others/osilookup/READ-ME create mode 100644 usr/src/contrib/isode/others/osilookup/make create mode 100644 usr/src/contrib/isode/others/osilookup/osilookup.c create mode 100644 usr/src/contrib/isode/others/pingpong/Makefile create mode 100644 usr/src/contrib/isode/others/pingpong/READ-ME create mode 100644 usr/src/contrib/isode/others/pingpong/make create mode 100644 usr/src/contrib/isode/others/pingpong/pingpong.c create mode 100644 usr/src/contrib/isode/others/quipu/make create mode 100644 usr/src/contrib/isode/others/quipu/photo/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/photo/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/photo/build_trees.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/code_word.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/d_main.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/decode.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/e_main.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/encode.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/faxtopbm.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/faxx.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/hexphoto.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/interface.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/make create mode 100644 usr/src/contrib/isode/others/quipu/photo/pbmtofax.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/ps.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/sunview.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/t4014.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/template.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/tty.c create mode 100644 usr/src/contrib/isode/others/quipu/photo/winx.c create mode 100644 usr/src/contrib/isode/others/quipu/tools/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsaconfig/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaconfig.8 create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaptailor create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsaconfig/make create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/dsastats.dist create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/make create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/quipulocaladds create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/quipulocaladds.example create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/quipulocaladds.ucl create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/quiputechusers create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/quiputechusers.example create mode 100644 usr/src/contrib/isode/others/quipu/tools/dsastats/quiputechusers.ucl create mode 100644 usr/src/contrib/isode/others/quipu/tools/make create mode 100644 usr/src/contrib/isode/others/quipu/tools/scripts/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/tools/scripts/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/tools/scripts/aei2dsa create mode 100644 usr/src/contrib/isode/others/quipu/tools/scripts/dsa2aei create mode 100644 usr/src/contrib/isode/others/quipu/tools/scripts/ent2aei create mode 100644 usr/src/contrib/isode/others/quipu/tools/scripts/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/clist create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/dishinit create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/dlist create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/dsalist create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/dsaping create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/osearch create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/ousearch create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/pipe.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/psearch create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/quipurc.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/socket.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/dish/unbind.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist1 create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist2 create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist3 create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/host create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/localmess create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/localmess.dist create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/localmess.ucl create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/localphone create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/localphone.dist create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/localphone.ucl create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/dsc/paa create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/dad.8c create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/fred.1c create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/fred.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/fredrc create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/fredsh.sh create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/mh-patches create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/miscellany.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/ufnrc create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/whitepages.sh create mode 100644 usr/src/contrib/isode/others/quipu/uips/fred/whois.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/manage/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/manage/add_alias.1c create mode 100644 usr/src/contrib/isode/others/quipu/uips/manage/add_alias.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/manage/alias_chk.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/manage/del_alias.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/manage/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/Pod.ad create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/bitmap create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/calls.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/conf_read.y create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/cpr create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/defs.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/filt.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/filt.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/list.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/main.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/modify.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/photo.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/pod.1c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/pod.5 create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/pod.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/pod.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/search.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/sequence.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/sequence.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/util.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/pod/util.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/calls.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/conf_read.y create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/filt.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/help.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/main.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/sd.1c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/sd.5 create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/sequence.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/sequence.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/symtab.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/symtab.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/wdgtdefs.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/widget.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/sd/widget.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/Xd.1c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/Xd.ad create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/Xd.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/calls.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/conf_read.y create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/dirtitle.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/filt.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/filt.h create mode 100644 usr/src/contrib/isode/others/rfa/Makefile create mode 100644 usr/src/contrib/isode/others/rfa/READ-ME create mode 100644 usr/src/contrib/isode/others/rfa/advise.c create mode 100644 usr/src/contrib/isode/others/rfa/config.h create mode 100644 usr/src/contrib/isode/others/rfa/dirname.c create mode 100644 usr/src/contrib/isode/others/rfa/error.c create mode 100644 usr/src/contrib/isode/others/rfa/filedata.c create mode 100644 usr/src/contrib/isode/others/rfa/fileinfo.c create mode 100644 usr/src/contrib/isode/others/rfa/filemode.c create mode 100644 usr/src/contrib/isode/others/rfa/getfile.c create mode 100644 usr/src/contrib/isode/others/rfa/llock.c create mode 100644 usr/src/contrib/isode/others/rfa/ls.c create mode 100644 usr/src/contrib/isode/others/rfa/make create mode 100644 usr/src/contrib/isode/others/rfa/printerr.c create mode 100644 usr/src/contrib/isode/others/rfa/reqmaster.c create mode 100644 usr/src/contrib/isode/others/rfa/rfa.1c create mode 100644 usr/src/contrib/isode/others/rfa/rfa.c create mode 100644 usr/src/contrib/isode/others/rfa/rfa.h create mode 100644 usr/src/contrib/isode/others/rfa/rfa.ry create mode 100644 usr/src/contrib/isode/others/rfa/rfa.tr create mode 100644 usr/src/contrib/isode/others/rfa/rfa2fi.c create mode 100644 usr/src/contrib/isode/others/rfa/rfad.8c create mode 100644 usr/src/contrib/isode/others/rfa/rfad.c create mode 100644 usr/src/contrib/isode/others/rfa/rfainfo.c create mode 100644 usr/src/contrib/isode/others/rfa/rfainfo.h create mode 100644 usr/src/contrib/isode/others/rfa/rfatailor create mode 100644 usr/src/contrib/isode/others/rfa/rfatime.c create mode 100644 usr/src/contrib/isode/others/rfa/ryinitiator.c create mode 100644 usr/src/contrib/isode/others/rfa/ryresponder.c create mode 100644 usr/src/contrib/isode/others/rfa/ryresponder.h create mode 100644 usr/src/contrib/isode/others/rfa/sync.c create mode 100644 usr/src/contrib/isode/others/rfa/synctime.c create mode 100644 usr/src/contrib/isode/others/rfa/tailor.c diff --git a/usr/src/contrib/isode/others/listen/Makefile b/usr/src/contrib/isode/others/listen/Makefile new file mode 100644 index 0000000000..8fde3aca54 --- /dev/null +++ b/usr/src/contrib/isode/others/listen/Makefile @@ -0,0 +1,108 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE listen demo +############################################################################### + +############################################################################### +# Options +############################################################################### + +BINDIR = /usr/new/ + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = listen.h +CFILES = listen.c initiate.c + + +################################################################## +# Here it is... +################################################################## + +all: listen initiate +inst-all: inst-listen inst-initiate +install: inst-all clean +lint: l-listen l-initiate + + +################################################################## +# listen +################################################################## + +inst-listen: $(BINDIR)listen + +$(BINDIR)listen: xlisten + -cp $@ zxlisten + -rm -f $@ + cp xlisten $@ + -@ls -gls $@ + -@echo "" + +listen: xlisten + +xlisten: listen.o report.o + $(LDCC) $(LDFLAGS) -o $@ listen.o report.o $(LIBES) \ + $(LSOCKET) + +l-listen:; $(LINT) $(LFLAGS) listen.c ../callback/report.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +listen.o: $(HFILES) + +report.o: ../callback/report.c + $(CC) $(CFLAGS) -c ../callback/report.c + + +################################################################## +# initiate +################################################################## + +inst-initiate: $(BINDIR)initiate + +$(BINDIR)initiate: xinitiate + -cp $@ zxinitiate + -rm -f $@ + cp xinitiate $@ + -@ls -gls $@ + -@echo "" + +initiate: xinitiate + +xinitiate: initiate.o report.o + $(LDCC) $(LDFLAGS) -o $@ initiate.o report.o $(LIBES) \ + $(LSOCKET) + +l-initiate:; $(LINT) $(LFLAGS) initiate.c ../callback/report.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +initiate.o: $(HFILES) + + +################################################################## +# clean +################################################################## + +clean:; rm -f *.o x* z* _* core + +grind:; iprint Makefile + tgrind -lc $(HFILES) $(CFILES) + +true:; diff --git a/usr/src/contrib/isode/others/listen/READ-ME b/usr/src/contrib/isode/others/listen/READ-ME new file mode 100644 index 0000000000..9547085f78 --- /dev/null +++ b/usr/src/contrib/isode/others/listen/READ-ME @@ -0,0 +1,7 @@ +[ READ-ME - Sun Feb 14 08:11:32 1988 - ISODE listen demo notes - jrp ] + + + This is just a simple demonstration of network listening. You + probably don't want to install it unless you're interested in + trying the code out, for example when adding support for a new + type of network or machine. diff --git a/usr/src/contrib/isode/others/listen/initiate.c b/usr/src/contrib/isode/others/listen/initiate.c new file mode 100644 index 0000000000..88beb50527 --- /dev/null +++ b/usr/src/contrib/isode/others/listen/initiate.c @@ -0,0 +1,142 @@ +/* initiate.c -- initiator for listen demo */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/listen/RCS/initiate.c,v 7.1 91/02/22 09:27:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/listen/RCS/initiate.c,v 7.1 91/02/22 09:27:24 mrose Interim $ + * + * + * $Log: initiate.c,v $ + * Revision 7.1 91/02/22 09:27:24 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:00:17 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "listen.h" + +/* */ + +static char *mycontext = "isode listen demo"; + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + register struct SSAPaddr *sz; + struct SSAPconnect scs; + register struct SSAPconnect *sc = &scs; + struct SSAPdata sxs; + register struct SSAPdata *sx = &sxs; + struct SSAPrelease srs; + register struct SSAPrelease *sr = &srs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + AEI aei; + struct PSAPaddr *pa; + struct sblk outgoing; + SB sbo = &outgoing; + + reportailor (argv[0]); + + if (argc != 2) + adios (NULLCP, "usage: %s \"host\"", argv[0]); + + if ((aei = str2aei (argv[1], mycontext)) == NULLAEI) + adios (NULLCP, "%s-%s: unknown application-entity", + argv[1], mycontext); + if ((pa = aei2addr (aei)) == NULLPA) + adios (NULLCP, "address translation failed"); + sz = &pa -> pa_addr; + + bzero ((char *) sbo, sizeof *sbo); + sbo -> sb_requirements = SR_BASUBSET; + sbo -> sb_settings = 0; +#define dotoken(requires,shift,bit,type) \ +{ \ + if (sbo -> sb_requirements & requires) \ + sbo -> sb_settings |= ST_INIT_VALUE << shift; \ +} + dotokens (); +#undef dotoken + sbo -> sb_isn = SERIAL_NONE; + + if (SConnRequest (&sbo -> sb_connect, NULLSA, sz, sbo -> sb_requirements, + sbo -> sb_settings, sbo -> sb_isn, NULLCP, 0, NULLQOS, sc, si) + == NOTOK) + adios (NULLCP, "S-CONNECT.REQUEST: %s", SErrString (sa -> sa_reason)); + if (sc -> sc_result != SC_ACCEPT) + adios (NULLCP, "connection rejected by peer: %s", + SErrString (sc -> sc_result)); + advise (LLOG_NOTICE, NULLCP, + "S-CONNECT.CONFIRMATION: <%d, %s, %s, %s, %ld, %d>", + sc -> sc_sd, sprintref (&sc -> sc_connect), + saddr2str (&sc -> sc_responding), + sprintb (sc -> sc_requirements, RMASK), sc -> sc_isn, + sc -> sc_ssdusize); + + sbo -> sb_sd = sc -> sc_sd; + sbo -> sb_requirements = sc -> sc_requirements; + sbo -> sb_settings = sc -> sc_settings; +#define dotoken(requires,shift,bit,type) \ +{ \ + if (sbo -> sb_requirements & requires) \ + if ((sbo -> sb_settings & (ST_MASK << shift)) == ST_INIT_VALUE) \ + sbo -> sb_owned |= bit; \ +} + dotokens (); +#undef dotoken + sbo -> sb_ssn = sbo -> sb_isn = sc -> sc_isn; + + SCFREE (sc); + +/* do work here */ + + if (SRelRequest (sbo -> sb_sd, NULLCP, 0, NOTOK, sr, si) == NOTOK) + adios (NULLCP, "S-RELEASE.REQUEST: %s", SErrString (sa -> sa_reason)); + if (sr -> sr_affirmative) { + exit(0); + /* NOTREACHED */ + } else { + switch (SReadRequest (sbo -> sb_sd, sx, NOTOK, si)) { + case NOTOK: + adios (NULLCP, "S-READ.REQUEST: %s", SErrString (sa -> sa_reason)); + + case OK: + adios (NULLCP, "not expecting DATA indication 0x%x", sx -> sx_type); + + case DONE: + if (si -> si_type != SI_FINISH) + adios (NULLCP, "not expecting indication 0x%x", si -> si_type); + if (SRelResponse (sbo -> sb_sd, SC_ACCEPT, NULLCP, 0, si) + == NOTOK) + adios (NULLCP, "S-RELEASE.RESPONSE: %s", + SErrString (sa -> sa_reason)); + break; + } + } + + exit (1); +} diff --git a/usr/src/contrib/isode/others/listen/listen.c b/usr/src/contrib/isode/others/listen/listen.c new file mode 100644 index 0000000000..0a7fca52ef --- /dev/null +++ b/usr/src/contrib/isode/others/listen/listen.c @@ -0,0 +1,168 @@ +/* listen.c -- responder for listen demo */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/listen/RCS/listen.c,v 7.1 91/02/22 09:27:25 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/listen/RCS/listen.c,v 7.1 91/02/22 09:27:25 mrose Interim $ + * + * + * $Log: listen.c,v $ + * Revision 7.1 91/02/22 09:27:25 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:00:18 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "listen.h" + +/* */ + +static char *mycontext = "isode listen demo"; + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int secs, + vecp; + char *vec[4]; + struct TSAPdisconnect tds; + struct TSAPdisconnect *td = &tds; + struct SSAPstart sss; + register struct SSAPstart *ss = &sss; + struct SSAPdata sxs; + register struct SSAPdata *sx = &sxs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + AEI aei; + struct PSAPaddr *pa; + struct sblk incoming; + SB sbi = &incoming; + + reportailor (argv[0]); + + if (argc > 2) + adios (NULLCP, "usage: %s [secs]", argv[0]); + + secs = (argc == 2) ? atoi(argv[1]) : 15; /* Wait 15s after release + by default */ + + if ((aei = str2aei (PLocalHostName(), mycontext)) == NULLAEI) + adios (NULLCP, "%s-%s: unknown application-entity", + PLocalHostName (), mycontext); + + if ((pa = aei2addr (aei)) == NULLPA) + adios (NULLCP, "address translation failed"); + + if (TNetListen (&pa -> pa_addr.sa_addr, td) == NOTOK) + if (td -> td_cc > 0) + adios (NULLCP, "TNetListen: [%s] %*.*s", TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data); + else + adios (NULLCP, "TNetListen: [%s]", TErrString (td -> td_reason)); + + /* now wait for incoming call */ + for (;;) { + if (TNetAccept (&vecp, vec, 0, NULLFD, NULLFD, NULLFD, NOTOK, td) + == NOTOK) { + if (td -> td_cc > 0) + adios (NULLCP, "TNetAccept: [%s] %*.*s", TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data); + else + adios (NULLCP, "TNetAccept: [%s]", TErrString (td -> td_reason)); + } + + if (vecp > 0) + break; + } + + if (SInit (vecp, vec, ss, si) == NOTOK) + adios (NULLCP, "S-CONNECT.INDICATION: %s", SErrString (sa -> sa_reason)); + advise (LLOG_NOTICE, NULLCP, + "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>", + ss -> ss_sd, sprintref (&ss -> ss_connect), + saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called), + sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn, + ss -> ss_ssdusize); + + /* stop listening, we have what we want */ + (void) TNetClose (NULLTA, td); + + bzero ((char *) sbi, sizeof *sbi); + sbi -> sb_sd = ss -> ss_sd; + sbi -> sb_connect = ss -> ss_connect; /* struct copy */ + sbi -> sb_requirements = ss -> ss_requirements & SR_BASUBSET; + sbi -> sb_settings = ss -> ss_settings; +#define dotoken(requires,shift,bit,type) \ +{ \ + if (sbi -> sb_requirements & requires) \ + switch (sbi -> sb_settings & (ST_MASK << shift)) { \ + case ST_CALL_VALUE << shift: \ + sbi -> sb_settings &= ~(ST_MASK << shift); \ + sbi -> sb_settings |= ST_INIT_VALUE << shift; \ + break; \ + \ + case ST_INIT_VALUE: \ + break; \ + \ + case ST_RESP_VALUE: \ + sbi -> sb_owned |= bit; \ + break; \ + \ + default: \ + adios (NULLCP, "%s token: reserved", type); \ + break; \ + } \ +} + dotokens (); +#undef dotoken + sbi -> sb_ssn = sbi -> sb_isn = ss -> ss_isn; + + SSFREE (ss); + + if (SConnResponse (sbi -> sb_sd, &sbi -> sb_connect, NULLSA, SC_ACCEPT, + sbi -> sb_requirements, sbi -> sb_settings, sbi -> sb_isn, + NULLCP, 0, si) == NOTOK) + adios (NULLCP, "S-CONNECT.RESPONSE: %s", SErrString (sa -> sa_reason)); + +/* do work here */ + + switch (SReadRequest (sbi -> sb_sd, sx, secs, si)) { + case NOTOK: + adios (NULLCP, "S-READ.REQUEST: %s", SErrString (sa -> sa_reason)); + + case OK: + adios (NULLCP, "not expecting DATA indication 0x%x", sx -> sx_type); + + case DONE: + if (si -> si_type != SI_FINISH) + adios (NULLCP, "not expecting indication 0x%x", si -> si_type); + if (SRelResponse (sbi -> sb_sd, SC_ACCEPT, NULLCP, 0, si) == NOTOK) + adios (NULLCP, "S-RELEASE.RESPONSE: %s", SErrString (sa -> sa_reason)); + break; + } + + exit (0); +} diff --git a/usr/src/contrib/isode/others/listen/listen.h b/usr/src/contrib/isode/others/listen/listen.h new file mode 100644 index 0000000000..18ca5a1239 --- /dev/null +++ b/usr/src/contrib/isode/others/listen/listen.h @@ -0,0 +1,51 @@ +/* listen.h - listen demo definitions */ + +/* + * $Header: /f/osi/others/listen/RCS/listen.h,v 7.1 91/02/22 09:27:27 mrose Interim $ + * + * + * $Log: listen.h,v $ + * Revision 7.1 91/02/22 09:27:27 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:00:19 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "psap2.h" +#include "ssap.h" +#include "tsap.h" +#include "logger.h" + +#define RMASK \ + "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\ +\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA" + + +typedef struct sblk { + int sb_sd; /* session-descriptor */ + + struct SSAPref sb_connect; /* session connection reference */ + + int sb_requirements; /* session requirements */ + int sb_settings; /* initial settings */ + int sb_owned; /* session tokens we own */ + + long sb_ssn; /* session serial number */ + long sb_isn; /* initial serial number */ +} *SB; + + +void adios (), advise (); diff --git a/usr/src/contrib/isode/others/listen/make b/usr/src/contrib/isode/others/listen/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/listen/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/lookup/Makefile b/usr/src/contrib/isode/others/lookup/Makefile new file mode 100644 index 0000000000..cbe9fe4fe4 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/Makefile @@ -0,0 +1,193 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE password lookup demo +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/lookup/RCS/Makefile,v 7.4 91/02/22 09:27:29 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.4 91/02/22 09:27:29 mrose +# Interim 6.8 +# +# Revision 7.3 90/12/23 18:44:24 mrose +# update +# +# Revision 7.2 90/10/29 18:40:18 mrose +# updates +# +# Revision 7.1 90/07/01 21:04:24 mrose +# pepsy +# +# Revision 7.0 89/11/23 22:56:32 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Options +############################################################################### + +BINDIR = /usr/new/ + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +PEPYPATH= -DPEPYPATH + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = ryinitiator.h ryresponder.h +CFILES = lookupd.c lookup.c ryinitiator.c ryresponder.c +RYFILES = lookup.ry + + +################################################################## +# Here it is... +################################################################## + +all: lookupd lookup +inst-all: inst-lookupd inst-lookup manuals +install: inst-all clean +lint: l-lookupd l-lookup + + +################################################################## +# lookupd +################################################################## + +inst-lookupd: $(SBINDIR)ros.lookup + +$(SBINDIR)ros.lookup: lookupd + -cp $@ zros.lookup + -rm -f $@ + cp lookupd $@ + -@ls -gls $@ + -@echo "" + +lookupd: lookupd.o PasswordLookup-Rops.o ryresponder.o \ + PasswordLookup_tables.o + $(LDCC) $(LDFLAGS) -o $@ lookupd.o \ + PasswordLookup-Rops.o ryresponder.o \ + PasswordLookup_tables.o $(LIBES) $(LSOCKET) + +l-lookupd: PasswordLookup-ops.c PasswordLookup_tables.c true + $(LINT) $(LFLAGS) -DPERFORMER lookupd.c \ + PasswordLookup-ops.c ryresponder.c \ + PasswordLookup_tables.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +lookupd.o: ryresponder.h PasswordLookup-ops.h \ + PasswordLookup-types.h + +PasswordLookup-Rops.o: PasswordLookup-ops.c PasswordLookup-ops.h + $(CC) $(CFLAGS) -DPERFORMER -c PasswordLookup-ops.c + mv PasswordLookup-ops.o $@ + +ryresponder.o: ryresponder.h + + +################################################################## +# lookup +################################################################## + +inst-lookup: $(BINDIR)lookup + +$(BINDIR)lookup: lookup + -cp $@ zlookup + -rm -f $@ + cp lookup $@ + -@ls -gls $@ + -@echo "" + +lookup: lookup.o PasswordLookup-Iops.o ryinitiator.o \ + PasswordLookup_tables.o + $(LDCC) $(LDFLAGS) -o $@ lookup.o PasswordLookup-Iops.o \ + ryinitiator.o PasswordLookup_tables.o $(LIBES) \ + $(LSOCKET) + +l-lookup: PasswordLookup-ops.c PasswordLookup_tables.c true + $(LINT) $(LFLAGS) -DINVOKER lookup.c PasswordLookup-ops.c \ + ryinitiator.c PasswordLookup-stubs.c \ + PasswordLookup-tables.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +lookup.o: ryinitiator.h PasswordLookup-ops.h PasswordLookup-types.h + +PasswordLookup-Iops.o: PasswordLookup-ops.c PasswordLookup-ops.h + $(CC) $(CFLAGS) -DINVOKER -c PasswordLookup-ops.c + mv PasswordLookup-ops.o $@ + +ryinitiator.o: ryinitiator.h + + +################################################################ +# liblookup +################################################################ + +PasswordLookup_tables.o: PasswordLookup_tables.c PasswordLookup-types.h + +PasswordLookup_tables.c PasswordLookup-types.h: PasswordLookup-asn.py \ + $(TOPDIR)pepsy/xpepsy + $(TOPDIR)pepsy/xpepsy -A -f -h -m PasswordLookup-asn.py + +PasswordLookup-asn.py: lookup.ry $(TOPDIR)rosy/xrosy + $(TOPDIR)rosy/xrosy -m -pepsy -o $@ lookup.ry +PasswordLookup-ops.c: lookup.ry +PasswordLookup-ops.h: lookup.ry +PasswordLookup-stubs.c: lookup.ry + + +################################################################ +# manual pages +################################################################ + +MANUALS = lookupd.8c lookup.1c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a PasswordLookup* lookupd lookup z* _* core + +grind:; iprint READ-ME Makefile + tgrind -lc $(HFILES) $(CFILES) + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(RYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/others/lookup/READ-ME b/usr/src/contrib/isode/others/lookup/READ-ME new file mode 100644 index 0000000000..3eef83acdd --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/READ-ME @@ -0,0 +1,5 @@ +[ READ-ME - Sun Feb 14 08:11:18 1988 - ISODE password lookup demo notes - /mtr ] + + + This is just a simple demonstration of the use of the Applications + Cookbook. diff --git a/usr/src/contrib/isode/others/lookup/lookup.1c b/usr/src/contrib/isode/others/lookup/lookup.1c new file mode 100644 index 0000000000..6ff4fbc159 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/lookup.1c @@ -0,0 +1,59 @@ +.TH LOOKUP 1C "03 Jul 1988" +.\" $Header: /f/osi/others/lookup/RCS/lookup.1c,v 7.1 91/02/22 09:27:31 mrose Interim $ +.\" +.\" +.\" $Log: lookup.1c,v $ +.\" Revision 7.1 91/02/22 09:27:31 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:56:35 mrose +.\" Release 6.0 +.\" +.SH NAME +lookup \- password lookup service -- initiator +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B lookup +host +\%[operation\0[\0arguments\0...\0]\0] +.in -.5i +.SH DESCRIPTION +The \fIlookup\fR program requests an operation from the password +lookup service provided by a server using remote operations. +The currently supported operations are: +.sp +.in +.5i +.nf +.ta \w'\fBlookupUser\fR 'u +\fIoperation\fR \fIdescription\fR +\fBlookupUser\fR lookup based on user-name +\fBlookupUID\fR lookup based on user-ID +.re +.fi +.in -.5i +.sp +This program is provided primarily as an example of how one can use +\fIThe Application Cookbook\fR to write programs which use remote operations. +It initiates remote operations to the \*(lqisode passwd lookup +demo\*(rq service. +.PP +If no operation is given on the command line, +then \fIlookup\fR enters interactive mode: +\fIlookup\fR will examine each line of the standard\-input, +treating the first word as the operation, and any remaining words as +arguments. +.PP +The pseudo\-operations \fIhelp\fR and \fIquit\fR do the obvious things. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/others/lookup/lookup.c b/usr/src/contrib/isode/others/lookup/lookup.c new file mode 100644 index 0000000000..d5eda838e8 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/lookup.c @@ -0,0 +1,253 @@ +/* lookup.c - password lookup service -- initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/lookup/RCS/lookup.c,v 7.2 91/02/22 09:27:32 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/lookup/RCS/lookup.c,v 7.2 91/02/22 09:27:32 mrose Interim $ + * + * + * $Log: lookup.c,v $ + * Revision 7.2 91/02/22 09:27:32 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:04:26 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:56:36 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "PasswordLookup-types.h" /* type definitions */ +#include "ryinitiator.h" /* for generic interctive initiators */ +#include "PasswordLookup-ops.h" /* operation definitions */ + +/* DATA */ + +static char *myservice = "passwdstore"; + +static char *mycontext = "isode passwd lookup demo"; +static char *mypci = "isode passwd lookup demo pci"; + + + /* ARGUMENTS */ +int do_lookupUser (), do_lookupUID (), do_help (), do_quit (); + + /* RESULTS */ +int lookup_result (); + + /* ERRORS */ +int lookup_error (); + + +static struct dispatch dispatches[] = { + "lookupUser", operation_PasswordLookup_lookupUser, + do_lookupUser, &_ZPasswordLookup_mod, _ZUserNamePasswordLookup, + lookup_result, lookup_error, + "find user by name", + + "lookupUID", operation_PasswordLookup_lookupUID, + do_lookupUID, &_ZPasswordLookup_mod, _ZUserIDPasswordLookup, + lookup_result, lookup_error, + "find user by id", + + "help", 0, + do_help, (modtyp *) 0, 0, + NULLIFP, NULLIFP, + "print this information", + + "quit", 0, + do_quit, (modtyp *) 0, 0, + NULLIFP, NULLIFP, + "terminate the association and exit", + + NULL +}; + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + (void) ryinitiator (argc, argv, myservice, mycontext, mypci, + table_PasswordLookup_Operations, dispatches, do_quit); + + exit (0); /* NOTREACHED */ +} + +/* ARGUMENTS */ + +/* ARGSUSED */ + +static int do_lookupUser (sd, ds, args, arg) +int sd; +struct dispatch *ds; +char **args; +register struct type_PasswordLookup_UserName **arg; +{ + char *cp; + + if ((cp = *args++) == NULL) { + advise (NULLCP, "usage: lookupUser username"); + return NOTOK; + } + + if ((*arg = str2qb (cp, strlen (cp), 1)) == NULL) + adios (NULLCP, "out of memory"); + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int do_lookupUID (sd, ds, args, arg) +int sd; +struct dispatch *ds; +char **args; +register struct type_PasswordLookup_UserID **arg; +{ + char *cp; + + if ((cp = *args++) == NULL) { + advise (NULLCP, "usage: lookupUID userid"); + return NOTOK; + } + + if ((*arg = (struct type_PasswordLookup_UserID *) calloc (1, sizeof **arg)) + == NULL) + adios (NULLCP, "out of memory"); + + (*arg) -> parm = atoi (cp); + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int do_help (sd, ds, args, dummy) +int sd; +register struct dispatch *ds; +char **args; +caddr_t *dummy; +{ + printf ("\nCommands are:\n"); + for (ds = dispatches; ds -> ds_name; ds++) + printf ("%s\t%s\n", ds -> ds_name, ds -> ds_help); + + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +static int do_quit (sd, ds, args, dummy) +int sd; +struct dispatch *ds; +char **args; +caddr_t *dummy; +{ + struct AcSAPrelease acrs; + register struct AcSAPrelease *acr = &acrs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + + if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) == NOTOK) + acs_adios (aca, "A-RELEASE.REQUEST"); + + if (!acr -> acr_affirmative) { + (void) AcUAbortRequest (sd, NULLPEP, 0, aci); + adios (NULLCP, "release rejected by peer: %d", acr -> acr_reason); + } + + ACRFREE (acr); + + exit (0); +} + +/* RESULTS */ + +/* ARGSUSED */ + +static int lookup_result (sd, id, dummy, result, roi) +int sd, + id, + dummy; +register struct type_PasswordLookup_Passwd *result; +struct RoSAPindication *roi; +{ + print_qb (result -> name); + putchar (':'); + print_qb (result -> passwd); + printf (":%d:%d:", result -> uid -> parm, result -> gid -> parm); + print_qb (result -> gecos); + putchar (':'); + print_qb (result -> dir); + putchar (':'); + print_qb (result -> shell); + putchar ('\n'); + + return OK; +} + + +static print_qb (q) +register struct qbuf *q; +{ + register struct qbuf *p; + + if (q == NULL) + return; + + for (p = q -> qb_forw; p != q; p = p -> qb_forw) + printf ("%*.*s", p -> qb_len, p -> qb_len, p -> qb_data); +} + +/* ERRORS */ + +/* ARGSUSED */ + +static int lookup_error (sd, id, error, parameter, roi) +int sd, + id, + error; +caddr_t parameter; +struct RoSAPindication *roi; +{ + register struct RyError *rye; + + if (error == RY_REJECT) { + advise (NULLCP, "%s", RoErrString ((int) parameter)); + return OK; + } + + if (rye = finderrbyerr (table_PasswordLookup_Errors, error)) + advise (NULLCP, "%s", rye -> rye_name); + else + advise (NULLCP, "Error %d", error); + + return OK; +} diff --git a/usr/src/contrib/isode/others/lookup/lookup.ry b/usr/src/contrib/isode/others/lookup/lookup.ry new file mode 100644 index 0000000000..9f79bc8f8d --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/lookup.ry @@ -0,0 +1,109 @@ +-- lookup.ry - the ISODE password lookup demo + +-- $Header: /f/osi/others/lookup/RCS/lookup.ry,v 7.1 91/02/22 09:27:33 mrose Interim $ +-- +-- +-- $Log: lookup.ry,v $ +-- Revision 7.1 91/02/22 09:27:33 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:56:37 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +PasswordLookup DEFINITIONS ::= + +BEGIN + +-- operations + + -- given a user name, return a Passwd type +lookupUser OPERATION + ARGUMENT UserName + RESULT Passwd + ERRORS { noSuchUser, congested } + ::= 0 + + -- given a user ID, return a Passwd type +lookupUID OPERATION + ARGUMENT UserID + RESULT Passwd + ERRORS { noSuchUser, congested } + ::= 1 + + +-- errors + + -- no matching user in the database +noSuchUser ERROR + ::= 0 + + -- congestion at responder +congested ERROR + ::= 1 + + +-- types + + -- similar to an entry in +Passwd ::= + [APPLICATION 1] + IMPLICIT SEQUENCE { + name[0] + IMPLICIT UserName, + + passwd[1] + IMPLICIT IA5String + OPTIONAL, + + uid[2] + IMPLICIT UserID, + + gid[3] + IMPLICIT GroupID, + + quota[4] + IMPLICIT INTEGER + DEFAULT 0, + + comment[5] + IMPLICIT IA5String + OPTIONAL, + + gecos[6] + IMPLICIT IA5String + OPTIONAL, + + dir[7] + IMPLICIT IA5String + OPTIONAL, + + shell[8] + IMPLICIT IA5String + OPTIONAL + } + +UserName ::= + [APPLICATION 2] + IMPLICIT GraphicString + +UserID ::= + [APPLICATION 3] + IMPLICIT INTEGER + +GroupID ::= + [APPLICATION 4] + IMPLICIT INTEGER + +END diff --git a/usr/src/contrib/isode/others/lookup/lookupd.8c b/usr/src/contrib/isode/others/lookup/lookupd.8c new file mode 100644 index 0000000000..c0f3484853 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/lookupd.8c @@ -0,0 +1,58 @@ +.TH LOOKUPD 8C "03 Jul 1988" +.\" $Header: /f/osi/others/lookup/RCS/lookupd.8c,v 7.1 91/02/22 09:27:34 mrose Interim $ +.\" +.\" +.\" $Log: lookupd.8c,v $ +.\" Revision 7.1 91/02/22 09:27:34 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:56:38 mrose +.\" Release 6.0 +.\" +.SH NAME +lookupd \- password lookup service -- responder +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDros.lookup +\fImagic\0arguments\fR +.in -.5i +(under \fI\*(SDtsapd\fR\0) +.SH DESCRIPTION +The \fIlookupd\fR server implements a password lookup service using +remote operations. +The currently supported operations are: +.sp +.in +.5i +.nf +.ta \w'\fBlookupUser\fR 'u +\fIoperation\fR \fIdescription\fR +\fBlookupUser\fR lookup based on user-name +\fBlookupUID\fR lookup based on user-ID +.re +.fi +.in -.5i +.sp +This program is provided primarily as an example of how one can use +\fIThe Applications Cookbook\fR to write programs which use remote operations. +Formally, +it is known as the \*(lqpasswdstore\*(rq, +responding with the \*(lqisode password lookup demo\*(rq application +context utilizing the \*(lqisode password lookup demo pci\*(rq +presentation context. +.PP +This program is not invoked directly by the user, +rather the \fItsapd\fR\0(8c) daemon starts this in response to a request to +associated with the isode image service. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/others/lookup/lookupd.c b/usr/src/contrib/isode/others/lookup/lookupd.c new file mode 100644 index 0000000000..610bdf0c3f --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/lookupd.c @@ -0,0 +1,227 @@ +/* lookupd.c - password lookup service -- responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/lookup/RCS/lookupd.c,v 7.2 91/02/22 09:27:35 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/lookup/RCS/lookupd.c,v 7.2 91/02/22 09:27:35 mrose Interim $ + * + * + * $Log: lookupd.c,v $ + * Revision 7.2 91/02/22 09:27:35 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:39:50 mrose + * sync + * + * Revision 7.0 89/11/23 22:56:39 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "ryresponder.h" /* for generic idempotent responders */ +#include "PasswordLookup-ops.h" /* operation definitions */ +#include "PasswordLookup-types.h" /* type definitions */ + + +#define xalloc(p, type) \ + ((p) = (type) calloc (1, sizeof *(p))) + +#define salloc(s) \ + str2qb ((s), strlen (s), 1) + + +#ifdef SYS5 +struct passwd *getpwnam (), *getpwuid (); +#endif + +/* DATA */ + +static char *myservice = "passwdstore"; + +static char *mycontext = "isode passwd lookup demo"; + + + /* OPERATIONS */ +int op_lookupUser (), op_lookupUID (); + +static struct dispatch dispatches[] = { + "lookupUser", operation_PasswordLookup_lookupUser, op_lookupUser, + + "lookupUID", operation_PasswordLookup_lookupUID, op_lookupUID, + + NULL +}; + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + (void) ryresponder (argc, argv, PLocalHostName (), myservice, mycontext, + dispatches, table_PasswordLookup_Operations, + NULLIFP, NULLIFP); + + exit (0); /* NOTREACHED */ +} + +/* OPERATIONS */ + +static int op_lookupUser (sd, ryo, rox, in, roi) +int sd; +struct RyOperation *ryo; +struct RoSAPinvoke *rox; +caddr_t in; +struct RoSAPindication *roi; +{ + int result; + char *cp; + register struct type_PasswordLookup_UserName *arg = + (struct type_PasswordLookup_UserName *) in; + + if (rox -> rox_nolinked == 0) { + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", + sd, ryo -> ryo_name, rox -> rox_linkid); + return ureject (sd, ROS_IP_LINKED, rox, roi); + } + if (debug) + advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", + sd, ryo -> ryo_name); + + if ((cp = qb2str (arg)) == NULL) + result = error (sd, error_PasswordLookup_congested, (caddr_t) NULL, + rox, roi); + else { + result = lookup (sd, getpwnam (cp), rox, roi); + free (cp); + } + + return result; +} + +/* */ + +static int op_lookupUID (sd, ryo, rox, in, roi) +int sd; +struct RyOperation *ryo; +struct RoSAPinvoke *rox; +caddr_t in; +struct RoSAPindication *roi; +{ + register struct type_PasswordLookup_UserID *arg = + (struct type_PasswordLookup_UserID *) in; + + if (rox -> rox_nolinked == 0) { + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", + sd, ryo -> ryo_name, rox -> rox_linkid); + return ureject (sd, ROS_IP_LINKED, rox, roi); + } + if (debug) + advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", + sd, ryo -> ryo_name); + + return lookup (sd, getpwuid (arg -> parm), rox, roi); +} + +/* */ + +static int lookup (sd, pw, rox, roi) +int sd; +struct passwd *pw; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + int result; + + if (pw) { + register struct type_PasswordLookup_Passwd *res = NULL; + + if (xalloc (res, struct type_PasswordLookup_Passwd *) == NULL + || (res -> name = salloc (pw -> pw_name)) == NULL + || (*pw -> pw_passwd + && (res -> passwd = salloc (pw -> pw_passwd)) == NULL) + || xalloc (res -> uid, struct type_PasswordLookup_UserID *) + == NULL + || xalloc (res -> gid, struct type_PasswordLookup_GroupID *) + == NULL + || (pw -> pw_comment + && (res -> comment = salloc (pw -> pw_comment)) + == NULL) + || (pw -> pw_gecos + && (res -> gecos = salloc (pw -> pw_gecos)) == NULL) + || (pw -> pw_dir + && (res -> dir = salloc (pw -> pw_dir)) == NULL) + || (pw -> pw_shell + && (res -> shell = salloc (pw -> pw_shell)) == NULL)) + result = error (sd, error_PasswordLookup_congested, (caddr_t) NULL, + rox, roi); + else { + res -> uid -> parm = pw -> pw_uid; + res -> gid -> parm = pw -> pw_gid; +/* + res -> quota = pw -> pw_quota; + */ + + if (RyDsResult (sd, rox -> rox_id, (caddr_t) res, ROS_NOPRIO, roi) + == NOTOK) + ros_adios (&roi -> roi_preject, "RESULT"); + result = OK; + } + + free_PasswordLookup_Passwd (res); + } + else + result = error (sd, error_PasswordLookup_noSuchUser, (caddr_t) NULL, + rox, roi); + + return result; +} + +/* ERROR */ + +static int error (sd, err, param, rox, roi) +int sd, + err; +caddr_t param; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + if (RyDsError (sd, rox -> rox_id, err, param, ROS_NOPRIO, roi) == NOTOK) + ros_adios (&roi -> roi_preject, "ERROR"); + + return OK; +} + +/* U-REJECT */ + +static int ureject (sd, reason, rox, roi) +int sd, + reason; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + if (RyDsUReject (sd, rox -> rox_id, reason, ROS_NOPRIO, roi) == NOTOK) + ros_adios (&roi -> roi_preject, "U-REJECT"); + + return OK; +} diff --git a/usr/src/contrib/isode/others/lookup/make b/usr/src/contrib/isode/others/lookup/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/lookup/ryinitiator.c b/usr/src/contrib/isode/others/lookup/ryinitiator.c new file mode 100644 index 0000000000..c18d83c235 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/ryinitiator.c @@ -0,0 +1,429 @@ +/* ryinitiator.c - generic interactive initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/lookup/RCS/ryinitiator.c,v 7.6 91/02/22 09:27:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/lookup/RCS/ryinitiator.c,v 7.6 91/02/22 09:27:37 mrose Interim $ + * + * + * $Log: ryinitiator.c,v $ + * Revision 7.6 91/02/22 09:27:37 mrose + * Interim 6.8 + * + * Revision 7.5 90/12/23 18:44:26 mrose + * update + * + * Revision 7.4 90/12/11 10:54:05 mrose + * lock-and-load + * + * Revision 7.3 90/10/29 18:40:21 mrose + * updates + * + * Revision 7.2 90/07/09 14:39:53 mrose + * sync + * + * Revision 7.1 90/07/01 21:04:28 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:56:41 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "PasswordLookup-types.h" +#include "ryinitiator.h" + +/* DATA */ + +static char *myname = "ryinitiator"; + + +extern char *isodeversion; + +/* INITIATOR */ + +ryinitiator (argc, argv, myservice, mycontext, mypci, ops, dispatches, quit) +int argc; +char **argv, + *myservice, + *mycontext, + *mypci; +struct RyOperation ops[]; +struct dispatch *dispatches; +IFP quit; +{ + int iloop, + sd; + char buffer[BUFSIZ], + *vec[NVEC + 1]; + register struct dispatch *ds; + struct SSAPref sfs; + register struct SSAPref *sf; + register struct PSAPaddr *pa; + struct AcSAPconnect accs; + register struct AcSAPconnect *acc = &accs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + AEI aei; + OID ctx, + pci; + struct PSAPctxlist pcs; + register struct PSAPctxlist *pc = &pcs; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + if (argc < 2) + adios (NULLCP, "usage: %s host [operation [ arguments ... ]]", myname); + + if ((aei = _str2aei (argv[1], myservice, mycontext, argc < 3, NULLCP, + NULLCP)) == NULLAEI) + adios (NULLCP, "unable to resolve service: %s", PY_pepy); + if ((pa = aei2addr (aei)) == NULLPA) + adios (NULLCP, "address translation failed"); + + if ((ctx = ode2oid (mycontext)) == NULLOID) + adios (NULLCP, "%s: unknown object descriptor", mycontext); + if ((ctx = oid_cpy (ctx)) == NULLOID) + adios (NULLCP, "out of memory"); + if ((pci = ode2oid (mypci)) == NULLOID) + adios (NULLCP, "%s: unknown object descriptor", mypci); + if ((pci = oid_cpy (pci)) == NULLOID) + adios (NULLCP, "out of memory"); + pc -> pc_nctx = 1; + pc -> pc_ctx[0].pc_id = 1; + pc -> pc_ctx[0].pc_asn = pci; + pc -> pc_ctx[0].pc_atn = NULLOID; + + if ((sf = addr2ref (PLocalHostName ())) == NULL) { + sf = &sfs; + (void) bzero ((char *) sf, sizeof *sf); + } + + if (argc < 3) { + printf ("%s", myname); + if (sf -> sr_ulen > 2) + printf (" running on host %s", sf -> sr_udata + 2); + if (sf -> sr_clen > 2) + printf (" at %s", sf -> sr_cdata + 2); + printf (" [%s, ", oid2ode (ctx)); + printf ("%s]\n", oid2ode (pci)); + printf ("using %s\n", isodeversion); + + printf ("%s... ", argv[1]); + (void) fflush (stdout); + + iloop = 1; + } + else { + for (ds = dispatches; ds -> ds_name; ds++) + if (strcmp (ds -> ds_name, argv[2]) == 0) + break; + if (ds -> ds_name == NULL) + adios (NULLCP, "unknown operation \"%s\"", argv[2]); + + iloop = 0; + } + + if (AcAssocRequest (ctx, NULLAEI, aei, NULLPA, pa, pc, NULLOID, + 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP, 0, NULLQOS, + acc, aci) + == NOTOK) + acs_adios (aca, "A-ASSOCIATE.REQUEST"); + + if (acc -> acc_result != ACS_ACCEPT) { + if (iloop) + printf ("failed\n"); + + adios (NULLCP, "association rejected: [%s]", + AcErrString (acc -> acc_result)); + } + if (iloop) { + printf ("connected\n"); + (void) fflush (stdout); + } + + sd = acc -> acc_sd; + ACCFREE (acc); + + if (RoSetService (sd, RoPService, roi) == NOTOK) + ros_adios (rop, "set RO/PS fails"); + + if (iloop) { + for (;;) { + if (getline (buffer) == NOTOK) + break; + + if (str2vec (buffer, vec) < 1) + continue; + + for (ds = dispatches; ds -> ds_name; ds++) + if (strcmp (ds -> ds_name, vec[0]) == 0) + break; + if (ds -> ds_name == NULL) { + advise (NULLCP, "unknown operation \"%s\"", vec[0]); + continue; + } + + invoke (sd, ops, ds, vec + 1); + } + } + else + invoke (sd, ops, ds, argv + 3); + + (*quit) (sd, (struct dispatch *) NULL, (char **) NULL, (caddr_t *) NULL); +} + +/* */ + +static invoke (sd, ops, ds, args) +int sd; +struct RyOperation ops[]; +register struct dispatch *ds; +char **args; +{ + int result; + caddr_t in; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + in = NULL; + if (ds -> ds_argument && (*ds -> ds_argument) (sd, ds, args, &in) == NOTOK) + return; + + switch (result = RyStub (sd, ops, ds -> ds_operation, RyGenID (sd), NULLIP, + in, ds -> ds_result, ds -> ds_error, ROS_SYNC, + roi)) { + case NOTOK: /* failure */ + if (ROS_FATAL (rop -> rop_reason)) + ros_adios (rop, "STUB"); + ros_advise (rop, "STUB"); + break; + + case OK: /* got a result/error response */ + break; + + case DONE: /* got RO-END? */ + adios (NULLCP, "got RO-END.INDICATION"); + /* NOTREACHED */ + + default: + adios (NULLCP, "unknown return from RyStub=%d", result); + /* NOTREACHED */ + } + + if (ds -> ds_mod && ds -> ds_ind >= 0 && in) + (void) fre_obj (in, ds -> ds_mod -> md_dtab[ds -> ds_ind], + ds -> ds_mod, 1); +} + +/* */ + +static int getline (buffer) +char *buffer; +{ + register int i; + register char *cp, + *ep; + static int sticky = 0; + + if (sticky) { + sticky = 0; + return NOTOK; + } + + printf ("%s> ", myname); + (void) fflush (stdout); + + for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) { + if (i == EOF) { + printf ("\n"); + clearerr (stdin); + if (cp != buffer) { + sticky++; + break; + } + + return NOTOK; + } + + if (cp < ep) + *cp++ = i; + } + *cp = NULL; + + return OK; +} + +/* */ + +void ros_adios (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + ros_advise (rop, event); + + _exit (1); +} + + +void ros_advise (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + char buffer[BUFSIZ]; + + if (rop -> rop_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data); + else + (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason)); + + advise (NULLCP, "%s: %s", event, buffer); +} + +/* */ + +void acs_adios (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + acs_advise (aca, event); + + _exit (1); +} + + +void acs_advise (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + char buffer[BUFSIZ]; + + if (aca -> aca_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + AcErrString (aca -> aca_reason), + aca -> aca_cc, aca -> aca_cc, aca -> aca_data); + else + (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason)); + + advise (NULLCP, "%s: %s (source %d)", event, buffer, + aca -> aca_source); +} + +/* */ + +#ifndef lint +void _advise (); + + +void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + + +#ifndef lint +void ryr_advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} +#else +/* VARARGS */ + +void ryr_advise (what, fmt) +char *what, + *fmt; +{ + ryr_advise (what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/others/lookup/ryinitiator.h b/usr/src/contrib/isode/others/lookup/ryinitiator.h new file mode 100644 index 0000000000..a5d53df210 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/ryinitiator.h @@ -0,0 +1,52 @@ +/* ryinitiator.h - include file for the generic interactive initiator */ + +/* + * $Header: /f/osi/others/lookup/RCS/ryinitiator.h,v 7.2 91/02/22 09:27:39 mrose Interim $ + * + * + * $Log: ryinitiator.h,v $ + * Revision 7.2 91/02/22 09:27:39 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:04:30 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:56:43 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "rosy.h" + + +static struct dispatch { + char *ds_name; + int ds_operation; + + IFP ds_argument; + modtyp *ds_mod; /* pointer to module table */ + int ds_ind; /* Index into module table */ + + IFP ds_result; + IFP ds_error; + + char *ds_help; +}; + + +void adios (), advise (); +void acs_adios (), acs_advise (); +void ros_adios (), ros_advise (); + +int ryinitiator (); diff --git a/usr/src/contrib/isode/others/lookup/ryresponder.c b/usr/src/contrib/isode/others/lookup/ryresponder.c new file mode 100644 index 0000000000..d4fc3ed6cb --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/ryresponder.c @@ -0,0 +1,443 @@ +/* ryresponder.c - generic idempotent responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/lookup/RCS/ryresponder.c,v 7.3 91/02/22 09:27:40 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/lookup/RCS/ryresponder.c,v 7.3 91/02/22 09:27:40 mrose Interim $ + * + * + * $Log: ryresponder.c,v $ + * Revision 7.3 91/02/22 09:27:40 mrose + * Interim 6.8 + * + * Revision 7.2 90/12/11 10:40:05 mrose + * sync + * + * Revision 7.1 90/07/09 14:39:56 mrose + * sync + * + * Revision 7.0 89/11/23 22:56:44 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "ryresponder.h" +#include "tsap.h" /* for listening */ + +/* DATA */ + +int debug = 0; + +static LLog _pgm_log = { + "responder.log", NULLCP, NULLCP, + LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1, + LLOGCLS | LLOGCRT | LLOGZER, NOTOK +}; +LLog *pgm_log = &_pgm_log; + +static char *myname = "ryresponder"; + + +static jmp_buf toplevel; + + +static IFP startfnx; +static IFP stopfnx; + +int ros_init (), ros_work (), ros_indication (), ros_lose (); + + +extern int errno; + +/* RESPONDER */ + +int ryresponder (argc, argv, host, myservice, mycontext, dispatches, ops, + start, stop) +int argc; +char **argv, + *host, + *myservice, + *mycontext; +struct dispatch *dispatches; +struct RyOperation *ops; +IFP start, + stop; +{ + register struct dispatch *ds; + AEI aei; + struct TSAPdisconnect tds; + struct TSAPdisconnect *td = &tds; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + isodetailor (myname, 0); + if (debug = isatty (fileno (stderr))) + ll_dbinit (pgm_log, myname); + else { + static char myfile[BUFSIZ]; + + (void) sprintf (myfile, "%s.log", + (strncmp (myname, "ros.", 4) + && strncmp (myname, "lpp.", 4)) + || myname[4] == NULL + ? myname : myname + 4); + pgm_log -> ll_file = myfile; + ll_hdinit (pgm_log, myname); + } + + advise (LLOG_NOTICE, NULLCP, "starting"); + + if ((aei = str2aei (host, myservice, mycontext, 0)) == NULLAEI) + adios (NULLCP, "unable to resolve service: %s", PY_pepy); + + for (ds = dispatches; ds -> ds_name; ds++) + if (RyDispatch (NOTOK, ops, ds -> ds_operation, ds -> ds_vector, roi) + == NOTOK) + ros_adios (rop, ds -> ds_name); + + startfnx = start; + stopfnx = stop; + + if (isodeserver (argc, argv, aei, ros_init, ros_work, ros_lose, td) + == NOTOK) { + if (td -> td_cc > 0) + adios (NULLCP, "isodeserver: [%s] %*.*s", + TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data); + else + adios (NULLCP, "isodeserver: [%s]", + TErrString (td -> td_reason)); + } + + return 0; +} + +/* */ + +static int ros_init (vecp, vec) +int vecp; +char **vec; +{ + int reply, + result, + sd; + struct AcSAPstart acss; + register struct AcSAPstart *acs = &acss; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + register struct PSAPstart *ps = &acs -> acs_start; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + if (AcInit (vecp, vec, acs, aci) == NOTOK) { + acs_advise (aca, "initialization fails"); + return NOTOK; + } + advise (LLOG_NOTICE, NULLCP, + "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>", + acs -> acs_sd, oid2ode (acs -> acs_context), + sprintaei (&acs -> acs_callingtitle), + sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo); + + sd = acs -> acs_sd; + + for (vec++; *vec; vec++) + advise (LLOG_EXCEPTIONS, NULLCP, "unknown argument \"%s\"", *vec); + + reply = startfnx ? (*startfnx) (sd, acs) : ACS_ACCEPT; + + result = AcAssocResponse (sd, reply, + reply != ACS_ACCEPT ? ACS_USER_NOREASON : ACS_USER_NULL, + NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult, + ps -> ps_prequirements, ps -> ps_srequirements, SERIAL_NONE, + ps -> ps_settings, &ps -> ps_connect, NULLPEP, 0, aci); + + ACSFREE (acs); + + if (result == NOTOK) { + acs_advise (aca, "A-ASSOCIATE.RESPONSE"); + return NOTOK; + } + if (reply != ACS_ACCEPT) + return NOTOK; + + if (RoSetService (sd, RoPService, roi) == NOTOK) + ros_adios (rop, "set RO/PS fails"); + + return sd; +} + +/* */ + +static int ros_work (fd) +int fd; +{ + int result; + caddr_t out; + struct AcSAPindication acis; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + switch (setjmp (toplevel)) { + case OK: + break; + + default: + if (stopfnx) + (*stopfnx) (fd, (struct AcSAPfinish *) 0); + case DONE: + (void) AcUAbortRequest (fd, NULLPEP, 0, &acis); + (void) RyLose (fd, roi); + return NOTOK; + } + + switch (result = RyWait (fd, NULLIP, &out, OK, roi)) { + case NOTOK: + if (rop -> rop_reason == ROS_TIMER) + break; + case OK: + case DONE: + ros_indication (fd, roi); + break; + + default: + adios (NULLCP, "unknown return from RoWaitRequest=%d", result); + } + + return OK; +} + +/* */ + +static int ros_indication (sd, roi) +int sd; +register struct RoSAPindication *roi; +{ + int reply, + result; + + switch (roi -> roi_type) { + case ROI_INVOKE: + case ROI_RESULT: + case ROI_ERROR: + adios (NULLCP, "unexpected indication type=%d", roi -> roi_type); + break; + + case ROI_UREJECT: + { + register struct RoSAPureject *rou = &roi -> roi_ureject; + + if (rou -> rou_noid) + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-REJECT-U.INDICATION/%d: %s", + sd, RoErrString (rou -> rou_reason)); + else + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-REJECT-U.INDICATION/%d: %s (id=%d)", + sd, RoErrString (rou -> rou_reason), + rou -> rou_id); + } + break; + + case ROI_PREJECT: + { + register struct RoSAPpreject *rop = &roi -> roi_preject; + + if (ROS_FATAL (rop -> rop_reason)) + ros_adios (rop, "RO-REJECT-P.INDICATION"); + ros_advise (rop, "RO-REJECT-P.INDICATION"); + } + break; + + case ROI_FINISH: + { + register struct AcSAPfinish *acf = &roi -> roi_finish; + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION/%d: %d", + sd, acf -> acf_reason); + + reply = stopfnx ? (*stopfnx) (sd, acf) : ACS_ACCEPT; + + result = AcRelResponse (sd, reply, ACR_NORMAL, NULLPEP, 0, + &acis); + + ACFFREE (acf); + + if (result == NOTOK) + acs_advise (aca, "A-RELEASE.RESPONSE"); + else + if (reply != ACS_ACCEPT) + break; + longjmp (toplevel, DONE); + } + /* NOTREACHED */ + + default: + adios (NULLCP, "unknown indication type=%d", roi -> roi_type); + } +} + +/* */ + +static int ros_lose (td) +struct TSAPdisconnect *td; +{ + if (td -> td_cc > 0) + adios (NULLCP, "TNetAccept: [%s] %*.*s", + TErrString (td -> td_reason), td -> td_cc, td -> td_cc, + td -> td_data); + else + adios (NULLCP, "TNetAccept: [%s]", TErrString (td -> td_reason)); +} + +/* ERRORS */ + +void ros_adios (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + ros_advise (rop, event); + + longjmp (toplevel, NOTOK); +} + + +void ros_advise (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + char buffer[BUFSIZ]; + + if (rop -> rop_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data); + else + (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason)); + + advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s", event, buffer); +} + +/* */ + +void acs_advise (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + char buffer[BUFSIZ]; + + if (aca -> aca_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + AcErrString (aca -> aca_reason), + aca -> aca_cc, aca -> aca_cc, aca -> aca_data); + else + (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason)); + + advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s (source %d)", event, buffer, + aca -> aca_source); +} + +/* */ + +#ifndef lint +void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_FATAL, ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS2 */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +void advise (va_alist) +va_dcl +{ + int code; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + _ll_log (pgm_log, code, ap); + + va_end (ap); +} +#else +/* VARARGS3 */ + +void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif + + +#ifndef lint +void ryr_advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_NOTICE, ap); + + va_end (ap); +} +#else +/* VARARGS2 */ + +void ryr_advise (what, fmt) +char *what, + *fmt; +{ + ryr_advise (what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/others/lookup/ryresponder.h b/usr/src/contrib/isode/others/lookup/ryresponder.h new file mode 100644 index 0000000000..f848357012 --- /dev/null +++ b/usr/src/contrib/isode/others/lookup/ryresponder.h @@ -0,0 +1,53 @@ +/* ryresponder.h - include file for the generic idempotent responder */ + +/* + * $Header: /f/osi/others/lookup/RCS/ryresponder.h,v 7.2 91/02/22 09:27:43 mrose Interim $ + * + * + * $Log: ryresponder.h,v $ + * Revision 7.2 91/02/22 09:27:43 mrose + * Interim 6.8 + * + * Revision 7.1 90/12/11 10:40:07 mrose + * sync + * + * Revision 7.0 89/11/23 22:56:46 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#ifndef PEPSY_VERSION +#define PEPSY_VERSION 1 +#endif +#include "rosy.h" +#include "logger.h" + + +static struct dispatch { + char *ds_name; + int ds_operation; + + IFP ds_vector; +}; + + +extern int debug; + + +void adios (), advise (); +void acs_advise (); +void ros_adios (), ros_advise (); +void ryr_advise (); + +int ryresponder (); diff --git a/usr/src/contrib/isode/others/mosy/Makefile b/usr/src/contrib/isode/others/mosy/Makefile new file mode 100644 index 0000000000..483039831e --- /dev/null +++ b/usr/src/contrib/isode/others/mosy/Makefile @@ -0,0 +1,165 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE MOSY processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/mosy/RCS/Makefile,v 7.8 91/02/22 09:28:39 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.8 91/02/22 09:28:39 mrose +# Interim 6.8 +# +# Revision 7.7 90/12/23 18:44:31 mrose +# update +# +# Revision 7.6 90/11/04 19:15:23 mrose +# update +# +# Revision 7.5 90/09/07 17:33:57 mrose +# new-macros +# +# Revision 7.4 90/08/29 12:26:59 mrose +# touch-up +# +# Revision 7.3 90/07/09 14:39:59 mrose +# sync +# +# Revision 7.2 90/07/01 21:04:35 mrose +# pepsy +# +# Revision 7.1 90/01/16 20:43:13 mrose +# last check-out +# +# Revision 7.0 89/11/23 22:00:33 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.SUFFIXES: .c .o + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = mosy-defs.h +YFILES = yacc.y lex.l + + +################################################################## +# Here it is... +################################################################## + +all: mosy +inst-all: inst-mosy manuals +install: inst-all clean +lint: l-mosy + + +################################################################## +# mosy +################################################################## + +inst-mosy: $(BINDIR)mosy + +$(BINDIR)mosy: xmosy + -cp $@ zxmosy + -rm -f $@ + cp xmosy $@ + -@ls -gls $@ + -@echo "" + +mosy: xmosy + +xmosy: mosyvrsn.o + $(LDCC) $(LDFLAGS) -o $@ mosy.o yacc.o pepy_misc.o mosyvrsn.o \ + $(LIBES) $(LSOCKET) -lm + +mosy.o: mosy.c $(HFILES) + +pepy_misc.o: $(TOPDIR)pepy/pepy_misc.c + $(CC) $(CFLAGS) -c $? + +mosyvrsn.c: mosy.o yacc.o pepy_misc.o + @$(UTILDIR)version.sh mosy > $@ + +yacc.o: yacc.c lex.c $(HFILES) + +yacc.c: yacc.y + -@echo "expect 21 shift/reduce and 9 reduce/reduce conflicts" + yacc $(YACCFLAGS) yacc.y + mv y.tab.c $@ + +yacc.y: $(TOPDIR)pepy/yacc.y.gnrc + $(UTILDIR)extract.sh MOSY < $? > $@ + +lex.c: lex.l + $(LEX) $(LEXFLAGS) lex.l + mv lex.yy.c $@ + +lex.l: $(TOPDIR)pepy/lex.l.gnrc + $(UTILDIR)extract.sh MOSY < $? > $@ + +mosy-defs.h: $(TOPDIR)pepsy/pepsy.h.gnrc + $(UTILDIR)extract.sh MOSY < $? > $@ + +l-mosy: yacc.c lex.c true + $(LINT) -I$(TOPDIR)h $(LFLAGS) mosy.c yacc.c \ + $(TOPDIR)pepy/pepy_misc.c mosyvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# manual pages +################################################################ + +MANUALS = mosy.1 + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a x* z* _* core mosy-defs.h yacc.y yacc.c lex.l \ + lex.c mosyvrsn.c *.defs + +grind:; iprint Makefile + tgrind -lc $(HFILES) mosy.c mosyvrsn.c + tgrind -ly $(YFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/others/mosy/make b/usr/src/contrib/isode/others/mosy/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/mosy/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/mosy/mosy.1 b/usr/src/contrib/isode/others/mosy/mosy.1 new file mode 100644 index 0000000000..b04909728e --- /dev/null +++ b/usr/src/contrib/isode/others/mosy/mosy.1 @@ -0,0 +1,55 @@ +.TH MOSY 1 "15 May 1988" +.\" $Header: /f/osi/others/mosy/RCS/mosy.1,v 7.2 91/02/22 09:28:41 mrose Interim $ +.\" Contributed by NYSERNet Inc. This work was partially supported by the +.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development +.\" Center of the U.S. Air Force Systems Command under contract number +.\" F30602-88-C-0016. +.\" +.\" +.\" +.\" $Log: mosy.1,v $ +.\" Revision 7.2 91/02/22 09:28:41 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/10/18 11:33:30 mrose +.\" psi +.\" +.\" Revision 7.0 89/11/23 22:00:37 mrose +.\" Release 6.0 +.\" +.SH NAME +mosy - Managed Object Syntax-compiler (yacc-based) +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B mosy +\%[\-o\0module.defs] +\%[\-s] +\fImodule.my\fR +.in -.5i +.SH DESCRIPTION +The \fImosy\fR program reads a description of a \fImanaged objects\fR +module and produces a simple ascii file containing equivalent definitions. +This file is meant to be read as configuration data by a network +management program. +.PP +The `\-o' switch sets the name of the output file, +which is normally derived from the name of the input file. +The distinguished file \*(lq\-\*(rq can be used to force the use of the +standard output. +.PP +Normally, \fImosy\fR prints the name of each object, identifier, or type +as it works. +The `\-s' switch disables this behavior. +.SH "SEE ALSO" +pepy(1), +.br +\fIThe ISO Development Environment: User's Manual\fR, +.SH AUTHOR +Marshall T. Rose, +Performance Systems International +.PP +This work was partially supported by the +U.S. Defense Advanced Research Projects Agency and the Rome Air Development +Center of the U.S. Air Force Systems Command under contract number +F30602-88-C-0016. diff --git a/usr/src/contrib/isode/others/osilookup/Makefile b/usr/src/contrib/isode/others/osilookup/Makefile new file mode 100644 index 0000000000..6f657e04b5 --- /dev/null +++ b/usr/src/contrib/isode/others/osilookup/Makefile @@ -0,0 +1,98 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE/SunLink osilookup program +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/osilookup/RCS/Makefile,v 7.2 91/02/22 09:28:45 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.2 91/02/22 09:28:45 mrose +# Interim 6.8 +# +# Revision 7.1 90/12/23 18:44:33 mrose +# update +# +# Revision 7.0 89/11/23 22:00:57 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = +LLIBS = + + +############################################################################### +# Files +############################################################################### + +HFILES = +CFILES = osilookup.c + + +################################################################## +# Here it is... +################################################################## + +all: osilookup +inst-all: inst-osilookup +install: inst-all clean +lint: l-osilookup + + +################################################################## +# osilookup +################################################################## + +inst-osilookup: $(SBINDIR)osilookup + +$(SBINDIR)osilookup: xosilookup + -cp $@ zxosilookup + -rm -f $@ + cp xosilookup $@ + -@ls -gls $@ + -@echo "" + +osilookup: xosilookup + +xosilookup: osilookup.o + $(LDCC) $(LDFLAGS) -o $@ osilookup.o $(LIBES) $(LSOCKET) + +l-osilookup:; $(LINT) $(LFLAGS) osilookup.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################## +# clean +################################################################## + +clean:; rm -f *.o x* z* _* core + +grind:; iprint Makefile + tgrind -lc $(HFILES) $(CFILES) + +true:; diff --git a/usr/src/contrib/isode/others/osilookup/READ-ME b/usr/src/contrib/isode/others/osilookup/READ-ME new file mode 100644 index 0000000000..2f7aae3f04 --- /dev/null +++ b/usr/src/contrib/isode/others/osilookup/READ-ME @@ -0,0 +1,8 @@ +[ READ-ME - Mon Oct 30 12:44:01 1989 - ISODE/SunLink OSI notes - /mtr ] + + + This program is used to convert entries from the /usr/etc/osi.hosts file + into network addresses formatted for the isoentities file. + + Note that in SunLink OSI 6.0 and later, the osi.hosts file is called + /etc/sunlink/osi/hosts diff --git a/usr/src/contrib/isode/others/osilookup/make b/usr/src/contrib/isode/others/osilookup/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/osilookup/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/osilookup/osilookup.c b/usr/src/contrib/isode/others/osilookup/osilookup.c new file mode 100644 index 0000000000..5d3b9afb46 --- /dev/null +++ b/usr/src/contrib/isode/others/osilookup/osilookup.c @@ -0,0 +1,126 @@ +/* osilookup.c - convert entry in /etc/osi.hosts to isoentities format */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/osilookup/RCS/osilookup.c,v 7.1 91/02/22 09:28:48 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/osilookup/RCS/osilookup.c,v 7.1 91/02/22 09:28:48 mrose Interim $ + * + * Contributed by John A. Scott, the MITRE Corporation + * + * N.B.: I whipped up this code quickly to fill a need I had. I + * do not, it any way, shape, or form, warrant its output. + * + * + * $Log: osilookup.c,v $ + * Revision 7.1 91/02/22 09:28:48 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:00 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "config.h" +#include +#include +#include +#ifndef SUNLINK_6_0 +#include +#else +#include +#endif +#include +#include +#include + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int len, + paddr_type; + char *prefix, + *service, + buf[BUFSIZ], + buf2[BUFSIZ]; + OSI_ADDR p_addr; + + if (argc < 2) { + fprintf (stderr,"usage: %s host [service]\n", argv[0]); + exit (0); + } + service = (argc > 2) ? argv[2] : "FTAM"; + + /* SUNLink OSI directory lookup */ + mds_lookup (argv[1], service, &p_addr); + + /* SUNLink function to slice out SAP bytes from full address */ + paddr_type = 0; + if ((len = osi_get_sap (&p_addr, buf, sizeof buf, OSI_NSAP, &paddr_type)) + <= 0) { + fprintf (stderr, "no entry for %s %s\n", argv[1], service); + exit (1); + } + + buf2[explode (buf2, (u_char *) buf, len)]= NULL; + switch (paddr_type) { + case AF_NBS: + prefix = "49"; + break; + + case AF_OSINET: + prefix = "470004"; + break; + + default: + prefix = ""; + break; + } + printf ("\t\t\t\tNS+%s%s\n\n", prefix, buf2); + + exit (0); +} + +/* so we don't have to load libisode.a */ + +static char nib2hex[0x10] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; + + +static int explode (a, b, n) +register char *a; +register u_char *b; +register int n; +{ + register int i; + register u_char c; + + for (i = 0; i < n; i++) { + c = *b++; + *a++ = nib2hex[(c & 0xf0) >> 4]; + *a++ = nib2hex[(c & 0x0f)]; + } + *a = NULL; + + return (n * 2); +} diff --git a/usr/src/contrib/isode/others/pingpong/Makefile b/usr/src/contrib/isode/others/pingpong/Makefile new file mode 100644 index 0000000000..dc7037a514 --- /dev/null +++ b/usr/src/contrib/isode/others/pingpong/Makefile @@ -0,0 +1,52 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE xSAP processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/pingpong/RCS/Makefile,v 7.2 91/02/22 09:28:49 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.2 91/02/22 09:28:49 mrose +# Interim 6.8 +# +# Revision 7.1 90/12/23 18:44:35 mrose +# update +# +# Revision 7.0 89/11/23 22:01:08 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + +all: pingpong +inst-all: +install: +lint: l-pingpong + +pingpong: xpingpong + +xpingpong: pingpong.o + $(LDCC) -o $@ pingpong.o $(LIBES) $(LSOCKET) + +l-pingpong:; $(LINT) $(LFLAGS) pingpong.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +clean:; rm -f x* z* _* *.o core diff --git a/usr/src/contrib/isode/others/pingpong/READ-ME b/usr/src/contrib/isode/others/pingpong/READ-ME new file mode 100644 index 0000000000..b55d5f441d --- /dev/null +++ b/usr/src/contrib/isode/others/pingpong/READ-ME @@ -0,0 +1,18 @@ +[ READ-ME - Mon Nov 6 08:01:30 1989 - pingpong notes - jpo ] + +This is a simple demonstration of asynchronous connection +establishment. It runs as follows. + + pingpong address1 address2 + +If both addresses are the same it will connect to itself and then +exit. If the addresses are different then it is intended that two +pingpong's are run to allow interconnection with each other. It is +useful both as a simple example of the way to form asynchronous +connections and as a useful way to test that these connections work. + +NOTE: This is not the full story, if you are using services above +transport (the usual case) you will need to add a magic parameter to +the TNetListen call to allow fully async establishment. + + diff --git a/usr/src/contrib/isode/others/pingpong/make b/usr/src/contrib/isode/others/pingpong/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/pingpong/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/pingpong/pingpong.c b/usr/src/contrib/isode/others/pingpong/pingpong.c new file mode 100644 index 0000000000..5efa4cdc52 --- /dev/null +++ b/usr/src/contrib/isode/others/pingpong/pingpong.c @@ -0,0 +1,304 @@ +/* pingpong.c - listen and call out at the same time */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/pingpong/RCS/pingpong.c,v 7.1 91/02/22 09:28:52 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/pingpong/RCS/pingpong.c,v 7.1 91/02/22 09:28:52 mrose Interim $ + * + * + * $Log: pingpong.c,v $ + * Revision 7.1 91/02/22 09:28:52 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:11 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include + +struct PSAPaddr * pingaddr; +struct PSAPaddr * pongaddr; +int cn_state = NOTOK; +int cn_sd = NOTOK; + +fd_set wfds, rfds; +int nfds = 0; +int doneit = 0; +int retry = 1; + +main (argc,argv) +int argc; +char ** argv; +{ + + do_args (argc,argv); + + start_listener (); + + printf ("Started to listen\n"); + + ping_address (); + + wait_for_result (); + + printf ("Got Result\n"); + + stop_nicely (); +} + +do_args (argc,argv) +int argc; +char ** argv; +{ + char * myname; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + if (argc != 3) { + (void) fprintf (stderr,"Usage pingpong listen_address call_address\n"); + exit (-1); + } + + isodetailor (myname, 0); + + if ((pongaddr = str2paddr (argv[1])) == NULLPA) { + (void) fprintf (stderr,"Invalid listen address %s\n", argv[1]); + exit (-1); + } + + if ((pingaddr = str2paddr (argv[2])) == NULLPA) { + (void) fprintf (stderr,"Invalid call address %s\n", argv[2]); + exit (-1); + } +} + + +start_listener () +{ + struct TSAPdisconnect td_s; + struct TSAPdisconnect * td = &(td_s); + + if(TNetListen(&pongaddr->pa_addr.sa_addr, td) == NOTOK) { + ts_advise ("TNetListen", td); + exit (-2); + } +} + +ping_address () +{ + struct TSAPstart tss; + register struct TSAPstart *ts = &tss; + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + struct TSAPconnect tcs; + struct TSAPconnect *tc = &tcs; + + cn_state = TAsynConnRequest (NULLTA, &pingaddr->pa_addr.sa_addr, 0, + NULLCP, ts -> ts_cc, &ts -> ts_qos, + tc, td, 1); + + cn_sd = tc -> tc_sd; + printf ("Starting ping on %d state ", cn_sd); + updatemask (); + if (cn_state == NOTOK) + ts_advise ("TAsynConnRequest", td); + else + retry = 0; +} + + +wait_for_result () +{ + int vecp = 0; + char *vec[4]; + int i; + struct TSAPdisconnect td_s; + struct TSAPdisconnect *td = &td_s; + struct TSAPconnect tcs; + struct TSAPconnect *tc = &tcs; + struct TSAPstart tss; + struct TSAPstart *ts = &tss; + fd_set ifds, ofds; + + for (;;) { + + ifds = rfds; + ofds = wfds; + printf ("TNetAccept nfds=%d rfds=0x%x wfds=0x%x\n", nfds, + rfds.fds_bits[0], wfds.fds_bits[0]); + if(TNetAccept(&vecp, vec, nfds, &ifds, &ofds, NULLFD, + NOTOK, td) == NOTOK) + { + ts_advise ("TNetAccept failed", td); + exit (-3); + } + if (retry) + ping_address (); + + if (vecp > 0) { + if (TInit (vecp, vec, ts, td) == NOTOK) { + ts_advise ("TInit failed failed", td); + exit (-1); + } + if (TConnResponse (ts->ts_sd, NULLTA, 0, NULLCP, 0, + &tc -> tc_qos, td) == NOTOK) { + ts_advise ("TConnResponse", td); + exit (-1); + } + printf ("Connection accepted on %d\n", ts -> ts_sd); + FD_SET (ts -> ts_sd, &rfds); + if (ts -> ts_sd >= nfds) + nfds = ts -> ts_sd + 1; + } + + for (i = 0; i < nfds; i++) { + if (FD_ISSET (i, &ofds) || FD_ISSET (i, &ifds)) { + if (i == cn_sd) + progress_connection (); + else { + if (sink_data (i) != OK) { + FD_CLR (i, &rfds); + if (doneit ++ > 0) + return; + } + + } + } + } + if (cn_state == DONE) { + if (doneit ++ > 0) + return; + cn_state = NOTOK; + } + } +} + +sink_data (sd) +int sd; +{ + struct TSAPdisconnect tds; + struct TSAPdisconnect *td = &tds; + struct TSAPdata txs, *tx = &txs; + + if (TReadRequest (sd, tx, OK, td) == NOTOK) { + if (td -> td_reason = DR_NORMAL) + ts_advise ("Normal disconnection", td); + else ts_advise ("TReadRequest", td); + return NOTOK; + } + TXFREE (tx); + return OK; +} + +progress_connection () +{ + struct TSAPdisconnect td_s; + struct TSAPdisconnect *td = &td_s; + struct TSAPconnect tcs; + struct TSAPconnect *tc = &tcs; + + switch(cn_state) + { + case CONNECTING_1: + printf ("CONNECTING_1 -> "); + cn_state = TAsynRetryRequest(cn_sd,tc,td); + if (cn_state == NOTOK) + ts_advise ("\nTAsynRetryRequest", td); + updatemask (); + break; + case CONNECTING_2: + printf ("CONNECTING_2 -> "); + cn_state = TAsynRetryRequest(cn_sd,tc,td); + if (cn_state == NOTOK) + ts_advise ("\nTAsynRetryRequest", td); + updatemask(); + break; + case NOTOK: + printf ("NOTOK\n"); + updatemask (); + break; + case DONE: + printf ("DONE->"); + updatemask (); + break; + default: + printf ("cn_state weird\n"); + exit (-4); + } +} + +stop_nicely () +{ + struct TSAPdisconnect td_s; + struct TSAPdisconnect * td = &(td_s); + + (void) TNetClose (&pongaddr->pa_addr.sa_addr, td); +} + + +updatemask () +{ + struct TSAPdisconnect td_s; + struct TSAPdisconnect * td = &(td_s); + + if (cn_sd != NOTOK) { + FD_CLR (cn_sd, &rfds); + FD_CLR (cn_sd, &wfds); + if (cn_sd >= nfds) + nfds = cn_sd + 1; + } + switch (cn_state) { + case NOTOK: + printf ("NOTOK\n"); + break; + + default: + printf ("weird!\n"); + break; + + case CONNECTING_1: + printf ("CONNECTING_1\n"); + FD_SET (cn_sd, &wfds); + break; + + case CONNECTING_2: + printf ("CONNECTING_2\n"); + FD_SET (cn_sd, &rfds); + break; + case DONE: + printf ("DONE\n"); + (void) TDiscRequest (cn_sd, NULLCP, 0, td); + cn_sd = NOTOK; + printf ("Disconnect sent\n"); + break; + } +} + +ts_advise (str, td) +char *str; +struct TSAPdisconnect *td; +{ + if (td -> td_cc > 0) + printf ("%s : %s [%*.*s]\n", str, TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data); + else printf ("%s : %s\n", str, TErrString (td -> td_reason)); +} + diff --git a/usr/src/contrib/isode/others/quipu/make b/usr/src/contrib/isode/others/quipu/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/photo/Makefile b/usr/src/contrib/isode/others/quipu/photo/Makefile new file mode 100644 index 0000000000..0afada02be --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/Makefile @@ -0,0 +1,174 @@ +############################################################################### +# Instructions to Make, for compilation of QUIPU photo programs +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/photo/RCS/Makefile,v 7.7 91/02/22 09:28:57 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.7 91/02/22 09:28:57 mrose +# Interim 6.8 +# +# Revision 7.6 91/01/15 13:42:34 mrose +# KEJ +# +# Revision 7.5 90/12/23 18:46:23 mrose +# update +# +# Revision 7.4 90/09/24 16:25:26 mrose +# touch-up +# +# Revision 7.3 90/09/24 16:22:11 mrose +# touch-up +# +# Revision 7.2 90/09/24 16:21:19 mrose +# touch-up +# +# Revision 7.1 90/03/27 08:52:54 mrose +# pbmplus +# +# Revision 7.0 89/11/23 22:01:31 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +# should really go in config/CONFIG.make +DISPLAY = ttyphoto fax2ps +# DISPLAY = sunphoto Xphoto xfax ttyphoto hexphoto t4014 fax2ps + +####################################################################### +# Here we go... +####################################################################### + +DEC = decode.o build_trees.o +ENC = encode.o code_word.o +UTIL = interface.o + + +all: libphoto.a $(DISPLAY) + +lint:; $(LINT) $(LFLAGS) decode.c build_trees.c interface.c d_main.c tty.c \ + | grep -v "warning: possible pointer alignment problem" + +libphoto.a: $(DEC) $(UTIL) + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(DEC) $(UTIL) + +pr2pe: $(ENC) $(UTIL) e_main.o + $(LDCC) $(LDFLAGS) -o pr2pe e_main.o $(ENC) $(UTIL) -lpixrect $(LIBISODE) + +sunphoto: libphoto.a d_main.o sunview.o + $(LDCC) $(LDFLAGS) -o sunphoto \ + d_main.o libphoto.a sunview.o -lsuntool -lsunwindow \ + -lpixrect $(LIBISODE) + +Xphoto: libphoto.a d_main.o winx.o + $(LDCC) $(LDFLAGS) -o Xphoto \ + d_main.o libphoto.a winx.o -lX11 $(LIBISODE) + +xfax: libphoto.a d_main.o faxx.o + $(LDCC) $(LDFLAGS) -o xfax \ + d_main.o libphoto.a faxx.o -lX11 $(LIBISODE) + +fax2ps: libphoto.a d_main.o ps.o + $(LDCC) $(LDFLAGS) -o fax2ps \ + d_main.o libphoto.a ps.o -lX11 $(LIBISODE) + +t4014: libphoto.a d_main.o t4014.o + $(LDCC) $(LDFLAGS) -o t4014 \ + d_main.o libphoto.a t4014.o -l4014 -lm $(LIBISODE) + +ttyphoto: libphoto.a d_main.o tty.o + $(LDCC) $(LDFLAGS) -o ttyphoto \ + d_main.o libphoto.a tty.o $(LIBISODE) + +hexphoto: hexphoto.o d_main.o + $(LDCC) $(LDFLAGS) -o hexphoto hexphoto.o d_main.o $(LIBISODE) + +decode.o: decode.c $(HDIR)quipu/photo.h + $(CC) -c $(CFLAGS) $*.c + + +############################################################################### +# some programs for Jef Poskanzer's pbm package +############################################################################### + +PBMDIR = /usr/src/pbmplus/pbm/ +LIBPBM = $(PBMDIR)libpbm.a + +pbm: faxtopbm pbmtofax + +faxtopbm: faxtopbm.o libphoto.a $(LIBPBM) + $(LDCC) $(LDFLAGS) -o $@ faxtopbm.o libphoto.a $(LIBPBM) \ + $(LIBISODE) $(LSOCKET) + +faxtopbm.o: faxtopbm.c + $(CC) $(CFLAGS) -I$(PBMDIR) -c faxtopbm.c + +pbmtofax: pbmtofax.o encode.o code_word.o interface.o $(LIBPBM) + $(LDCC) $(LDFLAGS) -o $@ pbmtofax.o encode.o code_word.o \ + interface.o $(LIBPBM) + +pbmtofax.o: pbmtofax.c + $(CC) $(CFLAGS) -I$(PBMDIR) -c pbmtofax.c + + +##################################################################### +# Installation... +##################################################################### + +install: inst-all clean + +inst-all: $(DISPLAY) libphoto.a + -mkdir $(SBINDIR)g3fax + -mv $(SBINDIR)g3fax/ttyphoto zttyphoto + -cp ttyphoto $(SBINDIR)g3fax/ttyphoto + -mv $(SBINDIR)g3fax/hexphoto zhexphoto + -cp hexphoto $(SBINDIR)g3fax/hexphoto + -mv $(SBINDIR)g3fax/sunphoto zsunphoto + -cp sunphoto $(SBINDIR)g3fax/sunphoto + -mv $(SBINDIR)g3fax/Xphoto zXphoto + -cp Xphoto $(SBINDIR)g3fax/Xphoto + -mv $(SBINDIR)g3fax/xfax zxfax + -cp xfax $(SBINDIR)g3fax/xfax + -mv $(SBINDIR)g3fax/fax2ps zfax2ps + -cp fax2ps $(SBINDIR)g3fax/fax2ps + -mv $(SBINDIR)g3fax/t4014 zt4014 + -cp t4014 $(SBINDIR)g3fax/t4014 + -mv $(SBINDIR)g3fax/faxtopbm zfaxtopbm + -cp faxtopbm $(SBINDIR)g3fax/faxtopbm + -mv $(SBINDIR)g3fax/pbmtofax zpbmtofax + -cp pbmtofax $(SBINDIR)g3fax/pbmtofax + -mv $(SBINDIR)g3fax/pr2pe zpr2pe + -cp pr2pe $(SBINDIR)g3fax/pr2pe + -rm -f $(SBINDIR)g3fax/libphoto.a + cp libphoto.a $(SBINDIR)g3fax/libphoto.a + @$(UTILDIR)make-lib.sh $(SYSTEM) $(SBINDIR)g3fax/libphoto.a -ranlib + -@ls -gls $(SBINDIR)g3fax/libphoto.a + -@echo "" + +$(SBINDIR)g3fax: g3fax + -rm -rf $@ + -cp -r g3fax $(SBINDIR) + +clean: + rm -f _* *.o *.old *% foo* core z* *.a \ + *.orig \ + sunphoto hexphoto ttyphoto \ + pr2pe Xphoto xfax t4014 \ + faxtopbm pbmtofax \ + faxtops diff --git a/usr/src/contrib/isode/others/quipu/photo/READ-ME b/usr/src/contrib/isode/others/quipu/photo/READ-ME new file mode 100644 index 0000000000..f21e63ce77 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/READ-ME @@ -0,0 +1,49 @@ +PHOTOGRAPHS in the QUIPU directory service. + +Use pr2pe to convert sunview pixrect files into `pe' files. + +Currently there are several picture display processes defined:- +Xphoto - Display photo in X11 window environment +xfax - Display photo in X11 window environment (fine resolution) +sunphoto - Display photo in sunview environment +ttyphoto - Display photo on a simple terminal +hexphoto - Display photo in hex !!! +t4014 - Display on Tetronix 4014 (emulating !) terminals. +fax2ps - Convert the photo to postscript + +Each can be tested with the file "sk" +e.g. ttyphoto < sk + +Display for other devices can be easily added. +Take a copy of template.c, and supply the 5 routines defined. +Look at sunview.c hexphoto.c ttyphoto.c t4014.c and winx.c examples. +Then compile using: +cc -o myphoto d_main.o decode.o build_trees.o interface.o myphoto.o + +To get the QUIPU interfaces to call these routine when a photo is loaded, an +entry of the form +photo falco ttyphoto +is needed in your dsaptailor file. +This will tell the interfaces to use the program `typhoto' if your +terminal type (determined from the TERM environment variable) is `falco'. + +ttyphoto's output can be modified with 4 environment variables: + +photo_scale: set to `small' (default), `medium' or `large'. +photo_invert: set true or false. +photo_equal: false - display photo as is. + true - apply histogram equalisation to try and improve quality. + edge - Used `edges by expansion' to try to get a better photo +photo_mapping: This must contain a 16 charcter string. + The string is used to create the greyscale. +Suggestions as to how to improve `ttyphoto' are welcome. + +To install pbmtofax and faxtopbm, you will need a copy of the PBMPLUS +package. If you don't have a copy, contact Jef Poskanzer +Once you have acquired PBMPLUS, build the libpbm.a library (go to the +pbm/ directory in the PBMPLUS source tree and type make). Next edit the +Makefile in this directory to set the PBMDIR make variable to reflect +where the top of the PBMPLUS source tree is located. Finally, type + + % make pbm + # make inst-all diff --git a/usr/src/contrib/isode/others/quipu/photo/build_trees.c b/usr/src/contrib/isode/others/quipu/photo/build_trees.c new file mode 100644 index 0000000000..84b1a9e508 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/build_trees.c @@ -0,0 +1,425 @@ +/* build_trees.c - build decode trees */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/build_trees.c,v 7.3 91/02/22 09:29:00 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/build_trees.c,v 7.3 91/02/22 09:29:00 mrose Interim $ + * + * + * $Log: build_trees.c,v $ + * Revision 7.3 91/02/22 09:29:00 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/15 13:42:36 mrose + * KEJ + * + * Revision 1.1 91/01/02 21:34:39 kej + * Initial revision + * + * Revision 7.0 89/11/23 22:01:33 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include "quipu/photo.h" + +int built = 0; +char * malloc (); + +extern node * bl_tree_top; /* pointers to the decode trees */ +extern node * wt_tree_top; +extern node * two_tree_top; + +/* + * Decoding tables + */ + +static char *bl_make [] = { +"0000001111", +"000011001000", +"000011001001", +"000001011011", +"000000110011", +"000000110100", +"000000110101", +"0000001101100", +"0000001101101", +"0000001001010", +"0000001001011", +"0000001001100", +"0000001001101", +"0000001110010", +"0000001110011", +"0000001110100", +"0000001110101", +"0000001110110", +"0000001110111", +"0000001010010", +"0000001010011", +"0000001010100", +"0000001010101", +"0000001011010", +"0000001011011", +"0000001100100", +"0000001100101", +"00000001000", +"00000001100", +"00000001101", +"000000010010", +"000000010011", +"000000010100", +"000000010101", +"000000010110", +"000000010111", +"000000011100", +"000000011101", +"000000011110", +"000000011111", +NULL +}; + +static char *bl_term [] = { +"0000110111", +"010", +"11", +"10", +"011", +"0011", +"0010", +"00011", +"000101", +"000100", +"0000100", +"0000101", +"0000111", +"00000100", +"00000111", +"000011000", +"0000010111", +"0000011000", +"0000001000", +"00001100111", +"00001101000", +"00001101100", +"00000110111", +"00000101000", +"00000010111", +"00000011000", +"000011001010", +"000011001011", +"000011001100", +"000011001101", +"000001101000", +"000001101001", +"000001101010", +"000001101011", +"000011010010", +"000011010011", +"000011010100", +"000011010101", +"000011010110", +"000011010111", +"000001101100", +"000001101101", +"000011011010", +"000011011011", +"000001010100", +"000001010101", +"000001010110", +"000001010111", +"000001100100", +"000001100101", +"000001010010", +"000001010011", +"000000100100", +"000000110111", +"000000111000", +"000000100111", +"000000101000", +"000001011000", +"000001011001", +"000000101011", +"000000101100", +"000001011010", +"000001100110", +"000001100111", +NULL +}; + +static char *two_dim [] = { +"0001", +"001", +"0000010", +"000010", +"010", +"1", +"011", +"000011", +"0000011", +NULL +}; + +static char *wt_make [] = { +"11011", +"10010", +"010111", +"0110111", +"00110110", +"00110111", +"01100100", +"01100101", +"01101000", +"01100111", +"011001100", +"011001101", +"011010010", +"011010011", +"011010100", +"011010101", +"011010110", +"011010111", +"011011000", +"011011001", +"011011010", +"011011011", +"010011000", +"010011001", +"010011010", +"011000", +"010011011", +"00000001000", +"00000001100", +"00000001101", +"000000010010", +"000000010011", +"000000010100", +"000000010101", +"000000010110", +"000000010111", +"000000011100", +"000000011101", +"000000011110", +"000000011111", +NULL +}; + +static char *wt_term [] = { +"00110101", +"000111", +"0111", +"1000", +"1011", +"1100", +"1110", +"1111", +"10011", +"10100", +"00111", +"01000", +"001000", +"000011", +"110100", +"110101", +"101010", +"101011", +"0100111", +"0001100", +"0001000", +"0010111", +"0000011", +"0000100", +"0101000", +"0101011", +"0010011", +"0100100", +"0011000", +"00000010", +"00000011", +"00011010", +"00011011", +"00010010", +"00010011", +"00010100", +"00010101", +"00010110", +"00010111", +"00101000", +"00101001", +"00101010", +"00101011", +"00101100", +"00101101", +"00000100", +"00000101", +"00001010", +"00001011", +"01010010", +"01010011", +"01010100", +"01010101", +"00100100", +"00100101", +"01011000", +"01011001", +"01011010", +"01011011", +"01001010", +"01001011", +"00110010", +"00110011", +"00110100", +NULL +}; + +static char * uncompressed_1d = "000000001111"; +static char * uncompressed_2d = "0000001111"; + +/* ROUTINE: get_node */ +/* */ +/* SYNOPSIS: creates a new node. */ +/* */ +/* DESCRIPTION: Uses malloc to allocate sufficient memory for a node to */ +/* be stored, and the sets all the pointer fields of the */ +/* node to NULL, and initialises the other fields */ + +node * +get_node () + +{ +node * mem; + + mem = (node *) malloc (sizeof (node)); + mem->n_type = INTERNAL; /* The most common node type */ + mem->zero = NULL; + mem->one = NULL; + + return (mem); +} + + +/* ROUTINE: build_trees. +/* +/* SYNOPSIS: build the decode tree. +/* +/* DESCRIPTION: For each of the three trees, read the data in from a file +/* in string form, convert this into an integer, then add this integer to the +/* tree. +/* Also contained in the node is the value associated with the string read in, +/* so we need to count each string as it is read in. +*/ + +build_trees () +{ + register i; + char ** string; + + if (built) + return (0); + + /* create the tops of the trees */ + + bl_tree_top = get_node (); + wt_tree_top = get_node (); + two_tree_top = get_node (); + +/* Add the white terminals to the white tree */ + + i=0; + for (string = wt_term; *string; ++string) + add_tree (*string,i++,WT_TERM,wt_tree_top); + + /* Add the black terminals to the black tree */ + + i=0; + for (string = bl_term; *string; ++string) + add_tree (*string,i++,BL_TERM,bl_tree_top); + + /* Add the white make codes to the white tree */ + + i = 64; + for (string = wt_make; *string; ++string) { + add_tree (*string,i,MAKE,wt_tree_top); + i += 64; + } + + /* Add the black make up codes to the black tree */ + + i = 64; + for (string = bl_make; *string; ++string) { + add_tree (*string,i,MAKE,bl_tree_top); + i += 64; + } + + /* make the two dimensional decode tree */ + + i = 1; + for (string = two_dim; *string; ++string) + add_tree (*string,i++,MAKE,two_tree_top); + + /* put uncompressed mode entrance codewords on all three trees */ + + add_tree (uncompressed_1d,-1,MAKE,bl_tree_top); + add_tree (uncompressed_1d,-1,MAKE,wt_tree_top); + add_tree (uncompressed_2d,-1,MAKE,two_tree_top); + + /* put end of line markers on all three trees */ + + add_tree ("00000000000",EOLN,EOLN,bl_tree_top); + add_tree ("00000000000",EOLN,EOLN,wt_tree_top); + add_tree ("00000000000",EOLN,EOLN,two_tree_top); + + built = 1; + return(0); +} + +/* ROUTINE: add_tree */ +/* */ +/* SYNOPSIS: adds a run to the tree */ +/* */ + +add_tree (string,run,mode,root) + +char * string; /* string containing the bit sequence */ +int run; /* the run length associated with the sequence */ +char mode; /* the type of data we are entering */ +node * root; /* top of the tree string should be added to */ +{ + +char * ptr; +node * treeptr; +register i; + + ptr = string; + treeptr = root; + + for ( i=0; i< strlen(string); i++,ptr++) + if (*ptr == '0') { + if (treeptr->zero == NULL) + treeptr->zero = get_node (); + treeptr = treeptr->zero; + + } else { + if (treeptr->one == NULL) + treeptr->one = get_node (); + treeptr = treeptr->one; + } + + treeptr->n_type = mode; + treeptr->value = run; +} + diff --git a/usr/src/contrib/isode/others/quipu/photo/code_word.c b/usr/src/contrib/isode/others/quipu/photo/code_word.c new file mode 100644 index 0000000000..541e54e354 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/code_word.c @@ -0,0 +1,293 @@ +/* code_word.c - define code words for one dimensional encoding */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/code_word.c,v 7.1 91/02/22 09:29:01 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/code_word.c,v 7.1 91/02/22 09:29:01 mrose Interim $ + * + * + * $Log: code_word.c,v $ + * Revision 7.1 91/02/22 09:29:01 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:34 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include "quipu/photo.h" + +extern int PIC_LINESIZE; + +/* The following are declarations of the code words that are used with one +/* dimensional encoding. The first number in each pair give the length +/* of the string, the second gives the string in hex, starting at the 13th bit +/* position. +/* The declarations are made this way so that the arays are made at compile +/* time as opposed to run time. +*/ + + +/* White terminal run lengths */ + +static code_word wt_term [] = { + { 8 , 0x6a0 }, /* 0 : 00110101 */ + { 6 , 0x380 }, /* 1 : 000111 */ + { 4 , 0xe00 }, /* 2 : 0111 */ + { 4 , 0x1000 }, /* 3 : 1000 */ + { 4 , 0x1600 }, /* 4 : 1011 */ + { 4 , 0x1800 }, /* 5 : 1100 */ + { 4 , 0x1c00 }, /* 6 : 1110 */ + { 4 , 0x1e00 }, /* 7 : 1111 */ + { 5 , 0x1300 }, /* 8 : 10011 */ + { 5 , 0x1400 }, /* 9 : 10100 */ + { 5 , 0x700 }, /* 10: 00111 */ + { 5 , 0x800 }, /* 11: 01000 */ + { 6 , 0x400 }, /* 12: 001000 */ + { 6 , 0x180 }, /* 13: 000011 */ + { 6 , 0x1a00 }, /* 14: 110100 */ + { 6 , 0x1a80 }, /* 15: 110101 */ + { 6 , 0x1500 }, /* 16: 101010 */ + { 6 , 0x1580 }, /* 17: 101011 */ + { 7 , 0x9c0 }, /* 18: 0100111 */ + { 7 , 0x300 }, /* 19: 0001100 */ + { 7 , 0x200 }, /* 20: 0001000 */ + { 7 , 0x5c0 }, /* 21: 0010111 */ + { 7 , 0xc0 }, /* 22: 0000011 */ + { 7 , 0x100 }, /* 23: 0000100 */ + { 7 , 0xa00 }, /* 24: 0101000 */ + { 7 , 0xac0 }, /* 25: 0101011 */ + { 7 , 0x4c0 }, /* 26: 0010011 */ + { 7 , 0x900 }, /* 27: 0100100 */ + { 7 , 0x600 }, /* 28: 0011000 */ + { 8 , 0x40 }, /* 29: 00000010 */ + { 8 , 0x60 }, /* 30: 00000011 */ + { 8 , 0x340 }, /* 31: 00011010 */ + { 8 , 0x360 }, /* 32: 00011011 */ + { 8 , 0x240 }, /* 33: 00010010 */ + { 8 , 0x260 }, /* 34: 00010011 */ + { 8 , 0x280 }, /* 35: 00010100 */ + { 8 , 0x2a0 }, /* 36: 00010101 */ + { 8 , 0x2c0 }, /* 37: 00010110 */ + { 8 , 0x2e0 }, /* 38: 00010111 */ + { 8 , 0x500 }, /* 39: 00101000 */ + { 8 , 0x520 }, /* 40: 00101001 */ + { 8 , 0x540 }, /* 41: 00101010 */ + { 8 , 0x560 }, /* 42: 00101011 */ + { 8 , 0x580 }, /* 43: 00101100 */ + { 8 , 0x5a0 }, /* 44: 00101101 */ + { 8 , 0x80 }, /* 45: 00000100 */ + { 8 , 0xa0 }, /* 46: 00000101 */ + { 8 , 0x140 }, /* 47: 00001010 */ + { 8 , 0x160 }, /* 48: 00001011 */ + { 8 , 0xa40 }, /* 49: 01010010 */ + { 8 , 0xa60 }, /* 50: 01010011 */ + { 8 , 0xa80 }, /* 51: 01010100 */ + { 8 , 0xaa0 }, /* 52: 01010101 */ + { 8 , 0x480 }, /* 53: 00100100 */ + { 8 , 0x4a0 }, /* 54: 00100101 */ + { 8 , 0xb00 }, /* 55: 01011000 */ + { 8 , 0xb20 }, /* 56: 01011001 */ + { 8 , 0xb40 }, /* 57: 01011010 */ + { 8 , 0xb60 }, /* 58: 01011011 */ + { 8 , 0x940 }, /* 59: 01001010 */ + { 8 , 0x960 }, /* 60: 01001011 */ + { 8 , 0x640 }, /* 61: 00110010 */ + { 8 , 0x660 }, /* 62: 00110011 */ + { 8 , 0x680 }, /* 63: 00110100 */ + }; + +/* Black terminal run lengths */ + +static code_word bl_term [] = { + { 10, 0x1b8 }, /* 0 : 0000110111 */ + { 3 , 0x800 }, /* 1 : 010 */ + { 2 , 0x1800 }, /* 2 : 11 */ + { 2 , 0x1000 }, /* 3 : 10 */ + { 3 , 0xc00 }, /* 4 : 011 */ + { 4 , 0x600 }, /* 5 : 0011 */ + { 4 , 0x400 }, /* 6 : 0010 */ + { 5 , 0x300 }, /* 7 : 00011 */ + { 6 , 0x280 }, /* 8 : 000101 */ + { 6 , 0x200 }, /* 9 : 000100 */ + { 7 , 0x100 }, /* 10: 0000100 */ + { 7 , 0x140 }, /* 11: 0000101 */ + { 7 , 0x1c0 }, /* 12: 0000111 */ + { 8 , 0x80 }, /* 13: 00000100 */ + { 8 , 0xe0 }, /* 14: 00000111 */ + { 9 , 0x180 }, /* 15: 000011000 */ + { 10, 0xb8 }, /* 16: 0000010111 */ + { 10, 0xc0 }, /* 17: 0000011000 */ + { 10, 0x40 }, /* 18: 0000001000 */ + { 11, 0x19c }, /* 19: 00001100111 */ + { 11, 0x1a0 }, /* 20: 00001101000 */ + { 11, 0x1b0 }, /* 21: 00001101100 */ + { 11, 0xdc }, /* 22: 00000110111 */ + { 11, 0xa0 }, /* 23: 00000101000 */ + { 11, 0x5c }, /* 24: 00000010111 */ + { 11, 0x60 }, /* 25: 00000011000 */ + { 12, 0x194 }, /* 26: 000011001010 */ + { 12, 0x196 }, /* 27: 000011001011 */ + { 12, 0x198 }, /* 28: 000011001100 */ + { 12, 0x19a }, /* 29: 000011001101 */ + { 12, 0xd0 }, /* 30: 000001101000 */ + { 12, 0xd2 }, /* 31: 000001101001 */ + { 12, 0xd4 }, /* 32: 000001101010 */ + { 12, 0xd6 }, /* 33: 000001101011 */ + { 12, 0x1a4 }, /* 34: 000011010010 */ + { 12, 0x1a6 }, /* 35: 000011010011 */ + { 12, 0x1a8 }, /* 36: 000011010100 */ + { 12, 0x1aa }, /* 37: 000011010101 */ + { 12, 0x1ac }, /* 38: 000011010110 */ + { 12, 0x1ae }, /* 39: 000011010111 */ + { 12, 0xd8 }, /* 40: 000001101100 */ + { 12, 0xda }, /* 41: 000001101101 */ + { 12, 0x1b4 }, /* 42: 000011011010 */ + { 12, 0x1b6 }, /* 43: 000011011011 */ + { 12, 0xa8 }, /* 44: 000001010100 */ + { 12, 0xaa }, /* 45: 000001010101 */ + { 12, 0xac }, /* 46: 000001010110 */ + { 12, 0xae }, /* 47: 000001010111 */ + { 12, 0xc8 }, /* 48: 000001100100 */ + { 12, 0xca }, /* 49: 000001100101 */ + { 12, 0xa4 }, /* 50: 000001010010 */ + { 12, 0xa6 }, /* 51: 000001010011 */ + { 12, 0x48 }, /* 52: 000000100100 */ + { 12, 0x6e }, /* 53: 000000110111 */ + { 12, 0x70 }, /* 54: 000000111000 */ + { 12, 0x4e }, /* 55: 000000100111 */ + { 12, 0x50 }, /* 56: 000000101000 */ + { 12, 0xb0 }, /* 57: 000001011000 */ + { 12, 0xb2 }, /* 58: 000001011001 */ + { 12, 0x56 }, /* 59: 000000101011 */ + { 12, 0x58 }, /* 60: 000000101100 */ + { 12, 0xb4 }, /* 61: 000001011010 */ + { 12, 0xcc }, /* 62: 000001100110 */ + { 12, 0xce }, /* 63: 000001100111 */ + }; + +/* White make up codes */ + +static code_word wt_make [] = { + { 5 , 0x1b00 }, /* 64 : 11011 */ + { 5 , 0x1200 }, /* 128 : 10010 */ + { 6 , 0xb80 }, /* 192 : 010111 */ + { 7 , 0xdc0 }, /* 256 : 0110111 */ + { 8 , 0x6c0 }, /* 320 : 00110110 */ + { 8 , 0x6e0 }, /* 384 : 00110111 */ + { 8 , 0xc80 }, /* 448 : 01100100 */ + { 8 , 0xca0 }, /* 512 : 01100101 */ + { 8 , 0xd00 }, /* 576 : 01101000 */ + { 8 , 0xce0 }, /* 640 : 01100111 */ + { 9 , 0xcc0 }, /* 704 : 011001100 */ + { 9 , 0xcd0 }, /* 768 : 011001101 */ + { 9 , 0xd20 }, /* 832 : 011010010 */ + { 9 , 0xd30 }, /* 896 : 011010011 */ + { 9 , 0xd40 }, /* 960 : 011010100 */ + { 9 , 0xd50 }, /* 1024: 011010101 */ + { 9 , 0xd60 }, /* 1088: 011010110 */ + { 9 , 0xd70 }, /* 1152: 011010111 */ + { 9 , 0xd80 }, /* 1216: 011011000 */ + { 9 , 0xd90 }, /* 1280: 011011001 */ + { 9 , 0xda0 }, /* 1344: 011011010 */ + { 9 , 0xdb0 }, /* 1408: 011011011 */ + { 9 , 0x980 }, /* 1472: 010011000 */ + { 9 , 0x990 }, /* 1536: 010011001 */ + { 9 , 0x9a0 }, /* 1600: 010011010 */ + { 6 , 0xc00 }, /* 1664: 011000 */ + { 9 , 0x9b0 }, /* 1728: 010011011 */ + { 11, 0x20 }, /* 1792: 00000001000 */ + { 11, 0x30 }, /* 1856: 00000001100 */ + { 11, 0x34 }, /* 1920: 00000001101 */ + { 12, 0x24 }, /* 1984: 000000010010 */ + { 12, 0x26 }, /* 2048: 000000010011 */ + }; + +/* Black make up codes */ + +static code_word bl_make [] = { + { 10, 0x78 }, /* 64 : 0000001111 */ + { 12, 0x190 }, /* 128 : 000011001000 */ + { 12, 0x192 }, /* 192 : 000011001001 */ + { 12, 0xb6 }, /* 256 : 000001011011 */ + { 12, 0x66 }, /* 320 : 000000110011 */ + { 12, 0x68 }, /* 384 : 000000110100 */ + { 12, 0x6a }, /* 448 : 000000110101 */ + { 13, 0x6c }, /* 512 : 0000001101100 */ + { 13, 0x6d }, /* 576 : 0000001101101 */ + { 13, 0x4a }, /* 640 : 0000001001010 */ + { 13, 0x4b }, /* 704 : 0000001001011 */ + { 13, 0x4c }, /* 768 : 0000001001100 */ + { 13, 0x4d }, /* 832 : 0000001001101 */ + { 13, 0x72 }, /* 896 : 0000001110010 */ + { 13, 0x73 }, /* 960 : 0000001110011 */ + { 13, 0x74 }, /* 1024: 0000001110100 */ + { 13, 0x75 }, /* 1088: 0000001110101 */ + { 13, 0x76 }, /* 1152: 0000001110110 */ + { 13, 0x77 }, /* 1216: 0000001110111 */ + { 13, 0x52 }, /* 1280: 0000001010010 */ + { 13, 0x53 }, /* 1344: 0000001010011 */ + { 13, 0x54 }, /* 1408: 0000001010100 */ + { 13, 0x55 }, /* 1472: 0000001010101 */ + { 13, 0x5a }, /* 1536: 0000001011010 */ + { 13, 0x5b }, /* 1600: 0000001011011 */ + { 13, 0x64 }, /* 1664: 0000001100100 */ + { 13, 0x65 }, /* 1728: 0000001100101 */ + { 11, 0x20 }, /* 1792: 00000001000 */ + { 11, 0x30 }, /* 1856: 00000001100 */ + { 11, 0x34 }, /* 1920: 00000001101 */ + { 12, 0x24 }, /* 1984: 000000010010 */ + { 12, 0x26 }, /* 2048: 000000010011 */ + }; + + + + +/* ROUTINE: Get_code () */ +/* */ +/* SYNOPSIS: Gets a code word from an array given the run_length */ +/* and the colour (0 = white, 1 = black) */ + +extern int forcesize; + +full_code +get_code (run, colour) + +char colour; +int run; +{ + +full_code result; + result.make.length = 0; + if (run > (forcesize ? forcesize : PIC_LINESIZE)) + (void) fprintf (stderr,"Run too long\n"); + + if (colour == WHITE) { + if (run > 63) + result.make = wt_make [(run/64)-1]; + result.term = wt_term [run%64]; + + } else { + if (run > 63) + result.make = bl_make [(run/64)-1]; + result.term = bl_term [run%64]; + } + + return (result); + +} diff --git a/usr/src/contrib/isode/others/quipu/photo/d_main.c b/usr/src/contrib/isode/others/quipu/photo/d_main.c new file mode 100644 index 0000000000..2d022ea914 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/d_main.c @@ -0,0 +1,148 @@ +/* d_main.c - make the decode routine into a stand alone program */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/d_main.c,v 7.4 91/02/22 09:29:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/d_main.c,v 7.4 91/02/22 09:29:06 mrose Interim $ + * + * + * $Log: d_main.c,v $ + * Revision 7.4 91/02/22 09:29:06 mrose + * Interim 6.8 + * + * Revision 1.3 91/01/07 23:49:49 kej + * Support fax images encoded as a SEQUENCE which contains a SET followed by + * a SEQUENCE of BIT STRING. + * + * Revision 1.2 91/01/05 00:29:07 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:35:05 kej + * Initial revision + * + * Revision 7.1 90/03/15 11:18:08 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:01:36 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include +#include "psap.h" +#include "quipu/photo.h" + + +#define ALLOCATION_SIZE 16384L + +int two_passes = 0; + +char *getenv (); + +main (argc, argv) +int argc; +char ** argv; +{ + int count; + char *cp; + char *data; + int fd; + char *file = ""; + char *inbuf; + int len; + long limit; + int n; + char *name; + char *newData; + long size; + + if ((name = getenv ("RDN")) == NULL) + name = "unknown"; + + /* process commmand line options and parameters */ + + if (argc > 1) + name = *(++argv); + + fd = fileno (stdin); + + /* read the entire source file into memory */ + + data = (char *)malloc (ALLOCATION_SIZE); + if ( !data ) { + fputs ("decode_fax: out of memory\n", stderr); + exit (1); + } + limit = ALLOCATION_SIZE; + size = 0L; + + for (;;) { + if (size + ALLOCATION_SIZE > limit) { + newData = (char *)realloc (data, limit + ALLOCATION_SIZE); + if ( !newData ) { + fputs ("decode_fax: out of memory\n", stderr); + exit (1); + } + data = newData; + limit += ALLOCATION_SIZE; + } + len = read (fd, &data[size], ALLOCATION_SIZE); + if (len == -1) { + perror (file); + exit (1); + } + else if (len == 0) + break; + size += len; + } + + if (size < 1) { + fprintf (stderr, "%s: is not a fax image\n", file); + exit (1); + } + if (decode_t4 (data, name, (int)size) == -1) { + (void) fprintf (stderr,"\n"); + exit (-1); + } + if (two_passes && decode_t4 (data, name, (int)size) == -1) { + (void) fprintf (stderr,"\n"); + exit (-1); + } +} + +/* ERRORS */ + +static ps_die (ps, s) +register PS ps; +register char *s; +{ + fprintf (stderr, "%s: %s\n", s, ps_error (ps -> ps_errno)); + exit (1); +} + + +static pe_die (pe, s) +register PE pe; +register char *s; +{ + fprintf (stderr, "%s: %s\n", s, pe_error (pe -> pe_errno)); + exit (1); +} diff --git a/usr/src/contrib/isode/others/quipu/photo/decode.c b/usr/src/contrib/isode/others/quipu/photo/decode.c new file mode 100644 index 0000000000..cdf1a645f9 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/decode.c @@ -0,0 +1,984 @@ +/* decode.c - the generic decoder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/decode.c,v 7.6 91/02/22 09:29:08 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/decode.c,v 7.6 91/02/22 09:29:08 mrose Interim $ + * + * + * $Log: decode.c,v $ + * Revision 7.6 91/02/22 09:29:08 mrose + * Interim 6.8 + * + * Revision 1.3 91/01/07 23:50:17 kej + * Support fax images encoded as a SEQUENCE which contains a SET followed by + * a SEQUENCE of BIT STRING. + * + * Revision 1.2 91/01/05 00:31:29 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:35:13 kej + * Initial revision + * + * Revision 7.1 90/07/09 14:40:20 mrose + * sync + * + * Revision 7.0 89/11/23 22:01:37 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include "quipu/photo.h" +#include "psap.h" + +#define UNCOMPRESSED_1D 0x0e +#define ERR_RUN 0x0f + +/* this file contains the main routines for decoding X400 */ + +extern int PIC_LINESIZE, STOP, NUMLINES; + +/* variables for top of the code word trees */ + +node * bl_tree_top; +node * wt_tree_top; +node * two_tree_top; + +unsigned int position; + +static char ref_colour; +static char colour; +char * malloc (); +char *bitmap; + +static void resync (); +static int seqerrs = 0; + +int decode_t4 (data, name, size) +char *data; +char *name; +int size; +{ + PE member; + PE pe; + PS ps; + PE seq; + PE set; + int twoDimensional = 0; + int res; + + /* + * If the first byte does not indicate that the data is an ASN.1-encoded + * SET or BIT STRING, attempt to convert the data as a non-ASN.1 image. + */ + + if ((unsigned char)*data != 0xa3 && *data != 0x03) + return decode_t4_aux (data, name, (int)size, twoDimensional); + + /* attempt to decode the source */ + + if ((ps = ps_alloc (str_open)) == NULLPS) { + fprintf (stderr, "ps_alloc: unable to allocate presentation stream\n"); + return (-1); + } + if (str_setup (ps, data, (int)size, 0) == NOTOK) { + ps_free (ps); + return -1; + } + if ((pe = ps2pe (ps)) == NULLPE) { /* maybe it's a non-ASN.1 image */ + ps_free (ps); + return decode_t4_aux (data, name, (int)size, 1); + } + + if (pe->pe_class == PE_CLASS_UNIV && pe->pe_form == PE_FORM_PRIM && + pe->pe_id == PE_PRIM_BITS) { /* old BIT STRING-like form */ + if (pe_pullup (pe) == NOTOK) { + pe_free (pe); + ps_free (ps); + return -1; + } + res = decode_t4_aux (pe -> pe_prim, name, ps_get_abs (pe), 1); + } + else if (pe->pe_class == PE_CLASS_CONT && pe->pe_form == PE_FORM_CONS && + pe->pe_id == 3) { + + /* first member must be SET which describes G3-Fax options */ + + set = first_member (pe); + if (!set || set->pe_class != PE_CLASS_UNIV || + set->pe_form != PE_FORM_CONS || set->pe_id != PE_CONS_SET) { + fprintf (stderr, "decode_fax: %s is not a fax image\n", name); + pe_free (pe); + ps_free (ps); + return -1; + } + + for (member = first_member (set); member; member = next_member (set, member)) { + if (member->pe_class == PE_CLASS_CONT && + member->pe_form == PE_FORM_PRIM && member->pe_id == 1) { + twoDimensional = bit_test (prim2bit (member), 8); + if (twoDimensional == -1) { + pe_free (pe); + ps_free (ps); + return -1; + } + } + } + + /* SEQUENCE of BIT STRING should follow SET */ + + seq = next_member (pe, set); + if (!seq || seq->pe_class != PE_CLASS_UNIV || + seq->pe_form != PE_FORM_CONS || seq->pe_id != PE_CONS_SEQ) { + fprintf (stderr, "%s: is not a fax image\n", name); + pe_free (pe); + ps_free (ps); + return -1; + } + + for (member = first_member (seq); member; member = next_member (seq, member)) { + if (member->pe_class != PE_CLASS_UNIV || + member->pe_form != PE_FORM_PRIM || + member->pe_id != PE_PRIM_BITS) { + fprintf (stderr, "%s: is not a fax image\n", name); + pe_free (pe); + ps_free (ps); + return -1; + } + res = decode_t4_aux ((member->pe_prim) + 1, name, + ps_get_abs (member) - 1, twoDimensional); + } + } + else /* maybe its a non-ASN.1 image */ + res = decode_t4_aux (data, name, (int)size, 1); + + pe_free (pe); + ps_free (ps); + + return res; + + +} + +/* + * Uncompressed mode black and white pel count tables. These tables + * are indexed by the count of leading zeros in the uncompressed mode + * code word. + */ + +#define UC_EXIT 6 + +static int uc_white_pels [] = { + /* image pattern code word */ + 0, /* 1 1 */ + 1, /* 01 01 */ + 2, /* 001 001 */ + 3, /* 0001 0001 */ + 4, /* 00001 00001 */ + 5, /* 00000 000001 */ + 0, /* 0000001 */ + 1, /* 0 00000001 */ + 2, /* 00 000000001 */ + 3, /* 000 0000000001 */ + 4, /* 0000 00000000001 */ +}; + +static int uc_black_pels [] = { + /* image pattern code word */ + 1, /* 1 1 */ + 1, /* 01 01 */ + 1, /* 001 001 */ + 1, /* 0001 0001 */ + 1, /* 00001 00001 */ + 0, /* 00000 000001 */ + 0, /* 0000001 */ + 0, /* 0 00000001 */ + 0, /* 00 000000001 */ + 0, /* 000 0000000001 */ + 0, /* 0000 00000000001 */ +}; + +/* ROUTINE: Decode_t4 +/* +/* SYNOPSIS: Decodes a bit map stored in format T4 as recommended +/* by CCITT. +/* +/* DESCRIPTION: After setting up the buffers, a line at a time is dealt with. +/* Each line is recognised as being one or two dimensionally coded, depending +/* upon the tag bit. +/* The run change buffers for each line are kept incase the next line is two +/* dimensionally, when it will be used as a reference. +/* +*/ + + +int decode_t4_aux (inbuf, winname, length, twoDimensional) +char *inbuf; +char *winname; +int length; +int twoDimensional; +{ + bit_string code_line, /* output line */ + ref_line, /* reference line */ + t4_line; /* input line */ + + int done; + run_type run; + int *buffer1, *buffer2; + int *run_buf1, *run_buf2; + char oneDtag, tag; + + seqerrs = 0; + + if (photo_start (winname) == -1) + return (-1); + + if (build_trees () == -1) + return (-1); + + buffer1 = (int *) malloc (LINEBUF * sizeof(int)); + buffer2 = (int *) malloc (LINEBUF * sizeof(int)); + buffer1[0] = 0; /* to halt backtracting if needed at start of line */ + buffer2[0] = 0; + run_buf1 = buffer1; + run_buf2 = buffer2; + ref_line.run_top = ++run_buf1; + code_line.run_top = ++run_buf2; + + code_line.dbuf_top = malloc (BUFSIZ); + t4_line.dbuf_top = inbuf; + + if (set_dinput (&t4_line, length) == -1) + return (-1); + set_doutput (&code_line); + + /* images must always start with a 1-d encoded line */ + + position = 1; + NUMLINES = 1; + done = decode_one (&code_line, &t4_line); + if (done < 0) return (-1); + if ( !done ) { /* no leading EOL */ + flush_doutput (&code_line); + set_doutput (&code_line); + photo_line_end (&code_line); + } + else { /* leading EOL */ + NUMLINES = 0; + done = 0; + } + + if (twoDimensional) + oneDtag = tag = get_bit(&t4_line); + + while ( done != 1 ) { + ++NUMLINES; + position = 1; + + if ( twoDimensional && tag != oneDtag ) { + if (code_line.run_top == run_buf1) { + ref_line.run_top = run_buf1; + code_line.run_top = run_buf2; + } + else { + ref_line.run_top = run_buf2; + code_line.run_top = run_buf1; + } + done = decode_two (&ref_line, &code_line, &t4_line); + } + else { + done = decode_one (&code_line, &t4_line); + } + + if (done == -1) return (-1); + + flush_doutput (&code_line); + set_doutput (&code_line); + photo_line_end (&code_line); + + if ( twoDimensional && done != 1 ) + tag = get_bit (&t4_line); + + if ( done == -2 && twoDimensional ) { + while ( tag != oneDtag ) { + resync (&t4_line); + tag = get_bit (&t4_line); + } + } + + } + + bitmap = code_line.dbuf_top; + + (void) free ((char *)buffer1); + (void) free ((char *)buffer2); + + return (photo_end (winname)); + +} + + + +/* ROUTINE: find_node + * + * SYNOPSIS: Reads a sequence of bits from a source line and traverses + * a code word tree to find a matching code word. + */ + +static node * +find_node (lineptr, tree_top) +bit_string * lineptr; +node * tree_top; +{ + node * ptr; + + ptr = tree_top; + + do { + + if (get_bit (lineptr) == 0) { + ptr = ptr->zero; + } + else { + ptr = ptr->one; + } + + if (ptr == NULL) { + (void) fprintf (stderr, + "decode_fax: WARNING - sequencing error in line %d\n", + NUMLINES); + return (NULL); + } + + } while (ptr->n_type == INTERNAL); + + return (ptr); +} + + + +/* ROUTINE: next_run + * + * SYNOPSIS: Reads the next run length from the input file. + * + * DESCRIPTION: As each bit is read, it is used to move down the decode tree, + * when a node is found that contains a value, the value is returned. + * The code is assumed to be one dimensional. +*/ + +run_type +next_run (lineptr,xcolour) +bit_string * lineptr; +char xcolour; +{ + + node * ptr; + run_type result; + + result.run_length = 0; + + if (xcolour == BLACK) + ptr = find_node (lineptr, bl_tree_top); + else + ptr = find_node (lineptr, wt_tree_top); + + if (ptr == NULL) { + result.r_type = ERR_RUN; + return (result); + } + + /* if the above value was a make up code, now read the terminal code */ + + if (ptr->n_type == MAKE) { + if (ptr->value == -1) { + result.r_type = UNCOMPRESSED_1D; + return (result); + } + result.run_length = ptr->value; + if (xcolour == BLACK) + ptr = find_node (lineptr, bl_tree_top); + else + ptr = find_node (lineptr, wt_tree_top); + + if (ptr == NULL) { + result.r_type = ERR_RUN; + return (result); + } + } + + result.run_length += ptr->value; + result.r_type = ptr->n_type; + return (result); +} + + + +/* ROUTINE: decode_one +/* +/* SYNOPSIS: decodes one line of t4. +/* +/* DESCRIPTION: reads a run, then writes that many bits of the appropiate +/* colour to the output. +/* +/* RETURNS: 0 if successful +/* 1 if successful and end of page detected +/* -1 if line could not be decoded +/* -2 if error detected and resync succeeded +*/ + +decode_one (lineptr, t4_lineptr) +bit_string * lineptr; +bit_string * t4_lineptr; + +{ + run_type run; + char xcolour = WHITE; + int done; + int i; + int savelinesize; + + lineptr->run_pos = lineptr->run_top; + + savelinesize = PIC_LINESIZE; + PIC_LINESIZE = 0; + + for (;;) { + run = next_run (t4_lineptr, xcolour); + if (run.r_type == ERR_RUN) { + if (++seqerrs < 10) { + resync (t4_lineptr); + return (-2); + } + else { + fputs ("decode_fax: too many sequencing errors\n", stderr); + return (-1); + } + } + else if (run.r_type == UNCOMPRESSED_1D) { + xcolour = undo_uncompressed_mode (lineptr, t4_lineptr, xcolour, 0); + if (xcolour == -1) return (-1); + } + else if (run.r_type == EOLN) { + break; + } + else { + PIC_LINESIZE += run.run_length; + put_run (lineptr, run.run_length, xcolour); + xcolour = 1 - xcolour; + } + } + + while (get_bit(t4_lineptr) != 01) + ; /* skip fill characters */ + + if (lineptr->run_pos == lineptr->run_top){ + done = 1; + PIC_LINESIZE = savelinesize; + } + else + done = 0; + + STOP = PIC_LINESIZE + 1; + *lineptr->run_pos++ = STOP; + *lineptr->run_pos = STOP; + + return (done); +} + + + +/* ROUTINE: decode_two +/* +/* SYNOPSIS: decodes a two dim line. +/* +/* DESCRIPTION: The binary codes read in are looked up in the decode tree, +/* and the appropiate routine called to decode that mode. +/* +/* RETURNS: 0 if successful +/* -1 if too many sequencing errors +/* -2 if resynch performed +*/ + +decode_two (ref_lineptr, code_lineptr, t4_lineptr) + +bit_string * ref_lineptr; +bit_string * code_lineptr; +bit_string * t4_lineptr; + +{ + int length; + node * ptr; + int status; + + ref_lineptr->run_pos = ref_lineptr->run_top; + code_lineptr->run_pos = code_lineptr->run_top; + + colour = WHITE; + ref_colour = BLACK; + + do { + ptr = find_node (t4_lineptr, two_tree_top); + if (ptr == NULL) { + if (++seqerrs < 10) { + resync (t4_lineptr); + return (-2); + } + else { + fputs ("decode_fax: too many sequencing errors\n", stderr); + return (-1); + } + } + + switch (ptr->value) { + + case -1: + colour = undo_uncompressed_mode (code_lineptr, t4_lineptr, + colour, 1); + if (colour < 0) return (colour); + break; + + case P: + undo_pass_mode (ref_lineptr, code_lineptr); + break; + + case H: + status = undo_horiz_mode (t4_lineptr, code_lineptr); + if (status < 0) return (status); + break; + + case EOLN: + break; + + default: + undo_vert_mode (ref_lineptr, code_lineptr, ptr->value); + break; + } + } while (ptr->n_type != EOLN); + + /* fill to end of line with current colour */ + + length = (int)(PIC_LINESIZE - position + 1); + if (length != 0) + put_run (code_lineptr, length, colour); + + while (get_bit (t4_lineptr) != 1) + ; /* skip fill characters */ + + *code_lineptr->run_pos++ = STOP; + *code_lineptr->run_pos = STOP; + + return (0); +} + + +/* ROUTINE: undo_uncompressed_mode +/* +/* SYNOPSIS: decodes a section recognised as uncompressed mode. +/* +/* DESCRIPTION: Process uncompressed code words until a terminating +/* code word is found. +/* +/* RETURNS: -1 if too many sequencing errors +/* -2 if resynch performed +/* else next colour +*/ + +undo_uncompressed_mode (lineptr, t4_lineptr, colour, twoD) +bit_string * lineptr; +bit_string * t4_lineptr; +int colour; +int twoD; + +{ + int black_length; + int next_colour; + int white_length; + int zeros; + + for (;;) { + zeros = 0; + while (get_bit(t4_lineptr) != 01) ++zeros; + if (zeros > 10) { + fputs ("decode_fax: bad code word in uncompressed mode string\n", + stderr); + if (++seqerrs < 10) { + resync (t4_lineptr); + return (-2); + } + else { + fputs ("decode_fax: too many sequencing errors\n", stderr); + return (-1); + } + } + white_length = uc_white_pels[zeros]; + black_length = uc_black_pels[zeros]; + if (white_length > 0) { + if (colour == BLACK) + --lineptr->run_pos; + put_run (lineptr, white_length, WHITE); + colour = BLACK; + } + if (black_length > 0) { + if (colour == WHITE) + --lineptr->run_pos; + put_run (lineptr, black_length, BLACK); + colour = WHITE; + } + if (!twoD) + PIC_LINESIZE += white_length + black_length; + + if (zeros >= UC_EXIT) { + next_colour = (get_bit(t4_lineptr) == 01) ? BLACK : WHITE; + if (next_colour != colour) + --lineptr->run_pos; + return (next_colour); + } + } +} + +/* ROUTINE: undo_pass_mode +/* +/* SYNOPSIS: decodes a section recognised as pass mode. +/* +/* DESCRIPTION: find b2, then write to output the same colour as before +/* up until position b2. +*/ + +undo_pass_mode (ref_lineptr, code_lineptr) +bit_string * ref_lineptr; +bit_string * code_lineptr; + +{ + int length; + + goto_b1 (ref_lineptr); + + if (*ref_lineptr->run_pos < STOP) { + ++ref_lineptr->run_pos; + ref_colour = 1 - ref_colour; + } + + length = (int)(*ref_lineptr->run_pos - position); + put_run (code_lineptr, length, colour); + --code_lineptr->run_pos; /* don't count this as a change */ +} + + + + +/* ROUTINE: undo_horiz_mode +/* +/* SYNOPSIS: decodes a section recognised as horizontal mode. +/* +/* DESCRIPTION: Read two run lengths for the input, and write the appropiate +/* number of 1's or 0's to the output. +/* +/* RETURNS: 0 if successful +/* -1 if too many sequencing errors +/* -2 if resynch performed +*/ + +undo_horiz_mode (t4_lineptr, code_lineptr) + +bit_string * t4_lineptr; +bit_string * code_lineptr; + +{ + run_type run; + + run = next_run (t4_lineptr, colour); + if (run.r_type == ERR_RUN) { + if (++seqerrs < 10) { + resync (t4_lineptr); + return (-2); + } + else { + fputs ("decode_fax: too many sequencing errors\n", stderr); + return (-1); + } + } + + put_run (code_lineptr, run.run_length, colour); + + run = next_run (t4_lineptr, 1 - colour); + if (run.r_type == ERR_RUN) { + if (++seqerrs < 10) { + resync (t4_lineptr); + return (-2); + } + else { + fputs ("decode_fax: too many sequencing errors\n", stderr); + return (-1); + } + } + + put_run (code_lineptr, run.run_length, 1 - colour); + + return (0); +} + + +/* ROUTINE: undo_vert_mode +/* +/* SYNOPSIS: decodes vertical mode +/* +/* DESCRIPTION: Find b1, the write 1's or 0's upto it allowing for the offset. +*/ + +undo_vert_mode (ref_lineptr, code_lineptr, offset) + +bit_string * ref_lineptr; +bit_string * code_lineptr; +char offset; + +{ + int length; + + goto_b1 (ref_lineptr); + + length = (*ref_lineptr->run_pos - position) + offset - FIXED_OFFSET; + put_run (code_lineptr, length , colour); + colour = 1 - colour; +} + + + +/* ROUTINE: goto_b1 + * + * SYNOPSIS: move the pointer in the reference line to b1 + * + * DESCRIPTION: b1 is the first changing bit in the reference line + * of a different colour to a0. May need to move backwards or forwards + * + */ + +goto_b1 (lineptr) +bit_string * lineptr; + +{ + while (*lineptr->run_pos > position) { + --lineptr->run_pos; + ref_colour = 1 - ref_colour; + } + + while (*lineptr->run_pos < position) { + ++lineptr->run_pos; + ref_colour = 1 - ref_colour; + } + + if (ref_colour == colour) { + ++lineptr->run_pos; + ref_colour = 1 - ref_colour; + } + else if (*lineptr->run_pos < STOP) + + /* special case when b1 = a0, and the colours are different, + move b1 to the next change of same colour, + this must be allowed at the beginning of a line to get a run of + zero, as every line must start with a white element */ + + if ((*lineptr->run_pos == position) && (*lineptr->run_pos > 1)) + lineptr->run_pos += 2; +} + + + +/* ROUTINE: resync +/* +/* SYNOPSIS: resynchronizes sequencing by locating the next EOL +/* +*/ + +static void +resync (lineptr) +bit_string * lineptr; + +{ + int i; + + for (;;) { + while (get_bit (lineptr) == 1) + ; + i = 1; + while (get_bit (lineptr) == 0) + ++i; + if (i > 10) return; + } +} + + + +/* ROUTINE: put_run */ +/* */ +/* SYNOPSIS: writes a run_length to the indicated bit_string. */ +/* */ + +put_run (lineptr, length, xcolour) +bit_string * lineptr; +int length; +char xcolour; +{ + register i; + register l; + +/* + if ( length < 0 ) { + (void) fprintf (stderr, + "decode_fax: WARNING - negative run length (%d) detected in line %d\n", + length, NUMLINES); + } +*/ + + if ( xcolour == WHITE) + photo_white (length); + else + photo_black (length); + + /* now fill line buffer for purpose of decoding 2-d lines */ + + if (length > 16) { + l = length; + if (lineptr->mask != BIT_MASK) { /* fill current byte */ + if (xcolour == WHITE) + do { + clr_bit (lineptr); + --l; + } while (lineptr->mask != BIT_MASK); + + else + do { + set_bit (lineptr); + --l; + } while (lineptr->mask != BIT_MASK); + } + + /* write out the bytes */ + + if (xcolour == WHITE) + for (i = 0; i < l / 8; i++) + *lineptr->dbuf++ = 0; + else + for (i = 0; i < l / 8; i++) + *lineptr->dbuf++ = 0xff; + + + /* put the last few bits into the next byte */ + + if (xcolour == WHITE) + for (i = 0; i < l % 8; i++) + clr_bit (lineptr); + else + for (i = 0; i < l % 8; i++) + set_bit (lineptr); + } + + /* length < 16 - can't optimise, so deal with bits */ + + else { + if (xcolour == WHITE) { + for (i = 0; i < length; i++) clr_bit (lineptr); + } + else { + for (i = 0; i < length; i++) + set_bit (lineptr); + } + } + + position += length; + *lineptr->run_pos++ = position; +} + + + + +/* ROUTINE: set_doutput; +/* +/* SYNOPSIS: Initialises the output buffers +*/ + +set_doutput (lineptr) +bit_string * lineptr; +{ + lineptr->dbuf = lineptr->dbuf_top; + lineptr->mask = BIT_MASK; +} + + + + +/* ROUTINE: flush_doutput; +/* +/* SYNOPSIS: flush the output buffer; +*/ + +flush_doutput (lineptr) +bit_string * lineptr; +{ +int count = 0; + + while ( lineptr->mask != BIT_MASK ) { + clr_bit (lineptr); + count++; + } + photo_white (count); +} + + + +/* ROUTINE: set_dinput; +/* +/* SYNOPSIS: Initialises the input buffers +*/ + +set_dinput (lineptr, length) +bit_string * lineptr; +int length; +{ + unsigned char cbyte; + int count; + int i; + + lineptr->dbuf = lineptr->dbuf_top; + + if (length == 0) { + if (*lineptr->dbuf++ != 0x03) { + (void) fputs ("decode_fax: input stream is not a BIT STRING\n", + stderr); + return (-1); + } + cbyte = *lineptr->dbuf++; + if (cbyte & 0x80) { /* long form */ + count = cbyte & 0x7f; + if (count > 4) { + (void) fputs ("decode_fax: length error\n", stderr); + return (-1); + } + for (i = 0; i < count; ++i) + ++lineptr->dbuf; + } + } + + lineptr->pos = *lineptr->dbuf++; + lineptr->mask = BIT_MASK; + + return (0); +} + diff --git a/usr/src/contrib/isode/others/quipu/photo/e_main.c b/usr/src/contrib/isode/others/quipu/photo/e_main.c new file mode 100644 index 0000000000..0a8d486f82 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/e_main.c @@ -0,0 +1,119 @@ +/* e_main.c - make the encoding routines into a stand alone program */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/e_main.c,v 7.2 91/02/22 09:29:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/e_main.c,v 7.2 91/02/22 09:29:13 mrose Interim $ + * + * + * $Log: e_main.c,v $ + * Revision 7.2 91/02/22 09:29:13 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/15 13:42:47 mrose + * KEJ + * + * Revision 1.2 91/01/05 00:31:32 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:35:21 kej + * Initial revision + * + * Revision 7.0 89/11/23 22:01:38 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include "quipu/photo.h" +#include + +struct pixrect *pr_load(); + +extern int PIC_LINESIZE; +extern int STOP; +extern int NUMLINES; +extern int optlen; + +/* ROUTINE: main +/* +/* DESCRIPTION: Interprets the command line parameters then calls the +/* encoding routine. The format of the command line is as follows:- +/* +/* encode [-K] infile outfile +/* +/* -K is the K parameter default 1 +/* if infile or outfile omitted then stdin or stdout is used. +*/ +char * encode_t4 (); + +main (argc,argv) +int argc; +char ** argv; + +{ +int k_param = 1; +int length; +char * inbuf; +char * outbuf; +FILE * fptr; +struct pixrect *pix; +struct mpr_data *src_mpr; +int skip; + + argv++; + + if ( (argc > 1) && (**argv == '-')) { + switch (*++*argv) { + case '1': k_param = 1;break; + case '2': k_param = 2;break; + case '4': k_param = 4;break; + case 'n': k_param = 1;break; + case 'l': k_param = 2;break; + case 'h': k_param = 4;break; + case 'v': k_param = 32767;break; + default : (void) fprintf (stderr,"Usage: %s -[124nlhv] \n",argv[0]); + exit (-1); + } + argv++; + argc--; + } + + + if ((pix = pr_load (stdin, NULL)) == (struct pixrect *)NULL) + (void) fprintf (stderr,"Not a pixrect.\n"); + + + PIC_LINESIZE = pix->pr_size.x; + STOP = PIC_LINESIZE + 1; + NUMLINES = pix->pr_size.y; + + src_mpr = (struct mpr_data *)(pix->pr_data); + inbuf = (char *) src_mpr->md_image; + + skip = 16 - (PIC_LINESIZE % 16); + if (skip == 16) skip = 0; + + outbuf = encode_t4 (k_param,inbuf,skip); + + fwrite (outbuf, optlen, 1, stdout); + +} + diff --git a/usr/src/contrib/isode/others/quipu/photo/encode.c b/usr/src/contrib/isode/others/quipu/photo/encode.c new file mode 100644 index 0000000000..a95b3cf66f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/encode.c @@ -0,0 +1,699 @@ +/* encode.c - implement encoding routines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/encode.c,v 7.4 91/02/22 09:29:14 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/encode.c,v 7.4 91/02/22 09:29:14 mrose Interim $ + * + * + * $Log: encode.c,v $ + * Revision 7.4 91/02/22 09:29:14 mrose + * Interim 6.8 + * + * Revision 1.6 91/01/08 21:56:34 kej + * Correct bug in flush_output; it wasn't writing the last incomplete + * byte to the output stream. + * + * Revision 1.5 91/01/07 22:20:34 kej + * Fully specify the BIT STRING which contains the G3NonBasicParams. + * + * Revision 1.4 91/01/07 23:50:25 kej + * Support fax images encoded as a SEQUENCE which contains a SET followed by + * a SEQUENCE of BIT STRING. + * + * Revision 1.3 91/01/05 23:31:07 kej + * Implement support for specification of all G3-Fax nonbasic parameters. + * + * Revision 1.2 91/01/05 00:31:34 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:35:28 kej + * Initial revision + * + * Revision 7.1 90/07/09 14:40:25 mrose + * sync + * + * Revision 7.0 89/11/23 22:01:39 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include "quipu/photo.h" + +extern int PIC_LINESIZE,STOP,NUMLINES; + +int a0, a1, b1, b2; /* markers */ +int optlen; + +char * malloc(); + +/* + * G3-Fax nonbasic parameters. + */ + +int twoDimensional = 0; +int fineResolution = 1; +int unlimitedLength = 0; +int b4Length = 0; +int a3Width = 0; +int b4Width = 0; +int uncompressed = 0; +int standardwidth = 0; +int forcesize = 0; +/* encoding format options */ + +int nopreamble = 0; +int oldformat = 0; + + +/* ROUTINE: encode_t4 +/* +/* SYNOPSIS: Implements CCITT recommendation T.4. +/* This recomendation is concerned with compressing of bit maps. +/* +/* DESCRIPTION: +/* This routine sets up the data buffers, then calls routines +/* to encode one line of the bit map. A line can be encoded either one +/* dimensionally or two dimensionally depending upon the 'k parameter'. +/* +/* When a line is encoded two dimensionally, the line before is used as a +/* reference. For each line encoded, a record of where the run changes occur +/* are kept. This is the used as the reference. +/* +*/ + + +char * encode_t4 (k_param, inbuf, eolnskip) +int k_param; +char * inbuf; +int eolnskip; + +{ + bit_string ref_line; /* Reference line */ + bit_string t4_line; /* Output encoded line */ + bit_string code_line; /* Line we are codeing */ + + short i,j; /* Loop variable */ + int run_buf [LINEBUF], run_buf2 [LINEBUF]; + + if (a3Width) + forcesize = 2432; + if (b4Width) + forcesize = 2048; + if (standardwidth) + forcesize = 1728; + + ref_line.run_top = run_buf; + code_line.run_top = run_buf2; + + code_line.dbuf_top = inbuf; + t4_line.dbuf_top = malloc ((PIC_LINESIZE * NUMLINES) + 28); + + set_input (&code_line); + set_output (&t4_line); + + /* Repeat this loop once for every input line expected */ + + for (i = 0; i < NUMLINES; i++) { + + if (code_line.run_top == run_buf) { /*swap buffers*/ + ref_line.run_top = run_buf; + code_line.run_top = run_buf2; + } else { + ref_line.run_top = run_buf2; + code_line.run_top = run_buf; + } + + /* reset pointers */ + + code_line.run_pos = code_line.run_top; + ref_line.run_pos = ref_line.run_top; + + /* fill buffer for coding line */ + + get_runs (&code_line); + code_line.run_pos = code_line.run_top; + + put_eoln (&t4_line); + + if (k_param > 1) { + if (i % k_param == 0) { + set_bit (&t4_line); /* tag bit, 1-d line follows */ + code_one (&code_line, &t4_line); + } + else { + clr_bit (&t4_line); /* tag bit, 2-d line follows */ + code_two (&ref_line, &code_line, &t4_line); + } + } + else + code_one (&code_line, &t4_line); + + /* skip any extra eoln bit in orig data */ + + for (j = 0; j < eolnskip; j++) + get_bit (&code_line); + + } + + /* now finish with 6 EOL's, as per T.4 */ + + for (i = 0; i < 5; ++i) { + put_eoln (&t4_line); + if (k_param > 1) set_bit (&t4_line); + } + + /* flush buffers, write preamble */ + + flush_output (&t4_line); + return (t4_line.dbuf_top); +} + + + +/* ROUTINE: code_one +/* +/* SYNOPSIS: codes one line of a bit map into t4 +/* +/* DESCRIPTION: +/* To encode a line one dimensionally, bits are read in until +/* a change is noticed, when this happens, the run_length code for the number +/* of bits read in is found, and written to the output file. +/* +/* A run_length code may consist of two parts if the run is large, a make up +/* and a terminal code. +*/ + +code_one (lineptr,t4_lineptr) + +bit_string * lineptr; /* input line */ +bit_string * t4_lineptr; /* output line */ + +{ + char colour = WHITE; /* the colour of the current bit */ + full_code code; /* the code for the characters run_length */ + int old_pos = 1; /* the number of bits of the same colur read in */ + int len = 0; + int tlen; + + if (forcesize) { + len = (forcesize - PIC_LINESIZE)/ 2; + code = get_code ( len, WHITE); + if (code.make.length != 0) + put_code (t4_lineptr,code.make); /* the make code */ + put_code (t4_lineptr, code.term); /* the terminal code */ + code = get_code (0,BLACK); + put_code (t4_lineptr, code.term); + } + + do { + + /* get code for next run = pos of current change - pos of last change */ + tlen = *++lineptr->run_pos - old_pos; + len += tlen; + code = get_code (tlen,colour); + + if (code.make.length != 0) + put_code (t4_lineptr,code.make); /* the make code */ + put_code (t4_lineptr, code.term); /* the terminal code */ + colour = 1 - colour; + old_pos = *lineptr->run_pos; + + } while (*lineptr->run_pos <= PIC_LINESIZE); + + if (forcesize) { + if (colour == BLACK) { + code = get_code (0,colour); + put_code (t4_lineptr, code.term); + } + colour = 1 - colour; + + code = get_code ( forcesize - len, colour); + if (code.make.length != 0) + put_code (t4_lineptr,code.make); /* the make code */ + put_code (t4_lineptr, code.term); /* the terminal code */ + } +} + + + + + + +/* ROUTINE: code_two +/* +/* SYNOPSIS: Codes one line of a bit map two dimensionally as +/* described by CCITT T.4. +/* +/* DESCRIPTION: Two lines are compared by looking at the list of run changes. +/* In order to do this, this list has to be created for the line we are about +/* to encode. The encoding procedure then follows the flow chart in the CCITT +/* recommendation. This is summarised as follows: +/* +/* 1. Find the positions a0, a1, b1, b2. +/* 2. Compare to see which mode is required. +/* +/* The positions of a1, b1, b2 are found from the run change list. a0 is known +/* in advance. +*/ + +code_two (ref_lineptr,code_lineptr,t4_lineptr) + +bit_string * ref_lineptr; /* reference line */ +bit_string * code_lineptr; /* line to encode */ +bit_string * t4_lineptr; /* output line */ + +{ + char colour = WHITE; + char ref_colour = WHITE; + + a0 = 0; + code_lineptr->run_pos = code_lineptr->run_top; + + do { + + /* find a1 */ + + while (*code_lineptr->run_pos > a0) + --code_lineptr->run_pos; + + while (*code_lineptr->run_pos <= a0 && *code_lineptr->run_pos < STOP) + ++code_lineptr->run_pos; + + a1 = *code_lineptr->run_pos; + + /* find b1 and b2 */ + + while (*ref_lineptr->run_pos > a0) { + ref_colour = 1 - ref_colour; + --ref_lineptr->run_pos; + } + + while (*ref_lineptr->run_pos <= a0 && *ref_lineptr->run_pos < STOP ) { + ref_colour = 1 - ref_colour; + ++ref_lineptr->run_pos; + } + + if (ref_colour == colour && *ref_lineptr->run_pos < STOP) { + ref_lineptr->run_pos++; + ref_colour = 1 - ref_colour; + } + + b1 = *ref_lineptr->run_pos; + if (b1 >= STOP) + b2 = STOP; + else + b2 = *(ref_lineptr->run_pos + 1); + + /* select mode and code it */ + + if (a1 > b2) { + pass_mode (t4_lineptr); + } + else if (abs (a1 - b1) <= 3) { + vertical_mode (t4_lineptr); + colour = 1 - colour; + } + else + horizontal_mode (code_lineptr,t4_lineptr,colour); + + } while (a0 < STOP); +} + + +/* ROUTINE: Pass_mode +/* +/* SYNOPSIS: Encodes pass_mode +/* +/* DESCRIPTION: When pass mode is detected, the pass mode code is written to +/* the output, and a0 is moved to underneath b2. +*/ + +pass_mode (t4_lineptr) +bit_string * t4_lineptr; + +{ + static code_word code = {4,0x0200}; + + put_code (t4_lineptr,code); + a0 = b2; +} + + +/* ROUTINE: Vertical_mode +/* +/* SYNOPSIS: Encodes vertical mode. +/* +/* DESCRIPTION: Vertical mode is encoded by writing a particualr code +/* depending on the offset between a1 and b1. +/* a0 is moved to a1 +*/ + +vertical_mode (t4_lineptr) + +bit_string * t4_lineptr; + +{ + static code_word code [7] = { + {7,0x080 }, /* -3 */ + {6,0x100 }, /* -2 */ + {3,0x800 }, /* -1 */ + {1,0x1000 }, /* 0 */ + {3,0xc00 }, /* 1 */ + {6,0x180 }, /* 2 */ + {7,0xc0 }, /* 3 */ + }; + + put_code (t4_lineptr, code[a1 - b1 + 3]); + a0 = a1; +} + + + + +/* ROUTINE: Horizontal_mode +/* +/* SYNOPSIS: Encodes horizontal mode +/* +/* DESCRIPTION: When horizontal mode is detected no further compaction can +/* can take place, so the next two run lengths are written to the output. +/* a0 is moved to after these runs. +*/ + +horizontal_mode (code_lineptr,t4_lineptr,colour) + +bit_string * t4_lineptr; +bit_string * code_lineptr; +char colour; + +{ + int a2; + static code_word h_code = {3,0x0400}; + full_code code; + + if (a0 == 0) /* special case at start of line */ + a0 = 1; + + /* find a2 */ + + a2 = *(++code_lineptr->run_pos); + if (a2 >= STOP) + code_lineptr->run_pos--; + + put_code (t4_lineptr, h_code); /* code for horiz mode */ + + /* get & put first run */ + + code = get_code (a1 - a0, colour); + if (code.make.length != 0) + put_code (t4_lineptr, code.make); + put_code (t4_lineptr, code.term); + + /* get & put second run */ + + code = get_code (a2 - a1, 1 - colour); + if (code.make.length != 0) + put_code (t4_lineptr, code.make); + put_code (t4_lineptr, code.term); + + a0 = a2; +} + + +/* ROUTINE: Put_code () */ +/* */ +/* SYNOPSIS: appends the code word to the 'line'. */ +/* */ + +put_code (lineptr,code) + +bit_string * lineptr; +code_word code; +{ + + int i; + short mask; + + mask = MSB_MASK; /* set mask to first bit of pattern */ + + for (i=0; i< code.length ; i++) { + if ((code.pattern & mask) == WHITE) + clr_bit (lineptr); + else + set_bit (lineptr); + + mask >>= 1; + } +} + + + + +/* ROUTINE: put_eoln */ +/* */ +/* SYNOPSIS: Puts an end of line marker at the end of a t4 line. */ +/* An end of line (eoln) marker is 11 (or more) zero's */ +/* followed by a 1. */ + +put_eoln (lineptr) + +bit_string * lineptr; + +{ + int i; + + for (i=0 ; i< 11; i++) + clr_bit (lineptr); + + set_bit (lineptr); +} + + + +/* ROUTINE: get_runs + * + * SYNOPSIS: set the runs change buffer fo the next input line + * + * DESCRIPTION: To optimise the input process, sequences of all 1's or 0's + * - the most likely combinations are looked for as special cases, if not + * found the runs are counted as bits. + * + */ + +get_runs (lineptr) +bit_string * lineptr; + +{ + register i,j; + char colour = WHITE; + + *lineptr->run_pos++ = 0; + + for (i = 1; i <= PIC_LINESIZE; i++) + if (get_bit (lineptr) != colour) { + *(lineptr->run_pos++) = i; + colour = 1 - colour; + } + + *lineptr->run_pos++ = STOP; + *lineptr->run_pos = STOP; +} + +/* ROUTINE: set_output; + * + * SYNOPSIS: Initialises the output buffers, writes the ENODE id, and + * leaves room for the length (to be filled in later); +*/ + +set_output (lineptr) +bit_string * lineptr; +{ + lineptr->dbuf_top += 28; /* leave room for ASN.1 preamble */ + lineptr->dbuf = lineptr->dbuf_top; + lineptr->mask = BIT_MASK; +} + + + +/* ROUTINE: flush_output; + * + * SYNOPSIS: Flush the output buffer, and set the ASN.1 preamble if + * allowed. The normal preamble consists of a SEQUENCE definition + * which wraps a SET and a SEQUENCE of BIT STRING. The SET + * includes G3-Fax nonbasic parameter indications (such as + * twoDimensional, fineResolution, etc.). Optionally, the + * old BIT STRING-ish preamble may be selected. + */ + +flush_output (lineptr) +bit_string * lineptr; +{ + long length, len; + int count, i; + + if ( lineptr->mask != BIT_MASK ) /* writes last char if necessary */ + *lineptr->dbuf++ = lineptr->pos; + + if ( nopreamble ) { + optlen = lineptr->dbuf - lineptr->dbuf_top; + return; + } + + /* set byte which indicates unused bits in last byte of image data */ + + if ( !oldformat ) + *(--lineptr->dbuf_top) = 0x00; + + /* set image length */ + + len = length = lineptr->dbuf - lineptr->dbuf_top; + + if (length <= 127) { /* short form length */ + *(--lineptr->dbuf_top) = length; + } + else { + + /* see how many bytes needed for length */ + + count = 0; + + while (len != 0) + { + len >>= 8; + count++; + } + + /* go back and write this info */ + + for (i = 0; i < count; i++) + *(--lineptr->dbuf_top) = (length >> (8 * i)); + + *(--lineptr->dbuf_top) = 0x80 + count; /* length marker*/ + } + + /* set BIT STRING identifier */ + + *(--lineptr->dbuf_top) = 0x03; + + if ( oldformat ) { + optlen = lineptr->dbuf - lineptr->dbuf_top; + return; + } + + /* set length of BIT STRING sequence */ + + len = length = lineptr->dbuf - lineptr->dbuf_top; + + if (length <= 127) { /* short form length */ + *(--lineptr->dbuf_top) = length; + } + else { + + /* see how many bytes needed for length */ + + count = 0; + + while (len != 0) + { + len >>= 8; + count++; + } + + /* go back and write this info */ + + for (i = 0; i < count; i++) + *(--lineptr->dbuf_top) = (length >> (8 * i)); + + *(--lineptr->dbuf_top) = 0x80 + count; /* length marker*/ + } + + /* set SEQUENCE identifier */ + + *(--lineptr->dbuf_top) = 0x30; + + /* set SET which includes g3NonBasicParams */ + + *(--lineptr->dbuf_top) = uncompressed ? 0x02 : 0x00; + + *(--lineptr->dbuf_top) = 0; + if (unlimitedLength) *lineptr->dbuf_top |= 0x08; + if (b4Length) *lineptr->dbuf_top |= 0x04; + if (a3Width) *lineptr->dbuf_top |= 0x02; + if (b4Width) *lineptr->dbuf_top |= 0x01; + + *(--lineptr->dbuf_top) = 0; + if (twoDimensional) *lineptr->dbuf_top |= 0x80; + if (fineResolution) *lineptr->dbuf_top |= 0x40; + + *(--lineptr->dbuf_top) = 0x00; /* first byte of BIT STRING */ + *(--lineptr->dbuf_top) = 0x01; /* count of unused bits */ + *(--lineptr->dbuf_top) = 5; /* BIT STRING length */ + *(--lineptr->dbuf_top) = 0x81; /* [1] IMPLICIT G3NonBasicParams */ + *(--lineptr->dbuf_top) = 7; /* length of SET */ + *(--lineptr->dbuf_top) = 0x31; /* SET */ + + /* set length of entire sequence */ + + len = length = lineptr->dbuf - lineptr->dbuf_top; + + if (length <= 127) { /* short form length */ + *(--lineptr->dbuf_top) = length; + } + else { + + /* see how many bytes needed for length */ + + count = 0; + + while (len != 0) + { + len >>= 8; + count++; + } + + /* go back and write this info */ + + for (i = 0; i < count; i++) + *(--lineptr->dbuf_top) = (length >> (8 * i)); + + *(--lineptr->dbuf_top) = 0x80 + count; /* length marker*/ + } + + /* set [3] IMPLICIT G3Fax identifier */ + + *(--lineptr->dbuf_top) = 0xa3; + + optlen = lineptr->dbuf - lineptr->dbuf_top; +} + + +/* ROUTINE: set_input; +/* +/* SYNOPSIS: Initialises the input buffers +*/ + +set_input (lineptr) +bit_string * lineptr; +{ + lineptr->mask = BIT_MASK; + lineptr->dbuf = lineptr->dbuf_top; + lineptr->pos = *lineptr->dbuf++; +} diff --git a/usr/src/contrib/isode/others/quipu/photo/faxtopbm.c b/usr/src/contrib/isode/others/quipu/photo/faxtopbm.c new file mode 100644 index 0000000000..6e1f5f9c21 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/faxtopbm.c @@ -0,0 +1,377 @@ +/* faxtopbm.c - FAX to pbm filter */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/faxtopbm.c,v 7.2 91/02/22 09:29:17 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/faxtopbm.c,v 7.2 91/02/22 09:29:17 mrose Interim $ + * + * + * $Log: faxtopbm.c,v $ + * Revision 7.2 91/02/22 09:29:17 mrose + * Interim 6.8 + * + * Revision 1.3 91/01/07 23:50:28 kej + * Support fax images encoded as a SEQUENCE which contains a SET followed by + * a SEQUENCE of BIT STRING. + * + * Revision 1.2 91/01/05 00:31:36 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:35:35 kej + * Initial revision + * + * Revision 7.0 89/11/23 22:01:41 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "psap.h" +#include "pbm.h" + +/* */ + +#define ALLOCATION_SIZE 16384L + +static int passno; + +static bit black, white; + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + char *cp; + char *data; + int fd; + char *file; + int len; + long limit; + PE member; + char *newData; + PE pe; + PS ps; + PE seq; + PE set; + long size; + int twoDimensional = 0; + + /* process command options and parameters */ + + black = PBM_BLACK; + white = PBM_WHITE; + + file = NULLCP; + fd = fileno (stdin); + + for (argv++; cp = *argv; argv++) { + if (*cp == '-') { + if (cp[1] == NULL) { + continue; + } + else if (strcmp (cp, "-reversebits") == 0) { + black = PBM_WHITE; + white = PBM_BLACK; + continue; + } + else if (strcmp (cp, "-2d") == 0) { + twoDimensional = 1; + continue; + } + goto usage; + } + else if (file) { +usage: ; + fprintf (stderr, "usage: faxtopbm [-2d] [file]\n"); + exit (1); + } + else { + file = cp; + } + } + + if ( file == NULLCP ) { + file = ""; + } + else { + fd = open (file, O_RDONLY); + if ( fd == -1 ) { + perror (file); + exit (1); + } + } + + /* read the entire source file into memory */ + + data = (char *)malloc (ALLOCATION_SIZE); + if ( !data ) { + fputs ("faxtopbm: out of memory\n", stderr); + exit (1); + } + limit = ALLOCATION_SIZE; + size = 0L; + + for (;;) { + if (size + ALLOCATION_SIZE > limit) { + newData = (char *)realloc (data, limit + ALLOCATION_SIZE); + if ( !newData ) { + fputs ("faxtopbm: out of memory\n", stderr); + exit (1); + } + data = newData; + limit += ALLOCATION_SIZE; + } + len = read (fd, &data[size], ALLOCATION_SIZE); + if (len == -1) { + perror (file); + exit (1); + } + else if (len == 0) + break; + size += len; + } + + if (size < 1) { + fprintf (stderr, "%s: is not a fax image\n", file); + exit (1); + } + + /* + * If the first byte does not indicate that the data is an ASN.1-encoded + * SET or BIT STRING, attempt to convert the data as a non-ASN.1 image. + */ + + if ((unsigned char)*data != 0xa3 && *data != 0x03) { + for (passno = 1; passno < 3; passno++) { + if (decode_t4_aux (data, file, (int)size, twoDimensional) == NOTOK) + exit (1); + } + free (data); + exit (0); + } + + /* attempt to decode the source */ + + if ((ps = ps_alloc (str_open)) == NULLPS) { + fprintf (stderr, "ps_alloc: unable to allocate presentation stream\n"); + exit (1); + } + if (str_setup (ps, data, (int)size, 0) == NOTOK) + ps_die (ps, "str_setup"); + if ((pe = ps2pe (ps)) == NULLPE) { /* maybe it's a non-ASN.1 image */ + ps_free (ps); + for (passno = 1; passno < 3; passno++) { + if (decode_t4_aux (data, file, (int)size, twoDimensional) == NOTOK) + exit (1); + } + free (data); + exit (0); + } + if (pe->pe_class == PE_CLASS_UNIV && pe->pe_form == PE_FORM_PRIM && + pe->pe_id == PE_PRIM_BITS) { /* old BIT STRING-like form */ + if (pe_pullup (pe) == NOTOK) + pe_die (pe, "pe_pullup"); + for (passno = 1; passno < 3; passno++) { + if (decode_t4_aux (pe -> pe_prim, file, ps_get_abs (pe), 1) == NOTOK) + exit (1); + } + } + else if (pe->pe_class == PE_CLASS_CONT && pe->pe_form == PE_FORM_CONS && + pe->pe_id == 3) { + + /* first member must be SET which describes G3-Fax options */ + + set = first_member (pe); + if (!set || set->pe_class != PE_CLASS_UNIV || + set->pe_form != PE_FORM_CONS || set->pe_id != PE_CONS_SET) { + fprintf (stderr, "decode_fax: %s is not a fax image\n", file); + exit (1); + } + + for (member = first_member (set); member; member = next_member (set, member)) { + if (member->pe_class == PE_CLASS_CONT && + member->pe_form == PE_FORM_PRIM && member->pe_id == 1) { + twoDimensional = bit_test (prim2bit (member), 8); + if (twoDimensional == -1) + pe_die (member, "bit_test"); + } + } + + /* SEQUENCE of BIT STRING should follow SET */ + + seq = next_member (pe, set); + if (!seq || seq->pe_class != PE_CLASS_UNIV || + seq->pe_form != PE_FORM_CONS || seq->pe_id != PE_CONS_SEQ) { + fprintf (stderr, "%s: is not a fax image\n", file); + exit (1); + } + + for (member = first_member (seq); member; member = next_member (seq, member)) { + if (member->pe_class != PE_CLASS_UNIV || + member->pe_form != PE_FORM_PRIM || + member->pe_id != PE_PRIM_BITS) { + fprintf (stderr, "%s: is not a fax image\n", file); + exit (1); + } + for (passno = 1; passno < 3; passno++) { + if (decode_t4_aux ((member->pe_prim) + 1, file, + ps_get_abs (member) - 1, + twoDimensional) == NOTOK) + exit (1); + } + } + } + else { /* maybe its a non-ASN.1 image */ + pe_free (pe); + ps_free (ps); + for (passno = 1; passno < 3; passno++) { + if (decode_t4_aux (data, file, (int)size, twoDimensional) == NOTOK) + exit (1); + } + free (data); + exit (0); + } + + pe_free (pe); + ps_free (ps); + free (data); + + exit (0); +} + +/* ERRORS */ + +static ps_die (ps, s) +register PS ps; +register char *s; +{ + fprintf (stderr, "%s: %s\n", s, ps_error (ps -> ps_errno)); + exit (1); +} + + +static pe_die (pe, s) +register PE pe; +register char *s; +{ + fprintf (stderr, "%s: %s\n", s, pe_error (pe -> pe_errno)); + exit (1); +} + +/* PHOTO */ + +static int x, y, maxx; + +static bit *bitrow, *bP; + + +/* ARGSUSED */ + +photo_start(name) +char *name; +{ + if (passno == 1) + maxx = 0; + x = y = 0; + + return OK; +} + + +/* ARGSUSED */ + +photo_end (name) +char *name; +{ + if (passno == 1) { + register int i; + + x = maxx, y--; + + pbm_writepbminit (stdout, maxx, y); + bitrow = pbm_allocrow (maxx); + + for (i = maxx, bP = bitrow; i-- > 0; ) + *bP++ = white; + bP = bitrow; + } + else + pbm_freerow (bitrow); + + return OK; +} + + +photo_black (length) +int length; +{ + if (passno == 2) { + register int i; + + for (i = length; i > 0; i--) + *bP++ = black; + } + + x += length; + + return OK; +} + + +photo_white (length) +int length; +{ + if (passno == 2) + bP += length; + + x += length; + + return OK; +} + + +/* ARGSUSED */ + +photo_line_end (line) +caddr_t line; +{ + if (passno == 1) { + if (x > maxx) + maxx = x; + } + else { + register int i; + + pbm_writepbmrow (stdout, bitrow, maxx); + + for (i = maxx, bP = bitrow; i-- > 0; ) + *bP++ = white; + bP = bitrow; + } + + x = 0, y++; + + return OK; +} diff --git a/usr/src/contrib/isode/others/quipu/photo/faxx.c b/usr/src/contrib/isode/others/quipu/photo/faxx.c new file mode 100644 index 0000000000..55dea78341 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/faxx.c @@ -0,0 +1,240 @@ +/* winx.c - xwindow version of display code */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/faxx.c,v 7.1 91/02/22 09:29:19 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/faxx.c,v 7.1 91/02/22 09:29:19 mrose Interim $ + * + * + * $Log: faxx.c,v $ + * Revision 7.1 91/02/22 09:29:19 mrose + * Interim 6.8 + * + * Revision 1.3 91/01/24 16:59:28 kej + * EPXA612. Fix various problems with the encoding and decoding of 2-d + * fax images. Also, make the code word tables complete and implement + * support for decoding of uncompressed mode. + * + * Revision 1.2 91/01/18 23:44:53 kej + * Critical. Fix problems introduced by Colin Robbins `fixes'. + * + * Revision 1.1 91/01/10 00:31:45 kej + * Initial revision + * + * Revision 1.2 91/01/05 00:31:41 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:36:47 kej + * Initial revision + * + * Revision 7.0 89/11/23 22:01:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include "quipu/photo.h" +#include +#include +#include + + +/* It appears that window manager writers have problems */ + +#ifndef NEVER_USE_WM +#define WM_DISAPPEARED_BUG /* wm screw up & loses the window ! */ +#define WM_WINGE_BUG /* When wm screws up, it also winges */ +#endif NEVER_USE_WM + +#ifndef NEVER_USE_TWM +#define TWM_RESIZE_BUG /* twm looses the resize if done too early. */ +#endif NEVER_USE_TWM + + +extern GC XCreateGC(); +Pixmap pixmap; +Display *dpy; +Screen *scr; +Window win; +int winX, winY, winW, winH; +XSetWindowAttributes xswa; +GC gc; +extern int NUMLINES,PIC_LINESIZE; +extern unsigned position; +unsigned long XorVal; +int buttons_down = 0; +int ignore_action = 0; + +static int passno = 1; +static int x, y, maxx; + +static int decimation = 2; + +extern int two_passes; + +photo_start (name) +char * name; +{ + x = y = 0; + if (passno == 1) { + maxx = 0; + two_passes = 1; + } + return 0; +} + + +photo_end (name) +char * name; +{ + + /* Decoding has finished - display the photo */ + + if (passno == 1) { + passno = 2; + x = maxx; + --y; + + /* Initialise a window to recieve a photo of 'name' */ + + if (!(dpy= XOpenDisplay((char *) 0))) { + (void) printf ("Cannot open X display"); + return (-1); + } + scr = DefaultScreenOfDisplay(dpy); + winW = x / decimation; + winH = y / decimation; + winX = WidthOfScreen(scr) - winW; + winY = HeightOfScreen(scr) - winH; + + xswa.event_mask = ExposureMask | ButtonReleaseMask | ButtonPressMask; + + xswa.background_pixel = BlackPixelOfScreen(scr); + xswa.backing_store = WhenMapped; + + win = XCreateWindow(dpy, RootWindowOfScreen(scr), + winX, winY, winW, winH, 0, + DefaultDepthOfScreen(scr), InputOutput, + DefaultVisualOfScreen(scr), + CWEventMask | CWBackPixel | CWBackingStore, &xswa); + pixmap = XCreatePixmap(dpy, win, + winW,winH, DefaultDepthOfScreen(scr)); + if (!pixmap) { + (void) fprintf (stderr,"decode_fax: Pixmap failed"); + return (-1); + } + + /* Set up a graphics context: */ + + gc = XCreateGC(dpy, pixmap, 0, NULL); + + /* Clear pixmap */ + + XSetForeground(dpy, gc, BlackPixelOfScreen(scr)); + XFillRectangle(dpy, pixmap, gc, 0, 0, winW,winH); + + XSetForeground(dpy, gc, WhitePixelOfScreen(scr)); + XSetBackground(dpy, gc, BlackPixelOfScreen(scr)); + + XorVal = WhitePixelOfScreen(scr) ^ BlackPixelOfScreen(scr); + + return (0); + } + + XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8, + PropModeReplace, "Fax", 3); + XMapWindow(dpy, win); + XSetForeground(dpy, gc, XorVal); + for (;;) + { XEvent xev; + + XNextEvent(dpy, &xev); + switch (xev.type) + { + case ButtonPress: + if (buttons_down++) + { if (!ignore_action++) + { XSetFunction(dpy, gc, GXcopy); + XCopyArea(dpy, pixmap, win, + gc, 0, 0, + PIC_LINESIZE, NUMLINES, + 0, 0); + } + } + else + { XSetFunction(dpy, gc, GXxor); + XFillRectangle(dpy, win, gc, + 0, 0, PIC_LINESIZE, NUMLINES); + } + continue; + case ButtonRelease: + if (!buttons_down) buttons_down++; + if (--buttons_down) continue; + if (!ignore_action) break; + ignore_action = 0; + continue; + case Expose: + XSetFunction(dpy, gc, GXcopy); + XCopyArea(dpy, pixmap, win, gc, + xev.xexpose.x, xev.xexpose.y, + xev.xexpose.width, xev.xexpose.height, + xev.xexpose.x, xev.xexpose.y); + default: + continue; + } + break; + } + return 0; +} + +photo_black (length) +int length; +{ + x += length; + return 0; +} + +photo_white (length) +int length; +{ + int x1; + int x2; + int y1; + + if (passno == 2 && length > 0 && y % decimation == 0) { + y1 = y / decimation; + x1 = x / decimation; + x2 = (x + length - 1) / decimation; + XDrawLine (dpy, pixmap, gc, x1, y1, x2, y1); + } + x += length; + return 0; +} + + +photo_line_end (line) +bit_string * line; +{ + if (passno == 1 && x > maxx) + maxx = x; + x = 0; + ++y; + return 0; +} diff --git a/usr/src/contrib/isode/others/quipu/photo/hexphoto.c b/usr/src/contrib/isode/others/quipu/photo/hexphoto.c new file mode 100644 index 0000000000..a1d39d73ed --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/hexphoto.c @@ -0,0 +1,72 @@ +/* hexphoto.c - your comments here */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/hexphoto.c,v 7.2 91/02/22 09:29:20 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/hexphoto.c,v 7.2 91/02/22 09:29:20 mrose Interim $ + * + * + * $Log: hexphoto.c,v $ + * Revision 7.2 91/02/22 09:29:20 mrose + * Interim 6.8 + * + * Revision 7.1 90/09/24 15:36:47 mrose + * update + * + * Revision 7.0 89/11/23 22:01:42 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/photo.h" +#include "psap.h" + +decode_t4 (picture,persons_name, len) +char *picture; +char *persons_name; +{ +int i; + + if (len == 0) len = photolen (picture); + + for (i=0; i 127 for now */ + for (i=0; i +#include "quipu/photo.h" + +/* This file contains utility routines used by both the */ +/* encoding and decoding programs. */ +/* The routines are concerned with getting and setting bits of */ +/* a bit string. */ + +/* All these routine work in basically the same way. +/* a mask is used to get at each individual bit within +/* a byte. Each time the next bit is required, the +/* mask is shifted right, when the mask is zero, the byte is either +/* written to the file, or the next byte read in depending upon the +/* routine. +*/ + +int PIC_LINESIZE,STOP,NUMLINES; + +/* ROUTINE: Get_bit */ +/* */ +/* SYNOPSIS: Gets the next bit from the input. */ +/* Returns 0 if it is a zero. */ +/* Returns 1 if it is a one */ +char +get_bit (lineptr) + +bit_string * lineptr; /* the line to get the bit from */ + +{ +unsigned char result; + + /* Anding the mask and the data gives a 0 if the bit masked is 0, 1 otherwis +e */ + result = lineptr->mask & lineptr->pos; + + lineptr->mask >>= 1; + + if (lineptr->mask == 0) { + lineptr->pos = *lineptr->dbuf++; + lineptr->mask = BIT_MASK; + } + + if( result != 0 ) /* may not be 1, may be 0001000 for example */ + result = 1; + + return ( (char) result ); +} + + + +/* ROUTINE: Set_bit */ +/* */ +/* SYNOPSIS: Sets the next bit of the bit string pointed to by */ +/* lineptr to a one. */ + +set_bit (lineptr) + +bit_string * lineptr; + +{ + /* This sets the masked bit */ + lineptr->pos |= lineptr->mask; + + lineptr->mask >>= 1; + + if (lineptr->mask == 0) { + *lineptr->dbuf++ = lineptr->pos; + lineptr->mask = BIT_MASK; + } + +} + + + + +/* ROUTINE: Clr_bit */ +/* */ +/* SYNOPSIS: clears the next bit of the bit string pointed to by */ +/* lineptr. i.e set it to zero. */ + +clr_bit (lineptr) + +bit_string * lineptr; + +{ + /* clear the masked bit */ + lineptr->pos &= ~(lineptr->mask) ; + + lineptr->mask >>= 1; /* right shift the mask */ + + if (lineptr->mask == 0) { /* may need to move on to the next byte */ + *lineptr->dbuf++ = lineptr->pos; + lineptr->mask = BIT_MASK; + } + +} + + + + diff --git a/usr/src/contrib/isode/others/quipu/photo/make b/usr/src/contrib/isode/others/quipu/photo/make new file mode 100644 index 0000000000..652a89e9e4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../ -f ../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/photo/pbmtofax.c b/usr/src/contrib/isode/others/quipu/photo/pbmtofax.c new file mode 100644 index 0000000000..efb01bcfb3 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/pbmtofax.c @@ -0,0 +1,222 @@ +/* pbmtofax.c - pbm to FAX filter */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/pbmtofax.c,v 7.4 91/02/22 09:29:23 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/pbmtofax.c,v 7.4 91/02/22 09:29:23 mrose Interim $ + * + * + * $Log: pbmtofax.c,v $ + * Revision 7.4 91/02/22 09:29:23 mrose + * Interim 6.8 + * + * Revision 1.4 91/01/07 23:50:30 kej + * Support fax images encoded as a SEQUENCE which contains a SET followed by + * a SEQUENCE of BIT STRING. + * + * Revision 1.3 91/01/05 23:32:00 kej + * Implement support for specification of all G3-Fax nonbasic parameters. + * + * Revision 1.2 91/01/05 00:31:39 kej + * ISODE claimed to be creating fax images as ASN.1-encoded BIT STRING's. + * However, the encoding was incorrect. This revision corrects the + * problem, implements 1-d and 2-d encoding of fax images, and it provides + * a backward compatible mechanism for reading the old, broken images. + * + * Revision 1.1 91/01/02 21:36:31 kej + * Initial revision + * + * Revision 7.1 90/07/09 14:40:29 mrose + * sync + * + * Revision 7.0 89/11/23 22:01:46 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "quipu/photo.h" +#include "pbm.h" + +/* DATA */ + +int PIC_LINESIZE, STOP, NUMLINES; + +extern int optlen; + +char *encode_t4 (); + +char *malloc (); + +/* + * G3-Fax nonbasic parameters. + */ + +extern int twoDimensional; +extern int fineResolution; +extern int unlimitedLength; +extern int b4Length; +extern int a3Width; +extern int b4Width; +extern int uncompressed; +extern int nopreamble; +extern int oldformat; +extern int standardwidth; + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int bitcount; + bit *bitrow; + register bit *bP; + unsigned char *byteP; + register int i; + register int j; + int cols, + format, + rows, + skip; + char *cp, + *data, + *file, + *optbuf; + bit black; + FILE *fp; + + black = PBM_BLACK; + + file = NULL; + fp = stdin; + + for (argv++; cp = *argv; argv++) { + if (*cp == '-') { + if (cp[1] == NULL) + continue; + + else if (strcmp (cp, "-reversebits") == 0) + black = PBM_WHITE; + + else if (strcmp (cp, "-2d") == 0) + twoDimensional = 1; + + else if (strcmp (cp, "-cr") == 0) + fineResolution = 0; + + else if (strcmp (cp, "-ul") == 0) + unlimitedLength = 1; + + else if (strcmp (cp, "-b4l") == 0) + b4Length = 1; + + else if (strcmp (cp, "-a3w") == 0) + a3Width = 1; + + else if (strcmp (cp, "-b4w") == 0) + b4Width = 1; + + else if (strcmp (cp, "-uc") == 0) + uncompressed = 1; + + else if (strcmp (cp, "-sw") == 0) + standardwidth = 1; + + else if (strcmp (cp, "-old") == 0) { + oldformat = 1; + twoDimensional = 1; + } + + else if (strcmp (cp, "-nopreamble") == 0) + nopreamble = 1; + + else + goto usage; + } + else if (file) { +usage: ; + fputs ("usage: pbmtofax [-2d] [-cr] [-ul] [-b4l] [-a3w] [-b4w] [-uc]\n", + stderr); + fputs (" [-old] [-nopreamble] [file]\n", stderr); + fputc ('\n', stderr); + fputs (" -2d select two dimensional encoding mode\n", stderr); + fputs (" -cr set coarse resolution indication\n", stderr); + fputs (" -ul set unlimited image length indication\n", stderr); + fputs (" -b4l set B4 length indication\n", stderr); + fputs (" -a3w set A3 width indication\n", stderr); + fputs (" -b4w set B4 width indication\n", stderr); + fputs (" -sw force standard width (1728 pels)\n", stderr); + fputs (" -uc set uncompressed mode indication\n", stderr); + fputs (" -old encode fax using old photo format\n", stderr); + fputs (" -nopreamble encode fax without any preamble info\n", stderr); + fputs (" -reversebits create an inverse image\n", stderr); + exit (1); + } + else + file = cp; + } + + if (file) { + fp = pm_openr (file); + if (fp == NULL) { + perror (file); + exit (1); + } + } + else + file = ""; + + pbm_readpbminit (fp, &cols, &rows, &format); + bitrow = pbm_allocrow (cols); + + data = malloc ((unsigned) (cols * rows)); + byteP = (unsigned char *) data; + + for (i = rows; i-- > 0; ) { + pbm_readpbmrow (fp, bP = bitrow, cols, format); + *byteP = NULL, bitcount = 7; + + for (j = cols; j-- > 0; ) { + unsigned char mask = 1 << bitcount; + + if (*bP++ == black) + *byteP |= mask; + else + *byteP &= ~mask; + if (--bitcount < 0) + *++byteP = NULL, bitcount = 7; + } + if (bitcount != 7) + byteP++; + } + + pm_close (fp); + + STOP = (PIC_LINESIZE = cols) + 1; + NUMLINES = rows; + if ((skip = 8 - (PIC_LINESIZE % 8)) == 8) + skip = 0; + + optbuf = encode_t4 (twoDimensional ? 4 : 1, data, skip); + + (void) fwrite (optbuf, optlen, sizeof *optbuf, stdout); + + exit (0); +} diff --git a/usr/src/contrib/isode/others/quipu/photo/ps.c b/usr/src/contrib/isode/others/quipu/photo/ps.c new file mode 100644 index 0000000000..3c1f5ac47c --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/ps.c @@ -0,0 +1,93 @@ +/* ps.c - fax to postscript */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/ps.c,v 7.1 91/02/22 09:29:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/ps.c,v 7.1 91/02/22 09:29:24 mrose Interim $ + * + * + * $Log: ps.c,v $ + * Revision 7.1 91/02/22 09:29:24 mrose + * Interim 6.8 + * + * Revision 7.0 91/01/25 11:47:45 mrose + * *** empty log message *** + * + * Revision 1.1 91/01/24 17:03:35 kej + * Initial revision + * + * Revision 1.1 91/01/02 21:36:47 kej + * Initial revision + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include + +#define HEIGHT 2200 + +static int x, y; + +extern int two_passes; + +photo_start (name) +char * name; +{ + x = 0; + y = HEIGHT; + two_passes = 0; + puts ("%!\n0 setlinewidth 72 200 div 72 200 div scale"); + return 0; +} + + +photo_end (name) +char * name; +{ + /* Decoding has finished - display the image */ + + if (y < HEIGHT) puts ("showpage"); + return 0; +} + +photo_black (length) +int length; +{ + if (length > 0) + printf ("%d %d moveto %d %d lineto stroke\n", x, y, x + length - 1, y); + x += length; + return 0; +} + +photo_white (length) +int length; +{ + x += length; + return 0; +} + + +photo_line_end (line) +bit_string * line; +{ + x = 0; + --y; + if (y < 0) { + puts ("showpage"); + y = HEIGHT; + } + return 0; +} + diff --git a/usr/src/contrib/isode/others/quipu/photo/sunview.c b/usr/src/contrib/isode/others/quipu/photo/sunview.c new file mode 100644 index 0000000000..43a615c518 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/sunview.c @@ -0,0 +1,128 @@ +/* sunview.c - sunview display process */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/sunview.c,v 7.2 91/02/22 09:29:25 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/sunview.c,v 7.2 91/02/22 09:29:25 mrose Interim $ + * + * + * $Log: sunview.c,v $ + * Revision 7.2 91/02/22 09:29:25 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:40:30 mrose + * sync + * + * Revision 7.0 89/11/23 22:01:47 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* sunview display process */ + +#include +#include "quipu/photo.h" +#include +#include +#include +#include + +static struct gfxsubwindow *gfx; +static struct tool *tool; +static struct toolsw *gfx_sw; +static int sx=20,sy=20,x,y; +extern int PIC_LINESIZE; + + +sigwinched () +{ + tool_sigwinch (tool); +} + +photo_start (name) +char * name; +{ +char * getenv (); + + /* Initialise a window to recieve a photo of 'name' */ + + if (getenv ("WINDOW_PARENT") == (char *)NULL) { + (void) fprintf (stderr,"PHOTO: Must be running suntools on the console"); + return (-1); + } + + if (( tool = tool_make (WIN_LABEL,name,WIN_TOP,sx,WIN_LEFT,sy,0)) == NULL) { + (void) fprintf (stderr,"PHOTO: can't create window"); + return (-1); + } + + signal (SIGWINCH,sigwinched); + + gfx_sw = gfxsw_createtoolsubwindow (tool,"",TOOL_SWEXTENDTOEDGE,TOOL_SWEXTENDTOEDGE,NULL); + gfx = (struct gfxsubwindow *) gfx_sw->ts_data; + gfxsw_getretained (gfx); + + tool_install (tool); + + /* return 0 if sucessful -1 if not */ + return (0); +} + + +photo_end (name) +char * name; +{ + /* Decoding has finished - display the photo */ + + (void) printf ("(See sunview window)"); + (void) fflush (stdout); + (void) close (1); + + /* return 0 if sucessful -1 if not */ + tool_set_attributes (tool,WIN_WIDTH,PIC_LINESIZE+40,WIN_HEIGHT,sy+40,0); + tool_select (tool,0); + + return (0); +} + +photo_black (length) +int length; +{ + /* draw a black line of 'length' pixels */ +} + +photo_white (length) +int length; +{ + /* draw a white line of 'length' pixels */ +} + + +photo_line_end (line) +bit_string * line; +{ +struct pixrect * pix; + + /* the end of a line has been reached */ + /* A bit string is stored in line->dbuf_top */ + + pix = mem_point (PIC_LINESIZE,1,1,line->dbuf_top); + pw_write (gfx->gfx_pixwin, sx, sy, PIC_LINESIZE-sx, 1, PIX_SRC,pix,0,0); + sy++; + +} + + diff --git a/usr/src/contrib/isode/others/quipu/photo/t4014.c b/usr/src/contrib/isode/others/quipu/photo/t4014.c new file mode 100644 index 0000000000..52a6e29280 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/t4014.c @@ -0,0 +1,101 @@ +/* t4014.c - display on tetronix 4014 terminals */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/t4014.c,v 7.1 91/02/22 09:29:26 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/t4014.c,v 7.1 91/02/22 09:29:26 mrose Interim $ + * + * + * $Log: t4014.c,v $ + * Revision 7.1 91/02/22 09:29:26 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:47 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include "stdio.h" +#include "quipu/photo.h" +#include "signal.h" +extern int NUMLINES,PIC_LINESIZE; +extern unsigned position; + +/* Any errors should be written to *stdout* */ +/* if the process exits, with out giving an error message, quipu may hang */ + +#define SCALE 5 +#define Y_OFFSET 2700 +#define X_OFFSET 3000 +#define X_SKIP 8 + +int y = Y_OFFSET; + +photo_quit () +{ + putch (030); /* Return to non-graphic mode */ + exit (0); +} + +photo_start (name) +char * name; +{ + putch (035); /* Enter graphic mode */ + + openpl (); + erase (); + linemod ("solid"); + + signal (SIGTERM,photo_quit); + /* return 0 if sucessful -1 if not */ + + return (0); +} + + +photo_end (name) +char * name; +{ + /* Decoding has finished - display the photo */ + move (0,Y_OFFSET - 100); + closepl(); + + (void) printf ("\n"); + (void) fflush (stdout); + (void) close (1); /* this is needed for QUIPU */ + /* wait until signalled to Terminate */ + for (;;) + ; +} + +photo_black (length) +int length; +{ +} + +photo_white (length) +int length; +{ + line ((position*SCALE)+X_OFFSET,y,((length+position-1)*SCALE)+X_OFFSET,y); +} + + +photo_line_end (line) +bit_string * line; +{ + y -= SCALE; +} diff --git a/usr/src/contrib/isode/others/quipu/photo/template.c b/usr/src/contrib/isode/others/quipu/photo/template.c new file mode 100644 index 0000000000..af129c404d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/template.c @@ -0,0 +1,78 @@ +/* template.c - template for display processes */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/template.c,v 7.1 91/02/22 09:29:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/template.c,v 7.1 91/02/22 09:29:27 mrose Interim $ + * + * + * $Log: template.c,v $ + * Revision 7.1 91/02/22 09:29:27 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:48 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "stdio.h" +#include "quipu/photo.h" + +/* Any errors should be written to *stdout* */ +/* if the process exits, with out giving an error message, quipu may hang */ + +photo_start (name) +char * name; +{ + /* Initialise a window to recieve a photo of 'name' */ + + /* return 0 if sucessful -1 if not */ + (void) fprintf (stderr,"PHOTO: not implemented yet"); + return (-1); +} + + +photo_end (name) +char * name; +{ + /* Decoding has finished - display the photo */ + (void) printf ("done it"); + (void) fflush (stdout); + (void) close (1); /* this is needed for QUIPU if the process does not exit */ + + /* return 0 if sucessful -1 if not */ + return (-1); +} + +photo_black (length) +int length; +{ + /* draw a black line of 'length' pixels */ +} + +photo_white (length) +int length; +{ + /* draw a white line of 'length' pixels */ +} + + +photo_line_end (line) +bit_string * line; +{ + /* the end of a line has been reached */ + /* A bit string is stored in line->dbuf_top */ +} diff --git a/usr/src/contrib/isode/others/quipu/photo/tty.c b/usr/src/contrib/isode/others/quipu/photo/tty.c new file mode 100644 index 0000000000..d9f6d11ad1 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/tty.c @@ -0,0 +1,279 @@ +/* tty.c - display on any terminal */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/tty.c,v 7.1 91/02/22 09:29:28 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/tty.c,v 7.1 91/02/22 09:29:28 mrose Interim $ + * + * + * $Log: tty.c,v $ + * Revision 7.1 91/02/22 09:29:28 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:49 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include "stdio.h" +#include "quipu/photo.h" + +#define GREYSCALE "#OI&\\*o=_\"-;:,. " + +char mapping[16]; +char * strcpy (); + +char buffer[500][500]; +int lineno = 0, + pos = 0; +extern int PIC_LINESIZE; +extern int NUMLINES; +int scale = 8; +int invert = 0; +int equal = 0; +int ln = 0; +int scalediv = 0; +int edges = 0; + +char level[128]; +char show[128]; +char display[50][50]; + +/* ARGSUSED */ +photo_start (name) +char *name; +{ + char *ptr, + *getenv (); + + + if ((ptr = getenv ("photo_invert")) != (char *) NULL) + if (strcmp (ptr, "true") == 0) + invert = 1; + + if ((ptr = getenv ("photo_equal")) != (char *) NULL) { + if (strcmp (ptr, "true") == 0) + equal = 1; + else if (strcmp (ptr, "edge") == 0) { + int i, + j; + + for (i = 1; i < PIC_LINESIZE; i++) + for (j = 1; j < NUMLINES; j++) + buffer[i][j] = 0; + edges = 1; + } + } + if ((ptr = getenv ("photo_mapping")) != (char *) NULL) + (void) strcpy (mapping, ptr); + else + (void) strcpy (mapping, GREYSCALE); + + if ((ptr = getenv ("photo_scale")) != (char *) NULL) { + if (strcmp (ptr, "large") == 0) + scale = 1; + else if (strcmp (ptr, "small") == 0) + scale = 8; + else if (strcmp (ptr, "medium") == 0) + scale = 4; + } + scalediv = scale * scale / 8; + + (void) printf ("\n"); + return (0); +} + +/* ARGSUSED */ +photo_end (name) +char *name; +{ + int i, + j, + k; + int numlev; + int total = 0; + int totlevel = 0; + int cnt; + + if (equal) { + numlev = scale * scale * 2; + for (i = 0; i < numlev; i++) + level[i] = 0; + + for (i = 0; i < ln; i++) + for (j = 0; j < PIC_LINESIZE / scale; j++) + level[display[i][j]]++; + + for (i = 0; i < numlev; i++) + totlevel += level[i]; + + for (i = 0; i < numlev; i++) { + total += level[i]; + show[i] = (total * 16) / totlevel; + if (show[i] >= 16) + show[i] = 15; + } + + for (i = 0; i < ln; i++) { + for (j = 0; j < PIC_LINESIZE / scale; j++) { + if (invert) + (void) putc (mapping[show[display[i][j]]],stdout); + else + (void) putc (mapping[15 - show[display[i][j]]],stdout); + } + (void) printf ("\n"); + } + } else if (edges) { + /* edges by expansion */ + char ebuf[500][500]; + + for (i = 1; i < PIC_LINESIZE; i++) + for (j = 1; j < NUMLINES; j++) + ebuf[i][j] = 0; + + for (i = 1; i < PIC_LINESIZE; i++) + for (j = 1; j < NUMLINES; j++) + if (buffer[i][j] == 1) { + ebuf[i - 1][j - 1] = 1; + ebuf[i - 1][j] = 1; + ebuf[i - 1][j + 1] = 1; + ebuf[i][j - 1] = 1; + ebuf[i][j + 1] = 1; + ebuf[i + 1][j - 1] = 1; + ebuf[i + 1][j] = 1; + ebuf[i + 1][j + 1] = 1; + } + for (i = 1; i < PIC_LINESIZE; i++) + for (j = 1; j < NUMLINES; j++) + if (buffer[i][j] == 1) + ebuf[i][j] = 0; + + for (lineno = 0; lineno < NUMLINES; lineno += (2 * scale)) { + for (k = 0; k < PIC_LINESIZE; k += scale) { + cnt = 0; + for (i = k; i < k + scale; i++) + for (j = lineno; j < (2 * scale) + lineno; j++) + cnt += ebuf[i][j]; + +/* Need to select a grey level on the strength of the edge + * + * cnt *= 4; + * if (cnt == (scalediv * 16)) + * cnt = (scalediv * 16) -1; + * + * Just set "strong" edge cells "on" for now ... + */ + if (cnt > (scalediv * 2) ) + cnt = (scalediv * 16) -1; + else + cnt = 0; + + if (invert) + (void) putc (mapping[(cnt / scalediv)],stdout); + else + (void) putc (mapping[15 - (cnt / scalediv)],stdout); + } + (void) putc ('\n',stdout); + } + + } + return (0); + +} + +photo_black (length) +int length; +{ + int i; + + if (scale == 1) { + for (i = pos; i < length + pos; i++) + if (invert) + (void) putc (' ',stdout); + else + (void) putc ('#',stdout); + return; + } + for (i = pos; i < length + pos; i++) + buffer[i][lineno] = 1; + pos += length; +} + +photo_white (length) +int length; +{ + int i; + + if (scale == 1) { + for (i = pos; i < length + pos; i++) + if (invert) + (void) putc ('#',stdout); + else + (void) putc (' ',stdout); + return; + } + for (i = pos; i < length + pos; i++) + buffer[i][lineno] = 0; + pos += length; +} + +/* ARGSUSED */ +photo_line_end (line) +bit_string *line; +{ + int i, + j, + k, + cnt; + + if (scale == 1) { + (void) putc ('\n',stdout); + return; + } + lineno++; + pos = 0; + + if (edges) + return; + + if (lineno >= 2 * scale) { + ln++; + lineno = 0; + for (k = 0; k < PIC_LINESIZE; k += scale) { + cnt = 0; + for (i = k; i < k + scale; i++) + for (j = 0; j < 2 * scale; j++) + cnt += buffer[i][j]; + + if (equal) { + display[ln][k / scale] = cnt; + continue; + } + if (cnt == (scalediv * 16)) + cnt--; + + + if (invert) + (void) putc (mapping[cnt / scalediv],stdout); + else + (void) putc (mapping[15 - (cnt / scalediv)],stdout); + } + + if (!equal) + (void) putc ('\n',stdout); + } +} diff --git a/usr/src/contrib/isode/others/quipu/photo/winx.c b/usr/src/contrib/isode/others/quipu/photo/winx.c new file mode 100644 index 0000000000..f34b8ec7b8 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/photo/winx.c @@ -0,0 +1,225 @@ +/* winx.c - xwindow version of display code */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/photo/RCS/winx.c,v 7.1 91/02/22 09:29:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/photo/RCS/winx.c,v 7.1 91/02/22 09:29:29 mrose Interim $ + * + * + * $Log: winx.c,v $ + * Revision 7.1 91/02/22 09:29:29 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:01:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include "quipu/photo.h" +#include +#include +#include + + +/* It appears that window manager writers have problems */ + +#ifndef NEVER_USE_WM +#define WM_DISAPPEARED_BUG /* wm screw up & loses the window ! */ +#define WM_WINGE_BUG /* When wm screws up, it also winges */ +#endif NEVER_USE_WM + +#ifndef NEVER_USE_TWM +#define TWM_RESIZE_BUG /* twm looses the resize if done too early. */ +#endif NEVER_USE_TWM + + +extern GC XCreateGC(); +Pixmap pixmap; +Display *dpy; +Screen *scr; +Window win; +int winX, winY, winW, winH; +XSetWindowAttributes xswa; +GC gc; +extern int NUMLINES,PIC_LINESIZE; +extern unsigned position; +unsigned long XorVal; +int buttons_down = 0; +int ignore_action = 0; + +static int passno = 1; +static int x, y, maxx; + +extern int two_passes; + +photo_start (name) +char * name; +{ + x = y = 0; + if (passno == 1) { + maxx = 0; + two_passes = 1; + } + return 0; +} + + +photo_end (name) +char * name; +{ + /* Decoding has finished - display the photo */ + char buff[128]; + + if (passno == 1) { + passno = 2; + x = maxx; + --y; + + /* Initialise a window to recieve a photo of 'name' */ + + if (!(dpy= XOpenDisplay((char *) 0))) { + (void) printf ("Cannot open X display"); + return (-1); + } + scr = DefaultScreenOfDisplay(dpy); + winW = x; + winH = y; + winX = WidthOfScreen(scr) - winW; + winY = HeightOfScreen(scr) - winH; + + xswa.event_mask = ExposureMask | ButtonReleaseMask | ButtonPressMask; + + xswa.background_pixel = BlackPixelOfScreen(scr); + xswa.backing_store = WhenMapped; + + win = XCreateWindow(dpy, RootWindowOfScreen(scr), + winX, winY, winW, winH, 0, + DefaultDepthOfScreen(scr), InputOutput, + DefaultVisualOfScreen(scr), + CWEventMask | CWBackPixel | CWBackingStore, &xswa); + pixmap = XCreatePixmap(dpy, win, + winW,winH, DefaultDepthOfScreen(scr)); + if (!pixmap) { + (void) fprintf (stderr,"decode_fax: Pixmap failed"); + return (-1); + } + + /* Set up a graphics context: */ + + gc = XCreateGC(dpy, pixmap, 0, NULL); + + /* Clear pixmap */ + + XSetForeground(dpy, gc, BlackPixelOfScreen(scr)); + XFillRectangle(dpy, pixmap, gc, 0, 0, winW,winH); + + XSetForeground(dpy, gc, WhitePixelOfScreen(scr)); + XSetBackground(dpy, gc, BlackPixelOfScreen(scr)); + + XorVal = WhitePixelOfScreen(scr) ^ BlackPixelOfScreen(scr); + + return (0); + } + + if (strcmp (name, "unknown") == 0) + name = NULL; + + if (name == NULL) { + (void) printf ("(See X window, pid %d)", getpid()); + (void) fflush (stdout); + } + (void) close (1); + + (void) sprintf(buff, name ? "%s" : "%s (%d)", + name ? name : "Photo", getpid()); + XChangeProperty(dpy, win, XA_WM_NAME, XA_STRING, 8, + PropModeReplace, buff, strlen(buff)); + XMapWindow(dpy, win); + XSetForeground(dpy, gc, XorVal); + for (;;) + { XEvent xev; + + XNextEvent(dpy, &xev); + switch (xev.type) + { + case ButtonPress: + if (buttons_down++) + { if (!ignore_action++) + { XSetFunction(dpy, gc, GXcopy); + XCopyArea(dpy, pixmap, win, + gc, 0, 0, + PIC_LINESIZE, NUMLINES, + 0, 0); + } + } + else + { XSetFunction(dpy, gc, GXxor); + XFillRectangle(dpy, win, gc, + 0, 0, PIC_LINESIZE, NUMLINES); + } + continue; + case ButtonRelease: + if (!buttons_down) buttons_down++; + if (--buttons_down) continue; + if (!ignore_action) break; + ignore_action = 0; + continue; + case Expose: + XSetFunction(dpy, gc, GXcopy); + XCopyArea(dpy, pixmap, win, gc, + xev.xexpose.x, xev.xexpose.y, + xev.xexpose.width, xev.xexpose.height, + xev.xexpose.x, xev.xexpose.y); + default: + continue; + } + break; + } + return 0; +} + +photo_black (length) +int length; +{ + x += length; + return 0; +} + +photo_white (length) +int length; +{ + + /* draw a white line of 'length' pixels */ + + if (passno == 2 && length > 0) + XDrawLine (dpy, pixmap, gc, x, y, x + length - 1, y); + + x += length; + return 0; +} + + +photo_line_end (line) +bit_string * line; +{ + if (passno == 1 && x > maxx) + maxx = x; + x = 0; + y++; + return 0; +} diff --git a/usr/src/contrib/isode/others/quipu/tools/Makefile b/usr/src/contrib/isode/others/quipu/tools/Makefile new file mode 100644 index 0000000000..9c3799797b --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/Makefile @@ -0,0 +1,76 @@ +############################################################################### +# Instructions to Make, for compilation of QUIPU tools +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/tools/RCS/Makefile,v 7.4 91/02/22 09:29:32 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.4 91/02/22 09:29:32 mrose +# Interim 6.8 +# +# Revision 7.3 91/01/16 10:22:33 mrose +# dsastats +# +# Revision 7.2 90/07/09 14:40:35 mrose +# sync +# +# Revision 7.1 90/02/19 13:10:54 mrose +# update +# +# Revision 7.0 89/11/23 22:02:28 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +DIRS = dsaconfig dsastats scripts + + +################################################################## +# Here it is... +################################################################## + +all:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) all"; \ + cd $$i; $(MAKE) all); \ + done + +inst-all:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) inst-all"; \ + cd $$i; $(MAKE) inst-all); \ + done + +install:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) install"; \ + cd $$i; $(MAKE) install); \ + done + +lint:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) lint"; \ + cd $$i; $(MAKE) lint); \ + done + +clean:; rm -f _* + @for i in $(DIRS) $(OTHERS); \ + do (echo "cd $$i; $(MAKE) clean"; \ + cd $$i; $(MAKE) clean); \ + done + +grind:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) grind"; \ + cd $$i; $(MAKE) grind); \ + done diff --git a/usr/src/contrib/isode/others/quipu/tools/dsaconfig/Makefile b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/Makefile new file mode 100644 index 0000000000..7f225f9837 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/Makefile @@ -0,0 +1,137 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE QUIPU DSA configurator +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/tools/dsaconfig/RCS/Makefile,v 7.6 91/02/22 09:29:39 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.6 91/02/22 09:29:39 mrose +# Interim 6.8 +# +# Revision 7.5 91/02/12 22:54:07 mrose +# dsaptailor.root-dsas +# +# Revision 7.4 90/12/23 23:42:29 mrose +# one-more-time +# +# Revision 7.3 90/12/23 18:47:16 mrose +# update +# +# Revision 7.2 90/08/29 15:08:55 mrose +# update +# +# Revision 7.1 90/07/09 14:40:38 mrose +# sync +# +# Revision 7.0 89/11/23 22:02:36 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a $(TOPDIR)quipu/quipuvrsn.o +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# FILES +############################################################################### + +CFILES = dsaconfig.c + + +############################################################## +# Here it is... +############################################################## + +all: dsaconfig +inst-all: inst-pilot inst-dsaconfig manuals +install: inst-all clean +lint: l-dsaconfig + + +################################################################### +# pilot +################################################################### + +inst-pilot: $(ETCDIR)dsaptailor true + cp -r quipu $(ETCDIR) + +$(ETCDIR)dsaptailor: true + if ln $(ETCDIR)dsaptailor $(ETCDIR)dsaptailor.old; \ + then rm -f $@; cat dsaptailor $(TOPDIR)dsap/dsaptailor.root-dsas > $@; ls -gls $@; \ + else exit 0; \ + fi + + +################################################################### +# dsaconfig +################################################################### + +inst-dsaconfig: $(SBINDIR)dsaconfig + +$(SBINDIR)dsaconfig: xdsaconfig + -cp $@ zxdsaconfig + -rm -f $@ + cp xdsaconfig $@ + -@ls -gls $@ + -@echo "" + +dsaconfig: xdsaconfig + +xdsaconfig: dsaconfig.o $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ dsaconfig.o $(LIBES) $(LSOCKET) + +l-dsaconfig:; $(LINT) $(LFLAGS) dsaconfig.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# manual pages +################################################################ + +MANUALS = dsaconfig.8 + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +############################################################## +# clean +############################################################## + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig core + +grind:; iprint Makefile + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaconfig.8 b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaconfig.8 new file mode 100644 index 0000000000..164cb64dd4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaconfig.8 @@ -0,0 +1,41 @@ +.TH DSACONFIG 8 "06 Jun 1989" +.\" $Header: /f/osi/others/quipu/tools/dsaconfig/RCS/dsaconfig.8,v 7.2 91/02/22 09:29:41 mrose Interim $ +.\" +.\" +.\" $Log: dsaconfig.8,v $ +.\" Revision 7.2 91/02/22 09:29:41 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/10/18 11:33:35 mrose +.\" psi +.\" +.\" Revision 7.0 89/11/23 22:02:37 mrose +.\" Release 6.0 +.\" +.SH NAME +dsaconfig \- build a database directory for a Level-1 DSA +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDdsaconfig +\%[\-d] +\fIwildlife\fR +.in -.5i +.SH DESCRIPTION +The \fIdsaconfig\fR program reads the file \fIwildlife\fR.dsa and +creates a new directory, \fIwildlife/\fR, containing the initial +database for a Level-1 DSA. +.SH FILES +.nf +.ta \w'\*(EDdsaptailor 'u +\*(EDdsaptailor QUIPU DUA tailoring file +\*(EDfredrc Whitepages tailoring file +.re +.fi +.SH "SEE ALSO" +\fIPSI White Pages Pilot Project: Administrator's Guide\fR +.SH DIAGNOSTICS +All obvious. +.SH AUTHOR +Marshall T. Rose, +Performance Systems International diff --git a/usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaptailor b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaptailor new file mode 100644 index 0000000000..1b8e56ea5b --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/dsaptailor @@ -0,0 +1,67 @@ +############################################################################### +# +# dsaptailor - ISODE DSAP Specific Tailoring File +# +# for PSI White Pages Pilot Project +# +# +# $Header: /f/osi/others/quipu/tools/dsaconfig/RCS/dsaptailor,v 7.6 91/02/22 09:29:46 mrose Interim $ +# +# +# $Log: dsaptailor,v $ +# Revision 7.6 91/02/22 09:29:46 mrose +# Interim 6.8 +# +# Revision 7.5 91/02/12 22:54:08 mrose +# dsaptailor.root-dsas +# +# Revision 7.4 90/10/18 11:33:41 mrose +# psi +# +# Revision 7.3 90/07/27 08:44:56 mrose +# update +# +# Revision 7.2 90/03/15 11:20:25 mrose +# quipu-sync +# +# Revision 7.1 90/01/11 18:36:14 mrose +# real-sync +# +# Revision 7.0 89/11/23 22:02:40 mrose +# Release 6.0 +# +############################################################################### + + +# this line must occur first +oidtable oidtable + +# the ``closest'' level-2 DSA +#dsa_address "wildlife name" '0101'H/Internet=aaa.bbb.ccc.ddd+portno + +# the level-1 DSA +#dsa_address "@(dsa)" '0101'H/Internet=@(ipaddr)+@(port) + +# logging +dsaplog level=exceptions dflags=tty +stats level=none dflags=tty + +# local DIT position (where a DUA starts in the DIT) +#local_DIT "c=@(country)@o=@(organization)" + +# oid format +oidformat short + +# photograph process routines +photo dumb ttyphoto +photo xterm Xphoto + +# automatic quipurc creation +quipurc off + +# DUA search/list sizelimit +sizelimit 20 + + +# some other DSAs of interest (added automatically) + diff --git a/usr/src/contrib/isode/others/quipu/tools/dsaconfig/make b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsaconfig/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/tools/dsastats/Makefile b/usr/src/contrib/isode/others/quipu/tools/dsastats/Makefile new file mode 100644 index 0000000000..ba8ad71f05 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsastats/Makefile @@ -0,0 +1,50 @@ +# other/quipu/tools/dsastats/Makefile + +############################## +# Configuration - see README # +############################## + +# The file the DSA logs to +LOGFILE= $(LOGDIR)quipu.log + +# The DSAs tailor file +TAILORFILE=$(ETCDIR)quiputailor + +# The DN of your organisation +LOCALORGDN=c=GB@o=University College London + +# Where to install the scripts +LOCALPATH=$(BINDIR) + +# Where to place the two config files +LETCDIR=$(ETCDIR) + +##################################### +# Rules... +##################################### + +all: dsastats + +inst-all: + cp dsastats $(LOCALPATH) + ls -gls $(LOCALPATH)dsastats + cp quipulocaladds $(LETCDIR) + ls -gls $(LETCDIR)quipulocaladds + cp quiputechusers $(LETCDIR) + ls -gls $(LETCDIR)quiputechusers + +install: inst-all clean + +lint:; + +clean:; -rm -f dsastats + +grind:; + +dsastats: dsastats.dist + sed 's#QUIPULOG#$(LOGFILE)#g' dsastats.dist | \ + sed 's#QUIPUTAILOR#$(TAILORFILE)#g' | \ + sed 's#QUIPULOCALORG#$(LOCALORGDN)#g' | \ + sed 's#QUIPUETCDIR#$(LETCDIR)#g' >dsastats + chmod +x dsastats + diff --git a/usr/src/contrib/isode/others/quipu/tools/dsastats/READ-ME b/usr/src/contrib/isode/others/quipu/tools/dsastats/READ-ME new file mode 100644 index 0000000000..49aa408bfa --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsastats/READ-ME @@ -0,0 +1,99 @@ +[ READ-ME - Wed Jan 16 10:24:40 1991 - dsastats - /mtr ] + +dsastats is a script which processes the log file produced by a quipu DSA +of normal operation. This file is by default called quipu.log, which +is by default written to the /usr/tmp directory. The script produces +a summary of usage of a DSA. + +To use the script successfully, you must have set the logging levels as +described in the note "Tailoring Quipu's logging" by Paul Barker. +Briefly, you must have the "stats" variable in the quiputailor set thus: + +stats level=TRACE level=NOTICE + +OR + +you can omit this line entirely: the defaults give the appropriate level +of logging. + +Helpful comments on the script will be gratefully received. Please email +quipu-support@uk.ac.ucl.cs. + + +If you would like to port these logging scripts, you first need to +configure a few things in the Makefile. + +# this is where the script will by default find the log file. +LOGFILE= /usr/etc/quipu.log + +# this is the quiputailor file. This is accessed to get the name of the +# DSA's logs to be processed, ready for inclusion in the report. +TAILORFILE=/usr/ucl/etc/isode/quiputailor + +# The DN of your local organisation. This allows DSA activity to be +# categorised as either "local" or "remote" +LOCALORGDN=c=GB@o=University College London + +# The "etc" directory, where a couple of configuration files (quipulocaladds +# and quiputechusers) will be installed +ETCDIR=/usr/etc + +# where you want the script installed +LOCALPATH=/usr/local/bin + +You now have to configure a couple of files. + +The file quipulocaladds contains leading substrings from local DUA and DSA +addresses. The surest method to get these to examine the file quipu.log +and see what the DSA is writing out. +You can extract all the addresses from the quipu.log file by + +grep "context association" quipu.log | awk '{print $NF}' + +Note that the quipulocaladds file must be terminated with a +line beginning with a #. An example quipulocaladdsfile is given in +quipulocaladds.example + +The file quiputechusers is mainly for the benefit of sites where one or +more users make heavy use of the directory by testing it or verifying that +it is working correctly. This file allows use of the Directory by such users +to be filtered out and classed as "system" usage. The file +consists of a number of distinguished names. Again, the file must +be terminated with a line beginning with a #. An example quiputechusers file +is given in quiputechusers.example + +Then type: + +make dsastats + +to configure the script ready for use. + +make install + +installs the dsastats script in the $(LOCALPATH) directory. + + +To run it: + +dsastats [-summary] [] + +The summary flag doesn't do anything at the moment! + +If no filename is supplied, the script uses the file which is configured by +the makefile macro, LOGFILE. + +If the filename contains the string ".usage", it is assumed that the file +is called something like "vicuna.usage" or "giant.usage" (at UCL, we have +to rename our quipu.log files as we often have more than one DSA on a +machine). Otherwise, the file configured by the makefile macro, TAILORFILE, +is consulted to discover the name of the local DSA. + +The report is written to standard output. + +Thus, usage might be as follows: + +dsastats giant.usage >giant.report + +or + +dsastats > stats.report diff --git a/usr/src/contrib/isode/others/quipu/tools/dsastats/dsastats.dist b/usr/src/contrib/isode/others/quipu/tools/dsastats/dsastats.dist new file mode 100644 index 0000000000..e03253aae8 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/dsastats/dsastats.dist @@ -0,0 +1,687 @@ +#!/bin/sh +# +# next 3 lines configured by make dsastats +LOGFILE="QUIPULOG" +TAILORFILE="QUIPUTAILOR" +LOCALORG="QUIPULOCALORG" +ETCDIR="QUIPUETCDIR" + +logfile=$LOGFILE +summary="FALSE" + +while [ $# -gt 0 ] +do + case $1 in + -s|-summary) + summary="TRUE"; shift;; + *) + logfile=$1; shift;; + esac +done + +if [ ! -r $logfile ]; then + echo "No such file <$logfile>" >&2 + exit 1 +fi + +echo "$LOCALORG" |tr "A-Z" "a-z" >/tmp/dsastats$$.localorg + +# try and sort out the format of the time into something a bit nicer +nicetime () { +awk ' BEGIN { + montharray[1] = "Jan" + montharray[2] = "Feb" + montharray[3] = "Mar" + montharray[4] = "Apr" + montharray[5] = "May" + montharray[6] = "Jun" + montharray[7] = "Jul" + montharray[8] = "Aug" + montharray[9] = "Sep" + montharray[10] = "Oct" + montharray[11] = "Nov" + montharray[12] = "Dec" +} + { + monthno = substr($0, 1, 2) + 0 + dayno = substr($0, 4, 2) + time = substr($0, 7, 8) + printf("%s on %02d %s", time, dayno, montharray[monthno]) + } ' +} + +echo $logfile | grep -s ".usage" +if [ "$?" = "0" ]; then + dsaname=`basename $logfile .usage` +else + dsaname=` grep mydsa $TAILORFILE | \ + awk -F@ '{split($NF,parts, "=") + print parts[2] }' |sed 's/"//g'` +fi +starttime=`head -1 $logfile | nicetime` +endtime=`tail -1 $logfile | nicetime` +echo "fordsa $dsaname" >/tmp/dsastats$$.2 +echo "starts $starttime" >>/tmp/dsastats$$.2 +echo "ends $endtime" >>/tmp/dsastats$$.2 + +sed 's/[^)]*) //' < $logfile | awk ' BEGIN { + gotfirst = "FALSE" +} +/^(Add|Read|List|Modify|Modifyrdn|Remove|Search|Compare|Getedb) \(.*/ { + split ($2,opids,":") + lastassoc = opids[1] +} + +{ + if (gotfirst == "TRUE") + { + split($0, op, ":") + if (op[1] != "DSA control") + { + print saveline + saveline = $0 + } + else + saveline = "DSAControl " lastassoc ": " $(NF-1) " " $(NF) + } + else + { + gotfirst = "TRUE" + saveline = $0 + } +} +END { + print saveline +} ' >/tmp/dsastats$$.1 +cat $ETCDIR/quipulocaladds /tmp/dsastats$$.1 | awk ' +BEGIN { + nextdsa = 1; + lastcn=0 + conns_open["dummy"] = "" + locadd["dummy"] = 0 + while (getline > 0) + { + if (substr($0, 1, 1) == "#") + break + no_localadds++ + locadd[no_localadds] = $0 + } +} + +/^Bind.*/ { + conn_op[$2] = 1 + conn [$2 "#" 1] = conn[$2 "#" 1] " " $0 + conns_open[$2] = $2 +} +/^(Add|Read|List|Modify|Modifyrdn|Remove|Search|Compare|Getedb|DSAControl) \(.*/ { + split ($2,opids,":") + opid = opids[1] + conn_op[opid]++ + split ($0,oper,":") + if (oper[2] == " ") + conn [opid "#" conn_op[opid]] = $1 " ROOT" + else + conn [opid "#" conn_op[opid]] = $1 oper[2] + lastcn = opid +} +/^Unbind.*/ { + if (conn[$2 "#" 0] == "") + { + print conn[$2 "#" 1] + if (chain[$2] == 1) + print "\tChained " chain[$2] " operation" + else + print "\tChained " chain[$2] " operations" + } + else + { + print conntype[$2] " " conn[$2 "#" 1] + for ( i=2; i<= conn_op[$2]; i++) + print " " conn[$2 "#" i] + } + print "" + conn_op[$2] = 0 + conns_open[$2] = "" +} + +/ has started / { + for (j in conns_open) + { + if (conns_open[j] != "") + { + if (conn[j "#" 0] == "") + { + print conn[j "#" 1] + if (chain[j] == 1) + print "\tChained " chain[j] " operation" + else + print "\tChained " chain[j] " operations" + } + else + { + print conntype[j] " " conn[j "#" 1] + for (i = 2; i <= conn_op[j]; i++) + print " " conn[j "#" i] + } + print "" + conn_op[j] = 0 + conns_open[j] = "" + } + } +} + +/^X500 DAP.*/ { + split ($5,opids,":") + opid = opids[1] + conn_op[opid] = 0 + split ($0,oper,":") + conn [opid "#" 0] = "from" oper[2] + conn [opid "#" 1] = "DAP" + conntype [opid] = "remote" + y = index($0, ":") + thisadd = substr($0, y+1) + for (z =1 ; z <= no_localadds; z++) + if (substr(thisadd, 2, length(locadd[z])) == locadd[z]) + { + conntype [opid] = "local" + break + } +} +/^QUIPU DSP.*/ { + split ($5,opids,":") + opid = opids[1] + conn_op[opid] = 0 + split ($0,oper,":") + conn [opid "#" 0] = "Quipu DSP from" oper[2] + conn [opid "#" 1] = "QuipuDSP" + conntype [opid] = "remote" + y = index($0, ":") + thisadd = substr($0, y+1) + for (z =1 ; z <= no_localadds; z++) + if (substr(thisadd, 2, length(locadd[z])) == locadd[z]) + { + conntype [opid] = "local" + break + } +} +/^X500 DSP.*/ { + split ($5,opids,":") + opid = opids[1] + conn_op[opid] = 0 + split ($0,oper,":") + conn [opid "#" 0] = "from" oper[2] + conn [opid "#" 1] = "DSP" + conntype [opid] = "remote" + y = index($0, ":") + thisadd = substr($0, y+1) + for (z =1 ; z <= no_localadds; z++) + if (substr(thisadd, 2, length(locadd[z])) == locadd[z]) + { + conntype [opid] = "local" + break + } +} +/^DAP Originator.*/ { + split ($0,dn,":") + if (dn[2] != " ") + conn [lastcn "#" conn_op[lastcn]] = conn [lastcn "#" conn_op[lastcn]] "\n\tDAP Originator: " dn[2] + else + conn [lastcn "#" conn_op[lastcn]] = conn [lastcn "#" conn_op[lastcn]] "\n\tDAP Originator: anonymous" +} +/^Bound.*/ { + split ($6,opids,":") + opid = opids[1] + conn[opid "#" 0] = "" + conn[opid "#" 1] = $0 + conn_op[opid] = 1 +} +/^Chain.*/ { + chain[opid]++ +} +/^Trying.*/ { + split ($0,dn,":") + if (dsa[dn[2]] == 0) + { + dsa[dn[2]] = nextdsa + dsadn[nextdsa]=dn[2] + try[nextdsa]++ + nextdsa++ + } + else + try[dsa[dn[2]]]++ +} +/^Failed.*/ { + split ($0,dn,":") + fail[dsa[dn[2]]]++ +} +END { + print "Connections: " + for (i=1; i< nextdsa; i++) + { + printf " %-30s: tried %s", dsadn[i], try[i] + if (fail[i] != 0) + print ", failed " fail[i] + else + print + } +} ' >> /tmp/dsastats$$.2 + +cat /tmp/dsastats$$.localorg $ETCDIR/quiputechusers /tmp/dsastats$$.2 |tr "A-Z" "a-z" | awk ' +BEGIN { + techies["dummy"] = 0 + getline + localorg = $0 + while (getline > 0) + { + if (substr($0, 1, 1) == "#") + break + no_techs++ + techies[$0] = 0 + } + gotdspbind = "FALSE" + userorgnames["dummy"] = 0 + originators["dummy"] = 0 + realaccessed["dummy"] = 0 + sysaccessed["dummy"] = 0 + summary = "'$summary'" +} +/^fordsa/ { + dsaname = substr($0, 8, length($0)-8+1) +} + +/^starts/ { + starttime = substr($0, 8, 40) +} + +/^ends/ { + endtime = substr($0, 8, 40) +} + +# add any originators from last DSP connection examined to usernames array +/ bind/ { + if (gotdspbind == "TRUE") + for (origuser in originators) + if (originators[origuser] != 0) + { + usernames[origuser]++ + if (origuser == "anonymous") + if (remote == "TRUE") + remoteanon++ + else + localanon++ + originators[origuser] = 0 + } + if (substr($0, 1, 6) == "remote") + remote = "TRUE" + else + remote = "FALSE" +} + +/.* bind.*\(anonymous\).*/ { + if (substr($0, 1, 6) == "remote") + remoteanon++ + else + localanon++ + if ($2 == "dap") + gotdspbind = "FALSE" + else + gotdspbind = "TRUE" + usernames["anonymous"]++ +} + +/.* bind.*\(no auth\).*/ { + if (substr($0, 1, 6) == "remote") + if ($2 == "dap") + remotenoauthdap++ + else + remotenoauthdsp++ + else + if ($2 == "dap") + localnoauthdap++ + else + localnoauthdsp++ +} + +/.* bind.*\(simple\).*/ { + if (substr($0, 1, 6) == "remote") + remotesimple++ + else + localsimple++ +} + +/ bind.*\(no auth\)| bind.*\(simple\)/ { + n = index($0, ":") + username = substr($0, n+2) + if ($2 == "dap") + { + gotdspbind = "FALSE" + usernames[username]++ + } + else + gotdspbind = "TRUE" +} + +#/dap originator:/ { +# n = index($0, ":") +# username = substr($0, n+3) +# if (username != "anonymous") +# originators[username]++ +#} + +/^ getedb/ { + getedb++ +} + +/^ modifyrdn / { + modifyrdnops++ + opDN = substr($0, 13) +} + +/^ add/ { + addops++ + opDN = substr($0, 7) +} + +/^ modify / { + modifyops++ + opDN = substr($0, 10) +} + +/^ search/ { + searchops++ + opDN = substr($0, 10) +} + +/^ list/ { + listops++ + opDN = substr($0, 8) +} + +/^ read/ { + readops++ + opDN = substr($0, 8) +} + +/^ read|^ list|^ search|^ modify|^ add/ { + n = split(opDN, RDNparts, "@") + if (substr(RDNparts[n], 1, 2) == "cn") + if (($1 == "read") && (n < 3)) #reading a DSA entry + { + dsaread++ + next + } + else + { + opDN = RDNparts[1] + for (i = 2; i < n-1; i++) + opDN = opDN "@" RDNparts[i] + } + # was this a system or real use? + if (gotdspbind == "TRUE") + { + # get the originator + getline + n = index($0, ":") + origname = substr($0, n+3) + if (origname == username) + { + spotshadows++ + next + } + else + originators[origname]++ + } + else + origname = username + techfound = "false" + for (techperson in techies) + if (techperson == origname) + { + techfound = "true" + break + } + if (techfound == "true") + sysaccessed[opDN]++ + else + realaccessed[opDN]++ +} + +END { +# pick up any last dsp originators + if (gotdspbind == "TRUE") + for (origuser in originators) + if (originators[origuser] != 0) + { + usernames[origuser]++ + if (origuser == "anonymous") + if (remote == "TRUE") + remoteanon++ + else + localanon++ + originators[origuser] = 0 + } + + printf "Summary of calls to DSA <%s>\nFrom %s to %s\n\n", dsaname, \ + starttime, endtime + printf "%-30s%8s%8s\n\n", "No. of binds", "local", "remote" + printf "%-20s%10s%8d%8d\n", "Anonymous", "", localanon, remoteanon + printf "%-20s%10s%8d%8d\n", "Unauth name DAP", "", localnoauthdap, remotenoauthdap + printf "%-20s%10s%8d%8d\n", "Unauth name DSP", "",localnoauthdsp, remotenoauthdsp + printf "%-20s%10s%8d%8d\n", "Simple", "", localsimple, remotesimple + +#print "have this list of users" +#for (user in usernames) +# print user " " usernames[user] +#print "" + + for (user in usernames) + { + techfound = "false" + for (techperson in techies) + if (techperson == user) + { + techfound = "true" + break + } + if (techfound == "true") + techbinds += usernames[user] + else + { + n = split(user, RDNparts, "@") + if (n == 1) + userorg = user + else + userorg = RDNparts[1] ", " RDNparts[2] + orgfound = "false" + for (org in userorgnames) + if (org == userorg) + { + orgfound = "true" + break + } + if (orgfound == "false") + nontech++ + userorgnames[userorg]++ + userorgbinds[userorg] += usernames[user] + } + } + + printf "\nSystem usage (calls received)\n\n" + printf "%-38s%8d\n", "Binds by Directory technicians", techbinds + printf "%-38s%8d\n", "Reads of DSA entries", dsaread + printf "%-38s%8d\n", "Getedb operations", getedb + printf "%-38s%8d\n", "Spot shadows", spotshadows + + printf "\nWho has used the directory?\n" + printf "*Real* usage by organisation\n" + printf "%9s%10s\n", "No. users", "No. binds" + for (name in userorgnames) + if (userorgnames[name] != 0) + printf "%9d%10d %s\n", userorgnames[name], userorgbinds[name], name + + printf "\nWhich parts of the Directory have been accessed - real usage?\n" + printf "%s %s\n", "No. ops", "Subtree" + printf "Local subtree\n" + if (realaccessed[localorg] != 0) + { + printf "%7d %s\n", realaccessed[localorg], localorg + realaccessed[localorg] = 0 + } + n = 0 + for (dn in realaccessed) + if ((realaccessed[dn] != 0) && \ + (substr(dn, 1, length(localorg)) == localorg)) + { + n++ + sortarray[n] = dn + } + m = n + for (i = 1; i/support directory. This will load some default services into +the directory. + +Before these scripts are run, as with bootsvc, you should connect to +the DSA as the manager, using the dish 'bind' command e.g., + + bind -u "" -simple + +The data will be added below the part of the DIT your current dish process +is at. If this is not the right place (generally, the place defined by +'local_DIT' in the system wide 'dsaptailor' file is the "right place") +you should use the dish 'moveto' command e.g., + + moveto "" + +Now run the script + + dsa2aei + +This will connect to the directory and produce a file called +'quipuentities', which will contain data of the form + + hostname: application: application context: address: exec vector + +For example: + myhost: filestore: iso ftam: '0103'H/Int-X25(80)=23421920030013: iso.ftam + + +You can then edit this file and add or correct any entries (deletion +must be acheived by use of the dish 'delete' command). +Then the script aei2dsa will produce a script to update the OSI +directory e.g., + + aei2dsa | sh + + diff --git a/usr/src/contrib/isode/others/quipu/tools/scripts/aei2dsa b/usr/src/contrib/isode/others/quipu/tools/scripts/aei2dsa new file mode 100644 index 0000000000..70213b544d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/scripts/aei2dsa @@ -0,0 +1,58 @@ +#!/bin/sh + +# assumptions +# 1. we are bound with sufficient access rights (e.g manager) +# 2. we are positioned at the right part of the DIT + +sed 's/ */ /g +s/ :/:/g +s/\&/\\&/g' < quipuentities | awk -F: ' +BEGIN { + print "#!/bin/sh" +} +{ + if ( substr($0,1,1) == "#" ) + next + if ( $1 == "" ) + next + + + if ( last != $1 ) { + last = $1 + dn = "\"cn=" $1 "\"" + print "if ( showname " dn " 1>/dev/null 2>&1 )\nthen" + print "\techo " $1 "..." + print "else" + print "\techo \"objectClass=applicationProcess & quipuObject\" > /tmp/aet$$" + print "\tadd \"cn=" $1 "\" -draft /tmp/aet$$ -noedit" + print "fi\n" + } + + print "echo \" " $2 "...\"" + dn = "\"cn=" last "@cn=" $2 "\"" + print "if ( showentry " dn " -edb -all > /tmp/zaet$$ 2>/dev/null )\nthen" + print "\tsed \"s@supportedApplicationContext=.*@supportedApplicationContext= " $3 "@\" /tmp/aet$$ " + + if ( $5 != "" ) + print "\techo \"objectClass=isodeapplicationEntity & quipuObject\" >> /tmp/aet$$" + print "\tmodify " dn " -draft /tmp/aet$$ -noedit 2>&1 | sed '\''s/The draft.*/ No Change/\ns/are exactly.*//'\''" + print "\trm -f /tmp/zaet$$" + print "else" + print "\techo \"supportedApplicationContext=" $3 "\" > /tmp/aet$$" + print "\techo '\''presentationAddress=" $4 "'\'' >> /tmp/aet$$" + if ( $5 == "" ) + print "\techo \"objectClass=applicationEntity &quipuObject\" >> /tmp/aet$$" + else { + print "\techo '\''execVector=" $5 "'\'' >> /tmp/aet$$" + print "\techo \"objectClass=isodeapplicationEntity & quipuObject\" >> /tmp/aet$$" + } + print "\tadd " dn " -draft /tmp/aet$$ -noedit" + print "fi\n" + +} +END { + print "rm -f /tmp/aet$$" +} ' + diff --git a/usr/src/contrib/isode/others/quipu/tools/scripts/dsa2aei b/usr/src/contrib/isode/others/quipu/tools/scripts/dsa2aei new file mode 100644 index 0000000000..881d043548 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/scripts/dsa2aei @@ -0,0 +1,73 @@ +#!/bin/sh +search -filter objectclass=applicationEntity -nosize -notime -nopart \ + -type presentationaddress execvector supportedapplicationcontext \ + -show -subtree -noseq \ +| sed 's/cn=//g +s/@/ /g +s/ */ /g' | awk -F- ' +BEGIN { + print "# Flat representation of Application represented in the directory" + print "# Format" + print "# host : common name : application context : address : exec vector" + print "" +} +{ + + if ( NF == 1 ) { + if (started == 1) { + printf ":" + if (sac != "") + printf sac + printf ":" + if (addr != "") + printf addr + printf ":" + if (exec != "") + printf exec + printf "\n" + } else + started = 1 + + sac = "" + exec = "" + addr = "" + + n = split ($1, sp, " ") + + tmp = sp[2] + for (i=3; i<=n ; i++) + tmp = tmp " " sp[i] + + printf "%-14s:%-20s", sp[1], tmp + } else { + tmp = $2; + for (i=3; i<=NF ; i++) + tmp = tmp "-" $i + + if ( $1 == "supportedApplicationContext ") + sac = tmp + else if ( $1 == "presentationAddress ") + addr = tmp + else if ( $1 == "execVector ") { + tmp = $2; + for (i=3; i<=NF ; i++) + tmp = tmp " -" $i + exec = tmp + } else + print "\n**ERROR**" $1 "*** unexpected" + } + + +} +END { + printf ":" + if (sac != "") + printf sac + printf ":" + if (addr != "") + printf addr + printf ":" + if (exec != "") + printf exec + printf "\n" +}' > quipuentities diff --git a/usr/src/contrib/isode/others/quipu/tools/scripts/ent2aei b/usr/src/contrib/isode/others/quipu/tools/scripts/ent2aei new file mode 100644 index 0000000000..18e43c42b3 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/scripts/ent2aei @@ -0,0 +1,47 @@ +#!/bin/sh +awk ' +BEGIN { + mapping["filestore"] = "iso ftam" + mapping["terminal"] = "iso vt" + mapping["passwdstore"] = "isode passwd lookup demo" + mapping["Z39.50"] = "IRP Z39.50" + mapping["pp-qmgr"] = "pp qmgr interface" + mapping["\"pp qmgr\""] = "pp qmgr interface" +} +{ + if ( substr($0,1,1) == "#" ) + next + if ( $1 == "" ) + next + + if (new == "" ) { + tmp = $2 + for (i=3; i<=NF -2; i++) + tmp = tmp " " $i + + if ( $NF == "\\" ) + new = $1 + else { + if ($1 == "default") + continue + if (mapping [tmp] == "") + printf "%-14s %-20s %s\n", $1, tmp, $NF + else + printf "%-14s %-20s %s\n", $1, mapping[tmp], $NF + } + } else { + if (substr($1,1,1) == "\\") + $1 = substr ($1,2) + + if (new == "default") + next + if (mapping [tmp] == "") + printf "%-14s %-20s %s\n", new, tmp, $1 + else + printf "%-14s %-20s %s\n", new, mapping[tmp], $1 + + new = "" + } + +} ' + diff --git a/usr/src/contrib/isode/others/quipu/tools/scripts/make b/usr/src/contrib/isode/others/quipu/tools/scripts/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/tools/scripts/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/READ-ME b/usr/src/contrib/isode/others/quipu/uips/READ-ME new file mode 100644 index 0000000000..ed17029c21 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/READ-ME @@ -0,0 +1,20 @@ +[ READ-ME - Tue Jun 12 13:08:49 1990 - OSI Directory User Interfaces - /cwm ] + +The user interfaces and instructions for build them are described in +READ-ME files in each of the directories. It is anticipated that the +dish interface will have the broadest appeal. + +You may generate all of the user interface programs by executing make +in this directory: + + % ./make + +and then install them by executing make with the following parameter, + + % ./make install + +If you do not want to clean up following the install you should use +the following command instead: + + % ./make inst-all + diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/Makefile b/usr/src/contrib/isode/others/quipu/uips/dish/Makefile new file mode 100644 index 0000000000..d9d0be3fea --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/Makefile @@ -0,0 +1,296 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE QUIPU Directory Server +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/uips/dish/RCS/Makefile,v 7.5 91/02/22 09:30:14 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.5 91/02/22 09:30:14 mrose +# Interim 6.8 +# +# Revision 7.4 90/12/23 18:47:08 mrose +# update +# +# Revision 7.3 90/11/20 15:34:12 mrose +# update +# +# Revision 7.2 90/10/17 11:48:16 mrose +# sync +# +# Revision 7.1 90/07/09 14:40:55 mrose +# sync +# +# Revision 7.0 89/11/23 22:08:28 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libdsap.a $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode + + +############################################################################### +# FILES +############################################################################### + +HFILES = +CFILES = pipe.c unbind.c socket.c quipurc.c + + +############################################################## +# Here it is... +############################################################## + +all: xpipe xunbind xquipurc +inst-all: inst-pipe inst-unbind inst-dishinit inst-quipurc +install: inst-all clean +lint: l-pipe l-unbind l-quipurc + + +################################################################### +# pipe, et. al. +################################################################### + +inst-pipe: $(BINDIR)list + +$(BINDIR)list: xpipe + -cp $@ zxpipe + -rm -f $@ + cp xpipe $@ + -rm -f $(BINDIR)compare + ln $@ $(BINDIR)compare + -rm -f $(BINDIR)search + ln $@ $(BINDIR)search + -rm -f $(BINDIR)add + ln $@ $(BINDIR)add + -rm -f $(BINDIR)delete + ln $@ $(BINDIR)delete + -rm -f $(BINDIR)modify + ln $@ $(BINDIR)modify + -rm -f $(BINDIR)modifyrdn + ln $@ $(BINDIR)modifyrdn + -rm -f $(BINDIR)showentry + ln $@ $(BINDIR)showentry + -rm -f $(BINDIR)showname + ln $@ $(BINDIR)showname + -rm -f $(BINDIR)bind + ln $@ $(BINDIR)bind + -rm -f $(BINDIR)moveto + ln $@ $(BINDIR)moveto + -rm -f $(BINDIR)dsacontrol + ln $@ $(BINDIR)dsacontrol + -@ls -gls $@ + -@echo "" + +xpipe: pipe.o socket.o $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ pipe.o socket.o \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) + +l-pipe:; $(LINT) $(LFLAGS) pipe.c socket.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################### +# unbind +################################################################### + +inst-unbind: $(BINDIR)unbind + +$(BINDIR)unbind: xunbind + -cp $@ zxunbind + -rm -f $@ + cp xunbind $@ + -rm -f $(BINDIR)squid + ln $@ $(BINDIR)squid + -@ls -gls $@ + -@echo "" + +xunbind: unbind.o socket.o $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ unbind.o socket.o \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) + +l-unbind:; $(LINT) $(LFLAGS) unbind.c socket.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################### +# dishinit +################################################################### + +inst-dishinit: $(SBINDIR)dishinit + +$(SBINDIR)dishinit: dishinit + -cp $@ zdishinit + -rm -f $@ + cp dishinit $@ + chmod 600 $@ + -@ls -gls $@ + -@echo "" + + +################################################################### +# quipurc +################################################################### + +inst-quipurc: $(SBINDIR)new_quipurc + +$(SBINDIR)new_quipurc: xquipurc + -cp $@ zxquipurc + -rm -f $@ + cp xquipurc $@ + chmod ugo+s $@ + -@ls -gls $@ + -@echo "" + +xquipurc: quipurc.o $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ quipurc.o \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) $(LIBGDBM) + +l-quipurc:; $(LINT) $(LFLAGS) quipurc.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################### +# SID +################################################################### + +inst-sid: $(BINDIR)clist $(BINDIR)dlist $(BINDIR)osearch \ + $(BINDIR)ousearch $(BINDIR)psearch + +$(BINDIR)clist: clist + -cp $@ zclist + -rm -f $@ + cp clist $@ + chmod a+x $@ + -@ls -gls $@ + -@echo "" + +$(BINDIR)dlist: dlist + -cp $@ zdlist + -rm -f $@ + cp dlist $@ + chmod a+x $@ + -@ls -gls $@ + -@echo "" + +$(BINDIR)osearch: osearch + -cp $@ zosearch + -rm -f $@ + cp osearch $@ + chmod a+x $@ + -@ls -gls $@ + -@echo "" + +$(BINDIR)ousearch: ousearch + -cp $@ zousearch + -rm -f $@ + cp ousearch $@ + chmod a+x $@ + -@ls -gls $@ + -@echo "" + +$(BINDIR)psearch: psearch + -cp $@ zpsearch + -rm -f $@ + cp psearch $@ + chmod a+x $@ + -@ls -gls $@ + -@echo "" + +############################################################## +# clean +############################################################## + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig core + +grind:; iprint Makefile + tgrind -lc $(CFILES) +# @echo $(MANUALS) | \ +# tr " " "\012" | \ +# sed -e "s%.*%itroff -man &%" | \ +# sh -ve + +true:; + +# DO NOT DELETE THIS LINE +# Dependencies follow +pipe.o: ../../../../h/config.h +pipe.o: ../../../../h/dgram.h +pipe.o: ../../../../h/general.h +pipe.o: ../../../../h/internet.h +pipe.o: ../../../../h/logger.h +pipe.o: ../../../../h/manifest.h +pipe.o: ../../../../h/quipu/config.h +pipe.o: ../../../../h/quipu/util.h +pipe.o: ../../../../h/tailor.h +pipe.o: ../../../../h/usr.dirent.h +quipurc.o: ../../../../h/config.h +quipurc.o: ../../../../h/general.h +quipurc.o: ../../../../h/isoaddrs.h +quipurc.o: ../../../../h/logger.h +quipurc.o: ../../../../h/manifest.h +quipurc.o: ../../../../h/psap.h +quipurc.o: ../../../../h/quipu/attr.h +quipurc.o: ../../../../h/quipu/attrvalue.h +quipurc.o: ../../../../h/quipu/authen.h +quipurc.o: ../../../../h/quipu/bind.h +quipurc.o: ../../../../h/quipu/commonarg.h +quipurc.o: ../../../../h/quipu/config.h +quipurc.o: ../../../../h/quipu/dap.h +quipurc.o: ../../../../h/quipu/ds_error.h +quipurc.o: ../../../../h/quipu/ds_search.h +quipurc.o: ../../../../h/quipu/dsp.h +quipurc.o: ../../../../h/quipu/dua.h +quipurc.o: ../../../../h/quipu/entry.h +quipurc.o: ../../../../h/quipu/list.h +quipurc.o: ../../../../h/quipu/modify.h +quipurc.o: ../../../../h/quipu/name.h +quipurc.o: ../../../../h/quipu/oid.h +quipurc.o: ../../../../h/quipu/read.h +quipurc.o: ../../../../h/quipu/sequence.h +quipurc.o: ../../../../h/quipu/util.h +quipurc.o: ../../../../h/tailor.h +socket.o: ../../../../h/config.h +socket.o: ../../../../h/dgram.h +socket.o: ../../../../h/general.h +socket.o: ../../../../h/internet.h +socket.o: ../../../../h/logger.h +socket.o: ../../../../h/manifest.h +socket.o: ../../../../h/quipu/config.h +socket.o: ../../../../h/quipu/util.h +socket.o: ../../../../h/tailor.h +unbind.o: ../../../../h/config.h +unbind.o: ../../../../h/dgram.h +unbind.o: ../../../../h/general.h +unbind.o: ../../../../h/internet.h +unbind.o: ../../../../h/logger.h +unbind.o: ../../../../h/manifest.h +unbind.o: ../../../../h/quipu/config.h +unbind.o: ../../../../h/quipu/util.h +unbind.o: ../../../../h/tailor.h diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/READ-ME b/usr/src/contrib/isode/others/quipu/uips/dish/READ-ME new file mode 100644 index 0000000000..50f55a3644 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/READ-ME @@ -0,0 +1,22 @@ +[ READ-ME - Fri Dec 9 21:59:43 1988 - "dish" Directory Interface - /cwm ] + +This directory contains some additional features for the OSI Directory +Interface called "dish" which is build and installed from the +quipu/dish directory. To generate these additional features you +should: + + ./make install + +from this directory. If you do not want to clean up after the install +you can issue the following command instead: + + ./make inst-all + +The program "new_quipurc" is used to create a ".quipurc" file in users +home directories. If will only be called if the option + quipurc on +is specified in the file /etc/dsaptailor. +ALSO to use this option, you should edit "./dishinit", and enter the +name of the manager, their password, and the users part of the +local sub-tree, BEFORE you run make inst-all. + diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/clist b/usr/src/contrib/isode/others/quipu/uips/dish/clist new file mode 100644 index 0000000000..89a5c43015 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/clist @@ -0,0 +1,3 @@ +#!/bin/sh +echo Listing two letter country codes and descriptions +exec search @ -filter objectclass=country -type co -show diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/dishinit b/usr/src/contrib/isode/others/quipu/uips/dish/dishinit new file mode 100644 index 0000000000..87e3045133 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/dishinit @@ -0,0 +1,15 @@ +#The name of the manager of the Local DSA +manager: c=GB@o=University College London@ou=Computer Science@cn=incads +#Their passowrd +password: If_only_I_could_tell +#The part of the tree that should be searched fo users +local: @c=GB@o=University College London@ou=Computer Science + +##Anything after this line is copied into the users ~/.quipurc file +notype: acl +notype: treestructure +notype: masterdsa +notype: slavedsa +notype: objectclass +cache_time: 30 +connect_time: 2 diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/dlist b/usr/src/contrib/isode/others/quipu/uips/dish/dlist new file mode 100644 index 0000000000..59a87ab2fe --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/dlist @@ -0,0 +1,5 @@ +#!/bin/sh +echo Listing below: +showname $1 +echo "" +exec search -filter !objectclass=dsa -nosize $* diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/dsalist b/usr/src/contrib/isode/others/quipu/uips/dish/dsalist new file mode 100644 index 0000000000..b16a868e18 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/dsalist @@ -0,0 +1,41 @@ +#!/bin/sh +#Calculate unique TCP port based on PID +ppid=$$ +if ( test $ppid-lt10000 ) +then + ppid=`expr $ppid + 10000` +fi +DISHPROC="127.0.0.1 $ppid" +export DISHPROC +if ( bind ) +then + echo -n +else + exit 1 +fi +moveto @ +echo "Searching ROOT" +search -filter objectclass=DSA -nokey -seq dsas -nosize -nopart +for i in `search -filter objectclass=quipunonleafobject -noname -seq x -nosize -nopart` +do + echo -n "Searching " + moveto -seq x -nocheck $i -pwd + search -filter objectclass=DSA -norel -seq dsas -nosize -nopart + if ( search -filter objectclass=quipunonleafobject -nopart -noname -seq y -nosize > /tmp/dsalist 2>/dev/null ) + then + for j in `cat /tmp/dsalist` + do + echo -n "Searching " + moveto -seq y -nocheck $j -pwd + if (search -filter objectclass=quipuDSA -norel -subtree -seq dsas -nosize -nopart >/tmp/dsalist 2>/dev/null ) + then + cat /tmp/dsalist + fi + done + fi +done +echo +echo Summary... +squid -seq dsas +rm -f /tmp/dsalist +unbind diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/dsaping b/usr/src/contrib/isode/others/quipu/uips/dish/dsaping new file mode 100644 index 0000000000..3a376329e8 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/dsaping @@ -0,0 +1,51 @@ +#!/bin/sh +#Calculate unique TCP port based on PID +start=${1-c=GB} +ppid=$$ +gooddsa=0 +baddsa=0 +ditsize=0 +if ( test $ppid-lt10000 ) +then + ppid=`expr $ppid + 10000` +fi +DISHPROC="127.0.0.1 $ppid" +export DISHPROC +if ( bind -noa ) +then + echo -n +else + exit 1 +fi +moveto @ +if [ $start != "root" ] +then + moveto $start +fi +for j in `search -filter objectclass=quipuDSA -nosize -time 500 -type presentationaddress -noname` +do + echo -n "Trying " + moveto -nocheck -pwd $j + if ( bind -c `showentry -type presentationaddress -nokey` -noa 2>/dev/null ) + then + gooddsa=`expr $gooddsa + 1` + if ( dsacontrol -info > /tmp/dsainfo 2>/dev/null ) + then + dsasize=`awk < /tmp/dsainfo '{ printf $1 }'` + echo Size $dsasize + ditsize=`expr $ditsize + $dsasize` + else + echo Contacted + fi + else + echo Failed + baddsa=`expr $baddsa + 1` + fi +done +echo +echo $gooddsa DSAs contacted +echo $baddsa connections failed +echo +echo Counted $ditsize entries +rm -f /tmp/dsainfo +unbind diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/make b/usr/src/contrib/isode/others/quipu/uips/dish/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/osearch b/usr/src/contrib/isode/others/quipu/uips/dish/osearch new file mode 100644 index 0000000000..40ea88953b --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/osearch @@ -0,0 +1,23 @@ +#!/bin/sh +cf=$HOME/.country +if test $# -lt 1 -o $# -gt 2 +then + echo "Usage: osearch organisation [ country ]" + exit +fi + +if test $# -eq 2 +then + country=$2 + echo $country > $cf +else + if test -f $cf + then + country=`cat $cf` + else + country=gb + echo $country > $cf + fi +fi +echo Searching in country \"$country\" for Organisations matching \"$1\" +search @c=$country -filter "o~=$1 | o=\*$1\*" -type description -type telephonenumber -show diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/ousearch b/usr/src/contrib/isode/others/quipu/uips/dish/ousearch new file mode 100644 index 0000000000..59663dc324 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/ousearch @@ -0,0 +1,5 @@ +#!/bin/sh +echo Searching for Org Units matching $1 under: +showname $2 +echo "" +exec search -filter "ou~=$1 | ou=\*$1\*" -type description -type telephonenumber -show $2 diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/pipe.c b/usr/src/contrib/isode/others/quipu/uips/dish/pipe.c new file mode 100644 index 0000000000..ac882aed2c --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/pipe.c @@ -0,0 +1,413 @@ +/* pipe.c - Dish shell command handler */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/dish/RCS/pipe.c,v 7.3 91/02/22 09:30:25 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/dish/RCS/pipe.c,v 7.3 91/02/22 09:30:25 mrose Interim $ + * + * + * $Log: pipe.c,v $ + * Revision 7.3 91/02/22 09:30:25 mrose + * Interim 6.8 + * + * Revision 7.2 91/02/12 18:33:00 mrose + * upate + * + * Revision 7.1 90/03/15 11:20:36 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:08:32 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "quipu/util.h" +#include "tailor.h" +#include "general.h" +#include "usr.dirent.h" + +extern int errno; + +#ifdef SOCKETS /* USE INTERNET SOCKETS */ + +#include "internet.h" + +main(argc,argv) +int argc; +char *argv[]; +{ + int sd,res; + struct sockaddr_in sin_buf; + struct sockaddr_in * sin = &sin_buf; + char buffer [BUFSIZ]; + char dishname [BUFSIZ]; + char * ptr; + + isodetailor (argv[0], 1); + + if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) { + perror("start_tcp_client"); + exit(-20); + } + + if (get_dish_sock (sin, 0, 1) != 0) + exit (-21); + + if (join_tcp_server (sd, sin) == NOTOK) { + int pid; + (void) close_tcp_socket (sd); + +fork_again: ; + switch (pid = vfork ()) { + case 0: + /* child */ + (void) close_tcp_socket (sd); + (void) strcpy (dishname, + _isodefile (isodebinpath, "dish")); + { + int i, nfds = getdtablesize (); + + for (i = fileno(stderr) + 1; i < nfds; i++) + (void) close (i); + } + execl (dishname, "dish","-pipe",NULLCP); + (void) fprintf (stderr, "unable to exec "); + perror (dishname); + _exit (-21); + case -1: + perror ("fork"); + (void) close_tcp_socket (sd); + exit (-22); + default: + /* parent */ + for (;;) { + if ((sd = start_tcp_client ((struct sockaddr_in *) 0, + 0)) == NOTOK) { + perror("start_tcp_client"); + exit(-23); + } + if (join_tcp_server (sd, sin) != NOTOK) + break; + + /* need to introduce a timeout !!! */ + (void) close_tcp_socket (sd); + + sleep (5); + + if (kill (pid, 0) == NOTOK) { + (void) fprintf (stderr,"Trying again...\n"); + goto fork_again; + } + } + break; + } + } + + if ((ptr = rindex (argv[0], '/')) == NULLCP) + (void) strcpy (buffer,argv[0]); + else + (void) strcpy (buffer,++ptr); + + argc--,argv++; + + while (argc--) { + (void) strcat (buffer, " \""); + (void) strcat (buffer, *argv++); + (void) strcat (buffer, "\""); + } + (void) strcat (buffer, "\n"); + + if (send(sd, buffer, strlen(buffer), 0) == -1) { + perror("send"); + (void) close_tcp_socket (sd); + exit (-25); + } + + for (;;) { + if ((res = recv(sd, buffer, BUFSIZ - 1, 0)) == -1) { +err_recv: ; + perror ("recv"); + (void) close_tcp_socket (sd); + exit (-26); + } + *(buffer + res) = 0; + if (res == 0) { + (void) close_tcp_socket (sd); + exit (0); + } + + if (*buffer == '2') { + if (res > 1) + (void) write (2,&buffer[1],--res); + while ( (res = recv(sd, buffer, BUFSIZ, 0)) > 0) + (void) write (2,buffer,res); + (void) close_tcp_socket (sd); + exit (1); + } else if ((*buffer == '1') || (*buffer == '3')) { + int eval; + eval = (*buffer == '1' ? 0 : 2); + if (res > 1) + (void) write (1,&buffer[1],--res); + while ( (res = recv(sd, buffer, BUFSIZ, 0)) > 0) + (void) write (1,buffer,res); + (void) close_tcp_socket (sd); + exit (eval); + } else { /* 'e', 'y', 'm', or 'p' */ + register char *cp, *ep; + char where[BUFSIZ]; + + cp = buffer + res - 1; + ep = buffer + sizeof buffer - 1; + while (*cp != '\n') { + ++cp; + switch (res = recv (sd, cp, ep - cp, 0)) { + case NOTOK: + goto err_recv; + case OK: + fprintf (stderr, + "eof reading '%c' directive\n", + *buffer); + exit (-28); + default: + cp += res - 1; + if (cp < ep) + continue; + fprintf (stderr, + "'%c' directive exceeds %d octets\n", + *buffer, sizeof buffer - 1); + exit(-29); + } + } + *cp = NULL; + + if (*buffer == 'e') { + if (system (&buffer[1])) + (void) strcpy (where, "e"); + else + (void) getcwd (where, sizeof where); + } else if (*buffer == 'm') { + (void) fprintf (stderr, "\n%s\n", buffer + 1); + (void) strcpy (where, "m"); + } else if (*buffer == 'y') { + (void) fprintf (stderr,"%s",buffer + 1); + (void) fgets (where, sizeof where, stdin); + if (cp = index (where, '\n')) + *cp = NULL; + } else { /* 'p' */ + (void) sprintf (where, + "Enter password for \"%s\": ", + buffer + 1); + (void) sprintf (where, "p%s", + getpassword (where)); + } + (void) strcat (where, "\n"); + + if (send(sd, where, strlen(where), 0) == -1) { + perror("send"); + (void) close_tcp_socket (sd); + exit (-27); + } + + } + + } +} + + +#else /* USE UNIX NAMED PIPES */ + +#include +#include +#include +#include + +char retfile[BUFSIZ]; +int fd; +int wfd; + +main (argc, argv) +int argc; +char **argv; +{ + int res; + char buffer[BUFSIZ]; + char sendfile[BUFSIZ]; + char dishname[BUFSIZ]; + int i; + char *ptr, *getenv(), *sprintf(), *getpassword (); + void pipe_quit (); + + + (void) umask (0); + (void) sprintf (retfile, "/tmp/dish%d", getpid ()); + if ((ptr = getenv ("DISHPROC")) == NULLCP) { + (void) sprintf (sendfile, "/tmp/dish-%d", getppid ()); + (void) setenv ("DISHPROC", sendfile); + } + else + (void) strcpy (sendfile, ptr); + + setbuf (stdout,NULLCP); + setbuf (stderr,NULLCP); + + if (mknod (retfile, S_IFIFO | 0600, 0) == -1) { + (void) fprintf (stderr,"Can't create pipe '%s'\n",retfile); + exit (-12); + } + + for (i = 1; i <= 15; i++) + (void) signal (i, pipe_quit); + + if ((fd = open (sendfile, O_WRONLY | O_NDELAY)) == -1) { + (void) fprintf (stderr, "(Dish starting)\n"); + if (mknod (sendfile, S_IFIFO | 0600, 0) == -1) { + (void) fprintf (stderr,"Can't create pipe '%s'\n",sendfile); + exit (-11); + } + (void) strcpy (dishname, _isodefile (isodebinpath, "dish")); + if (vfork () == 0) { + /* child */ + execl (dishname, "dish","-pipe",NULLCP); + (void) fprintf (stderr, "unable to exec "); + perror (dishname); + (void) unlink (retfile); + _exit (-2); + } else { + fd = open (sendfile, O_WRONLY); + setbuf (stderr,NULLCP); + } + } + argc--; + if ((ptr = rindex (argv[0], '/')) == NULLCP) + (void) sprintf (buffer, "%s:%s", retfile, argv[0]); + else + (void) sprintf (buffer, "%s:%s", retfile, ++ptr); + argv++; + + while (argc--) { + (void) strcat (buffer, " \""); + (void) strcat (buffer, *argv++); + (void) strcat (buffer, "\""); + } + + if ((res = write (fd, buffer, strlen (buffer))) == -1) { + (void) fprintf (stderr, "Write to DUA failed... Please retry\n"); + (void) close (fd); + (void) unlink (retfile); + exit (-3); + } + (void) close (fd); + + /* get results */ + if ((fd = open (retfile, O_RDONLY)) < 0) { + (void) fprintf (stderr, "Can't read results\n"); + (void) unlink (retfile); + exit (-4); + } + + if ((wfd = open (retfile, O_WRONLY)) < 0) { + (void) fprintf (stderr, "Can't lock results failed\n"); + (void) unlink (retfile); + (void) close (fd); + exit (-5); + } + + for (;;) { + if ((res = read (fd, buffer, BUFSIZ - 1)) == -1) { + (void) fprintf (stderr, "Read failed (%d)\n", errno); + (void) unlink (retfile); + (void) close (fd); + (void) close (wfd); + exit (-6); + } + *(buffer + res) = 0; + + if (*buffer == '2') { + (void) write (2,&buffer[1],--res); + while ( (res = read (fd, buffer, BUFSIZ)) > 0) + (void) write (2,buffer,res); + (void) close (fd); + (void) close (wfd); + (void) unlink (retfile); + exit (-1); + } else if ((*buffer == '1') || (*buffer == '3')) { + int eval; + eval = (*buffer == '1' ? 0 : 2); + (void) write (1,&buffer[1],--res); + while ( (res = read (fd, buffer, BUFSIZ)) > 0) + (void) write (1,buffer,res); + (void) close (fd); + (void) close (wfd); + (void) unlink (retfile); + exit (eval); + else { /* 'e', 'y', 'm', or 'p' */ + int res2, + nfd; + char where[BUFSIZ]; + + if (*buffer == 'e') { + if (system (&buffer[1])) + (void) strcpy (where, "e"); + else + (void) getcwd (where, sizeof where); + } else if (*buffer == 'm') { + (void) fprintf (stderr, "\n%s\n", buffer + 1); + (void) strcpy (where, "m"); + } else if (*buffer == 'y') { + char *cp; + + (void) fprintf (stderr,"%s",buffer + 1); + (void) fgets (where, sizeof where, stdin); + if (cp = index (where, '\n')) + *cp = NULL; + } else { /* 'p' */ + (void) sprintf (where, + "Enter password for \"%s\": ", + buffer + 1); + (void) sprintf (where, "p%s", + getpassword (where)); + } + (void) strcat (where, "\n"); + + if ((nfd = open (sendfile, O_WRONLY)) == -1) { + (void) fprintf (stderr, "re-write open error\n"); + (void) close (wfd); + (void) close (fd); + (void) unlink (retfile); + exit (-9); + } + if ((res2 = write (nfd, where, strlen (where))) == -1) { + (void) fprintf (stderr, "Write to DUA failed (%d)... Please retry\n", res2); + (void) close (fd); + (void) close (nfd); + (void) close (wfd); + (void) unlink (retfile); + exit (-10); + } + (void) close (nfd); + } + } +} + +void pipe_quit (sig) +int sig; +{ + (void) unlink (retfile); + (void) fprintf (stderr,"(signal %d) exiting...\n",sig); + exit(0); +} +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/psearch b/usr/src/contrib/isode/others/quipu/uips/dish/psearch new file mode 100644 index 0000000000..14e4b1784d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/psearch @@ -0,0 +1,5 @@ +#!/bin/sh +echo Searching for People matching \"$1\" under: +showname $2 +echo "" +search -filter "cn~=$1 | cn=\*$1\*" -type telephonenumber -show -subtree $2 diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/quipurc.c b/usr/src/contrib/isode/others/quipu/uips/dish/quipurc.c new file mode 100644 index 0000000000..3dcf342b71 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/quipurc.c @@ -0,0 +1,700 @@ +/* A 'C' version of the shellscript dishinit + * By Steve Titcombe + * + * Most of this has fixed calls to other functions, and will require going + * through again to strip out all unnecessary error trapping, etc. + * (Utterly Horrible Hack.) + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/dish/RCS/quipurc.c,v 7.5 91/02/22 09:30:27 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include "manifest.h" +#include +#include +#include +#include "quipu/read.h" +#include "quipu/sequence.h" +#include "quipu/name.h" +#include "quipu/bind.h" +#include "quipu/dsp.h" +#include "quipu/ds_error.h" +#include "tailor.h" +#include "quipu/util.h" +#include "quipu/dua.h" +#include "quipu/ds_search.h" +#include "quipu/list.h" +#include "quipu/entry.h" +#include "quipu/modify.h" + +#define ORG_PERSON "thornPerson & quipuObject" + /* this should probably go elsewhere !!! */ + + LLog *log_dua; + DN sequence_dn() ; + DN dn, moddn ; + DN fixed_pos = NULLDN ; + PS opt; + PS rps; + PS fileps ; + + FILE *fp_quipurc ; + FILE *fp_draft ; + FILE *fp_tailor ; + + Filter get_filter (); +struct entrymod *ems_append() ; +struct entrymod *modify_avs() ; + +static struct ds_bind_arg bindarg ; +static struct ds_bind_arg bindresult ; +static struct ds_bind_error binderr ; + + struct ds_read_arg read_arg; + struct DSError read_error; + + struct ds_read_result read_result; + struct ds_modifyentry_arg mod_arg ; + struct DSError mod_error ; + + struct DSError search_error; + struct ds_search_result search_result; +static struct ds_search_arg search_arg = + { + default_common_args, + NULLDN, + SRA_ONELEVEL, + NULLFILTER, /* filter */ + FALSE, + { /* eis */ + FALSE, + NULLATTR, + EIS_ATTRIBUTESANDVALUES + } + }; + +static struct dua_sequence *current_sequence = NULL_DS; + struct entrymod *emnew ; + +AV_Sequence avst = NULLAV ; +Attr_Sequence as_flag = NULLATTR ; +Attr_Sequence trail = NULLATTR ; +Attr_Sequence eptr ; +Attr_Sequence temp ; +Attr_Sequence as ; +AttributeType at; + +#ifdef TURBO_DISK +extern Attr_Sequence fget_attributes() ; +#else +extern Attr_Sequence get_attributes() ; +#endif +extern char *TidyString() ; + + Entry current_entry ; + Entry entry_ptr ; + + char Manager[LINESIZE] ; + char Password[LINESIZE] ; + char Local[LINESIZE] ; + char filterstring[LINESIZE] ; + +main() +{ + struct passwd *pw_entry ; + struct passwd *getpwuid() ; + struct stat buf ; + + int i = 1 ; + int uid ; + int um ; + char pass1[LINESIZE] ; + char pass2[LINESIZE] ; + char Read_in_Stuff[LINESIZE] ; + char **vecptr ; + char *tmpdraft ; + char home_dir[LINESIZE] ; + char *p, *part1, *part2 ; + char quipurc_file[100] ; + char tailor_file[100] ; + char user_name[9] ; + char *localptr = Local ; + char print_format = EDBOUT ; + EntryInfo *ptr ; + static CommonArgs ca = default_common_args; + + vecptr = (char **) malloc(100) ; + vecptr[0] = malloc (LINESIZE) ; + (void) strcpy(vecptr[0], "showentry") ; + (void) strcpy(pass1, "x") ; + (void) strcpy(pass2, "y") ; + tmpdraft = malloc (LINESIZE) ; + (void) strcpy(tmpdraft, "/tmp/dish-") ; + + if ((opt = ps_alloc (std_open)) == NULLPS) + fatal (-62, "ps_alloc failed"); + if (std_setup (opt, stderr) == NOTOK) + fatal (-63, "std_setup failed"); + if ((rps = ps_alloc (std_open)) == NULLPS) + fatal (-64, "ps_alloc 2 failed"); + if (std_setup (rps, stdout) == NOTOK) + fatal (-65, "std_setup 2 failed"); + (void) strcpy(filterstring, "userid=") ; + + /* Sort out files, userids etc. */ + uid=getuid() ; + if ((pw_entry=getpwuid(uid)) == 0) + { + ps_printf(rps, "Who are you? (no name for your uid number)\n") ; + exit(1) ; + } + (void) strcpy(user_name, pw_entry->pw_name) ; + (void) strcat(tmpdraft, user_name) ; + + if (getenv("HOME") == 0) + { + ps_printf(rps, "No home directory?!!") ; + (void) strcpy(home_dir, pw_entry->pw_dir) ; + } + else + { + (void) strcpy(home_dir, getenv("HOME")) ; + } + + (void) strcpy(quipurc_file, home_dir) ; + (void) strcat(quipurc_file, "/.quipurc") ; + + (void) strcpy(tailor_file, isodefile ("dishinit", 1)); + + Manager[0] = 0; + Password[0] = 0; + Local[0] = 0; + + (void) stat(tailor_file, &buf) ; + (void) seteuid(buf.st_uid) ; /* set effective to enable */ + /* us to read protected file */ + + if ((fp_tailor = fopen(tailor_file, "r")) == 0) + { + ps_print(rps, "Can't open Tailor File. Abort.\n") ; + exit(1) ; + } + + while (fgets (Read_in_Stuff, LINESIZE, fp_tailor) != 0) + { + if (!strcmp(Read_in_Stuff, "##Anything after this line is copied into the users ~/.quipurc file\n")) + { + break ; + } + + p = SkipSpace (Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; /* ignore comments and blanks */ + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) { + ps_printf (opt,"Seperator missing '%s'. Ignoring..\n",p); + } + + *part2++ = '\0'; + part2 = TidyString (part2); + + if (lexequ(part1, "manager") == 0) + { + (void) strcpy(Manager, part2) ; + } + else + if (lexequ(part1, "password") == 0) + { + (void) strcpy(Password, part2) ; + } + else + if (lexequ(part1, "local") == 0) + { + (void) strcpy(Local, part2) ; + } + else + { + ps_printf(rps, "Error in tailor. What's a %s?\n", part1) ; + } + + } + (void) setuid(uid) ; /* Restore Userid to original user. */ + +/* create ~/.quipurc file. NB this does eradicate anything in there. + * (Theoretically nothing.) + */ + + if (Manager[0] == 0) { + ps_print(rps, "Can't find out the managers name\n") ; + exit(1) ; + } + if (Password[0] == 0) { + ps_print(rps, "Can't find out the managers password\n") ; + exit(1) ; + } + if (Local[0] == 0) { + ps_print(rps, "Can't find out where to search\n") ; + exit(1) ; + } + + um = umask(0177) ; + if ((fp_quipurc = fopen(quipurc_file, "w")) == 0) + { + ps_printf(rps, "Can't open ~/.quipurc. Aborting..\n") ; + exit(1) ; + } + (void) umask(um) ; + + if ((fileps = ps_alloc(std_open)) == NULLPS) + { + fatal (-66, "ps_alloc 2 failed"); + } + if (std_setup (fileps, fp_quipurc) == NOTOK) + { + fatal (-67, "std_setup 2 failed"); + } + + + /* Sorting out the bind section */ + quipu_syntaxes() ; /* set up the needed function pointers */ + dsap_init(&i, &vecptr) ; + + (void) strcpy(bindarg.dba_passwd, Password) ; + bindarg.dba_version = DBA_VERSION_V1988; + bindarg.dba_passwd_len = strlen(bindarg.dba_passwd) ; + + if ((bindarg.dba_dn = str2dn (Manager)) == NULLDN) + { + ps_printf (opt,"Invalid Manager name %s (???!)\n",Manager) ; + exit(1) ; + } + + if (ds_bind (&bindarg, &binderr, &bindresult) != OK) + { + ps_printf(rps, "Can't bind as the manager.\n") ; + exit(1); + } + /* Hopefully, should be successfully bound */ + +/* + * We now call the search stuff with the right bits, to see if we can get a + * match of uid='user_name'. Once there, we echo lots of information from + * their entry out to the .quipurc file. + * Hopefully there should only be one match. This assumes that ALL dir info + * up to date, and that SG do not allow multiple users with the same login. + */ + +/* set up the appropriate structures and defaults. */ + + search_arg.sra_common = ca; /* struct copy */ + search_arg.sra_common.ca_servicecontrol.svc_sizelimit = 2 ; + search_arg.sra_eis.eis_allattributes = FALSE ; + search_arg.sra_searchaliases = FALSE; + search_arg.sra_subset = SRA_ONELEVEL; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES ; + search_arg.sra_eis.eis_select = NULLATTR ; + search_arg.sra_eis.eis_allattributes = TRUE ; + search_arg.sra_filter = filter_alloc() ; + /* Default filter. */ + search_arg.sra_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_type = FILTER_ITEM; + search_arg.sra_filter->FUFILT = NULLFILTER; + + + if (*localptr == '@') + { + localptr++; + } + if ((search_arg.sra_baseobject = str2dn(localptr)) == NULLDN) + { + ps_printf (opt,"Invalid sequence in username %s.\n", localptr); + exit(1) ; + } + + (void) strcat(filterstring, user_name) ; + + search_arg.sra_filter->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY ; + + if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new ("userid")) == NULLAttrT) + { + ps_printf(rps, "Oops, userid is not a valid attr type. ABORT!!\n") ; + exit(1) ; + } + if ((search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = str2AttrV (user_name, search_arg.sra_filter->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax)) == NULLAttrV) + { + ps_printf(rps, "%s is not a valid attribute value.\n", user_name) ; + } + +/* call search */ +/* We now ought to be in the right place, and with the search stuff set, + * ready to call search, and receive one (or no) entry back, which then + * gets processed accordingly. + */ + + if (ds_search (&search_arg, &search_error, &search_result) != DS_OK) + { + ps_printf(rps, "Search failed...\n") ; + exit (1) ; + /* This is not the same as coming back with */ + /* message "search failed to find anything. */ + } + +/* If the user does not exist in the DIT, print out the limited .quipurc + * and the warning message, and allow the user to play DISH. + */ + + if (search_result.CSR_entries == NULLENTRYINFO) + { + ps_printf(opt, "Unfortunately, you seem to have no entry in\n") ; + ps_printf(opt, "the directory. Contact '%s' who should be able to help.\n", Manager) ; + ps_printf(opt, "In the mean time, you can read, but not write.\n") ; + } + else + { + ptr = search_result.CSR_entries ; + dn = dn_cpy(ptr->ent_dn) ; /* Essence of move user_name. */ + + /* collect the info and put it into current_entry */ + + /* Set up the desired attribute type to be read*/ + /* from read.c */ + if ((at = AttrT_new ("userPassword")) != NULLAttrT) + { + as_flag = as_merge (as_flag, as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO)); + } + else + { + ps_printf(rps, "Oops, Serious error. unknown attribute type 'userPassword'.\n") ; + exit(1) ; + } + + if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY) + { + read_arg.rda_common = ca; /* struct copy */ + read_arg.rda_object = dn; + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + read_arg.rda_eis.eis_allattributes = TRUE ; + read_arg.rda_eis.eis_select = NULLATTR ; + + if (ds_read (&read_arg, &read_error, &read_result) != DS_OK) + { + ps_printf(rps, "We even seem to be having problems reading\n" ) ; + ps_printf(rps, "an entry we searched and found!! HELP!!\n") ; + exit(1) ; + } + if (read_result.rdr_entry.ent_attr == NULLATTR) + { + ps_printf(rps, "No attributes present. Even though\n") ; + ps_printf(rps, "we found you by userid attribute!!! HELP!!\n") ; + exit (1) ; + } + cache_entry (&(read_result.rdr_entry), read_arg.rda_eis.eis_allattributes, TRUE) ; + } + + if ((current_entry = local_find_entry (dn, FALSE)) == NULLENTRY) + { + ps_printf(rps, "We still have nothing.Even after reading? Abort.\n") ; + exit(1) ; + } + + ps_printf(fileps, "username: ") ; + dn_print(fileps, dn, EDBOUT) ; + ps_printf(fileps, "\n") ; + + ps_printf(fileps, "me: ") ; + dn_print(fileps, dn, EDBOUT) ; + ps_printf(fileps, "\n") ; + + /* now showattribute -nokey to display it. */ + + ps_printf(fileps, "password: ") ; + for (eptr = current_entry->e_attributes; eptr != NULLATTR; + eptr = eptr->attr_link) + { + /* Tiptoe through the list of types until one matches, and then print value. */ + if (AttrT_cmp (eptr->attr_type, at) == 0) + { + avs_print (fileps, eptr->attr_value,print_format); + break; + } + } + + if (eptr == NULLATTR) + { + while( strcmp(pass1, pass2)) + { + ps_printf(opt, "You need a password...\n") ; + (void) strcpy(pass1, getpassword("Enter Password: ")) ; + (void) strcpy(pass2, getpassword("Re-enter password: ")) ; + if (strcmp(pass1, pass2)) + { + ps_printf(opt, "\nMismatch - Try again.\n") ; + } + } + ps_printf(fileps, "%s\n", pass1) ; + + um = umask(0177) ; + if ((fp_draft = fopen(tmpdraft, "w")) == 0) + { + ps_print(rps, "Can't open draft file... Abort.\n") ; + exit(1) ; + } + (void) umask(um) ; + + (void) fprintf(fp_draft, "UserPassword = %s\n", pass1) ; + (void) fprintf(fp_draft, "acl = self # write # attributes # acl $ userPassword\n") ; + (void) fprintf(fp_draft, "acl = others # compare # attributes # acl $ userPassword\n\n") ; + (void) fclose(fp_draft) ; + + if ((fp_draft = fopen (tmpdraft, "r")) == NULL) { + ps_printf (opt, "Can't open draft entry %s\n", tmpdraft); + exit(1) ; + } + + entry_ptr = get_default_entry (NULLENTRY); +#ifdef TURBO_DISK + entry_ptr->e_attributes = fget_attributes (fp_draft); +#else + entry_ptr->e_attributes = get_attributes (fp_draft); +#endif + + (void) fclose (fp_draft); + + mod_arg.mea_common = ca; /* struct copy */ + mod_arg.mea_object = dn; + for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent) + ; + entry_ptr->e_name = rdn_cpy (moddn->dn_rdn); + + /* add rdn as attribute */ + avst = avs_comp_new (AttrV_cpy (&entry_ptr->e_name->rdn_av)); + temp = as_comp_new (AttrT_cpy (entry_ptr->e_name->rdn_at), avst, NULLACL_INFO); + entry_ptr->e_attributes = as_merge (entry_ptr->e_attributes, temp); + + for (as = entry_ptr->e_attributes; as != NULLATTR; as = as->attr_link) + { + emnew = NULLMOD; + trail = as->attr_link; + as->attr_link = NULLATTR; + temp = current_entry->e_attributes; + for (; temp != NULLATTR; temp = temp->attr_link) + if (AttrT_cmp (as->attr_type, temp->attr_type) == 0) + { + /* found it - does it need changing ? */ + if (avs_cmp (as->attr_value, temp->attr_value) != 0) + emnew = modify_avs (as->attr_value, temp->attr_value,as->attr_type); + break; + } + + if (temp == NULLATTR) + { + emnew = em_alloc (); + emnew->em_type = EM_ADDATTRIBUTE; + emnew->em_what = as_cpy(as); + emnew->em_next = NULLMOD; + } + if (emnew != NULLMOD) + { + mod_arg.mea_changes = ems_append (mod_arg.mea_changes,emnew); + } + as->attr_link = trail; + } + + while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK) + { + if (dish_error (opt, &mod_error) == 0) + { + ps_printf(rps,"We have a dish error. Bye.\n") ; + entry_free (entry_ptr); + exit(1) ; + } + mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + ps_print (rps, "Modified "); + dn_print (rps, dn, EDBOUT); + ps_print (rps, "\n"); + delete_cache (dn); /* re-cache when next read */ + + entry_free (entry_ptr); + ems_part_free (mod_arg.mea_changes); + } + } + + while(fgets(Read_in_Stuff, LINESIZE, fp_tailor) != 0) + { + fputs(Read_in_Stuff, fp_quipurc) ; + } + + (void) fclose(fp_quipurc) ; + (void) fclose(fp_tailor) ; + +/* (void) fprintf(fp_quipurc, "dsap: local_dit \"%s\"\n", Local) ; + (void) fprintf(fp_quipurc, "notype: acl\n") ; + (void) fprintf(fp_quipurc, "notype: treestructure\n") ; + (void) fprintf(fp_quipurc, "notype: masterdsa\n") ; + (void) fprintf(fp_quipurc, "notype: slavedsa\n") ; + (void) fprintf(fp_quipurc, "notype: objectclass\n") ; + (void) fprintf(fp_quipurc, "cache_time: 30\n") ; + (void) fprintf(fp_quipurc, "connect_time: 2\n") ; + */ + (void) ds_unbind() ; + (void) unlink(tmpdraft) ; +} + +void +advise() +{ +} + +void +set_sequence() +{ +} + +void +unset_sequence() +{ +} + +dish_error (ps,error) +PS ps; +struct DSError * error; +{ + + if (error->dse_type == DSE_ABANDONED) { + ps_printf (ps,"(DAP call interrupted - abandon successful)\n"); + return (0); + } + + if (error->dse_type == DSE_ABANDON_FAILED) { + ps_printf (ps,"(DAP call interrupted - abandon unsuccessful)\n"); + return (0); + } + + if (error->dse_type == DSE_INTRERROR) { + ps_printf (ps,"(DAP call interrupted)\n"); + return (0); + } + + ds_error (ps,error); + + return (0); +} + +DN sequence_dn(y) +int y; +{ +struct dua_seq_entry * ptr; +register int x = 1; + + if (current_sequence == NULL_DS) + return (NULLDN); + + for (ptr=current_sequence->ds_data; + (ptr != NULL_DE) && (xde_next,x++) + ; + + if (ptr == NULL_DE) + return (NULLDN); + if ( x == y ) + return (ptr->de_name); + return (NULLDN); + +} + +struct entrymod * ems_append (a,b) +struct entrymod *a; +struct entrymod *b; +{ +struct entrymod *ptr; + + if ((ptr = a) == NULLMOD) + return b; + + for ( ; ptr->em_next != NULLMOD; ptr = ptr->em_next) + ; + + ptr->em_next = b; + return a; +} + +struct entrymod * modify_avs (a,b,ent_mod_at) +AV_Sequence a; +AV_Sequence b; +AttributeType ent_mod_at; +{ +AV_Sequence x; +AV_Sequence y; +struct entrymod *em = NULLMOD, *em_new; +int removed_all = TRUE; + + for (x=b; x != NULLAV; x=x->avseq_next) { + em_new = NULLMOD; + for (y=a; y != NULLAV; y=y->avseq_next) + if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0) + break; + if (y == NULLAV) { + em_new = em_alloc (); + em_new->em_type = EM_REMOVEVALUES; + em_new->em_what = as_comp_new (ent_mod_at,avs_comp_new(&x->avseq_av),NULLACL_INFO); + em_new->em_next = NULLMOD; + } else + removed_all = FALSE; + if (em_new != NULLMOD) + em = ems_append (em,em_new); + } + + if (removed_all) { + ems_part_free (em); + em_new = em_alloc (); + em_new->em_type = EM_REMOVEATTRIBUTE; + em_new->em_what = as_comp_new (ent_mod_at,b,NULLACL_INFO); + em_new->em_next = em_alloc(); + em_new->em_next->em_type = EM_ADDATTRIBUTE; + em_new->em_next->em_what = as_comp_new (ent_mod_at,avs_cpy(a),NULLACL_INFO); + em_new->em_next->em_next = NULLMOD; + return (em_new); + } + + for (x=a; x != NULLAV; x=x->avseq_next) { + em_new = NULLMOD; + for (y=b; y != NULLAV; y=y->avseq_next) + if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0) + break; + if (y == NULLAV) { + em_new = em_alloc (); + em_new->em_type = EM_ADDVALUES; + em_new->em_what = as_comp_new (ent_mod_at,avs_comp_new(&x->avseq_av),NULLACL_INFO); + em_new->em_next = NULLMOD; + } + if (em_new != NULLMOD) + em = ems_append (em,em_new); + } + + + return (em); +} + +ems_part_free(emp) +struct entrymod *emp; +{ + if(emp == NULLMOD) + return; + ems_part_free(emp->em_next); + free((char *)emp); +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/socket.c b/usr/src/contrib/isode/others/quipu/uips/dish/socket.c new file mode 100644 index 0000000000..5498665a4c --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/socket.c @@ -0,0 +1,118 @@ +/* socket.c - dish -pipe support */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/dish/RCS/socket.c,v 7.1 91/02/22 09:30:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/dish/RCS/socket.c,v 7.1 91/02/22 09:30:30 mrose Interim $ + * + * + * $Log: socket.c,v $ + * Revision 7.1 91/02/22 09:30:30 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:36:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "quipu/util.h" +#include "tailor.h" +#include "general.h" + +#ifdef SOCKETS /* USE INTERNET SOCKETS */ + +#include "internet.h" + +get_dish_sock (isock, pid, islocal) +struct sockaddr_in *isock; +int pid, + islocal; +{ + int myppid; +char * getenv (); +char * ptr, * prnt; +static char buffer [BUFSIZ]; +static char parent [BUFSIZ]; +int portno; +char *dp; +register struct hostent *hp; + + if ((myppid = pid) == 0) + myppid = getppid (); + + if (pid != 0 || (ptr = getenv ("DISHPROC")) == NULLCP) { + char *cp; + + portno = (myppid & 0xffff) | 0x8000; + if (!islocal) { + if ((hp = gethostbystring (cp = getlocalhost ())) + == NULL) { + (void) fprintf (stderr,"%s: unknown host", cp); + return (-1); + } + (void) sprintf (buffer, "%s %d", + inet_ntoa (*(struct in_addr *) + hp -> h_addr), + portno); + } + else + (void) sprintf (buffer, "127.0.0.1 %d", portno); + + (void) setenv ("DISHPROC", ptr = buffer); + } + + if (pid !=0 || (prnt = getenv ("DISHPARENT")) == NULLCP) { + (void) sprintf (parent, "%d", myppid); + (void) setenv ("DISHPARENT", prnt = parent); + } + + + if (sscanf (prnt, "%d", &pid) != 1) { + (void) fprintf (stderr,"DISHPARENT malformed"); + return (-1); + } + + if ((dp = index (ptr, ' ')) == NULLCP || sscanf (dp + 1, "%d", &portno) != 1) { + (void) fprintf (stderr,"DISHPROC malformed"); + return (-1); + } + *dp = NULL; + + if ((hp = gethostbystring (ptr)) == NULL) { + (void) fprintf (stderr,"%s: unknown host in DISHPROC", ptr); + return (-1); + } + *dp = ' '; + + bzero ((char *) isock, sizeof *isock); + isock -> sin_family = hp -> h_addrtype; + isock -> sin_port = htons ((u_short) portno); + inaddr_copy (hp, isock); + + return (0); + +} + +#else /* USE UNIX NAMED PIPES */ + + +void dummy () +{ +; +} + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/dish/unbind.c b/usr/src/contrib/isode/others/quipu/uips/dish/unbind.c new file mode 100644 index 0000000000..d7b2b14164 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dish/unbind.c @@ -0,0 +1,222 @@ +/* unbind.c - dish shell unbind and squid commands */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/dish/RCS/unbind.c,v 7.2 91/02/22 09:30:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/dish/RCS/unbind.c,v 7.2 91/02/22 09:30:31 mrose Interim $ + * + * + * $Log: unbind.c,v $ + * Revision 7.2 91/02/22 09:30:31 mrose + * Interim 6.8 + * + * Revision 7.1 90/03/15 11:20:40 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:08:35 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "quipu/util.h" +#include "tailor.h" +#include "general.h" + +extern int errno; + + +#ifdef SOCKETS /* USE INTERNET SOCKETS */ + +#include "internet.h" + +main(argc,argv) +int argc; +char *argv[]; +{ + int sd,res,status; + struct sockaddr_in sin_buf; + struct sockaddr_in * sin = &sin_buf; + char buffer [BUFSIZ]; + char * ptr; + + if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) { + perror("start_tcp_client"); + exit(-20); + } + + if (get_dish_sock (sin, 0, 1) != 0) + exit (-21); + + if (join_tcp_server (sd, sin) == NOTOK) { + (void) fprintf (stderr,"No connection and no cache !!!\n"); + (void) close_tcp_socket (sd); + exit (0); + } + + if ((ptr = rindex (argv[0], '/')) == NULLCP) + (void) strcpy (buffer,argv[0]); + else + (void) strcpy (buffer,++ptr); + + argc--,argv++; + + while (argc--) { + (void) strcat (buffer, " \""); + (void) strcat (buffer, *argv++); + (void) strcat (buffer, "\""); + } + (void) strcat (buffer, "\n"); + + if (send(sd, buffer, strlen(buffer), 0) == -1) { + perror("send"); + (void) close_tcp_socket (sd); + exit (-25); + } + + if ((res = recv(sd, buffer, BUFSIZ-1, 0)) == -1) { + perror ("recv"); + (void) close_tcp_socket (sd); + exit (-26); + } + *(buffer + res) = 0; + + if (*buffer == '2') { + status = 1; + if (res > 1) + (void) write (2,&buffer[1],--res); + while ( (res = recv(sd, buffer, BUFSIZ, 0)) > 0) + (void) write (2,buffer,res); + } else if (*buffer == '1') { + status = 0; + if (res > 1) + (void) write (1,&buffer[1],--res); + while ( (res = recv(sd, buffer, BUFSIZ, 0)) > 0) + (void) write (1,buffer,res); + } + + (void) close_tcp_socket (sd); + + exit (status); +} + + +#else /* USE UNIX NAMED PIPES */ + +#include +#include +#include +#include + +char retfile [LINESIZE]; +int fd; + +main (argc,argv) +int argc; +char ** argv; +{ +int res; +char buffer [BUFSIZ]; +char sendfile [LINESIZE]; +int i; +char * ptr; +void pipe_quit (); +char * getenv(), *sprintf(); + + (void) umask(0); + (void) sprintf (retfile,"/tmp/dish%d",getpid()); + if ( (ptr = getenv ("DISHPROC")) == NULLCP ) { + (void) sprintf (sendfile, "/tmp/dish-%d", getppid ()); + (void) setenv ("DISHPROC", sendfile); + } + else + (void) strcpy (sendfile, ptr); + + setbuf (stdout,NULLCP); + setbuf (stderr,NULLCP); + + if (mknod (retfile,S_IFIFO|0660,0) == -1) { + (void) fprintf (stderr,"Can't create result file %s\n",retfile); + exit (-5); + } + + for (i=1; i<=15; i++) + (void) signal(i,pipe_quit); + + if ((fd = open (sendfile,O_WRONLY|O_NDELAY)) == -1) { + (void) fprintf (stderr,"No connection and no cache !!!\n"); + (void) unlink (retfile); + exit (0); + } + + argc--; + if ((ptr = rindex (argv[0],'/')) == NULLCP) + (void) sprintf (buffer,"%s:%s",retfile,argv[0]); + else + (void) sprintf (buffer,"%s:%s",retfile,++ptr); + *argv++; + + while (argc--) { + (void) strcat (buffer," "); + (void) strcat (buffer,*argv++); + } + + if (( res =write (fd, buffer,strlen (buffer))) == -1) { + (void) fprintf (stderr,"Write failed\n"); + (void) close (fd); + (void) unlink (retfile); + exit (-2); + } + (void) close (fd); + + + /* get results */ + if (( fd = open (retfile,O_RDONLY)) < 0) { + (void) fprintf (stderr,"Can't read results\n"); + (void) unlink (retfile); + exit (-3); + } + + if (( res = read (fd,buffer,BUFSIZ)) == -1) { + (void) fprintf (stderr,"Read failed (%d)\n",errno); + (void) unlink (retfile); + (void) close (fd); + exit (-4); + } + + *(buffer+res) = 0; + + if (*buffer == '2') + fputs (&buffer[1], stderr); + else if (*buffer == '1') + fputs (&buffer[1], stdout); + + (void) close (fd); + (void) unlink (retfile); + + if (*buffer == '2') + exit (-1); +} + +void pipe_quit (sig) +int sig; +{ + (void) unlink (retfile); + (void) fprintf (stderr,"(signal %d) exiting...\n",sig); + exit (0); +} + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/Makefile b/usr/src/contrib/isode/others/quipu/uips/dsc/Makefile new file mode 100644 index 0000000000..9612204977 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/Makefile @@ -0,0 +1,65 @@ +############################################### +# Configuration - see READ-ME for more details # +############################################### + +# the distinguished name of the "local" country (used by easy interface) +CDN=c=GB + +# the distinguished name of the "local" organisation (used by the easy +# interface) +ORGRDN=o=University College London + +# the directory where the easy interface deposits some logs. +LOGPLACE=$(LOGDIR)dsc + +# the directory where the dish binaries and sd may be found +LOCALPATH=$(BINDIR) + +# the short form name of your organisation - this appears in some of the +# help text +SITESHORTNAME=UCL + +# an "english" equivalent of the ORGDN +SITELONGNAME=GB, University College London + +# if you want the interface to bind as a user, specify the name of the user +# here. This is useful as it enables monitoring of the directory using this +# interface. +# BINDARG= +BINDARG=-u \\"@c=gb@o=university college london@cn=dir@cn=public access dua\\" + +# Dou you want greybook order mailboxes? Anything other than "yes" yields +# rfc822 order +EMAILUKORDER=no + +##################################### +# Rules... +##################################### + +all: dsc + +inst-all: $(LOGPLACE) + cp dsc $(LOCALPATH) + +install: inst-all clean + +lint:; + +clean:; -rm -f dsc + +grind:; + +dsc: dsc.dist1 localphone dsc.dist2 localmess dsc.dist3 + cat dsc.dist1 localphone dsc.dist2 localmess dsc.dist3 > dsc.dist + sed 's#DISTORGRDN#$(ORGRDN)#g' dsc.dist |\ + sed 's#DISTLOGPLACE#$(LOGPLACE)#g' |\ + sed 's#DISTLOCPATH#$(LOCALPATH)#g' |\ + sed 's#DISTSITESHORT#$(SITESHORTNAME)#g' |\ + sed 's#DISTSITELONG#$(SITELONGNAME)#g' |\ + sed 's#DISTBINDARG#$(BINDARG)#g' |\ + sed 's#DISTUKORDER#$(EMAILUKORDER)#g' >dsc + chmod +x dsc + +$(LOGPLACE): + -mkdir $(LOGPLACE) + diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/READ-ME b/usr/src/contrib/isode/others/quipu/uips/dsc/READ-ME new file mode 100644 index 0000000000..e5af67ef76 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/READ-ME @@ -0,0 +1,91 @@ +[ READ-ME - Wed Jan 16 10:14:24 1991 - dsc - /mtr ] + +dsc is an interface to the X.500 Directory which was originally designed as +an X.29 public access interface for use at UCL. It offers two modes of +usage: easy and advanced. + +The "easy" interface is a specially written dish (DIrectory SHell) script. + +WARNING - It only runs on shells, such as the SUNOS Bourne shell, which +support functions. + +It only searches within a single country - this was done to keep the number +of questions and the format of the input as simple as possible. +Clearly the interface could be tweaked to allow a wider scope of +querying. This script assumes that the dish binaries are already installed. + +The "advanced" interface is Brunel University's sd interface, which is +now available as part of the ISODE release. Obviously another interface +could be used if desired, although the help text would need to be rewritten. +This script assumes that the sd interface has already been installed. + +If you are in the UK and would like to try the interface, it is available +at ucl by calling uk.ac.ucl.dir, or 000005113200 for those in +mnemonic-free zones. + +Helpful comments on the script will be gratefully received. (Note that an +enhanced version of this interface, written in C, is now under development.) + +Comments should be sent to quipu-support@cs.ucl.ac.uk + +Thanks are due to a number of people who made comments on the interface, and +in particular to Andy Powell of the University of Bath, who provided +some code! + +Paul Barker +----------- + +If you would like to port the interface, you first need to configure a few +things in the Makefile. + +# the distinguished name of the "local" country (used by the easy interface) +CDN=c=GB + +# the distinguished name of the "local" organisation (used by the easy +# interface) +ORGRDN=o=University College London + +# the directory where the easy interface deposits some logs. +# THIS DIRECTORY MUST BE CREATED +LOGPLACE=/u2/quipu/logs/dsc + +# the directory where the dish binaries and sd may be found +LOCALPATH=/usr/local/bin + +# the short form name of your organisation - this appears in some of the +# help text +SITESHORTNAME=UCL + +# an "english" equivalent of the ORGDN - this is used in the help text +# maximum of about 30 chars +SITELONGNAME=GB, University College London + +# if you want the interface to bind as a user, specify the name of the user +# here. This is useful as it enables monitoring of the directory using this +# interface. The double backslashes are important to protect the quotes. +# If you don't want the interface to bind as a user, set BINDARG as +# illustrated immediately below (sample entries for "dir" and "public access +# dua" are given in the files host and paa): +# BINDARG= +BINDARG=-u \\"@c=gb@o=university college london@cn=dir@cn=public access dua\\" + +# Dou you want greybook order mailboxes? Anything other than "yes" yields +# rfc822 order +EMAILUKORDER=yes + +It also also possible to customise the appearance of telephone numbers. At +UCL, local phone numbers are shown just as extensions. UK numbers are +converted from the +44 format into leading 0 format. If you wish to do +something similar at your site, produce a file containing an awk script +fragment comparable to that in the file "localphone.ucl", and call this +file "localphone". + +Then type: + +make dsc + +to configure the script ready for use. + +make install + +installs the dsc script in the $(LOCALPATH) directory. diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist1 b/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist1 new file mode 100644 index 0000000000..41cfcd24ac --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist1 @@ -0,0 +1,237 @@ +#!/bin/sh +# these shell variables are configured by "make dsc" +CDN="@c=GB" +ORGRDN="DISTORGRDN" +INTLOGDIR=DISTLOGPLACE +LOCALPATH=DISTLOCPATH +SHORTSITE="DISTSITESHORT" +LONGSITE="DISTSITELONG" +BINDARG="DISTBINDARG" +EMAILUKORDER="DISTUKORDER" + +SHELL=/bin/echo +export SHELL +if [ "$HOME" = "" ]; then + HOME=/ + export HOME +fi +pid="$$" +trap "rm -f /tmp/dscresults$pid /tmp/dscresults${pid}2" 1 2 3 15 +trap "rm -f /tmp/dscresults$pid /tmp/dscresults${pid}2; exit" 2 +PATH=/bin:/usr/bin:/usr/ucb:/usr/5bin:$LOCALPATH +export PATH +OldIFS=$IFS +NewIFS=' +' +Mode="COMMAND-LINE" +cat <" + fi + fi + done + else if test "$iface" = "" + then + iface="e" + fi + fi +done +if test "$iface" = "e" -o "$iface" = "E" +then + ppid=$$ + if [ "$DISHPROC" = "" ]; then + if ( test $ppid-lt10000 ) + then + ppid=`expr $ppid + 10000` + fi + DISHPROC="127.0.0.1 $ppid" + export DISHPROC + fi + bind $BINDARG -noa > /dev/null 2>&1 & + +showhelp () { +cat < 1) && substr(RDNparts[n-1], 1, 3) == "ou=") + deptname = substr(RDNparts[n-1], 4) + else + deptname = "" + phone = email = "" + next + } + + # these next two actions to throw away lines we do not want + /^NOTE partial/ { + notepartial = "TRUE" + next + } + + { + if (notepartial == "TRUE") + next + } + + /\(Partial/ { + partialRes = "TRUE" + } + + /\(Admin limit exceeded/ { + partialRes = "TRUE" + } + +# all attributes need the type trimming off + { + n = index($0, "-") + 2 + } diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist2 b/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist2 new file mode 100644 index 0000000000..d94a2e35ad --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist2 @@ -0,0 +1,336 @@ + /^rfc822Mailbox/ { + tmp = substr($0, n) + no_mparts = split(tmp, mailparts, "@") + if (no_mparts == 2) + { + if ("'$EMAILUKORDER'" == "yes") + { + no_doms = split(mailparts[2], domains, ".") + email = mailparts[1] "@" domains[no_doms] + for (i = no_doms - 1; i > 0; i--) + email = email "." domains[i] + } + else + email = tmp + } + else + email = tmp + } + + END { + if (gotentry == "TRUE") + { + longform[entry ",name"] = sprintf ("\n%-15s %s", "name:", name) + if (deptname != "") + longform[entry ",dept"] = sprintf ("%-15s %s", "department:", deptname) + if (phone != "") + longform[entry ",phone"] = sprintf ("%-15s %s", "phone: ", phone) + if (email != "") + longform[entry ",email"] = sprintf ("%-15s %s", "email: ", email) + longform[entry ",org"] = sprintf ("%-15s %s", "organisation: ", org) + shortform[entry] = sprintf ("%-20s %-20s %-s", name, phone, deptname) + if (deptname == "") + { + shortform[entry] = shortform[entry] org + shortform[entry ",org"] = "" + } + else + shortform[entry ",org"] = org + gotentry = "FALSE" + } + if (entry == 0) + { + printf("\nCannot find an entry with that name\n") + exit + } + if (partialRes != "") + { + printf("\nThere are too many results to print.\n") + printf("Try and be more specific with your query to reduce the number\n") + printf("of results returned\n\n") + exit + } + if (entry > 20) + for (i=1; i <= entry; i++) + { + printf "%s", shortform[i] + if ((noOfOrgs > 1) && (shortform[i ",org"] != "")) + printf ",\n%44s%s", "", shortform[i ",org"] + printf "\n" + } + else + for (i=1; i <= entry; i++) + { + print longform[i ",name"] + if (longform[i ",dept"]) + print longform[i ",dept"] + if (longform[i ",phone"]) + print longform[i ",phone"] + if (longform[i ",email"]) + print longform[i ",email"] + if (noOfOrgs > 1) + print longform[i ",org"] + } + } ' /tmp/dscresults$pid | pg -e -n -p "RETURN for next screen; q to quit: " +} + +dodepts () { + grep "ou=" | sed 's/.*ou=//' | awk ' + { + print $0 + } + + END { + if (NR == 0) + printf("\nNo such department\n") > "/tmp/nodept'$pid'" + } ' +} + +deptlist () { + + partial=`awk ' BEGIN { + orgno = 0 + partial = "FALSE" + } + /^\(Partial/ { + partial = "TRUE" + next + } + { + n = index($0, "=") + orgno++ + org[orgno] = substr($0, n + 1) + } + END { + if (orgno == 0) + print "No departments!" > "/tmp/deptlist'$pid'" + else + for (i = 1;i <= orgno; i++) + print org[i] > "/tmp/deptlist'$pid'" + print partial + } '` + if [ -r /tmp/deptlist$pid ]; then + sort /tmp/deptlist$pid | pg -e -n -p "RETURN for next screen; q to quit: " + rm /tmp/deptlist$pid + if [ "$partial" = "TRUE" ]; then + echo + echo "Too many departments to print ... " + echo + fi + fi +} + + +dosites () { + grep "o=" | sed 's/.*o=//' | awk ' + { + orgs[NR] = $0 + } + END { + if ("'$site'" == "*") + { + printf("\nThese sites currently have entries in the Directory\n") > "/tmp/siteres'$pid'" + for (i = 1; i <= NR; i++) + print orgs[i] > "/tmp/siteres'$pid'" + print "" > "/tmp/siteres'$pid'" + } + else if (NR == 0) + printf("\nNo such site\n") > "/tmp/siteres'$pid'" + else + if (NR > 5) + { + printf("\nFound all the following sites - too many to search\n") > "/tmp/siteres'$pid'" + printf("Try and specify the organisation name more precisely\n\n") > "/tmp/siteres'$pid'" + for (i = 1; i <= NR; i++) + print orgs[i] > "/tmp/siteres'$pid'" + print "" > "/tmp/siteres'$pid'" + } + else + for (i = 1; i <= NR; i++) + print orgs[i] + } ' +} + + + fuzzy="" + connected="false" + breakout="false" + while true + do + rm -f /tmp/dscresults$pid /tmp/dscresults${pid}2 + name="" + while echo -n "Enter the person's name (or \"?\" for help, \"q\" to quit): "; read name + do + if [ "$name" = "?" ]; then + showhelp + name="" + else + break + fi + done + if [ "$name" = "q" ]; then + rm -f /tmp/dscresults$pid /tmp/dscresults${pid}2 + break + fi + deptname="" + echo -n "Enter department (\"Return\" to search all depts, * to list depts): " + read deptname + if [ "$deptname" != "" ]; then + deptstring="ou=$deptname" + if [ "$name" = "" ]; then + name="*" + fi + fi + echo -n "Enter site (\"Return\" for $SHORTSITE, * to list all sites): " + read site + if [ "$site" != "" ]; then + if [ "$name" = "" -a "$deptname" = "" ]; then + deptname="*" + deptstring="ou=$deptname" + fi + fi + + if [ "$name" = "" -a "$deptname" = "" -a "$site" = "" ]; then + if [ "$breakout" = "false" ]; then + breakout="true" + continue + else + break + fi + fi + breakout="false" + if [ "$connected" = "false" ]; then + echo "Connecting to the directory ..." + connected="true" + fi + matchtype="=" + if [ "$name" = "*" ]; then + searchname="*" + else + searchname="*$name*" + fi + if [ "$deptname" != "" ]; then + searchdept="*$deptname*" + fi + if [ "$site" = "*" ]; then + searchsitefilter="o=*" + else + searchsitefilter="o=*$site*" + fi + wait + + moveto "$CDN" -nocheck + if [ "$site" != "" ] + then #echo "Looking for sites..." # DEBUG + IFS=$NewIFS + search -nosizelimit -singlelevel -filter "$searchsitefilter & ! objectclass=dsa" -nopart 2>/dev/null | dosites > /tmp/sitelist$pid + if [ -r "/tmp/siteres$pid" ]; then + pg -e -n -p "RETURN for next screen; q to quit: " /tmp/siteres$pid + rm /tmp/siteres$pid + fi + for SITE in `cat /tmp/sitelist$pid` + do echo "Searching site: $SITE..." + echo "organization - $SITE" >> /tmp/dscresults${pid} + moveto "${CDN}@o=$SITE" -nocheck + if [ "$deptname" = "*" ]; then + echo " List of departments ..." + search -nosizelimit -relative -type ou \ + -filter "(objectclass=organizationalUnit)" 2>/dev/null | deptlist + else + if [ "$deptname" = "" ]; then + search -nosizelimit -norelative -show -subtree \ + -searchaliases -type commonName telephoneNumber rfc822Mailbox \ + -filter "(cn=$searchname) & (! objectclass=dsa)" 2>/tmp/dscresults${pid}2 >>/tmp/dscresults$pid + else + search -nosizelimit -singlelevel -filter "(ou$matchtype$searchdept)" -nopart 2>/dev/null | dodepts > /tmp/depts$pid + if [ -r "/tmp/nodept$pid" ]; then + cat /tmp/nodept$pid + rm /tmp/nodept$pid + fi + for ORGUNIT in `cat /tmp/depts$pid` + do + echo " Searching dept: $ORGUNIT..." + moveto "${CDN}@o=$SITE@ou=$ORGUNIT" -nocheck > /dev/null 2>&1 + search -nosizelimit -norelative -show -searchaliases \ + -subtree -type commonName telephoneNumber rfc822Mailbox \ + -filter "(cn$matchtype$searchname) & (! objectclass=dsa)" 2>>/tmp/dscresults${pid}2 >> /tmp/dscresults$pid + done + rm -f /tmp/depts$pid + fi + fi + done + rm -f /tmp/sitelist$pid + IFS=$OldIFS + else moveto "$ORGRDN" -nocheck + if [ "$deptname" = "*" ]; then + echo " List of departments ..." + search -nosizelimit -relative -type ou \ + -filter "(objectclass=organizationalUnit)" 2>/dev/null | deptlist + else + if [ "$deptname" = "" ]; then + search -nosizelimit -norelative -show -subtree \ + -searchaliases -type commonName telephoneNumber rfc822Mailbox \ + -filter "(cn=$searchname) & (! objectclass=dsa)" 2>/tmp/dscresults${pid}2 >/tmp/dscresults$pid + else + IFS=$NewIFS + search -nosizelimit -singlelevel -filter "(ou$matchtype$searchdept)" -nopart 2>/dev/null | dodepts > /tmp/depts$pid + if [ -r "/tmp/nodept$pid" ]; then + cat /tmp/nodept$pid + rm /tmp/nodept$pid + fi + for ORGUNIT in `cat /tmp/depts$pid` + do + echo "Searching dept: $ORGUNIT..." + moveto "$CDN@$ORGRDN@ou=$ORGUNIT" -nocheck >/dev/null 2>&1 + search -nosizelimit -norelative -show -searchaliases \ + -subtree -type commonName telephoneNumber rfc822Mailbox \ + -filter "(cn=$searchname) & (! objectclass=dsa)" 2>>/tmp/dscresults${pid}2 >> /tmp/dscresults$pid + done + rm -f /tmp/depts$pid + IFS=$OldIFS + fi + fi + fi + if [ ! "$deptname" = "*" ]; then + if [ -r /tmp/dscresults$pid ]; then + showentries + fi + fi + echo "" + done +else + echo -n "Do you need help?:(y/n) " + read help + case "$help" in + y|yes|Y|YES) + cat << ENDSUMMARY + +The 'advanced' user interface displays the commands (these are single +letters) and the 'Search area', which is the area of the database to +search. Initially this is '$LONGSITE'. The interface +can be used to search for a person, department, organisation or place - +this is selected by typing the 't' command until the required type is +displayed. To search for an entry, type 's' then the entry, followed +by Return. Entries that match will be listed (or the first 50, if there +are more than this). The screen can be scrolled down by typing [ and +back up by typing ]. Each entry has a number. To list an entry, type +its number. After a search, the search area will change to reflect the +current position in the database. The 'w' command is used to 'widen' +the search, for example to move from a person's entry to the department, +or from $SHORTSITE to GB, to search for other organisations that are running +directory services. The searching uses fuzzy matching (and so is different +from the 'simple' interface). + +The 'h' command will enter the help system, where a more detailed explanation +of each command can be obtained. The 'q' command will exit. + +The advanced interface is a prototype, and many of the directory services +at other organisations are still in an experimental stage. + +Type RETURN to continue +ENDSUMMARY + read junk;; + esac + sd +fi +cat << LOCALMESS diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist3 b/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist3 new file mode 100644 index 0000000000..abcb2057fc --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/dsc.dist3 @@ -0,0 +1,37 @@ +LOCALMESS +echo " +We would like to monitor usage of the directory service. First, we +need to gather statistics. Second, we would like to improve the service +offered. Could you answer the following questions? +" +echo -n "Please type your name (forename or initial, plus surname): " +read USERNAME +echo -n "Please type the name of your department: " +read USERDEPT + +echo "$USERNAME#$USERDEPT#`date`" | +awk -F# ' { +printf("%-20s%-20s%s\n", $1, $2, $3) >> "'$INTLOGDIR'/users" +} ' + +echo +echo -n "Would you like to comment on the interface, the usefulness +of the "help" information or the accuracy of the information in the +Directory? (y/n): " +read YN +if test "$YN" = "y" -o "$YN" = "yes" -o "$YN" = "Y" -o "$YN" = "YES" +then + echo "Please type your message now. Terminate your message" + echo "by typing \".\" at the start of the line following your message." + echo + echo $USERNAME of $USERDEPT > $INTLOGDIR/dsc$$ + echo "____________" >> $INTLOGDIR/dsc$$ + while read gunge + do + if test "$gunge" = "." + then + break + fi + echo $gunge >> $INTLOGDIR/dsc$$ + done +fi diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/host b/usr/src/contrib/isode/others/quipu/uips/dsc/host new file mode 100644 index 0000000000..2380b5c8a2 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/host @@ -0,0 +1,3 @@ +cn=Dir +masterDSA= c=GB@cn=YOUR DSA NAME HERE +objectClass= applicationProcess & top & quipuNonLeafObject diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/localmess b/usr/src/contrib/isode/others/quipu/uips/dsc/localmess new file mode 100644 index 0000000000..e573506417 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/localmess @@ -0,0 +1,3 @@ + +Any errors or omissions in the telephone data should be reported to +the Telephone Supervisor (X 2878). diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/localmess.dist b/usr/src/contrib/isode/others/quipu/uips/dsc/localmess.dist new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/localmess.dist @@ -0,0 +1 @@ + diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/localmess.ucl b/usr/src/contrib/isode/others/quipu/uips/dsc/localmess.ucl new file mode 100644 index 0000000000..e573506417 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/localmess.ucl @@ -0,0 +1,3 @@ + +Any errors or omissions in the telephone data should be reported to +the Telephone Supervisor (X 2878). diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/localphone b/usr/src/contrib/isode/others/quipu/uips/dsc/localphone new file mode 100644 index 0000000000..67e313af3a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/localphone @@ -0,0 +1,18 @@ + +# this bit needs local configuration + /^telephoneNumber/ { + phonestring = substr($0, n) + if (substr(phonestring, 1, 15) == "+44 71-387-7050") + phone = substr(phonestring, 18) + else if (substr(phonestring, 1, 10) == "+44 71-380") + phone = substr(phonestring, 12) + else if (substr(phonestring, 1, 10) == "+44 71-636") + phone = "82-" substr(phonestring, 18) + else if (substr(phonestring, 1, 15) == "+44 71-387-9300") + phone = "82-" substr(phonestring, 18) + else if (substr(phonestring, 1, 3) == "+44") + phone = "0" substr(phonestring, 5) + else + phone = phonestring + } + diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/localphone.dist b/usr/src/contrib/isode/others/quipu/uips/dsc/localphone.dist new file mode 100644 index 0000000000..c78280e2ca --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/localphone.dist @@ -0,0 +1,6 @@ + +# this bit can be locally configured + /^telephoneNumber/ { + phone = substr($0, n) + } + diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/localphone.ucl b/usr/src/contrib/isode/others/quipu/uips/dsc/localphone.ucl new file mode 100644 index 0000000000..67e313af3a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/localphone.ucl @@ -0,0 +1,18 @@ + +# this bit needs local configuration + /^telephoneNumber/ { + phonestring = substr($0, n) + if (substr(phonestring, 1, 15) == "+44 71-387-7050") + phone = substr(phonestring, 18) + else if (substr(phonestring, 1, 10) == "+44 71-380") + phone = substr(phonestring, 12) + else if (substr(phonestring, 1, 10) == "+44 71-636") + phone = "82-" substr(phonestring, 18) + else if (substr(phonestring, 1, 15) == "+44 71-387-9300") + phone = "82-" substr(phonestring, 18) + else if (substr(phonestring, 1, 3) == "+44") + phone = "0" substr(phonestring, 5) + else + phone = phonestring + } + diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/make b/usr/src/contrib/isode/others/quipu/uips/dsc/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/dsc/paa b/usr/src/contrib/isode/others/quipu/uips/dsc/paa new file mode 100644 index 0000000000..fdad6869c4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/dsc/paa @@ -0,0 +1,3 @@ +cn=Public Access DUA +presentationAddress= TELEX+00728722+X.25(80)+02+000005113200 +objectClass= quipuObject & applicationEntity & top diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/Makefile b/usr/src/contrib/isode/others/quipu/uips/fred/Makefile new file mode 100644 index 0000000000..dd89897d59 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/Makefile @@ -0,0 +1,273 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE QUIPU White Pages interface +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/uips/fred/RCS/Makefile,v 7.9 91/02/22 09:30:32 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.9 91/02/22 09:30:32 mrose +# Interim 6.8 +# +# Revision 7.8 90/12/23 18:47:05 mrose +# update +# +# Revision 7.7 90/12/17 22:14:35 mrose +# dad.8c +# +# Revision 7.6 90/10/28 22:40:56 mrose +# update +# +# Revision 7.5 90/07/27 08:45:21 mrose +# update +# +# Revision 7.4 90/07/09 14:41:09 mrose +# sync +# +# Revision 7.3 90/03/22 08:36:27 mrose +# touch-up +# +# Revision 7.2 90/03/15 11:20:43 mrose +# quipu-sync +# +# Revision 7.1 90/01/11 18:36:18 mrose +# real-sync +# +# Revision 7.0 89/11/23 22:08:51 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(LIBISODE) +LLIBS = $(TOPDIR)llib-lisode +#LIBES = $(TOPDIR)libdirent.a $(TOPDIR)libcompat.a +#LLIBS = $(TOPDIR)llib-ldirent $(TOPDIR)llib-lcompat + + +############################################################################### +# FILES +############################################################################### + +HFILES = fred.h +CFILES = fred.c dispatch.c miscellany.c pipe.c whois.c + + +############################################################## +# Here it is... +############################################################## + +all: fred whitepages fredrc ufnrc fredsh dad +inst-all: inst-fred inst-fredrc inst-ufnrc inst-fredsh inst-dad \ + inst-fredman manuals +# inst-whitepages +install: inst-all clean +lint: l-fred l-dad + + +################################################################### +# fred +################################################################### + +inst-fred: $(BINDIR)fred + +$(BINDIR)fred: xfred + -cp $@ zxfred + -rm -f $@ + cp xfred $@ + -rm -f $(SBINDIR)in.whitepages + if ln $@ $(SBINDIR)in.whitepages; \ + then exit 0; \ + else cp xfred $(SBINDIR)in.whitepages; \ + fi + -@ls -gls $@ $(SBINDIR)in.whitepages + -@echo "" + +fred: xfred + +xfred: fred.o dispatch.o miscellany.o pipe.o socket.o whois.o + $(LDCC) $(LDFLAGS) -o $@ fred.o dispatch.o miscellany.o \ + pipe.o socket.o whois.o \ + $(LIBES) $(LSOCKET) + +l-fred:; $(LINT) $(LFLAGS) fred.c dispatch.c miscellany.c pipe.c \ + ../dish/socket.c whois.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +fred.o: fred.h +dispatch.o: fred.h +miscellany.o: fred.h +pipe.o: fred.h + +socket.o: ../dish/socket.c + $(CC) $(CFLAGS) -c ../dish/socket.c + +whois.o: fred.h + + +################################################################### +# fredrc +################################################################### + +inst-fredrc: $(ETCDIR)fredrc + +$(ETCDIR)fredrc: true + if [ -s $@ ]; \ + then exit 0; \ + else cp fredrc $@; ls -gls $@; \ + fi + if ln $(ETCDIR)fredrc $(ETCDIR)fredrc.old; \ + then rm -f $@ ; cp fredrc $@; ls -gls $@; \ + else exit 0; \ + fi + +fredrc: + + +################################################################### +# ufnrc +################################################################### + +inst-ufnrc: $(ETCDIR)ufnrc + +$(ETCDIR)ufnrc: true + if [ -s $@ ]; \ + then exit 0; \ + else cp ufnrc $@; ls -gls $@; \ + fi + if ln $(ETCDIR)ufnrc $(ETCDIR)ufnrc.old; \ + then rm -f $@ ; cp ufnrc $@; ls -gls $@; \ + else exit 0; \ + fi + +ufnrc: + + +################################################################### +# fredsh +################################################################### + +inst-fredsh: $(SBINDIR)fredsh + +$(SBINDIR)fredsh: xfredsh Makefile + -cp $@ zxfredsh + -rm -f $@ + sed -e 's%@(BINDIR)%$(BINDIR)%' < fredsh.sh > $@ + chmod a+rx $@ + -@ls -gls $@ + -@echo "" + +fredsh: xfredsh + +xfredsh: fredsh.sh + cp fredsh.sh $@ + chmod a+rx $@ + + +################################################################### +# fredman +################################################################### + +inst-fredman: $(ETCDIR)fred.0 + +$(ETCDIR)fred.0: fred.1c Makefile + -cp $@ zfred.0 + -rm -f $@ + (echo '.ds ED $(ETCDIR)' ; cat fred.1c) | \ + nroff -man -Tlpr | \ + tr "\010" "_" | \ + sed -e "/^/s/__//g" > $@ + -@ls -gls $@ + -@echo "" + + +################################################################### +# dad +################################################################### + +inst-dad: $(SBINDIR)dad + +$(SBINDIR)dad: xdad + -cp $@ zxdad + -rm -f $@ + cp xdad $@ + -@ls -gls $@ + -@echo "" + +dad: xdad + +xdad: dad.o socket.o + $(LDCC) $(LDFLAGS) -o $@ dad.o socket.o $(LIBES) $(LSOCKET) + +l-dad:; $(LINT) $(LFLAGS) dad.c ../dish/socket.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################### +# whitepages +################################################################### + +inst-whitepages: $(BINDIR)whitepages + +$(BINDIR)whitepages: xwhitepages + -cp $@ zxwhitepages + -rm -f $@ + cp xwhitepages $@ + -@ls -gls $@ + -@echo "" + +whitepages: xwhitepages + +xwhitepages: whitepages.sh + cp whitepages.sh $@ + chmod a+rx $@ + + +################################################################ +# manual pages +################################################################ + +MANUALS = fred.1c dad.8c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +############################################################## +# clean +############################################################## + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig core + +grind:; iprint Makefile whitepages.sh fredsh + tgrind -lc $(HFILES) $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/dad.8c b/usr/src/contrib/isode/others/quipu/uips/fred/dad.8c new file mode 100644 index 0000000000..b7c8d30a4e --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/dad.8c @@ -0,0 +1,56 @@ +.TH DAD 8C "11 Dec 1990" +.\" $Header: /f/osi/others/quipu/uips/fred/RCS/dad.8c,v 7.2 91/02/22 09:30:34 mrose Interim $ +.\" +.\" +.\" $Log: dad.8c,v $ +.\" Revision 7.2 91/02/22 09:30:34 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/12/19 09:17:03 mrose +.\" touch-up +.\" +.\" Revision 7.0 90/12/12 00:22:35 mrose +.\" *** empty log message *** +.\" +.SH NAME +dad \- directory assistance server +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDdad +\%[\-d] +\%[\-p\0portno] +.in -.5i +(under /etc/rc.local) +.SH DESCRIPTION +The \fIdad\fR program implements a lightweight interface to the OSI +Directory Service, +termed the \*(lqdirectory assistance\*(rq protocol +(it helps other programs use the Directory, +it doesn't directly help people find things using the Directory). +.SH "DEBUG OPERATION" +If \fIdad\fR is started interactively, +or if the `\-d' switch is given, +then debug mode is entered. +In this case, +all logging activity is displayed on the user's terminal, +the logging information is more verbose, +and \fIdad\fR will terminate after it handles the first incoming connection +(this allows \fIdad\fR to be run under a debugger). +.SH FILES +.nf +.ta \w'\*(EDdsaptailor 'u +\*(EDdsaptailor system QUIPU tailoring file +\*(EDfredrc system runcom file +.re +.fi +.SH "SEE ALSO" +dish(1c), +.br +\fIDirectory Assistance Service\fR +.SH DIAGNOSTICS +All obvious. +.SH AUTHOR +Marshall T. Rose, +Performance Systens International + diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/fred.1c b/usr/src/contrib/isode/others/quipu/uips/fred/fred.1c new file mode 100644 index 0000000000..201a2c906f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/fred.1c @@ -0,0 +1,459 @@ +.TH FRED 1C "06 Jan 1990" +.\" $Header: /f/osi/others/quipu/uips/fred/RCS/fred.1c,v 7.10 91/02/22 09:30:39 mrose Interim $ +.\" +.\" +.\" $Log: fred.1c,v $ +.\" Revision 7.10 91/02/22 09:30:39 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.9 90/10/29 08:10:08 mrose +.\" touch-up +.\" +.\" Revision 7.8 90/10/28 23:21:01 mrose +.\" server +.\" +.\" Revision 7.7 90/10/23 20:42:23 mrose +.\" update +.\" +.\" Revision 7.6 90/10/18 11:33:48 mrose +.\" psi +.\" +.\" Revision 7.5 90/07/09 14:41:12 mrose +.\" sync +.\" +.\" Revision 7.4 90/06/11 10:55:09 mrose +.\" UFN +.\" +.\" Revision 7.3 90/03/22 08:36:32 mrose +.\" touch-up +.\" +.\" Revision 7.2 90/03/08 08:05:04 mrose +.\" phone +.\" +.\" Revision 7.1 90/01/11 18:36:25 mrose +.\" real-sync +.\" +.\" Revision 7.0 89/11/23 22:08:54 mrose +.\" Release 6.0 +.\" +.SH NAME +fred \- a white pages user interface (FRont-End to Dish) +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B fred +\%[options] +\%[command\0arguments\0...] +.sp +.ti -.5i +.B whois +arguments\0... +(as in \*(lq\fBfred\0whois\fR\0smith\0\fB-org\fR\0psi\*(rq) +.in -.5i +.SH DESCRIPTION +The \fIfred\fR program is a front-end to the OSI Directory, +and in particular the \fIdish\fR\0(1c) program. +It is most useful as an interface to the white pages service. +.PP +The \fIfred\fR program is meant to be similar to the WHOIS service +familiar to most users of the network. +There are some differences however. +.PP +First, +users in the white pages are uniquely identified by +their \fIdistinguished name\fR, e.g., +.sp +.in +.5i +.nf +\*(lq@c=US@o=Performance Systems International@cn=Manager\*(rq +.fi +.in -.5i +.sp +In contrast, +users of the WHOIS service are uniquely identified by their WHOIS +handle, +a brief key, e.g., \*(lqMTR\*(rq. +Since distinguished names are much longer than WHOIS handles, +\fIfred\fR maintains a list of aliases during its execution. +When an entry for something is retrieved, +it is assigned a numeric alias for its name. +.PP +Second, +searches in the white pages are relative to an \*(lqarea\*(rq. +The default area is set by your system administrator. +It can be changed using the \fIarea\fR command. +Because the white pages are distributed, +searches occurring at higher areas are more expensive in terms of +time, +networking resources, etc. +.PP +Third, +the white pages are highly structured. +As such, +you can potentially retrieve much more detailed information about an entry. +Although the \fIfred\fR should prove useful for the majority of +queries, +it is purposefully limited in its searching capabilities. +Users desiring a more powerful interface, +should use \fIdish\fR\0(1c) directly. +.SH EXAMPLES +The command syntax, +while meant to be intuitive, +is tedious. +Here are a few simple examples: +.IP whois\0\*(lqsmith\*(rq +looks for any entries with this name in the default area +(choice of matching on the entry's surname or fullname is based on the +value of the `namesearch' variable). +.IP whois\0surname\0\*(lqsmith\*(rq +looks for any entries with this surname. +.IP whois\0fullname\0\*(lqjohn\0smith\*(rq +looks for any entries with this fullname. +.IP whois\0\*(lqsmith\*(rq\0\-org\0psi +looks for any entries with this name in any organization with +\*(lqpsi\*(rq in its name. +This is probably the most common usage of the program. +.IP whois\0\*(lqsmith\*(rq\0\-area\0\*(lq@c=US@o=Performance\0Systems\0International\*(rq +could be used if you already know the \*(lqarea\*(rq that the user resides in. +.IP whois\0smith@psi +is identical to the preceeding example. +.IP whois\0\*(lqsmith\*(rq\0\-area\017 +could be used if an alias were already established for this area. +.IP whois\0@c=US@cn=Manager +looks for the entry with this distinguished name (handle). +.IP whois\0!7 +could be used if an alias were already established for this entry. +.IP whois\0smith@cheetah.ca.psi.com +looks for any entries with the given mailbox. +.IP whois\0\-title\0operator +looks for any entries who are operators. +.IP whois\0-org\0* +reports on all registered organizations (in the default geographical area). +.IP whois\0-org\0*\0-geo\0@c=GB +reports on all registered organizations under @c=GB. +.PP +Here is a somewhat more common example: +.sp +.in +.5i +.nf +fred> whois schoffstall -org psi +Trying @c=US@o=Performance Systems International ... +3 matches found. + 2. Marvin Schoffstall marv@psi.com + 3. Martin Schoffstall schoff@psi.com + 4. Steve Schoffstall steve@psi.com + +fred> whois !3 +Martin Schoffstall (3) schoff@psi.com + ... +.fi +.in -.5i +.SH COMMANDS +On start-up, \fIfred\fR will read a file called \fBfredrc\fR in the +ISODE system directory (usually \fB\*(ED\fR\0). +Then, +\fIfred\fR reads the file \fB\&.fredrc\fR in the user's home directory. +These files, if present, contain user-preference commands. +Afterwards, +\fIfred\fR prompts for commands. +.PP +Typing INTR at the top\-level does nothing, +but typing it twice in a row at the top\-level terminates \fIfred\fR; +typing INTR during additional prompting causes \fIfred\fR to abort +the command. +.TP +.B alias\fR\0\%[name] +With no arguments, +prints all aliases defined for this session. +With an argument, +defines a numeric alias for that name. +.TP +.B area\fR\0\%[\%[record-type] location] +With no arguments, +prints the default area used by the \fIwhois\fR command when +consulting the white pages. +With a single argument, +this sets the default area. +The distinguished value \*(lq\&.\&.\*(rq may be used to go up one +level in the tree. +If the value is relative (i.e., does not start with the +\*(lq@\*(rq-sign), +then the value is appended onto the current location. +With two arguments, +this sets the default area for searches of the indicated record type +(which are described in the next section). +This is particularly useful since it also provides heuristics to the +\fIwhois\fR command as to the depth to be used for searching. +.TP +.B edit +Invokes an editor to modify the user's entry in the white pages. +.TP +.B help\fR\0\%[command\0...] +Prints help information. +For detailed information, try \*(lqhelp\0?\*(rq. +.TP +.B manual +Prints this detailed documentation about \fIfred\fR. +.TP +.B quit +Terminates \fIfred\fR. +.TP +.B report\fR\0\%[subject] +Allows you to enter a report that is mailed to your local white pages manager. +.TP +.B set\fR\0\%[variable\0\%[value]] +Manipulates \fIfred\fR's settings: +.sp +.in +.5i +.nf +.ta \w'\fBnamesearch\fR 'u +\fBvariable\fR \fBfunction\fR +debug debug \fIfred\fR +manager mail-address of local white pages manager +namesearch type of name used for matching, + either \*(lqfullname\*(rq, \*(lqsurname\*(rq, + or \*(lqfriendly\*(rq +pager program to use for terminal pagination +phone display phone numbers in one-liner +query confirm two-step operations +server IP-address of directory assistance server +soundex use soundex for matching, + when no wildcards are present +timelimit maximum number of seconds to + spend searching +verbose verbose interaction +watch watch dialogue with \fIdish\fR +.re +.fi +.in -.5i +.TP +.B thisis\fR\0\%[name\0\%[password]] +Tells the white pages service who you are. +This is only needed when you want to modify your own entry. +Normally, +this is determined automatically when \fIfred\fR starts. +.TP +.B whois\fR\0\%[arguments\0...] +Consults the white pages. +.SH WHOIS +If the value of the `namesearch' variable is \*(lqfriendly\*(rq, +then Kille's user-friendly name notation is used. +Kille's notation is ordered but untyped, +with components separated by commas. +Typical names include: +.sp +.in +.5i +.nf +rose, psi +kille, cs, ucl, gb +L. Eagle, \*(lqSue, Grabbit and Runn\*(rq, GB +.fi +.in -.5i +.sp +Note that you don't have to know all of the components\0--\0just list +what you know, left-to-right, starting with the person's name. +The user-friendly searching algorithim will usually figure out what +you mean. +This is the preferred syntax as it is the most intuitive. +.PP +Otherwise, +the syntax of the \fIwhois\fR command is similar to that provided by +the WHOIS service: +.sp +.in +.5i +.nf +input-field \%[record-type] \%[area-designator] \%[output-control] +.fi +.in -.5i +.sp +These four components may occur in any order. +Only the \fIinput-field\fR need be present. +.SS "INPUT FIELD" +This component tells the white pages what to look for. +.TP +.B \&.\fR\0or\0\fBname\fR\0 +gives the name of the target. +.br +.B \fBsurname\fR\0 +.br +.B \fBfullname\fR\0 +.sp +Searching for names follows these rules: +if the \*(lq*\*(rq-sign appears at the beginning and/or end of the name, +then wildcard-style matching is used: +the \*(lq*\*(rq-sign matches zero or more characters at the beginning +or end of a name. +Otherwise, +if soundex has been enabled (set the variable `soundex' to `on'), +then imprecise matching occurs according to a Soundex algorithm. +Otherwise, +if searching is to occur for a person's surname, +then a case-insensitive match is used. +Finally, +as a last resort, +\fIfred\fR will force a rather liberal wildcard-style match. +.sp +For compatibility with the WHOIS service, +an input field of \*(lqNAME.\*(rq is equivalent to \*(lqNAME*\*(rq +(i.e., a partial match for names having the given prefix). +Similarly, +an input field of \*(lq*NAME\*(rq is equivalent to +\*(lqNAME\0expand\*(rq. +Thus, to have wildcard matching at the beginning of the name, +use two \*(lq*\*(rq-signs, +e.g., \*(lq**inc\*(rq matches names ending in \*(lqinc\*(rq. +(A terrible hack, but that's the price one pays to be consistent with the +WHOIS service.) +.TP +.B !\fR\0or\0\fBhandle\fR\0 +gives the unique handle (distinguished name) of the target. +This may be an alias rather than a distinguished name. +.TP +.B mailbox\fR\0 +gives the mailbox of the target. +.PP +If a keyword is not given, +then \fIfred\fR attempts to intuit which kind of input field is being provided. +In most cases, +\fIfred\fR will treat field as a name, +unless it contains the \*(lq@\*(rq-sign, +which makes it either a handle or a mailbox. +.SS "RECORD TYPE" +This component tells the white pages what kind of entry to look for. +.sp +.in +.5i +.nf +\fIperson\fR or \fI-title\fR\0NAME, +\fIorganization\fR, +\fIunit\fR (a division under an organization), +\fIrole\fR (a role within an organization), +\fIlocality\fR, or +\fIdsa\fR (a white pages server). +.fi +.in -.5i +.sp +If this component is not present, +\fIfred\fR will not limit its search to any particular kind of entry. +.SS "AREA DESIGNATOR" +This component takes one of two forms. +The most common form is one of the switches: +.sp +.in +.5i +.nf +\fI-org\fR (short for \fI-organization\fR\0), +\fI-unit\fR, or, +\fI-locality\fR, +.fi +.in -.5i +.sp +followed by a name. +For example, +.sp +.in +.5i +.nf +\&\-org psi +.fi +.in -.5i +.sp +tells \fIfred\fR to limit the search to those organizations whose name +contains \*(lqpsi\*(rq. +.PP +In addition +the switch `-geo' followed by a location in the white pages may be +used to override the default area for searching for these objects. +For example, +.sp +.in +.5i +.nf +\&\-org ucl \&\-area @c=GB +.fi +.in -.5i +.sp +tells \fIfred\fR to limit the search to those organizations whose name +contains \*(lqucl\*(rq that reside directly under @c=GB. +.PP +In the second form, +the area designator consists of the switch \fI-area\fR followed by a +location in the white pages; +e.g., +.sp +.in +.5i +.nf +\&\-area \*(lq@c=US@o=Performance Systems International\*(rq +.fi +.in -.5i +.sp +Note the use of double-quotes to make the string following area appear +as a single argument. +If an alias has already been established for this location, +then the number of the alias can be used instead. +.SS "OUTPUT CONTROL" +.TP +.B expand\fR\0or\0\fB*\fR +give a detailed listing and show children of matched entries. +.TP +.B \~ +The opposite of \fIexpand\fR. +(Included for compatibility with the WHOIS service.) +.TP +.B subdisplay\fR\0or\0\fB%\fR +give a one-line listing and show children of matched entries. +.TP +.B full\fR\0or\0\fB|\fR +give a detailed listing, +even on ambiguous matches +.TP +.B summary\fR\0or\0\fB$\fR +give a one-line listing, +even on unique matches. +.SH OPTIONS +.TP +.B \-f +Inhibits reading of the user's \fB\&.fredrc\fR on startup. +.TP +.B \-v +Sets \fBverbose\fR (default for interactive use). +.TP +.B \-w +Sets \fBwatch\fR. +.SH FILES +.nf +.ta \w'\*(EDdsaptailor 'u +\*(EDdsaptailor system QUIPU tailoring file +$HOME/\&.quipurc user's QUIPU tailoring file +\*(EDfredrc system runcom file +$HOME/\&.fredrc user's runcom file +.re +.fi +.SH "SEE ALSO" +dish(1c), +.br +\fIPSI White Pages Pilot Project: User's Guide\fR, +.br +\fIUsing the OSI Directory to achieve User Friendly Naming\fR, +.br +\fIThe ISO Development Environment: User's Manual--Volume 5: QUIPU\fR +.SH DIAGNOSTICS +All obvious. +.SH AUTHOR +Marshall T. Rose, +Performance Systems International +.SH BUGS +The emulation of the old \fIwhois\fR command format is imperfect. +Most notably, +you need to quote names so they appear as a single token to the \fIfred\fR. +For example: +.sp +.in +.5i +% fred whois\0\*(lqDal\0Santo\*(rq +.in -.5i +.sp +won't work, +whilst +.sp +.in +.5i +% fred whois\0'\*(lqDal\0Santo\*(rq' +.in -.5i +.sp +will work (the shell strips off one layer of quoting). +That's progress for you. diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/fred.c b/usr/src/contrib/isode/others/quipu/uips/fred/fred.c new file mode 100644 index 0000000000..7c3c0cf675 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/fred.c @@ -0,0 +1,1036 @@ +/* fred.c - FRont-End to Dish */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/fred.c,v 7.13 91/02/22 09:30:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/fred/RCS/fred.c,v 7.13 91/02/22 09:30:41 mrose Interim $ + * + * + * $Log: fred.c,v $ + * Revision 7.13 91/02/22 09:30:41 mrose + * Interim 6.8 + * + * Revision 7.12 91/02/15 10:42:04 mrose + * touch-up + * + * Revision 7.11 91/01/10 04:02:52 mrose + * update + * + * Revision 7.10 90/11/11 09:57:36 mrose + * touch-up + * + * Revision 7.9 90/11/04 19:15:54 mrose + * update + * + * Revision 7.8 90/11/01 22:02:43 mrose + * update + * + * Revision 7.7 90/09/07 11:14:27 mrose + * update + * + * Revision 7.6 90/07/27 08:45:23 mrose + * update + * + * Revision 7.5 90/06/11 10:55:14 mrose + * UFN + * + * Revision 7.4 90/01/16 20:43:24 mrose + * last check-out + * + * Revision 7.3 90/01/11 18:36:28 mrose + * real-sync + * + * Revision 7.2 89/12/14 18:48:59 mrose + * KIS project + * + * Revision 7.1 89/12/13 20:01:46 mrose + * errfp + * + * Revision 7.0 89/11/23 22:08:56 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include +#include "fred.h" +#include "internet.h" + +#ifdef BSD42 +#include +#endif +#ifdef SYS5 +#include +#endif +#ifndef R_OK +#define R_OK 4 +#endif + +/* DATA */ + +static char *myname = "fred"; + +static char **op = NULLVP; + +static int alarming = 0; +static int logging = 0; +static int ontty; +static int armed; +static jmp_buf alrmenv; +static jmp_buf intrenv; +int interrupted; + +int oneshot; + +SFP astat; +SFP istat; +SFP qstat; + +SFD alrmser (); +SFD intrser (); + +LLog _fred_log = { + "fred.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, + LLOG_NONE, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK +}; +LLog *fred_log = &_fred_log; + + +static char *from = NULL; +static char *reply_to = NULL; +static char *sender = NULL; +static char *subject = NULL; + +static struct pair { + char *p_name; + char **p_value; +} pairs[] = { + "From:", &from, + "Reply-To:", &reply_to, + "Sender:", &sender, + "Subject:", &subject, +}; + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int eof, + status, + vecp; + register char *cp; + char address[BUFSIZ], + buffer[BUFSIZ], + *vec[NVEC + 1]; + struct sockaddr_in in_socket, + *isock = &in_socket; + + arginit (argv); + + rcinit (); + + rcfile (isodefile ("fredrc", 0), 0, 1); + if (access (isodefile ("ufnrc", 0), R_OK) != NOTOK + && !strcmp (server, "internal")) + area_quantum = -1; + + status = 0; + + if (mail) { + register int c; + register char *ep; + register struct pair *p; + FILE *fp; + + for (;;) { + ep = (cp = buffer) + sizeof buffer - 1; + + while ((c = getc (stdin)) != EOF) + if (c == '\n') { + if ((c = getc (stdin)) == ' ' || c == '\t') { + *cp++ = ' '; + while ((c = getc (stdin)) == ' ' || c == '\t') + continue; + if (c != EOF) + (void) ungetc (c, stdin); + else { + c = NULL; + break; + } + } + else { + if (c == EOF) + c = NULL; + else + (void) ungetc (c, stdin); + break; + } + } + else + if (cp < ep) + *cp++ = c != '\t' ? c & 0xff : ' '; + + if (cp == buffer) + break; + *cp = NULL; + + for (p = pairs; p -> p_name; p++) + if (lexnequ (buffer, p -> p_name, c = strlen (p -> p_name)) + == 0) { + if (*p -> p_value == NULL) { + for (cp = buffer + c; *cp == ' ' || *cp == '\t'; cp++) + continue; + if (*cp) { + ep = cp + strlen (cp) - 1; + while (*ep == ' ') + ep--; + *++ep = NULL; + *p -> p_value = strdup (cp); + } + } + break; + } + + } + + if (!from && !reply_to && !sender) + adios (NULLCP, "unable to determine return address"); + + (void) sprintf (buffer, "/bin/mail \"%s\"", + ep = reply_to ? reply_to : from ? from : sender); + if (watch) { + fprintf (stderr, "%s\n", buffer); + (void) fflush (stderr); + } + + (void) signal (SIGPIPE, SIG_IGN); + if ((fp = popen (buffer, "w")) == NULL) + adios ("failed", "popen"); + + stdfp = errfp = fp; + + fprintf (stdfp, "To: %s\nSubject: Re: %s\n\n", + ep, subject ? subject : "white pages query"); + (void) fflush (stdfp); + + if (f_bind (NULLVP) == NOTOK) + adios (NULLCP, "unable to open the white pages"); + + if (subject) { + (void) strcpy (buffer, subject); + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%s asks: %s", + ep, buffer); + + bzero ((char *) vec, sizeof vec); + if (str2vecY (buffer, vec) < 1) + (void) f_help (NULLVP); + else + if (fredloop (vec, NOTOK) != OK) + status = 1; + } + else { + int didone = 0; + + while ((c = getc (stdin)) != EOF) + if (c != ' ' || c != '\t' || c != '\n') + break; + + if (c != EOF) + while (fgets (buffer, sizeof buffer, stdin)) { + if (cp = index (buffer, '\n')) + *cp = NULL; + if (buffer[0] == NULL) + break; + + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, + "%s asks: %s", ep, buffer); + + fprintf (stdfp, "%s>>> %s\n", didone ? "\n\n" : "", buffer); + + bzero ((char *) vec, sizeof vec); + if (str2vecY (buffer, vec) < 1) + break; + + if (fredloop (vec, NOTOK) != OK) { + status = 1; + break; + } + didone = 1; + } + + if (!didone) + (void) f_help (NULLVP); + } + + (void) fclose (fp); + + stdfp = stdout; + + goto were_out_of_here; + } + + if (network) { + int len; + + if (getpeername (fileno (stdin), (struct sockaddr *) isock, + (len = sizeof *isock, &len)) != NOTOK) { + (void) sprintf (address, "%s/%d", + inet_ntoa (isock -> sin_addr), + ntohs (isock -> sin_port)); + + rcmap (isock); + } + else { + (void) ll_log (fred_log, LLOG_EXCEPTIONS, "failed", "getpeername"); + (void) strcpy (address, "peer"); + } + } + else + { + register struct hostent *hp; + + (void) strcpy (address, getlocalhost ()); + + if (hp = gethostbystring (address)) { + bzero ((char *) isock, sizeof *isock); + isock -> sin_family = hp -> h_addrtype; + inaddr_copy (hp, isock); + rcmap (isock); + } + else + advise (NULLCP, "%s: unknown host", address); + + } + + if (!fflag) { + (void) sprintf (buffer, "%s/.fredrc", myhome); + rcfile (buffer, op ? 1 : 0, 0); + } + + if (f_bind (NULLVP) == NOTOK) + adios (NULLCP, "unable to open the white pages"); + + if (network) { + errfp = stdout; + + (void) strcpy (buffer, "whois "); + switch (fetchline (buffer + (sizeof "whois " - 1), + sizeof buffer - (sizeof "whois " - 1), stdin)) { + case NOTOK: + adios (NULLCP, "error reading query from %s", address); + /* NOTREACHED */ + + case DONE: + buffer[0] = NULL; + /* and fall... */ + + case OK: + default: + break; + } + if (cp = index (buffer, '\r')) + *cp = NULL; + if (cp = index (buffer, '\n')) + *cp = NULL; + + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%s asks: %s", + address, buffer); + + bzero ((char *) vec, sizeof vec); + if (str2vecY (buffer, vec) < 2) + (void) f_help (NULLVP); + else + if (fredloop (vec, NOTOK) != OK) + status = 1; + + goto were_out_of_here; + } + + if (op) { + vecp = 0; + if (nametype > 1 + && (strcmp (myname, "whois") == 0 || (*op && **op == 'w'))) { + register char **pp; + char *bp = ""; + + if (strcmp (myname, "whois") && *op) + op++; + + for (pp = op; *pp; pp++) + if (!test_ufn (*pp)) { + bp = "\""; + break; + } + + for (cp = buffer; *op; cp += strlen (cp)) + (void) sprintf (cp, " %s%s%s", bp, *op++, bp); + + vec[vecp++] = "whois"; + vec[vecp++] = buffer; + } + else { + if (strcmp (myname, "whois") == 0) + vec[vecp++] = myname; + + while (*op) + vec[vecp++] = *op++; + } + vec[vecp] = NULL; + + if (fredloop (vec, NOTOK) != NOTOK) + status = 1; + + goto were_out_of_here; + } + + istat = signal (SIGINT, intrser); + + eof = 0; + for (interrupted = 0;; interrupted = 0) { + if (alarming) { + astat = signal (SIGALRM, alrmser); + + switch (setjmp (alrmenv)) { + case OK: + (void) alarm ((unsigned) 300); + break; + + default: + adios (NULLCP, "timed out due to inactivity"); + } + } + + if (getline ("%s> ", buffer) == NOTOK) { + if (eof) + break; + + eof = 1; + continue; + } + eof = 0; + + if (alarming) + (void) alarm ((unsigned) 0); + + if (logging) + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "command: %s", + buffer); + + bzero ((char *) vec, sizeof vec); + if ((vecp = str2vecY (buffer, vec)) < 1) + continue; + + switch (fredloop (vec, OK)) { + case NOTOK: + status = 1; + break; + + case OK: + default: + continue; + + case DONE: + status = 0; + break; + } + break; + } + + (void) signal (SIGINT, istat); + +were_out_of_here: ; + (void) f_quit (NULLVP); + + exit (mail ? 0 : status); /* NOTREACHED */ +} + +/* ARGINIT */ + +static arginit (vec) +char **vec; +{ + register char *ap; + + if (myname = rindex (*vec, '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = *vec; + + if (strcmp (myname, "in.whitepages") == 0) + network++, fflag++; + + isodetailor (myname, 1); + ll_hdinit (fred_log, myname); + + if (ontty = isatty (fileno (stdin))) + verbose++; + oneshot = 0; + + for (vec++; ap = *vec; vec++) { + if (*ap == '-') { + while (*++ap) + switch (*ap) { + case 'a': + alarming++; + break; + + case 'd': + debug++; + break; + + case 'm': + mail++; + /* and fall... */ + + case 'n': + network++; + /* and fall... */ + + case 'f': + fflag++; + break; + + case 'k': + kflag++; + break; + + case 'l': + logging++; + break; + + case 'r': + readonly++; + pager = "internal"; + break; + + case 'v': + verbose = 1; + break; + + case 'w': + watch++; + break; + + default: + adios (NULLCP, "unknown switch -%c", *ap); + } + continue; + } + if (op == NULL) { + op = vec; + oneshot = 1; + break; + } + } + + if (debug) + ll_dbinit (fred_log, myname); + if (logging) + log_utmp (); +} + +/* INTERACTIVE */ + +int getline (prompt, buffer) +char *prompt, + *buffer; +{ + register int i; + register char *cp, + *ep; + static int sticky = 0; + + if (interrupted) { + interrupted = 0; + return NOTOK; + } + + if (sticky) { + sticky = 0; + return NOTOK; + } + + switch (setjmp (intrenv)) { + case OK: + armed++; + break; + + case NOTOK: + if (ontty) + printf ("\n"); /* and fall */ + default: + armed = 0; + return NOTOK; + } + + if (ontty) { + printf (prompt, myname); + (void) fflush (stdout); + } + + for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) { + if (i == EOF) { + if (ontty) + printf ("\n"); + clearerr (stdin); + if (cp == buffer) + longjmp (intrenv, DONE); + + sticky++; + break; + } + + if (cp < ep) + *cp++ = i; + } + *cp = NULL; + + armed = 0; + + return OK; +} + +/* */ + +#ifndef IAC +#define IAC 255 +#endif + + +static int fetchline (s, n, iop) +register char *s; +register int n; +register FILE *iop; +{ + register int c; + register char *p; + + p = s; + while (--n > 0 && (c = getc (iop)) != EOF) { + while (c == IAC) { + (void) getc (iop); + c = getc (iop); + } + if ((*p++ = c) == '\n') + break; + } + if (ferror (iop)) + return NOTOK; + if (c == EOF && p == s) + return DONE; + *p++ = NULL; + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static SFD alrmser (sig) +int sig; +{ +#ifndef BSDSIGS + (void) signal (SIGALRM, alrmser); +#endif + + longjmp (alrmenv, NOTOK); +} + +/* */ + +/* ARGSUSED */ + +static SFD intrser (sig) +int sig; +{ +#ifndef BSDSIGS + (void) signal (SIGINT, intrser); +#endif + + if (armed) + longjmp (intrenv, NOTOK); + + interrupted++; +} + +/* */ + +#ifndef lint +int ask (va_alist) +va_dcl +{ + int x, + y, + result; + char buffer[BUFSIZ]; + va_list ap; + + if (interrupted) { + interrupted = 0; + return DONE; + } + + if (!ontty) + return OK; + + switch (setjmp (intrenv)) { + case OK: + armed++; + break; + + case NOTOK: + default: + printf ("\n"); + armed = 0; + return DONE; + } + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + +again: ; + printf ("%s", buffer); + + x = y = getchar (); + while (y != '\n' && y != EOF) + y = getchar (); + + switch (x) { + case 'y': + case '\n': + result = OK; + break; + + case 'n': + result = NOTOK; + break; + + case EOF: + result = DONE; + break; + + default: + goto again; + } + + armed = 0; + + return result; +} +#else +/* VARARGS */ + +int ask (fmt) +char *fmt; +{ + return ask (fmt); +} +#endif + +/* */ + +int str2vecY (buffer, vec) +char *buffer, + **vec; +{ + int i; + register char *cp, + *dp; + + if (nametype <= 1) { +normal: ; + return str2vec (buffer, vec); + } + + for (cp = buffer; isspace (*cp); cp++) + continue; + for (dp = cp++; !isspace (*cp); cp++) + if (!*cp) + goto normal; + *cp = NULL; + if ((i = strlen (dp)) > 5 || strncmp ("whois", dp, i)) { + *cp = ' '; + goto normal; + } + + vec[0] = dp; + vec[1] = ++cp; + vec[2] = NULL; + + return 2; +} + +/* MAPPING */ + +/* reads fred's IP-address to DN mapping file. + + for environments like Rutgers where IP-addresses can be more or less + trusted, this allows an easy mechanism for mapping local Rutgers users into + some DN other than the NULL user + + Syntax: + + + + Each token is seperated by LWSP, though double-quotes may be used to + prevent separation. + + */ + +static rcmap (isock) +struct sockaddr_in *isock; +{ + u_long hostaddr, + netmask, + netaddr; + register char *cp; + char buffer[BUFSIZ + 1], + *vec[NVEC + 1]; + FILE *fp; + + if ((fp = fopen (isodefile ("fredmap", 0), "r")) == NULL) + goto done; + + hostaddr = isock -> sin_addr.s_addr; + + while (fgets (buffer, sizeof buffer, fp)) { + if (*buffer == '#') + continue; + if (cp = index (buffer, '\n')) + *cp = NULL; + bzero ((char *) vec, sizeof vec); + if (str2vec (buffer, vec) != 4) + continue; + netmask = inet_addr (vec[0]); + if ((netaddr = inet_network (vec[1])) == NOTOK) + continue; + netaddr = ntohl (netaddr); + if (!(netaddr & 0xff000000)) + netaddr <<= (netaddr & 0x00ff0000) ? 8 + : (netaddr & 0x0000ff00) ? 16 + : 24; + netaddr = htonl (netaddr); + if ((hostaddr & netmask) != netaddr) + continue; + + vec[1] = "thisis"; + + runcom = 1, rcmode = 0400; + if (f_thisis (vec + 1) == NOTOK) + adios (NULLCP, "unable to bind as %s for %s", + vec[2], inet_ntoa (isock -> sin_addr)); + + runcom = 0; + break; + } + + (void) fclose (fp); + +done: ; + (void) setgid (getgid ()); + (void) setuid (getuid ()); +} + +/* ERRORS */ + +#ifndef lint +void _advise (); + + +void adios (va_alist) +va_dcl +{ + va_list ap; + static int latch = 0; + + if (latch) + _exit (1); + latch = 1; + + va_start (ap); + + if (network) + (void) _ll_log (fred_log, LLOG_FATAL, ap); + + _advise (ap); + + va_end (ap); + + (void) f_quit (NULLVP); + + _exit (1); +} +#else +/* VARARGS */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + FILE *fp = network ? stdfp : stderr; + + asprintf (buffer, ap); + + (void) fflush (stdfp); + + fprintf (fp, "%s: ", myname); + (void) fputs (buffer, fp); + (void) fputs (EOLN, fp); + + (void) fflush (fp); +} +#else +/* VARARGS */ + +void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + +/* MISCELLANY */ + +#ifndef lint +char *strdup (s) +char *s; +{ + char *p; + + if ((p = malloc((unsigned) (strlen (s) + 1))) == NULL) + adios (NULLCP, "out of memory"); + + (void) strcpy (p, s); + + return p; +} +#endif + +/* */ + +#include + +#ifdef sun +#define BSD42 +#undef SYS5 +#endif + +#ifdef bsd43_ut_host +#undef BSD42 +#define SYS5 +#endif + +#ifdef BSD42 +#define HMAX (sizeof (ut -> ut_host)) +#endif +#define LMAX (sizeof (ut -> ut_line)) +#define NMAX (sizeof (ut -> ut_name)) + +#define SCPYN(a, b) strncpy(a, b, sizeof (a)) +#define SCMPN(a, b) strncmp(a, b, sizeof (a)) + + +#ifdef SYS5 +struct utmp *getutent (); +#endif + +char *ttyname (); + + +static log_utmp () { +#ifndef SYS5 + int ud; +#endif + char *line; + struct utmp uts; + register struct utmp *ut = &uts; + + if ((line = ttyname (fileno (stdin))) == NULL) + return; + if (strncmp (line, "/dev/", sizeof "/dev/" - 1) == 0) + line += sizeof "/dev/" - 1; +#ifndef SYS5 + if ((ud = open ("/etc/utmp", 0)) == NOTOK) + return; + while (read (ud, (char *) ut, sizeof *ut) == sizeof *ut) { + if (ut -> ut_name[0] == NULL || SCMPN (ut -> ut_line, line)) + continue; +#ifndef BSD42 + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%.*s on %.*s", + NMAX, ut -> ut_name, LMAX, ut -> ut_line); +#else + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, + "%.*s on %.*s (%.*s)", + NMAX, ut -> ut_name, LMAX, ut -> ut_line, + HMAX, ut -> ut_host); +#endif + break; + } + (void) close (ud); +#else + setutent (); + while (ut = getutent ()) { + if (ut -> ut_type != USER_PROCESS || SCMPN (ut -> ut_line, line)) + continue; + + (void) ll_log (fred_log, LLOG_NOTICE, NULLCP, "%.*s on %.*s", + NMAX, ut -> ut_name, LMAX, ut -> ut_line); + break; + } + endutent (); +#endif +} + + +#ifdef bsd43_ut_host +#define BSD42 +#undef SYS5 +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/fredrc b/usr/src/contrib/isode/others/quipu/uips/fred/fredrc new file mode 100644 index 0000000000..259586a9bd --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/fredrc @@ -0,0 +1,29 @@ +############################################################################### +# +# fredrc - System-wide fred tailoring file +# +# $Header: /f/osi/others/quipu/uips/fred/RCS/fredrc,v 7.2 91/02/22 09:30:46 mrose Interim $ +# +# +# $Log: fredrc,v $ +# Revision 7.2 91/02/22 09:30:46 mrose +# Interim 6.8 +# +# Revision 7.1 90/01/11 18:36:34 mrose +# real-sync +# +# Revision 7.0 89/11/23 22:08:58 mrose +# Release 6.0 +# +############################################################################### + + +area "@c=@(country)@o=@(organization)" +area organization "@c=@(country)" +area unit "@c=@(country)@o=@(organization)" +area locality "@" +area person "@c=@(country)@o=@(organization)" +area dsa "@c=@(country)" +area role "@c=@(country)@o=@(organization)" + +set manager "@(mailbox)" diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/fredsh.sh b/usr/src/contrib/isode/others/quipu/uips/fred/fredsh.sh new file mode 100644 index 0000000000..34470ecaf4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/fredsh.sh @@ -0,0 +1,79 @@ +: run this script through /bin/sh + +echo '' +echo '' +echo '' +echo 'Welcome to the PSI White Pages Pilot Project' +echo '' + +C=fred D=fred E= +if [ \( "x$USER" = "xxwp" -o "x$LOGNAME" = "xxwp" \) -a -x @(BINDIR)xwp ]; then + TERM="xterm" +fi +if [ "x$TERM" = "xxterm" ]; then + if [ -x @(BINDIR)xwp ]; then + D="xwp -D" + fi + + X="`who am i | sed -e 's%.*(\(.*\))%\1%'`" + if [ -l "$X" -ge 16 ]; then + X= + fi + echo 'If you want X window access, please enter your DISPLAY name,' + if [ "x$X" != "x" ]; then + if [ "x$DISPLAY" = "x" ]; then + DISPLAY="$X:0.0" + fi + echo 'otherwise, if you do not wish to use X, enter "none"' + echo '' + echo -n 'DISPLAY (default='$DISPLAY')=' + read X x + case "x$X" in + x) export DISPLAY + C="$D" + ;; + + xnone) ;; + + *) DISPLAY="$X" + export DISPLAY + C="$D" + ;; + esac + else + echo 'e.g., "192.33.4.21:0.0"' + echo '' + echo -n 'DISPLAY=' + + read X x + case "x$X" in + x|xnone) ;; + + *) DISPLAY="$X" + export DISPLAY + C="$D" + ;; + esac + fi + echo '' +fi + +if [ "$C" = "fred" ]; then + echo 'Try "help" for a list of commands' + echo ' "whois" for information on how to find people' + echo ' "manual" for detailed documentation' + echo ' "report" to send a report to the white pages manager' + echo '' + echo 'To find out about participating organizations, try' + echo ' "whois -org *"' + echo '' + echo ' accessing service, please wait...' +else + echo 'To find out about participating organizations,' + echo ' click on "US"' +fi +echo '' + +DISHDRAFT=/tmp/fred$$ export DISHDRAFT + +exec /bin/csh -ic "@(BINDIR)$C -a -l -r" diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/make b/usr/src/contrib/isode/others/quipu/uips/fred/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/mh-patches b/usr/src/contrib/isode/others/quipu/uips/fred/mh-patches new file mode 100644 index 0000000000..1794d874e7 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/mh-patches @@ -0,0 +1,1157 @@ +[ mh-patches - Tue Jul 18 00:47:38 1989 - WP patches to MH - /mtr ] + + +Here are patches to MH 6.5 to allow send/whom to expand names into addresses. + + NOTE WELL: These are very different from the patches supplied earlier + in the file MH-patches. You should revert your MH sources back to + their original condition and then apply the patches here... + + The user specifies a name by bracketing a WhitePages query between + '<<' and '>>' using the user-friendly naming syntax, e.g., + + To: << rose, psi, us >> + + At the "What now?" prompt, the user can say "whom" to have the + names expanded into addresses. Alternately, the "send" option can + be used as well. For each query appearing between '<<' and '>>', + the DA-server will be asked to perform a white pages resolution. All + matches are printed and the user is asked to select one. If one is + not selected, the user returns to what-now level. + + Note that expansion can occur only if whom/send is invoked + interactively. If you use push, then the expansion will fail + because the DA-server will be unable to query you to select/confirm the + right entry to use for the substitution. + + To enable these patches, add + + options WP + + to your MH config file, run mhconfig, apply the patches, and then + do "make" from the top-level. Note that this code will not work if you + have + + options BERK + + in your config file. Specifying this option will disable the WP option. + + Finally, you must run a DA-server. The Administrator's Guide says + how to do this. Basically: + + 1. start /usr/etc/dad from /etc/rc.local + + 2. (optionally) add + + set server hostname + + to your /usr/etc/fredrc file, where "hostname" is the + domain-name or IP-address of the machine running dad. + + 3. tell your MH users to add + + da-server: hostname + + to their MH profile. + +/mtr +cd /wp2/home/src/uci/mh-6.6 +diff -c sbr/addrsbr.c.orig sbr/addrsbr.c +diff -c sbr/m_whatnow.c.orig sbr/m_whatnow.c +diff -c uip/post.c.orig uip/post.c +diff -c uip/whatnowsbr.c.orig uip/whatnowsbr.c +diff -c uip/whom.c.orig uip/whom.c +diff -c zotnet/mf/mf.c.orig zotnet/mf/mf.c +diff -c zotnet/mts/client.c.orig zotnet/mts/client.c + +*** sbr/addrsbr.c.orig Thu Jan 10 02:12:32 1991 +--- sbr/addrsbr.c Thu Jan 10 03:53:04 1991 +*************** +*** 4,12 **** + #include "../h/addrsbr.h" + #include "../zotnet/mf.h" + #include +! #ifdef BERK + #include +! #endif BERK + + /* High level parsing of addresses: + +--- 4,12 ---- + #include "../h/addrsbr.h" + #include "../zotnet/mf.h" + #include +! #if defined(BERK) || defined(WP) + #include +! #endif + + /* High level parsing of addresses: + +*************** +*** 103,108 **** +--- 103,117 ---- + + char *getusr (); + ++ ++ #ifdef BERK ++ #undef WP ++ #endif ++ ++ #ifdef WP ++ int do_wp = 0; ++ #endif ++ + /* */ + + char *getname (addrs) +*************** +*** 824,826 **** +--- 833,1211 ---- + + return 0; + } ++ ++ /* */ ++ ++ #ifdef WP ++ #include ++ #include ++ #include ++ ++ ++ static char das_response[BUFSIZ]; ++ static char das_host[BUFSIZ]; ++ static char das_port[BUFSIZ]; ++ ++ static FILE *das_input = NULL; ++ static FILE *das_output; ++ ++ static int armed = 0; ++ static int interrupted; ++ static jmp_buf intrenv; ++ ++ int intrser (); ++ ++ ++ extern int errno; ++ ++ /* */ ++ ++ char *wp_expand (query, error) ++ char *query, ++ *error; ++ { ++ int result, ++ (*istat) (); ++ char buffer[BUFSIZ]; ++ ++ if (error) ++ (void) strcpy (error, "unable to expand WhitePages query: "); ++ ++ if (!isatty (fileno (stdout))) { ++ if (error) ++ (void) strcat (error, "not a tty"); ++ ++ return NULLCP; ++ } ++ ++ if (das_input == NULL && das_init () == NOTOK) { ++ if (error) ++ (void) strcat (error, das_response); ++ ++ return NULLCP; ++ } ++ ++ fprintf (stderr, "\n[ Expanding %s ]\n", query); ++ (void) fflush (stderr); ++ ++ (void) sprintf (buffer, "fred -ufn -mailbox,%s", query); ++ ++ setsigx (istat, SIGINT, intrser); ++ interrupted = 0; ++ ++ result = das_lookup (buffer); ++ ++ (void) signal (SIGINT, istat); ++ ++ if (result == NOTOK) { ++ if (error) ++ (void) strcat (error, das_response); ++ ++ return NULLCP; ++ } ++ ++ if (error) ++ error[0] = NULL; ++ return (getcpy (das_response)); ++ } ++ ++ /* */ ++ ++ static int das_init () ++ { ++ int fd1, ++ fd2; ++ char *daserver = m_find ("da-server"); ++ ++ if (!daserver && !(daserver = getenv ("DA-SERVER"))) { ++ (void) strcpy (das_response, "no entry for DA-server in MH-profile"); ++ return NOTOK; ++ } ++ ++ if ((fd1 = client (daserver, "tcp", "411", 0, das_response)) == NOTOK) ++ return NOTOK; ++ (void) ioctl (fd1, FIOCLEX, NULLCP); ++ ++ if ((fd2 = dup (fd1)) == NOTOK) { ++ (void) sprintf (das_response, ++ "unable to dup connection descriptor: Errno %d", ++ errno); ++ (void) close (fd1); ++ return NOTOK; ++ } ++ (void) ioctl (fd2, FIOCLEX, NULLCP); ++ ++ if ((das_input = fdopen (fd1, "r")) == NULL ++ || (das_output = fdopen (fd2, "w")) == NULL) { ++ (void) strcpy (das_response, "fdopen failed on connection descriptor"); ++ if (das_input) ++ (void) fclose (das_input), das_input = NULL; ++ else ++ (void) close (fd1); ++ (void) close (fd2); ++ return NOTOK; ++ } ++ ++ (void) signal (SIGPIPE, SIG_IGN); ++ ++ switch (getline (das_response, sizeof das_response, das_input)) { ++ case OK: ++ if (*das_response == '+') { ++ int a[5]; ++ ++ if (sscanf (das_response + sizeof "+OK " - 1, ++ "%d.%d.%d.%d %u", a, a + 1, a + 2, a + 3, a + 4) ++ != 5) { ++ (void) strcpy (das_host, das_response); ++ (void) sprintf (das_response, ++ "malformed response from DA-server (%s)", ++ das_host); ++ goto losing; ++ } ++ (void) sprintf (das_host, "%d.%d.%d.%d", ++ a[0], a[1], a[2], a[3]); ++ (void) sprintf (das_port, "%u", a[4]); ++ ++ return OK; ++ } ++ /* else fall... */ ++ ++ case NOTOK: ++ case DONE: ++ losing: ; ++ (void) fclose (das_input); ++ (void) fclose (das_output); ++ das_input = das_output = NULL; ++ return NOTOK; ++ } ++ /* NOTREACHED */ ++ } ++ ++ /* */ ++ ++ static int das_lookup (who) ++ char *who; ++ { ++ int fd1, ++ fd2; ++ FILE *in, ++ *out; ++ ++ if ((fd1 = client (das_host, "tcp", das_port, 0, das_response)) == NOTOK) { ++ losing: ; ++ (void) fclose (das_input); ++ (void) fclose (das_output); ++ das_input = das_output = NULL; ++ return NOTOK; ++ } ++ ++ if ((fd2 = dup (fd1)) == NOTOK) { ++ (void) sprintf (das_response, ++ "unable to dup connection descriptor: Errno %d", ++ errno); ++ (void) close (fd1); ++ goto losing; ++ } ++ ++ if ((in = fdopen (fd1, "r")) == NULL ++ || (out = fdopen (fd2, "w")) == NULL) { ++ (void) strcpy (das_response, "fdopen failed on connection descriptor"); ++ if (in) ++ (void) fclose (in); ++ else ++ (void) close (fd1); ++ (void) close (fd2); ++ goto losing; ++ } ++ ++ if (putline (who, out) == NOTOK) { ++ real_losing: ; ++ (void) fclose (in); ++ (void) fclose (out); ++ goto losing; ++ } ++ ++ for (;;) { ++ char c, ++ input[BUFSIZ]; ++ ++ if (getline (input, sizeof input, in) != OK) ++ goto real_losing; ++ ++ switch (c = input[0]) { ++ case 'm': ++ fprintf (stdout, "\n%s\n", input + 1); ++ (void) strcpy (input, "m"); ++ goto stuff_it; ++ ++ case 'y': ++ fprintf (stdout, "%s", input + 1); ++ (void) fflush (stdout); ++ switch (yesno ()) { ++ case DONE: ++ (void) strcpy (das_response, "interrupted"); ++ goto real_losing; ++ ++ case NOTOK: ++ default: ++ input[0] = 'n'; ++ break; ++ ++ case OK: ++ input[0] = 'y'; ++ break; ++ } ++ input[1] = NULL; ++ stuff_it: ; ++ if (putline (input, out) == NOTOK) ++ goto real_losing; ++ continue; ++ ++ case 'e': ++ case 'p': ++ case 'L': ++ case 'l': ++ case 'd': ++ unexpected: ; ++ (void) sprintf (das_response, ++ "unexpected response from DAP-listener: %c", ++ c); ++ goto real_losing; ++ ++ case '1': ++ (void) strcpy (das_response, input + 1); ++ (void) fclose (in); ++ (void) fclose (out); ++ return OK; ++ ++ case '2': ++ (void) strcpy (das_response, input + 1); ++ goto real_losing; ++ ++ default: ++ if (isdigit (c)) ++ goto unexpected; ++ ++ (void) sprintf (das_response, ++ "unknown response from DAP-listener: %c", c); ++ goto real_losing; ++ } ++ } ++ } ++ ++ /* */ ++ ++ static int getline (s, n, iop) ++ char *s; ++ int n; ++ FILE * iop; ++ { ++ int c; ++ char *p; ++ ++ p = s; ++ while (--n > 0 && (c = fgetc (iop)) != EOF) ++ if ((*p++ = c) == '\n') ++ break; ++ if (ferror (iop) && c != EOF) { ++ (void) strcpy (das_response, "error on connection"); ++ return NOTOK; ++ } ++ if (c == EOF && p == s) { ++ (void) strcpy (das_response, "connection closed by foreign host"); ++ return DONE; ++ } ++ *p = NULL; ++ if (*--p == '\n') ++ *p = NULL; ++ if (*--p == '\r') ++ *p = NULL; ++ ++ return OK; ++ } ++ ++ ++ static putline (s, iop) ++ char *s; ++ FILE * iop; ++ { ++ (void) fprintf (iop, "%s\n", s); ++ (void) fflush (iop); ++ if (ferror (iop)) { ++ (void) strcpy (das_response, "lost connection"); ++ return NOTOK; ++ } ++ ++ return OK; ++ } ++ ++ /* */ ++ ++ static int yesno () { ++ int x, ++ y, ++ result; ++ ++ if (interrupted) { ++ interrupted = 0; ++ return DONE; ++ } ++ ++ switch (setjmp (intrenv)) { ++ case OK: ++ armed++; ++ break; ++ ++ case NOTOK: ++ default: ++ printf ("\n"); ++ armed = 0; ++ return DONE; ++ } ++ ++ again: ; ++ x = y = getc (stdin); ++ while (y != '\n' && y != EOF) ++ y = getc (stdin); ++ ++ switch (x) { ++ case 'y': ++ case '\n': ++ result = OK; ++ break; ++ ++ case 'n': ++ result = NOTOK; ++ break; ++ ++ case EOF: ++ result = DONE; ++ clearerr (stdin); ++ break; ++ ++ default: ++ printf ("Please type 'y' or 'n': "); ++ goto again; ++ } ++ ++ armed = 0; ++ ++ return result; ++ } ++ ++ ++ /* ARGSUSED */ ++ ++ static int intrser (i) ++ int i; ++ { ++ #ifndef BSD42 ++ (void) signal (SIGINT, intrser); ++ #endif ++ ++ if (armed) ++ longjmp (intrenv, NOTOK); ++ ++ interrupted++; ++ } ++ #endif +*** sbr/m_whatnow.c.orig Thu Oct 29 15:00:45 1987 +--- sbr/m_whatnow.c Thu Jan 10 02:46:15 1991 +*************** +*** 27,32 **** +--- 27,34 ---- + vec[vecp++] = r1bindex (whatnowproc, '/'); + vec[vecp] = NULL; + ++ if (bp = m_find ("da-server")) ++ (void) putenv ("DA-SERVER", bp); + (void) putenv ("mhdraft", file); + if (mp) + (void) putenv ("mhfolder", mp -> foldpath); +*** uip/post.c.orig Thu Jan 10 02:14:15 1991 +--- uip/post.c Wed Jan 9 14:26:56 1991 +*************** +*** 122,127 **** +--- 122,130 ---- + #define SNOOPSW 29 + "snoop", -5, + ++ #define FILLSW 30 ++ "fill-in file", -7, ++ + NULL, NULL + }; + +*************** +*** 284,289 **** +--- 287,302 ---- + static int encryptsw = 0; /* encrypt it */ + + ++ #ifdef BERK ++ #undef WP ++ #endif ++ ++ #ifdef WP ++ extern int do_wp; /* fill-in white pages queries */ ++ #endif ++ static char *fill_in = NULLCP; ++ ++ + long lseek (), time (); + + /* MAIN */ +*************** +*** 486,491 **** +--- 499,511 ---- + snoop++; + continue; + #endif SENDMTS ++ ++ case FILLSW: ++ #ifdef WP ++ if (!(fill_in = *argp++) || *fill_in == '-') ++ adios (NULLCP, "missing argument to %s", argp[-2]); ++ #endif ++ continue; + } + if (msg) + adios (NULLCP, "only one message at a time!"); +*************** +*** 494,499 **** +--- 514,522 ---- + } + + (void) alias (AliasFile); ++ #ifdef WP ++ do_wp++; ++ #endif + + /* */ + +*************** +*** 534,540 **** + else + #endif MHMTS + if (whomsw) { +! if ((out = fopen ("/dev/null", "w")) == NULL) + adios ("/dev/null", "unable to open"); + } + else { +--- 557,563 ---- + else + #endif MHMTS + if (whomsw) { +! if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL) + adios ("/dev/null", "unable to open"); + } + else { +*************** +*** 575,581 **** + case BODY: + case BODYEOF: + finish_headers (out); +! if (whomsw) + break; + fprintf (out, "\n%s", buf); + while (state == BODY) { +--- 598,604 ---- + case BODY: + case BODYEOF: + finish_headers (out); +! if (whomsw && !fill_in) + break; + fprintf (out, "\n%s", buf); + while (state == BODY) { +*************** +*** 699,709 **** + } + + hdr = &hdrtab[i]; +! if (hdr -> flags & HIGN) + return; + if (hdr -> flags & HBAD) { +! advise (NULLCP, "illegal header line -- %s:", name); +! badmsg++; + return; + } + msgflags |= (hdr -> set & ~(MVIS | MINV)); +--- 722,739 ---- + } + + hdr = &hdrtab[i]; +! if (hdr -> flags & HIGN) { +! if (fill_in) +! fprintf (out, "%s: %s", name, str); + return; ++ } + if (hdr -> flags & HBAD) { +! if (fill_in) +! fprintf (out, "%s: %s", name, str); +! else { +! advise (NULLCP, "illegal header line -- %s:", name); +! badmsg++; +! } + return; + } + msgflags |= (hdr -> set & ~(MVIS | MINV)); +*************** +*** 711,716 **** +--- 741,751 ---- + if (hdr -> flags & HSUB) + subject = subject ? add (str, add ("\t", subject)) : getcpy (str); + if (hdr -> flags & HFCC) { ++ if (fill_in) { ++ fprintf (out, "%s: %s", name, str); ++ return; ++ } ++ + if (cp = rindex (str, '\n')) + *cp = NULL; + for (cp = pp = str; cp = index (pp, ','); pp = cp) { +*************** +*** 759,765 **** + + nameoutput = linepos = 0; + (void) sprintf (namep, "%s%s", +! (hdr -> flags & HMNG) ? "Original-" : "", name); + + for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np) + if (mp -> m_nohost) { /* also used to test (hdr -> flags & HTRY) */ +--- 794,801 ---- + + nameoutput = linepos = 0; + (void) sprintf (namep, "%s%s", +! !fill_in && (hdr -> flags & HMNG) ? "Original-" : "", +! name); + + for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np) + if (mp -> m_nohost) { /* also used to test (hdr -> flags & HTRY) */ +*************** +*** 810,817 **** + advise (NULLCP, "%s: field does not allow groups", name); + badmsg++; + } +! if (linepos) + (void) putc ('\n', out); + } + + /* */ +--- 846,856 ---- + advise (NULLCP, "%s: field does not allow groups", name); + badmsg++; + } +! if (linepos) { +! if (fill_in && grp > 0) +! (void) putc (';', out); + (void) putc ('\n', out); ++ } + } + + /* */ +*************** +*** 942,948 **** + + if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp))) + return 0; +! if ((flags & HBCC) || mp -> m_ingrp) + return 1; + + if (!nameoutput) { +--- 981,987 ---- + + if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp))) + return 0; +! if (!fill_in && ((flags & HBCC) || mp -> m_ingrp)) + return 1; + + if (!nameoutput) { +*************** +*** 953,959 **** + if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers) + mp -> m_pers = getcpy (aka); + if (format) { +! if (mp -> m_gname) + (void) sprintf (cp = buffer, "%s;", mp -> m_gname); + else + cp = adrformat (mp); +--- 992,998 ---- + if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers) + mp -> m_pers = getcpy (aka); + if (format) { +! if (mp -> m_gname && !fill_in) + (void) sprintf (cp = buffer, "%s;", mp -> m_gname); + else + cp = adrformat (mp); +*************** +*** 987,1004 **** + int len; + char *cp; + +! if (flags & HBCC) + return; + + if (!nameoutput) { + fprintf (out, "%s: ", name); + linepos += (nameoutput = strlen (name) + 2); + } + +! cp = concat (group, ";", NULLCP); + len = strlen (cp); + +! if (linepos != nameoutput) + if (len + linepos + 2 > outputlinelen) { + fprintf (out, ",\n%*s", nameoutput, ""); + linepos = nameoutput; +--- 1026,1045 ---- + int len; + char *cp; + +! if (!fill_in && (flags & HBCC)) + return; + + if (!nameoutput) { + fprintf (out, "%s: ", name); + linepos += (nameoutput = strlen (name) + 2); ++ if (fill_in) ++ linepos -= strlen (group); + } + +! cp = fill_in ? group : concat (group, ";", NULLCP); + len = strlen (cp); + +! if (linepos > nameoutput) + if (len + linepos + 2 > outputlinelen) { + fprintf (out, ",\n%*s", nameoutput, ""); + linepos = nameoutput; +*** uip/whatnowsbr.c.orig Thu Jan 10 02:14:55 1991 +--- uip/whatnowsbr.c Wed Jan 9 14:27:35 1991 +*************** +*** 6,11 **** +--- 6,16 ---- + #include + #include + ++ ++ #ifdef BERK ++ #undef WP ++ #endif ++ + /* */ + + static struct swit whatnowswitches[] = { +*************** +*** 758,764 **** +--- 763,778 ---- + int pid; + register int vecp; + char *vec[MAXARGS]; ++ #ifdef WP ++ char *cp, ++ draft[BUFSIZ], ++ backup[BUFSIZ]; ++ #endif + ++ #ifdef WP ++ (void) strcpy (draft, m_scratch (file, invo_name)); ++ #endif ++ + m_update (); + (void) fflush (stdout); + +*************** +*** 774,779 **** +--- 788,797 ---- + if (arg) + while (*arg) + vec[vecp++] = *arg++; ++ #ifdef WP ++ vec[vecp++] = "-fill-in"; ++ vec[vecp++] = draft; ++ #endif + vec[vecp] = NULL; + + execvp (whomproc, vec); +*************** +*** 782,787 **** +--- 800,827 ---- + _exit (-1); /* NOTREACHED */ + + default: ++ #ifndef WP + return (pidwait (pid, NOTOK) & 0377 ? 1 : 0); ++ #else ++ if (pidwait (pid, NOTOK)) { ++ (void) unlink (draft); ++ return 1; ++ } ++ break; ++ #endif + } ++ ++ #ifdef WP ++ if (rename (file, cp = m_backup (file)) == NOTOK) { ++ advise (cp, "unable to rename %s to", file); ++ (void) unlink (draft); ++ return 1; ++ } ++ if (rename (draft, file) == NOTOK) { ++ advise (file, "unable to rename %s to ", draft); ++ return 1; ++ } ++ ++ return 0; ++ #endif + } +*** uip/whom.c.orig Thu Jan 10 02:15:30 1991 +--- uip/whom.c Mon Jul 17 09:22:31 1989 +*************** +*** 35,40 **** +--- 35,43 ---- + #define SNOOPSW 10 + "snoop", -5, + ++ #define FILLSW 11 ++ "fill-in file", -7, ++ + NULL, NULL + }; + +*************** +*** 125,130 **** +--- 128,134 ---- + case ALIASW: + case CLIESW: + case SERVSW: ++ case FILLSW: + vec[vecp++] = --cp; + if (!(cp = *argp++) || *cp == '-') + adios (NULLCP, "missing argument to %s", argp[-2]); +*** zotnet/mf/mf.c.orig Thu Jan 10 02:10:25 1991 +--- zotnet/mf/mf.c Wed Jan 9 14:27:34 1991 +*************** +*** 4,9 **** +--- 4,14 ---- + #include + #include + ++ ++ #ifdef BERK ++ #undef WP ++ #endif ++ + /* */ + + static char *getcpy (s) +*************** +*** 298,303 **** +--- 303,311 ---- + + #define QUOTE '\\' + ++ #ifdef WP ++ #define LX_WP (-1) ++ #endif + #define LX_END 0 + #define LX_ERR 1 + #define LX_ATOM 2 +*************** +*** 351,361 **** +--- 359,380 ---- + + static struct adrx adrxs2; + ++ ++ #ifdef WP ++ char *concat (); ++ ++ extern int do_wp; ++ char *wp_expand (); ++ #endif ++ + /* */ + + struct adrx *getadrx (addrs) + register char *addrs; + { ++ #ifdef WP ++ int save_lex; ++ #endif + register char *bp; + register struct adrx *adrxp = &adrxs2; + +*************** +*** 385,390 **** +--- 404,432 ---- + return NULL; + } + ++ #ifdef WP ++ bp = cp, save_lex = last_lex; ++ if (my_lex (adr) == LX_WP) { ++ register char *ep, ++ *fp; ++ ++ if (fp = wp_expand (adr, err)) { ++ *bp = NULL; ++ ep = concat (dp, fp, cp, (char *) NULL); ++ cp = ep + strlen (dp), last_lex = save_lex; ++ free (dp); ++ dp = ep; ++ free (fp); ++ } ++ else { ++ ap = bp, save_lex = last_lex; ++ goto out; ++ } ++ } ++ else ++ cp = bp, last_lex = save_lex; ++ #endif ++ + switch (parse_address ()) { + case DONE: + free (dp); +*************** +*** 409,414 **** +--- 451,459 ---- + break; + } + ++ #ifdef WP ++ out: ; ++ #endif + if (err[0]) + for (;;) { + switch (last_lex) { +*************** +*** 798,803 **** +--- 843,863 ---- + cp = NULL; + return (last_lex = LX_END); + } ++ ++ #ifdef WP ++ if (do_wp && c == '<' && *cp == '<') ++ for (cp++;;) ++ switch (c = *cp++) { ++ case '>': ++ *bp = NULL; ++ cp++; ++ return (last_lex = LX_WP); ++ ++ default: ++ *bp++ = c; ++ continue; ++ } ++ #endif + + if (c == '(') + for (*bp++ = c, i = 0;;) +*** zotnet/mts/client.c.orig Thu Jan 10 02:09:09 1991 +--- zotnet/mts/client.c Thu Jan 10 02:09:48 1991 +*************** +*** 50,55 **** +--- 50,56 ---- + static struct addrent *he, *hz; + static struct addrent hosts[MAXHOSTS]; + ++ struct hostent *gethostbystring (); + + char *getcpy (), **brkstring (), **copyip (); + +*************** +*** 63,68 **** +--- 64,70 ---- + int rproto; + { + int sd; ++ unsigned int portno; + register char **ap; + char *arguments[MAXARGS]; + register struct hostent *hp; +*************** +*** 71,80 **** + #endif BIND + register struct servent *sp; + +! if ((sp = getservbyname (service, protocol)) == NULL) { +! (void) sprintf (response, "%s/%s: unknown service", protocol, service); +! return NOTOK; +! } + + ap = arguments; + if (args != NULL && *args != NULL) +--- 73,86 ---- + #endif BIND + register struct servent *sp; + +! if (sp = getservbyname (service, protocol)) +! portno = sp -> s_port; +! else +! if (sscanf (service, "%u", &portno) != 1) { +! (void) sprintf (response, "%s/%s: unknown service", +! protocol, service); +! return NOTOK; +! } + + ap = arguments; + if (args != NULL && *args != NULL) +*************** +*** 98,104 **** + while (hp = gethostent ()) + if (np -> n_addrtype == hp -> h_addrtype + && inet (hp, np -> n_net)) { +! switch (sd = rcaux (sp, hp, rproto, response)) { + case NOTOK: + continue; + case OOPS1: +--- 104,110 ---- + while (hp = gethostent ()) + if (np -> n_addrtype == hp -> h_addrtype + && inet (hp, np -> n_net)) { +! switch (sd = rcaux (portno, hp, rproto, response)) { + case NOTOK: + continue; + case OOPS1: +*************** +*** 116,123 **** + continue; + } + +! if (hp = gethostbyname (*ap)) { +! switch (sd = rcaux (sp, hp, rproto, response)) { + case NOTOK: + case OOPS1: + break; +--- 122,129 ---- + continue; + } + +! if (hp = gethostbystring (*ap)) { +! switch (sd = rcaux (portno, hp, rproto, response)) { + case NOTOK: + case OOPS1: + break; +*************** +*** 137,144 **** + + /* */ + +! static int rcaux (sp, hp, rproto, response) +! register struct servent *sp; + register struct hostent *hp; + int rproto; + register char *response; +--- 143,150 ---- + + /* */ + +! static int rcaux (portno, hp, rproto, response) +! unsigned int portno; + register struct hostent *hp; + int rproto; + register char *response; +*************** +*** 163,169 **** + + bzero ((char *) isock, sizeof *isock); + isock -> sin_family = hp -> h_addrtype; +! isock -> sin_port = sp -> s_port; + bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length); + + if (connect (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK) +--- 169,175 ---- + + bzero ((char *) isock, sizeof *isock); + isock -> sin_family = hp -> h_addrtype; +! isock -> sin_port = portno; + bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length); + + if (connect (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK) +*************** +*** 245,250 **** +--- 251,301 ---- + return NOTOK; + } + } ++ } ++ ++ /* */ ++ ++ #if defined(BIND) && !defined(h_addr) ++ #define h_addr h_addr_list[0] ++ #endif ++ ++ ++ static char *empty = NULL; ++ #ifdef h_addr ++ static char *addrs[2] = { NULL }; ++ #endif ++ ++ struct hostent *gethostbystring (s) ++ char *s; ++ { ++ register struct hostent *h; ++ #ifndef DG ++ static u_long iaddr; ++ #else ++ static struct in_addr iaddr; ++ #endif ++ static struct hostent hs; ++ ++ iaddr = inet_addr (s); ++ #ifndef DG ++ if (iaddr == NOTOK) ++ #else ++ if (iaddr.s_addr == NOTOK) ++ #endif ++ return gethostbyname (s); ++ ++ h = &hs; ++ h -> h_name = s; ++ h -> h_aliases = ∅ ++ h -> h_addrtype = AF_INET; ++ h -> h_length = sizeof (iaddr); ++ #ifdef h_addr ++ h -> h_addr_list = addrs; ++ bzero ((char *) addrs, sizeof addrs); ++ #endif ++ h -> h_addr = (char *) &iaddr; ++ ++ return h; + } + + /* */ diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/miscellany.c b/usr/src/contrib/isode/others/quipu/uips/fred/miscellany.c new file mode 100644 index 0000000000..c4139dfa9a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/miscellany.c @@ -0,0 +1,454 @@ +/* miscellany.c - fred miscellaneous functions */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/miscellany.c,v 7.18 91/02/22 09:30:52 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/fred/RCS/miscellany.c,v 7.18 91/02/22 09:30:52 mrose Interim $ + * + * + * $Log: miscellany.c,v $ + * Revision 7.18 91/02/22 09:30:52 mrose + * Interim 6.8 + * + * Revision 7.17 91/02/12 18:25:36 mrose + * update + * + * Revision 7.16 91/01/07 12:43:24 mrose + * update + * + * Revision 7.15 90/12/17 22:14:50 mrose + * DA-edit + * + * Revision 7.14 90/10/29 11:50:15 mrose + * more stuff + * + * Revision 7.13 90/10/29 08:10:11 mrose + * touch-up + * + * Revision 7.12 90/10/28 23:21:08 mrose + * server + * + * Revision 7.11 90/09/13 17:46:03 mrose + * thisis-botched + * + * Revision 7.10 90/08/29 15:06:37 mrose + * update + * + * Revision 7.9 90/07/27 08:45:28 mrose + * update + * + * Revision 7.8 90/06/11 10:55:27 mrose + * UFN + * + * Revision 7.7 90/05/12 17:03:22 mrose + * sync + * + * Revision 7.6 90/02/19 13:10:39 mrose + * update + * + * Revision 7.5 90/01/16 21:22:42 mrose + * one more time + * + * Revision 7.4 90/01/16 20:43:35 mrose + * last check-out + * + * Revision 7.3 90/01/11 18:36:37 mrose + * real-sync + * + * Revision 7.2 89/12/01 10:45:09 mrose + * touch-up + * + * Revision 7.1 89/11/27 10:32:24 mrose + * sync + * + * Revision 7.0 89/11/23 22:09:01 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "fred.h" + +/* DATA */ + +int area_quantum = 0; + +struct area_guide areas[] = { + W_ORGANIZATION, + "organization", "-singlelevel", "organization", "o", NULL, + + W_UNIT, + "unit", "-subtree", "organizationalUnit", "ou", NULL, + + W_LOCALITY, + "locality", "-singlelevel", "locality", "l", NULL, + + W_PERSON, + "person", "-subtree", "person", "cn", NULL, + + W_DSA, + "dsa", "-singlelevel", "dsa", "cn", NULL, + + W_ROLE, + "role", "-subtree", "organizationalRole", "cn", NULL, + + NULL +}; + +/* ALIAS */ + +/* ARGSUSED */ + +int f_alias (vec) +char **vec; +{ + char *cp, + buffer[BUFSIZ]; + + if ((cp = *++vec) == NULL) + return dish ("squid -fred -sequence default", 0); + + if (strcmp (cp, "-help") == 0) { + fprintf (stdfp, "alias [name]\n"); + fprintf (stdfp, " with no arguments, reports on active aliases\n"); + fprintf (stdfp, + " with one argument, defines an alias for the given name\n"); + + return OK; + } + + (void) sprintf (buffer, "squid -fred -alias \"%s\"", cp); + return dish (buffer, runcom); +} + +/* AREA */ + +int f_area (vec) +char **vec; +{ + int status; + char *cp, + *dp, + buffer[BUFSIZ]; + register struct area_guide *ag; + + if ((cp = *++vec) == NULL) { + if (myarea == NULL) { + if (dish ("moveto -pwd", 0) == NOTOK) + return NOTOK; + } + else + fprintf (stdfp, " default area %s\n", myarea); + + for (ag = areas; ag -> ag_record; ag++) + if (ag -> ag_area) + fprintf (stdfp, "area for record-type %-12.12s %s\n", + ag -> ag_key, ag -> ag_area); + + return OK; + } + + if (strcmp (cp, "-help") == 0) { + fprintf (stdfp, "area [[record] location]\n"); + fprintf (stdfp, + " with no arguments, lists areas current defined for various searches\n"); + fprintf (stdfp, + " with one argument, sets the default area for general searches\n"); + fprintf (stdfp, + " with two arguments, sets the default area for the given record type\n"); + + return OK; + } + + if ((dp = *++vec) == NULL) { + (void) sprintf (buffer, "moveto -pwd \"%s\"", cp); + if (dish (buffer, 1) == NOTOK) { + advise (NULLCP, "bad area: \"%s\"", cp); + return NOTOK; + } + if (!runcom) + fprintf (stdfp, "%s\n", myarea); + + area_quantum++; + return OK; + } + + for (ag = areas; ag -> ag_record; ag++) + if (strcmp (ag -> ag_key, cp) == 0) + break; + if (!ag -> ag_record) { + advise (NULLCP, "invalid record-type: \"%s\"", cp); + return NOTOK; + } + + if (cp = myarea) + myarea = NULL; + + (void) sprintf (buffer, "moveto -pwd \"%s\"", dp); + if ((status = dish (buffer, 1)) == OK) { + if (ag -> ag_area) + free (ag -> ag_area); + ag -> ag_area = myarea; + + if (!runcom) + fprintf (stdfp, "area for record-type %s: %s\n", + ag -> ag_key, ag -> ag_area); + } + else { + advise (NULLCP, "bad area: \"%s\"", dp); + if (myarea) + free (myarea), myarea = NULL; + } + + if (myarea = cp) { + (void) sprintf (buffer, "moveto -pwd \"%s\"", myarea); + (void) dish (buffer, 1); + } + + area_quantum++; + return status; +} + +/* DISH */ + +int f_dish (vec) +char **vec; +{ + register char *bp, + *cp; + char buffer[BUFSIZ]; + + if ((cp = *++vec) == NULL) + return dish ("squid -fred", 0); + if (strcmp (cp, "-help") == 0) { + fprintf (stdfp, "dish [command [arguments ...]]\n"); + fprintf (stdfp, " with no arguments, reports on status of dish\n"); + fprintf (stdfp, " with arguments, passes those directly to dish\n"); + + return OK; + } + + (void) strcpy (bp = buffer, cp); + bp += strlen (bp); + + while (cp = *++vec) { + (void) sprintf (bp, " \"%s\"", cp); + bp += strlen (bp); + } + + return dish (buffer, runcom); +} + +/* EDIT */ + +int f_edit (vec) +char **vec; +{ + int result; + char buffer[BUFSIZ]; + + if (*++vec != NULL && strcmp (*vec, "-help") == 0) { + fprintf (stdfp, "edit\n"); + fprintf (stdfp, " edit entry in the white pages\n"); + + return OK; + } + + if (mydn == NULL) { + advise (NULLCP, "who are you? use the \"thisis\" command first..."); + return NOTOK; + } + + (void) sprintf (buffer, "modify -nocache -dontusecopy -newdraft \"%s\"", + mydn); + dontpage = 1; + result = dish (buffer, 0); + dontpage = 0; + + if (result != OK) + return result; + + (void) sprintf (buffer, "showentry \"%s\" -fred -nocache -dontusecopy", + mydn); + (void) dish (buffer, 0); + return OK; +} + +/* MANUAL */ + +int f_manual (vec) +char **vec; +{ + char buffer[BUFSIZ]; + FILE *fp; + + if (*++vec != NULL && strcmp (*vec, "-help") == 0) { + fprintf (stdfp, "manual\n"); + fprintf (stdfp, " print detailed information\n"); + + return OK; + } + + (void) strcpy (buffer, isodefile ("fred.0", 0)); + if (fp = fopen (buffer, "r")) { + while (fgets (buffer, sizeof buffer, fp)) + paginate (stdfp, buffer, strlen (buffer)); + paginate (stdfp, NULLCP, 0); + + (void) fclose (fp); + } + else + advise (buffer, "unable to open"); + + return OK; +} + +/* REPORT */ + +int f_report (vec) +char **vec; +{ + register char *bp; + char *cp, + buffer[BUFSIZ]; + + if (*++vec != NULL && strcmp (*vec, "-help") == 0) { + fprintf (stdfp, "report [subject]\n"); + fprintf (stdfp, " send report to white pages manager\n"); + + return OK; + } + + if (readonly) + (void) strcpy (buffer, _isodefile (isodebinpath, "mhmail")); + bp = buffer; + cp = strcmp (manager, "internal") ? manager : "wpp-manager@psi.com"; + + if (!readonly || access (buffer, 0x01) == NOTOK) { + (void) strcpy (bp, "/usr/ucb/Mail "); + bp += strlen (bp); + + if (debug) { + (void) sprintf (bp, "-v "); + bp += strlen (bp); + } + + if (readonly) { + (void) sprintf (bp, "-r \"%s\" ", cp); + bp += strlen (bp); + } + + (void) sprintf (bp, "-s"); + } + else { + bp += strlen (bp); + + (void) sprintf (bp, " -subject"); + } + bp += strlen (bp); + + (void) sprintf (bp, " \"%s\" \"%s\"", + *vec ? *vec : "White Pages report", cp); + bp += strlen (bp); + + + fprintf (stdfp, "End report with CTRL-D%s.\n", + readonly ? ", it will then take 30 seconds to post message" : ""); + if (readonly) + fprintf (stdfp, + "In the message please specify your e-mail address, so a reply may be made.\n"); + (void) fflush (stdfp); + + if (watch) { + fprintf (stderr, "%s\n", buffer); + (void) fflush (stderr); + } + if (system (buffer)) + advise (NULLCP, "problem sending report"); + + return OK; +} + +/* THISIS */ + +int f_thisis (vec) +char **vec; +{ + register char *bp; + char *cp, + buffer[BUFSIZ]; + +again: ; + if ((cp = *++vec) == NULL) { + if (mydn == NULL) { + advise (NULLCP, "who are you?"); + return NOTOK; + } + + printf ("you are \"%s\"\n", mydn); + return OK; + } + + if (strcmp (cp, "-help") == 0) { + fprintf (stdfp, "thisis [name]\n"); + fprintf (stdfp, + " with no arguments, lists your name in the white pages\n"); + fprintf (stdfp, + " with one argument, identifies you in the white pages\n"); + + return OK; + } + + if (strcmp (cp, "is") == 0) + goto again; + + if (*cp == '!') + cp++; + for (bp = cp; isdigit (*bp); bp++) + continue; + if (*bp && (index (cp, '@') == NULL || index (cp, '=') == NULL)) { + advise (NULLCP, + "expecting a distinguished name (if you don't know what this is, punt)" + ); + return NOTOK; + } + + bp = buffer; + + (void) sprintf (bp, "bind -simple -user \"%s\"", cp); + bp += strlen (bp); + + if (*++vec) { + if (runcom && (rcmode & 077)) + adios (NULLCP, + "incorrect mode for runcom file -- use \"chmod 0600 $HOME/.fredrc\""); + + (void) sprintf (bp, " -password \"%s\"", *vec); + bp += strlen (bp); + } + + if (dish (buffer, 0) != OK) { + (void) f_quit (NULLVP); + exit (1); /* NOT REACHED */ + } + + if (runcom) + didbind = 1; + + (void) dish ("squid -user", 1); + + return OK; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/ufnrc b/usr/src/contrib/isode/others/quipu/uips/fred/ufnrc new file mode 100644 index 0000000000..10c10ecf9f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/ufnrc @@ -0,0 +1,28 @@ +############################################################################### +# +# ufnrc - System-wide UFN tailoring file +# +# $Header: /f/osi/others/quipu/uips/fred/RCS/ufnrc,v 7.1 91/02/22 09:30:56 mrose Interim $ +# +# +# $Log: ufnrc,v $ +# Revision 7.1 91/02/22 09:30:56 mrose +# Interim 6.8 +# +# Revision 7.0 90/07/22 11:44:34 mrose +# *** empty log message *** +# +############################################################################### + + +1: c=@(country)@o=@(organization) + c=@(country) + - + +2: c=@(country) + c=@(country)@o=@(organization) + - + +3,+: - + c=@(country) + c=@(country)@o=@(organization) diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/whitepages.sh b/usr/src/contrib/isode/others/quipu/uips/fred/whitepages.sh new file mode 100644 index 0000000000..cb9d482ec2 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/whitepages.sh @@ -0,0 +1,3 @@ +: run this script through /bin/sh + +exec /usr/ucb/whois -h wp.psi.net "$*" diff --git a/usr/src/contrib/isode/others/quipu/uips/fred/whois.c b/usr/src/contrib/isode/others/quipu/uips/fred/whois.c new file mode 100644 index 0000000000..64ccc2aa7f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/fred/whois.c @@ -0,0 +1,1091 @@ +/* whois.c - fred whois function */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/whois.c,v 7.26 91/02/22 09:30:58 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/fred/RCS/whois.c,v 7.26 91/02/22 09:30:58 mrose Interim $ + * + * + * $Log: whois.c,v $ + * Revision 7.26 91/02/22 09:30:58 mrose + * Interim 6.8 + * + * Revision 7.25 91/02/19 09:21:17 mrose + * ufn + * + * Revision 7.24 91/02/12 18:25:42 mrose + * update + * + * Revision 7.23 91/01/10 04:03:10 mrose + * update + * + * Revision 7.22 91/01/07 12:43:30 mrose + * update + * + * Revision 7.21 90/11/20 15:33:45 mrose + * update + * + * Revision 7.20 90/11/11 09:57:40 mrose + * touch-up + * + * Revision 7.19 90/11/01 22:02:52 mrose + * update + * + * Revision 7.18 90/10/29 11:50:22 mrose + * more stuff + * + * Revision 7.17 90/10/28 22:41:07 mrose + * update + * + * Revision 7.16 90/10/23 20:42:28 mrose + * update + * + * Revision 7.15 90/10/18 11:33:55 mrose + * psi + * + * Revision 7.14 90/07/27 08:45:10 mrose + * update + * + * Revision 7.13 90/07/09 14:41:21 mrose + * sync + * + * Revision 7.12 90/06/11 21:17:12 mrose + * touch-up + * + * Revision 7.11 90/06/11 10:55:38 mrose + * UFN + * + * Revision 7.10 90/03/23 02:39:29 mrose + * network + * + * Revision 7.9 90/03/15 11:20:45 mrose + * quipu-sync + * + * Revision 7.8 90/03/08 08:05:10 mrose + * phone + * + * Revision 7.7 90/01/16 20:43:45 mrose + * last check-out + * + * Revision 7.6 90/01/11 18:36:41 mrose + * real-sync + * + * Revision 7.5 89/12/18 08:44:23 mrose + * typo + * + * Revision 7.4 89/12/14 18:49:05 mrose + * KIS project + * + * Revision 7.3 89/12/01 10:45:11 mrose + * touch-up + * + * Revision 7.2 89/11/26 15:09:32 mrose + * sync + * + * Revision 7.1 89/11/26 14:25:22 mrose + * sync + * + * Revision 7.0 89/11/23 22:09:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "fred.h" + +/* DATA */ + +struct whois { + char *w_input; + int w_inputype; +#define W_NULL 0x00 +#define W_HANDLE 0x01 +#define W_MAILBOX 0x02 +#define W_NAME 0x03 + + int w_nametype; +#define W_COMMONAME 0x01 +#define W_SURNAME 0x02 + + int w_record; /* same values as ag_record */ + + char *w_title; + + char *w_area; + int w_areatype; + char *w_geography; + + int w_output; +#define W_EXPAND 0x01 +#define W_FULL 0x02 +#define W_SUMMARY 0x04 +#define W_SUBDISPLAY 0x08 +}; + + +char *eqstr (), *limits (); +FILE *capture (); + +/* */ + +char *whois_help[] = { + "whois input-field [record-type] [area-designator] [output-control]", + " input-field is one of:", + "\tname NAME\t\te.g., surname \"smith\", or fullname \"john smith\"", + "\thandle HANDLE\t\te.g., handle @c=US@cn=Manager", + "\tmailbox LOCAL@DOMAIN\te.g., mailbox postmaster@nisc.psi.net", + " record-type is one of:", + "\tperson or -title NAME\te.g., -title scientist", + "\torganization", + "\tunit (a division under an organization)", + "\trole (a role within an organization)", + "\tlocality", + "\tdsa (white pages server)", + " area-designator is one of:", + "\t-org NAME\t\te.g., -org psi", + "\t-unit NAME\t\te.g., -unit engineering", + "\t-locality NAME\t\te.g., -locality rensselaer", + "\t-area HANDLE\t\te.g., -area \"@c=US@o=Performance Systems...\"", + "\t and may be optionally followed by -geo HANDLE, e.g., -geo @c=GB", + " output-control is any of:", + "\texpand\t - give a detailed listing, followed by children", + "\tsubdisplay - give a one-listing listing, followed by children", + "\tfull\t - give a detailed listing, even on ambiguous matches", + "\tsummary\t - give a one-line listing, even on unique matches", + + NULL +}; + +/* WHOIS */ + +int f_whois (vec) +char **vec; +{ + if (strcmp (*vec, "whois") == 0) + vec++; + + return (nametype > 1 ? f_ufn (vec) : f_whois_aux (vec)); +} + +/* */ + +static int f_whois_aux (vec) +char **vec; +{ + int c, + mailbox, + multiple, + result; + register char *bp, + *cp, + *dp; + char buffer[BUFSIZ], + orgname[BUFSIZ]; + register struct area_guide *ag; + struct whois ws; + register struct whois *w = &ws; + FILE *fp; + + bzero ((char *) w, sizeof *w); + + while (cp = *vec++) { +postscan: ; + + switch (*cp) { + case '.': + if (w -> w_inputype != W_NULL) { +too_many_fields: ; + advise (NULLCP, + "only one of NAME, HANDLE, or MAILBOX allowed"); + goto you_really_lose; + } + if (*++cp == NULL) { + advise (NULLCP, "expecting NAME after \".\""); + goto you_really_lose; + } + w -> w_inputype = W_NAME; + w -> w_input = cp; + break; + + case '!': + if (w -> w_inputype != W_NULL) + goto too_many_fields; + if (*++cp == NULL) { + advise (NULLCP, "expecting HANDLE after \"!\""); + goto you_really_lose; + } + goto got_handle; + + case '*': + if (cp[1] == '*') { + cp++; + goto name_or_something; + } + w -> w_output |= W_EXPAND; + if (*++cp) + goto postscan; + break; + + case '~': + w -> w_output &= ~W_EXPAND; + if (*++cp) + goto postscan; + break; + + case '|': + w -> w_output |= W_FULL; + if (*++cp) + goto postscan; + break; + + case '$': + w -> w_output |= W_SUMMARY; + if (*++cp) + goto postscan; + break; + + case '%': + w -> w_output |= W_SUBDISPLAY; + if (*++cp) + goto postscan; + break; + + case '-': + if (test_arg (cp, "-area", 4)) { + result = W_NULL; + +stuff_area: ; + if (w -> w_area != NULL) { + advise (NULLCP, "only one AREA specification allowed"); + goto you_really_lose; + } + if (*vec == NULL) { + advise (NULLCP, "expecting %s after \"%s\"", + result != W_NULL ? "NAME" : "HANDLE", cp); + goto you_really_lose; + } + if (*(dp = *vec) == '!') + result = W_NULL; + else { + for (; *dp; dp++) + if (!isdigit (*dp)) + break; + if (!*dp) + result = NULL; + } + w -> w_area = *vec++, w -> w_areatype = result; + break; + + } + if (test_arg (cp, "-expand", 4)) { + w -> w_output |= W_EXPAND; + break; + } + if (test_arg (cp, "-full", 4)) { + w -> w_output |= W_FULL; + break; + } + if (test_arg (cp, "-geography", 4)) { + if (*vec == NULL) { + advise (NULLCP, + "expecting location after \"-geography\""); + goto you_really_lose; + } + w -> w_geography = *vec++; + break; + } + if (test_arg (cp, "-help", 5)) + goto print_help; + if (test_arg (cp, "-locality", 4)) { + result = W_LOCALITY; + goto stuff_area; + } + if (test_arg (cp, "-organization", 4)) { + result = W_ORGANIZATION; + goto stuff_area; + } + if (test_arg (cp, "-summary", 4)) { + w -> w_output |= W_SUMMARY; + break; + } + if (test_arg (cp, "-subdisplay", 4)) { + w -> w_output |= W_SUBDISPLAY; + break; + } + if (test_arg (cp, "-title", 4)) { + if (*vec == NULL) { + advise (NULLCP, + "expecting something after \"-title\""); + goto you_really_lose; + } + w -> w_title = *vec++; + break; + } + if (test_arg (cp, "-unit", 4)) { + result = W_UNIT; + goto stuff_area; + } + + advise (NULLCP, "unknown switch: %s", cp); +you_really_lose: ; + if (mail) { + fprintf (stdfp, "\n\n"); + goto print_help; + } + return NOTOK; + + case 'd': + if (strcmp (cp, "dsa")) + goto name_or_something; + if (w -> w_record != W_NULL) + goto too_many_fields; + w -> w_record = W_DSA; + break; + + case 'e': + if (strcmp (cp, "expand")) + goto name_or_something; + w -> w_output |= W_EXPAND; + break; + + case 'f': + if (strcmp (cp, "full") == 0) { + w -> w_output |= W_FULL; + break; + } + if (strcmp (cp, "fullname") == 0) { + w -> w_nametype = W_COMMONAME; + goto name; + } + goto name_or_something; + + case 'h': + if (strcmp (cp, "handle")) + goto name_or_something; + if (w -> w_inputype != W_NULL) + goto too_many_fields; + if ((cp = *vec++) == NULL) { + advise (NULLCP, "expecting HANDLE after \"handle\""); + goto you_really_lose; + } +got_handle: ; + if (!mail && strcmp (cp, "me") == 0) { + if (mydn == NULL) { + advise (NULLCP, + "who are you? use the \"thisis\" command first..."); + return NOTOK; + } + cp = mydn; + } + w -> w_inputype = W_HANDLE; + w -> w_input = cp; + break; + + case 'l': + if (strcmp (cp, "locality")) + goto name_or_something; + if (w -> w_record != W_NULL) + goto too_many_fields; + w -> w_record = W_LOCALITY; + break; + + case 'm': + if (strcmp (cp, "mailbox")) + goto name_or_something; + if (w -> w_inputype != W_NULL) + goto too_many_fields; + if ((cp = *vec++) == NULL) { + advise (NULLCP, "expecting MAILBOX after \"mailbox\""); + goto you_really_lose; + } + w -> w_inputype = W_MAILBOX; + w -> w_input = cp; + break; + + case 'n': + if (strcmp (cp, "name")) + goto name_or_something; +name: ; + if (w -> w_inputype != W_NULL) + goto too_many_fields; + if ((cp = *vec++) == NULL) { + advise (NULLCP, "expecting NAME after \"%sname\"", + w -> w_nametype == W_COMMONAME ? "full" + : w -> w_nametype == W_SURNAME ? "sur" : ""); + goto you_really_lose; + } + w -> w_inputype = W_NAME; + w -> w_input = cp; + break; + + case 'o': + if (strcmp (cp, "organization") && strcmp (cp, "org")) + goto name_or_something; + if (w -> w_record != W_NULL) + goto too_many_fields; + w -> w_record = W_ORGANIZATION; + break; + + case 'p': + if (strcmp (cp, "person")) + goto name_or_something; + if (w -> w_record != W_NULL) + goto too_many_fields; + w -> w_record = W_PERSON; + break; + + case 'r': + if (strcmp (cp, "role")) + goto name_or_something; + if (w -> w_record != W_NULL) + goto too_many_fields; + w -> w_record = W_ROLE; + break; + + case 's': + if (strcmp (cp, "subdisplay") == 0) { + w -> w_output |= W_SUBDISPLAY; + break; + } + if (strcmp (cp, "summary") == 0) { + w -> w_output |= W_SUMMARY; + break; + } + if (strcmp (cp, "surname") == 0) { + w -> w_nametype = W_SURNAME; + goto name; + } + goto name_or_something; + + case 'u': + if (strcmp (cp, "unit")) + goto name_or_something; + if (w -> w_record != W_NULL) + goto too_many_fields; + w -> w_record = W_UNIT; + break; + + default: +name_or_something: ; + if (w -> w_inputype != W_NULL) + goto too_many_fields; + for (dp = cp; *dp; dp++) + if (!isdigit (*dp)) + break; + if (!*dp) + goto got_handle; + if ((dp = index (cp, '@')) == NULL) { + w -> w_inputype = W_NAME; + w -> w_input = cp; + break; + } + if (index (dp + 1, '@') || index (dp + 1, '=')) { + w -> w_inputype = W_HANDLE; + w -> w_input = cp; + break; + } + if (!index (dp + 1, '.')) { + if (w -> w_area != W_NULL) { + advise (NULLCP, "only one AREA specification allowed"); + goto you_really_lose; + } + + *dp++ = NULL; + + w -> w_inputype = W_NAME; + w -> w_input = cp; + + w -> w_area = dp, w -> w_areatype = W_ORGANIZATION; + break; + } + w -> w_inputype = W_MAILBOX; + w -> w_input = cp; + break; + } + } + + if (w -> w_nametype != W_NULL) + switch (w -> w_record) { + default: + advise (NULLCP, "record-type ignored with \"%sname\"", + w -> w_nametype == W_COMMONAME ? "full" : "sur"); + /* and fall... */ + + case W_NULL: + w -> w_record = W_PERSON; + /* and fall... */ + + case W_PERSON: + break; + } + + if (w -> w_input && strcmp (w -> w_input, "*") == 0) + w -> w_input = NULL, w -> w_inputype = W_NULL; + if (w -> w_title && strcmp (w -> w_title, "*") == 0) + w -> w_title = NULL; + if ((w -> w_input || w -> w_title) + && w -> w_area + && strcmp (w -> w_area, "*") == 0) + w -> w_area = NULL, w -> w_areatype = W_NULL; + + if (w -> w_title) { + if (w -> w_inputype == W_NULL) + w -> w_inputype = W_NAME; + if (w -> w_inputype != W_NAME) { + advise (NULLCP, "title specification ignored with %s", + w -> w_inputype == W_HANDLE ? "HANDLE" : "MAILBOX"); + w -> w_title = NULL; + } + else + if (w -> w_record == W_NULL) + w -> w_record = W_PERSON; + } + + if (w -> w_inputype == W_HANDLE && w -> w_geography) { + advise (NULLCP, "geography specification ignored with HANDLE"); + w -> w_geography = NULL; + } + if (w -> w_geography) + if (w -> w_area == NULL) { + w -> w_area = w -> w_geography, w -> w_areatype = W_LOCALITY; + w -> w_geography = NULL; + } + else + if (*w -> w_geography == '!') + w -> w_geography++; + + if (w -> w_inputype == W_HANDLE && w -> w_area) { + advise (NULLCP, "area specification ignored with HANDLE"); + w -> w_area = NULL, w -> w_areatype = W_NULL; + } + if (w -> w_area) + if (w -> w_inputype == W_NULL) { + if (*w -> w_area != '!') { + for (dp = w -> w_area; *dp; dp++) + if (!isdigit (*dp)) + break; + w -> w_inputype = *dp ? W_NAME : W_HANDLE, + w -> w_input = w -> w_area; + } + else + w -> w_inputype = W_HANDLE, w -> w_input = w -> w_area + 1; + w -> w_record = w -> w_areatype; + w -> w_area = NULL, w -> w_areatype = W_NULL; + } + else + if (*w -> w_area == '!') + w -> w_area++; + + if (w -> w_inputype == W_NULL) { + register char **ap; + + if (w -> w_record != W_NULL || w -> w_output != W_NULL) { + advise (NULLCP, "input-field missing"); + return NOTOK; + } + +print_help: ; + for (ap = whois_help; *ap; ap++) + fprintf (stdfp, "%s%s", *ap, EOLN); + + return OK; + } + else + if (w -> w_inputype == W_NAME && w -> w_nametype == W_NULL) + w -> w_nametype = nametype ? W_SURNAME : W_COMMONAME; + + bp = buffer; + + mailbox = 0; + if (w -> w_areatype == W_NULL) { + if (w -> w_inputype == W_MAILBOX + && w -> w_area == NULL + && (cp = index (w -> w_input, '@')) + && !index (++cp, '*')) { + (void) sprintf (bp, "fred -dm2dn %s", cp); + bp += strlen (bp); + mailbox = 1; + + goto multiple_searching; + } + + return whois_aux (w); + } + + (void) sprintf (bp, + "search %s -norelative -singlelevel -dontdereference -sequence default -types aliasedObjectName -value -nosearchalias ", + limits (-1)); + bp += strlen (bp); + + for (ag = areas; ag -> ag_record; ag++) + if (ag -> ag_record == w -> w_areatype) + break; + if (w -> w_geography) { + (void) sprintf (bp, "\"%s\" ", w -> w_geography); + bp += strlen (bp); + + w -> w_geography = NULL; + } + else + if (ag -> ag_area) { + (void) sprintf (bp, "\"%s\" ", ag -> ag_area); + bp += strlen (bp); + } + + (void) sprintf (bp, "-filter \"objectClass=%s & %s%s\"", + ag -> ag_class, ag -> ag_rdn, eqstr (w -> w_area, 0)); + bp += strlen (bp); + +multiple_searching: ; + if ((fp = capture (buffer)) == NULL) + return NOTOK; + + if (interrupted) { +you_lose: ; + (void) fclose (fp); + return NOTOK; + } + + w -> w_area = orgname, w -> w_areatype = W_NULL; + + multiple = 0; + while (fgets (buffer, sizeof buffer, fp) && !interrupted) { + if ((cp = index (buffer, '\n')) == NULL) { + advise (NULLCP, "internal error(1)"); + goto you_lose; + } + *cp = NULL; + + if (!isdigit (*buffer)) { + fprintf (stderr, "%s\n", buffer); + continue; + } + + if ((cp = index (buffer, ' ')) == NULL) { + advise (NULLCP, "internal error(2)"); + goto you_lose; + } + *cp++ = NULL; + while (*cp == ' ') + cp++; + + if (multiple == 0 && (c = getc (fp)) != EOF) { + (void) ungetc (c, fp); + multiple = 1; + } + + if (mailbox && !index (cp, '@')) { + advise (NULLCP, "Unable to resolve domain beyond national level."); + continue; + } + if (multiple && query && !network) + switch (ask ("try %s [y/n] ? ", cp)) { + case NOTOK: + continue; + + case OK: + default: + break; + + case DONE: + goto out; + } + else + if (verbose) { + fprintf (stdfp, "Trying @%s ...\n", cp); + (void) fflush (stdfp); + } + + (void) sprintf (orgname, "@%s", cp); + (void) whois_aux (w); + + fprintf (stdfp, EOLN); + (void) fflush (stdfp); + } + +out: ; + (void) fclose (fp); + + return OK; +} + +/* */ + +static whois_aux (w) +register struct whois *w; +{ + register char *bp, + *cp; + char *handle, + buffer[BUFSIZ]; + register struct area_guide *ag; + + for (ag = areas; ag -> ag_record; ag++) + if (ag -> ag_record == w -> w_record) + break; + + bp = buffer; + switch (w -> w_inputype) { + case W_NULL: + default: + advise (NULLCP, "internal error(8)"); + return NOTOK; + + case W_HANDLE: + (void) sprintf (bp, "showentry \"%s\" %s -fred -dontdereference", + w -> w_input, limits (0)); + bp += strlen (bp); + goto options; + + case W_MAILBOX: + (void) sprintf (bp, "search %s -fred ", limits (1)); + bp += strlen (bp); + + if (w -> w_area) { + (void) sprintf (bp, "\"%s\" ", w -> w_area); + bp += strlen (bp); + } + + (void) sprintf (bp, "-subtree -filter \""); + bp += strlen (bp); + + cp = w -> w_input; + if (*cp == '@') + (void) sprintf (bp, "mail=*%s", cp); + else + if (*(cp + strlen (cp) - 1) == '@' || !index (cp, '@')) + (void) sprintf (bp, "mail=%s*", cp); + else + if (index (cp, '*')) + (void) sprintf (bp, "mail=%s", cp); + else + (void) sprintf (bp, + "(mail=%s | otherMailbox=internet$%s)", + cp, cp); + bp += strlen (bp); + break; + + case W_NAME: + if (cp = w -> w_input) { + cp += strlen (cp) - 1; + if (*cp == '.') + *cp = '*'; + } + + (void) sprintf (bp, "search %s -%s ", limits (1), + kflag ? "show" : "fred"); + bp += strlen (bp); + + if (w -> w_area) { + (void) sprintf (bp, "\"%s\" -subtree ", w -> w_area); + bp += strlen (bp); + } + else + if (w -> w_geography) { + (void) sprintf (bp, "\"%s\" ", w -> w_geography); + bp += strlen (bp); + } + else + if (ag -> ag_area) { + (void) sprintf (bp, "\"%s\" %s ", ag -> ag_area, + ag -> ag_search); + bp += strlen (bp); + } + else { + (void) sprintf (bp, "-subtree "); + bp += strlen (bp); + } + (void) sprintf (bp, "-filter \""); + bp += strlen (bp); + + handle = eqstr (w -> w_input, 0); + switch (w -> w_record) { + case W_NULL: + case W_PERSON: + if (handle) { + if (w -> w_title + && (w -> w_record == W_NULL + || w -> w_nametype == W_SURNAME)) { + (void) sprintf (bp, "( "); + bp += strlen (bp); + } + if (w -> w_record == W_NULL) { + (void) sprintf (bp, "o%s | ou%s | l%s | ", + handle, handle, handle, handle); + bp += strlen (bp); + } + + if (w -> w_nametype == W_SURNAME) { + if (w -> w_record == W_PERSON && !w -> w_title) { + (void) sprintf (bp, "( "); + bp += strlen (bp); + } + (void) sprintf (bp, "surname%s | mail=%s@* ", + eqstr (w -> w_input, 1), + w -> w_input); + bp += strlen (bp); + if (w -> w_record == W_PERSON && !w -> w_title) { + (void) sprintf (bp, ") "); + bp += strlen (bp); + } + } + else { + (void) sprintf (bp, "cn%s ", handle); + bp += strlen (bp); + } + + if (w -> w_title + && (w -> w_record == W_NULL + || w -> w_nametype == W_SURNAME)) { + (void) sprintf (bp, ") "); + bp += strlen (bp); + } + } + if (w -> w_title) { + (void) sprintf (bp, "%stitle%s", + handle ? "& " : "", + eqstr (w -> w_title, 1)); + bp += strlen (bp); + } + break; + + default: + if (strcmp (handle, "=*")) { + (void) sprintf (bp, "%s%s", ag -> ag_rdn, handle); + bp += strlen (bp); + } + break; + } + break; + } + + if (w -> w_record == W_PERSON + || (w -> w_record != W_NULL && strcmp (handle, "=*"))) { + (void) sprintf (bp, " & "); + bp += strlen (bp); + } + + if (w -> w_record != W_NULL) { + (void) sprintf (bp, "objectClass=%s", ag -> ag_class); + bp += strlen (bp); + } + + (void) sprintf (bp, "\""); + bp += strlen (bp); + +options: ; + if (w -> w_output & W_EXPAND) { + (void) sprintf (bp, " -expand"); + bp += strlen (bp); + } + if (w -> w_output & W_FULL) { + (void) sprintf (bp, " -full"); + bp += strlen (bp); + } + if (w -> w_output & W_SUMMARY) { + (void) sprintf (bp, " -summary"); + bp += strlen (bp); + } + if (w -> w_output & W_SUBDISPLAY) { + (void) sprintf (bp, " -subdisplay"); + bp += strlen (bp); + } + + (void) sprintf (bp, " -sequence %s", "default"); + bp += strlen (bp); + + return dish (buffer, 0); +} + +/* */ + +static int test_arg (user, full, minlen) +char *user, + *full; +int minlen; +{ + int i; + + if ((i = strlen (user)) < minlen + || i > strlen (full) + || strncmp (user, full, i)) + return 0; + + return 1; +} + +/* */ + +static char *eqstr (s, exact) +char *s; +int exact; +{ + static char buffer[BUFSIZ]; + + if (s == NULL) + return NULL; + + if (index (s, '*')) + (void) sprintf (buffer, "=%s", s); + else + if (soundex) + (void) sprintf (buffer, "~=%s", s); + else + if (exact) + (void) sprintf (buffer, "=%s", s); + else + (void) sprintf (buffer, "=%s*", s); + + return buffer; +} + +/* */ + +static char *limits (isearch) +int isearch; +{ + register char *bp; + static char buffer[100]; + + bp = buffer; + + if (phone) { + (void) strcpy (bp, "-phone "); + bp += strlen (bp); + } + +#ifdef notdef /* don't do this! */ + if (isearch) { + (void) strcpy (bp, "-searchalias "); + bp += strlen (bp); + } +#endif + + (void) strcpy (bp, "-nosizelimit "); + bp += strlen (bp); + + if (timelimit > 0) + (void) sprintf (bp, "-timelimit %d", timelimit); + else + (void) strcpy (bp, "-notimelimit"); + bp += strlen (bp); + + if (isearch >= 0 && (network || oneshot)) { + (void) strcpy (bp, " -nofredseq"); + bp += strlen (bp); + } + + return buffer; +} + +/* */ + +static FILE *capture (command) +char *command; +{ + int savnet, + savpage; + char tmpfil[BUFSIZ]; + FILE *fp, + *savfp; + + (void) strcpy (tmpfil, "/tmp/fredXXXXXX"); + (void) unlink (mktemp (tmpfil)); + + if ((fp = fopen (tmpfil, "w+")) == NULL) { + advise (tmpfil, "unable to create"); + return NULL; + } + (void) unlink (tmpfil); + + savfp = stdfp, stdfp = fp; + savnet = network, network = 0; + savpage = dontpage, dontpage = 1; + + (void) dish (command, 0); + + dontpage = savpage; + network = savnet; + stdfp = savfp; + + rewind (fp); + + return fp; +} + +/* */ + +static int f_ufn (vec) +char **vec; +{ + char *cp, + buffer[BUFSIZ]; + static int lastq = -1; + + if ((cp = vec[0]) == NULL || strcmp (cp, "-help") == 0) { + fprintf (stdfp, "whois name...\n"); + fprintf (stdfp, " find something in the white pages\n"); + + return OK; + } + + if (!test_ufn (cp)) { + (void) strcpy (buffer, cp); + (void) str2vec (buffer, vec); + return f_whois_aux (vec); + } + + (void) sprintf (buffer, "fred -ufn %s-options %x,%s", + phone ? "-phone," : "", ufn_options, cp); + + if (lastq != area_quantum) { + (void) sync_ufnrc (); + + lastq = area_quantum; + } + + return dish (buffer, 0); +} + +/* */ + +int test_ufn (cp) +char *cp; +{ + register char *dp; + + if (*(dp = cp) == '!') + dp++; + for (; *dp; dp++) + if (!isdigit (*dp)) + break; + if (!*dp || *dp == '-') /* a handle, or oldstyle */ + return 0; + + if (!index (dp = cp, ',')) { + while (dp = index (dp, ' ')) + if (*++dp == '-') + return 0; + if (index (cp, '@')) + return 0; + } + + if (strcmp (cp, "!me") == 0) + return 0; + + return 1; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/make b/usr/src/contrib/isode/others/quipu/uips/make new file mode 100644 index 0000000000..652a89e9e4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../ -f ../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/manage/Makefile b/usr/src/contrib/isode/others/quipu/uips/manage/Makefile new file mode 100644 index 0000000000..9c234f1812 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/manage/Makefile @@ -0,0 +1,235 @@ +############################################################################### +# Instructions to Make, for compilation of Management dish +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/uips/manage/RCS/Makefile,v 7.6 91/02/22 09:31:58 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.6 91/02/22 09:31:58 mrose +# Interim 6.8 +# +# Revision 7.5 91/01/24 14:43:09 mrose +# update +# +# Revision 7.1 90/07/09 14:42:37 mrose +# sync +# +# Revision 7.0 90/06/26 14:52:30 mrose +# *** empty log message *** +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + +LIBDISH = $(TOPDIR)quipu/dish/libdish.a +# sharded option... +# LIBDISH = -L $(TOPDIR)quipu/dish -ldish + +LIBES = libmanage.a $(LIBDISH) $(LIBDSAP) $(LIBISODE) $(LSOCKET) +LLIBS = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode + +CFILES = add_alias.c del_alias.c alias_chk.c +OFILES = add_alias.o del_alias.o alias_chk.o \ + schema.o + +############################################################## +# Here it is... +############################################################## + +all: dish +inst-all: inst-dish manuals # inst-shelldish +install: inst-all clean +lint: l-dish + + +################################################################### +# dish +################################################################### + +inst-dish: $(BINDIR)dish_manage + +$(BINDIR)dish_manage: xdish + -cp $@ zxdish_manage + -rm -f $@ + cp xdish $@ + -@ls -gls $@ + -@echo "" + +dish: xdish + +xdish: dish.o libmanage.a + $(LDCC) $(LDFLAGS) -o $@ dish.o $(LIBES) $(LSOCKET) + +l-dish: $(CFILES) true + $(LINT) $(LFLAGS) $(LLIBS) $(CFILES) + +dish.o: $(TOPDIR)quipu/dish/dish.c + $(CC) $(CFLAGS) -DMANAGE -c $(TOPDIR)quipu/dish/dish.c + +schema.o: $(TOPDIR)/quipu/schema.c + $(CC) $(CFLAGS) -c $(TOPDIR)quipu/schema.c + +shadow.o: $(TOPDIR)/quipu/shadow.c + $(CC) $(CFLAGS) -c $(TOPDIR)quipu/shadow.c + +############################################################## +# saber +############################################################## + +saber_src:; #load $(OPTIONS) $(CFILES) + #load $(CFLAGS) -DMANAGE -c $(TOPDIR)quipu/dish/dish.c + #load libmanage.a ../../../../quipu/dish/libdish.a ../../../../libdsap.a ../../../../libisode.a + +saber_obj:; #load $(OFILES) + +################################################################### +# libmanage +################################################################### + +inst-libmanage: $(LIBDIR)libmanage.a + +$(LIBDIR)libmanage.a: libmanage.a + -rm -f $@ + cp libmanage.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +libmanage: libmanage.a + +libmanage.a: managevrsn.o + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + managevrsn.o + -@echo "QUIPU-MANAGE library built normally" + +managevrsn.c: $(OFILES) + @$(UTILDIR)version.sh manage > $@ + +l-libmanage: $(CFILES) true + $(LINT) $(LFLAGS) $(CFILES) managevrsn.c $(LLIBS) + +################################################################### +# shell version of dish... +################################################################### + +inst-shelldish: $(BINDIR)add_alias $(BINDIR)del_alias $(BINDIR)dish + +$(BINDIR)add_alias: + -rm -f $@ + ln $(BINDIR)list $@ + +$(BINDIR)del_alias: + -rm -f $@ + ln $(BINDIR)list $@ + +$(BINDIR)dish: $(BINDIR)dish_manage + -cp $@ zxdish + -rm -f $@ + cp xdish $@ + -@ls -gls $@ + -@echo "" + +############################################################## +# manuals +############################################################## + +manuals:; echo + @$(UTILDIR)inst-man.sh $(MANOPTS) add_alias.1c + +############################################################## +# clean +############################################################## + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig \ + core managevrsn.c + +grind:; iprint Makefile + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; + + +# depend +add_alias.o: ../../../../h/config.h +add_alias.o: ../../../../h/general.h +add_alias.o: ../../../../h/isoaddrs.h +add_alias.o: ../../../../h/logger.h +add_alias.o: ../../../../h/manifest.h +add_alias.o: ../../../../h/psap.h +add_alias.o: ../../../../h/quipu/add.h +add_alias.o: ../../../../h/quipu/attr.h +add_alias.o: ../../../../h/quipu/attrvalue.h +add_alias.o: ../../../../h/quipu/authen.h +add_alias.o: ../../../../h/quipu/commonarg.h +add_alias.o: ../../../../h/quipu/compare.h +add_alias.o: ../../../../h/quipu/config.h +add_alias.o: ../../../../h/quipu/dap.h +add_alias.o: ../../../../h/quipu/ds_error.h +add_alias.o: ../../../../h/quipu/dsp.h +add_alias.o: ../../../../h/quipu/dua.h +add_alias.o: ../../../../h/quipu/entry.h +add_alias.o: ../../../../h/quipu/modify.h +add_alias.o: ../../../../h/quipu/name.h +add_alias.o: ../../../../h/quipu/oid.h +add_alias.o: ../../../../h/quipu/turbo.h +add_alias.o: ../../../../h/quipu/util.h +alias_chk.o: ../../../../h/config.h +alias_chk.o: ../../../../h/general.h +alias_chk.o: ../../../../h/isoaddrs.h +alias_chk.o: ../../../../h/logger.h +alias_chk.o: ../../../../h/manifest.h +alias_chk.o: ../../../../h/psap.h +alias_chk.o: ../../../../h/quipu/attr.h +alias_chk.o: ../../../../h/quipu/attrvalue.h +alias_chk.o: ../../../../h/quipu/authen.h +alias_chk.o: ../../../../h/quipu/commonarg.h +alias_chk.o: ../../../../h/quipu/compare.h +alias_chk.o: ../../../../h/quipu/config.h +alias_chk.o: ../../../../h/quipu/dap.h +alias_chk.o: ../../../../h/quipu/ds_error.h +alias_chk.o: ../../../../h/quipu/ds_search.h +alias_chk.o: ../../../../h/quipu/dsp.h +alias_chk.o: ../../../../h/quipu/entry.h +alias_chk.o: ../../../../h/quipu/name.h +alias_chk.o: ../../../../h/quipu/oid.h +alias_chk.o: ../../../../h/quipu/read.h +alias_chk.o: ../../../../h/quipu/util.h +del_alias.o: ../../../../h/config.h +del_alias.o: ../../../../h/general.h +del_alias.o: ../../../../h/isoaddrs.h +del_alias.o: ../../../../h/logger.h +del_alias.o: ../../../../h/manifest.h +del_alias.o: ../../../../h/psap.h +del_alias.o: ../../../../h/quipu/attr.h +del_alias.o: ../../../../h/quipu/attrvalue.h +del_alias.o: ../../../../h/quipu/authen.h +del_alias.o: ../../../../h/quipu/commonarg.h +del_alias.o: ../../../../h/quipu/compare.h +del_alias.o: ../../../../h/quipu/config.h +del_alias.o: ../../../../h/quipu/dap.h +del_alias.o: ../../../../h/quipu/ds_error.h +del_alias.o: ../../../../h/quipu/dsp.h +del_alias.o: ../../../../h/quipu/entry.h +del_alias.o: ../../../../h/quipu/modify.h +del_alias.o: ../../../../h/quipu/name.h +del_alias.o: ../../../../h/quipu/oid.h +del_alias.o: ../../../../h/quipu/remove.h +del_alias.o: ../../../../h/quipu/turbo.h +del_alias.o: ../../../../h/quipu/util.h diff --git a/usr/src/contrib/isode/others/quipu/uips/manage/add_alias.1c b/usr/src/contrib/isode/others/quipu/uips/manage/add_alias.1c new file mode 100644 index 0000000000..67ff664201 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/manage/add_alias.1c @@ -0,0 +1,82 @@ +.TH add_alias 1 "26 Jun 1990" +.\" $Header: /f/osi/others/quipu/uips/manage/RCS/add_alias.1c,v 7.2 91/02/22 09:31:59 mrose Interim $ +.\" +.\" +.\" $Log: add_alias.1c,v $ +.\" Revision 7.2 91/02/22 09:31:59 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 91/01/24 14:43:11 mrose +.\" update +.\" +.\" Revision 7.0 90/06/26 14:52:30 mrose +.\" *** empty log message *** +.\" +.SH NAME +add_alias \- adding aliases to the database +.br +delete_alias \- deleting aliases from the database +.br +alias_chk \- checking aliases in the database +.SH SYNOPSIS +.in +.5i +.B \*(SDadd_alias +\% +\% +.br +.B \*(SDdel_alias +\% +.br +.B \*(SDalias_chk +\% +.in -.5i +.SH DESCRIPTION +New management functions in the management dish. +.br +Add_alias attempts to add the first argument to the database as an +alias to the second argument. +.br + +.br +Del_alias removes the alias specified. +.br + +.br +Alias_chk checks the object specified or checks all aliases below the object +specified if the object is a leaf or not. It checks to see if and only if +the four types of object that are allowed are present, that the aliased +object points back to this alias, and that the schema of the aliased object +fits. +.LP +Examples of valid arguments are: +.in +.5i +add_alias cn=newalias cn=incads +.br +add_alias cn=newalias +.br +add_alias cn=newalias (ie @c=GB@o=Brunel) +.br + +.br +del_alias cn=newalias +.br +del_alias 1 +.br +del_alias (ie @c=GB@o=Brunel) +.br + +.br +alias_chk cn=newalias +.br +alias_chk 1 +.br +alias_chk (ie @c=GB@o=Cambridge University) +.br +.in -.5i +.SH "SEE ALSO" +.br +dish(1) +.br +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.SH AUTHOR +Steve Titcombe, UCL 1991 diff --git a/usr/src/contrib/isode/others/quipu/uips/manage/add_alias.c b/usr/src/contrib/isode/others/quipu/uips/manage/add_alias.c new file mode 100644 index 0000000000..2bc2b25d4a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/manage/add_alias.c @@ -0,0 +1,522 @@ +/* add_alias.c - a mutilated add.c*/ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/manage/RCS/add_alias.c,v 7.3 91/02/22 09:32:00 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/manage/RCS/add_alias.c,v 7.3 91/02/22 09:32:00 mrose Interim $ + * + * + * $Log: add_alias.c,v $ + * Revision 7.3 91/02/22 09:32:00 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/24 14:43:12 mrose + * update + * + * Revision 7.1 90/07/27 08:47:16 mrose + * update + * + * Revision 7.0 90/06/26 14:52:31 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/dua.h" +#include "quipu/add.h" +#include "quipu/entry.h" +#include "quipu/compare.h" +#include "quipu/modify.h" + +#define ORG_PERSON "thornPerson & quipuObject" + /* this should probably go elsewhere !!! */ + +extern DN dn; +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt; +extern PS rps; +extern Entry current_entry; +static char new_draft; + +call_add_alias (argc, argv) +int argc; +char **argv; +{ + DN oj_dn, aoj_dn ; + DN save_dn, dnptr, trail ; + DN moddn; +extern DN str2dn_aux() ; +extern DN sequence_dn() ; + Entry entry_ptr; + FILE *fd; + PS tmp ; + PS str_ps; + char str_buffer[1000]; + char fname[128]; + char alias = FALSE ; + + struct ds_addentry_arg add_arg; + struct DSError error; + struct DSError compare_error; + struct ds_compare_result compare_result; + struct ds_compare_arg compare_arg; + struct ds_modifyentry_arg mod_arg; + struct DSError mod_error; + struct entrymod *emnew ; + + AV_Sequence objClassAVS ; + AV_Sequence treeStrAVS = NULLAV; + Attr_Sequence get_attributes(); + + extern int parse_status; + + int draft_flag = 0; + char *home; + char objectname[80] ; + char aliasobjectname[160] ; + char *contact_compare[6] ; + char *contact_showentry[6] ; + char *contact_modify[1] ; + + contact_compare[0] = "compare" ; + contact_compare[1] = ""; + contact_compare[2] = "-attribute"; + contact_compare[4] = "-noprint"; + contact_compare[5] = "-dontdereferencealias" ; + contact_showentry[0] = "showentry"; + contact_showentry[1] = "-noshow" ; + contact_showentry[2] = "-all" ; + contact_showentry[3] = "-nokey" ; + contact_showentry[4] = "-dontdereferencealias"; + contact_modify[0] = "modify" ; + + emnew = em_alloc() ; + if (argc < 3) + { + ps_printf(OPT, "Not enough arguments.\n") ; + Usage (argv[0]) ; + return ; + } + contact_showentry[5] = (char *) malloc ((unsigned)strlen(argv[2])+1) ; + (void)strcpy(contact_showentry[5], argv[2]) ; + + contact_compare[3] = (char *) malloc ((unsigned)strlen("objectClass=alias.")) ; + (void)strcpy(contact_compare[3], "objectClass=alias") ; + + if (service_control (OPT, 6, contact_compare, &compare_arg.cma_common) == -1) + { + ps_print(OPT, "Problems with compare service control flags.\n") ; + return ; + } + + if (home = getenv ("HOME")) + (void) sprintf (fname, "%s/.dishdraft", home); + else + (void) strcpy (fname, "./.dishdraft"); + new_draft = FALSE; + + if ((argc = service_control (OPT, argc, argv, &add_arg.ada_common)) == -1) + return ; + + (void)strcpy(objectname, argv[1]) ; + (void)strcpy(aliasobjectname, argv[2]) ; + + /* Turn a sequence number back into a DN */ + if (*aliasobjectname >= '0' && *aliasobjectname <= '9') + { + /* First convert the number into a dn */ + aoj_dn = dn_cpy(sequence_dn(atoi(aliasobjectname))) ; + } + else + { + if (*aliasobjectname == '.') + { + ps_print(OPT, "..@ gives me a headache. Ambiguous. Abort... \n") ; + return ; + } + + if (*aliasobjectname == '@') + { + aoj_dn = dn_cpy(str2dn(aliasobjectname + 1)) ; + } + else + { + /*aoj_dn = dn_cpy(dn) ; + *dn_append(aoj_dn, dn_cpy(str2dn(aliasobjectname))) ; + */ + save_dn = str2dn_aux(aliasobjectname,&alias) ; + if (save_dn != NULLDN) + { + if (alias) + { + aoj_dn = dn_cpy(save_dn); + } + else + { + if (dn == NULLDN) + { + aoj_dn = dn_cpy(save_dn) ; + } + else + { + aoj_dn = dn_cpy(dn) ; + dn_append (aoj_dn,dn_cpy(save_dn)); + } + } + } + dn_free(save_dn) ; + } + } + + if (*objectname >= '0' && *objectname <= '9') + { + /* First convert the number into a dn */ + oj_dn = dn_cpy(sequence_dn(atoi(objectname))) ; + } + else + { + if (*objectname == '.') + { + ps_print(OPT, "..@ gives me a headache. Ambiguous. Abort... \n") ; + return ; + } + + if (*objectname == '@') + { + oj_dn = dn_cpy(str2dn(objectname + 1)) ; + } + else + { + oj_dn = dn_cpy(dn) ; + dn_append(oj_dn, dn_cpy(str2dn(objectname))) ; + } + } + + save_dn = dn_cpy(dn) ; + dn_free(dn) ; + dn = dn_cpy(aoj_dn) ; + ps_print(OPT, "Trying to move to ") ; + dn_print(OPT, dn, EDBOUT) ; + ps_print(OPT, ".\n") ; + if (test_move_dn() != TRUE) + { + ps_print(OPT, "Can't move to ") ; + dn_print(OPT, dn, EDBOUT) ; + ps_print(OPT, ".\nAborting.\n") ; + return ; + } + compare_arg.cma_object = aoj_dn; + if (get_ava (&compare_arg.cma_purported, "objectClass", "alias") != OK) + { + ps_print(OPT, "Oops, 'objectClass=alias' is a bad attribute!\n") ; + ps_print(OPT, "This is very bad...\n") ; + return ; + } + + if (rebind () != OK) + return ; + + while (ds_compare (&compare_arg, &compare_error, &compare_result) != DS_OK) + { + if (dish_error (OPT, &compare_error) == 0) + { + return ; + } + compare_arg.cma_object = compare_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + if ( compare_result.cmr_matched == 1 ) /* if is an alias, abort. */ + { + ps_printf(OPT, "Sorry, %s is an alias.\nAliasing to aliases is illegal.\n", aliasobjectname) ; + return ; + } + + /* Now we want to discover the objectClass of our object, and make + * sure that this will be OK when we add in the alias. (ie fitting + * in with the treeStructure.) + */ + + /* stick the aliasobjectname into the cache so we can read + * bits of information from it. + */ + + call_showentry(6, contact_showentry) ; + contact_showentry[5] = (char *) malloc ((unsigned)strlen(argv[2])+1) ; + (void)strcpy(contact_showentry[5], argv[2]) ; + + if (current_entry == NULLENTRY) + { + ps_print(OPT, "Can't read ") ; + dn_print(OPT, dn, EDBOUT) ; + ps_print(OPT, " for objectClass attribute. Aborting.\n") ; + return ; + } + else + { + /* Find the objectClass attribute to compare with the tree + * structure of the node we are going to dangle the alias + * from. + * While we are at it, find out how many seeAlso attributes + * are present, so we can decide whether we need to add + * the entire attribute or just another value. + */ + + Attr_Sequence eptr ; + AttributeType a_t = AttrT_new("objectClass") ; + AttributeType a_t2 = AttrT_new("seeAlso") ; + + emnew->em_type = EM_ADDATTRIBUTE ; + for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link) + { + if ( AttrT_cmp (eptr->attr_type, a_t) == 0 ) + { + objClassAVS = avs_cpy(eptr->attr_value); + } + if ( AttrT_cmp (eptr->attr_type, a_t2) == 0 ) + { + emnew->em_type = EM_ADDVALUES ; + } + } + } + if (objClassAVS == NULLAV) + { + ps_print(OPT, "We can't find Object Class.... Aborting.\n") ; + return ; + } + /* We should have got the ObjectClass now, so return to where we were + * and move up a level to grab the tree structure */ + + dn_free(dn) ; + dn = dn_cpy(oj_dn) ; + + for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + trail = dnptr; + dn_comp_free (dnptr); + trail->dn_parent = NULLDN; + + contact_showentry[1] = ( char *) malloc ((unsigned)strlen("-noshow") + 1) ; + (void)strcpy(contact_showentry[1], "-noshow") ; + contact_showentry[2] = ( char *) malloc ((unsigned)strlen("-all") + 1) ; + (void)strcpy(contact_showentry[2], "-all") ; + contact_showentry[3] = ( char *) malloc ((unsigned)strlen("-nokey") + 1) ; + (void)strcpy(contact_showentry[3], "-nokey") ; + contact_showentry[4] = ( char *) malloc ((unsigned)strlen("-dontdereferencealias") + 1) ; + (void)strcpy(contact_showentry[4], "-dontdereferencealias") ; + + call_showentry(5, contact_showentry) ; + + if (current_entry == NULLENTRY) + { + ps_print(OPT, "Can't read ") ; + dn_print(OPT, dn, EDBOUT) ; + ps_print(OPT, " for the treeStructure. Aborting.\n") ; + return ; + } + else + { + Attr_Sequence eptr ; + AttributeType a_t = AttrT_new("treeStructure") ; + + for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link) + { + if ( AttrT_cmp (eptr->attr_type, a_t) == 0 ) + { + treeStrAVS = avs_cpy (eptr->attr_value) ; + } + } + } + + if (treeStrAVS == NULLAV) + { + ps_print(OPT, "Tree Structure Missing in ") ; + dn_print(OPT, dn, EDBOUT) ; + ps_print(OPT, ".\nAssuming that the add will be valid.\n") ; + } + else + { + if (test_schema(treeStrAVS, objClassAVS) != OK) + { + ps_print(OPT, "Not allowed to add this alias here.\n") ; + ps_print(OPT, "It would break the directory schema to add this alias here.\n") ; + return ; + } + } + + /* This is where we have to start being rather careful, previously + * we have just being reading and checking, but now we start to add + * things in, changing in several places. Mistakes => inconsistencies + * ie BAD... + */ + + /* If we reach here, we should have the appropriate arguments, + * one is the new object, + * the other is an existing non-alias-entry object. + * We now write the information to a draft file, and 'whongo' + * the alias into the database. + */ + + /* open the draft file for writing... */ + + if ((fd = fopen (fname, "w")) == (FILE *) NULL) + { + ps_printf (OPT, "Can't open draft entry %s\n", fname); + return ; + } + + (void)fprintf(fd, "aliasedObjectName= ") ; + if ( ((tmp = ps_alloc (std_open)) != NULLPS) && + (std_setup (tmp, fd) != NOTOK) ) + { + dn_print(tmp, aoj_dn, EDBOUT) ; + } + else + { + ps_print(OPT, "Unable to open appropriate ps. Aborting..\n") ; + return ; + } + (void)fprintf(fd, "\nobjectClass= quipuObject & alias & top\n") ; + (void) fclose(fd) ; + + if (move (objectname) != OK) + { + ps_printf (OPT,"Unknown option %s\n",objectname); + return ; + } + + /* now parse the files */ + if ((fd = fopen (fname, "r")) == (FILE *) NULL) { + ps_printf (OPT, "Can't open draft entry %s\n", fname); + return ; + } + entry_ptr = get_default_entry (NULLENTRY); + entry_ptr->e_attributes = get_attributes (fd); + (void) fclose (fd); + if (parse_status != 0) + return ; + + add_arg.ada_object = dn; + for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent) + ; + entry_ptr->e_name = rdn_cpy (moddn->dn_rdn); + add_arg.ada_entry = entry_ptr->e_attributes; + + if (rebind () != OK) { + entry_free (entry_ptr); + return ; + } + + while (ds_addentry (&add_arg, &error) != DS_OK) { + if (dish_error (OPT, &error) == 0) { + entry_free (entry_ptr); + return ; + } + add_arg.ada_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + ps_print (RPS, "Added "); + dn_print (RPS, dn, EDBOUT); + ps_print (RPS, "\n"); + entry_free (entry_ptr); + make_old (fname,draft_flag); + + /* Now we have to add a "seeAlso=" attribute to the */ + + if (service_control(OPT, 1, contact_modify, &mod_arg.mea_common) == -1) + { + ps_printf(OPT, "Add_alias: Badly wrong. Service controls for modify in error...\n") ; + return ; + } + + dn_free(dn) ; + dn = dn_cpy(save_dn) ; + { + AV_Sequence new_avs = avs_comp_alloc() ; + AttributeValue new_AV = AttrV_alloc() ; + + if ((str_ps = ps_alloc(str_open)) == NULLPS) + { + ps_printf(OPT, "Ps alloc for your string failed.\n") ; + return ; + } + if (str_setup (str_ps, str_buffer, 998, 1) == NOTOK) + { + ps_printf (OPT, "str_setup: %s", ps_error (str_ps -> ps_errno)); + ps_free (str_ps); + return ; + } + dn_print(str_ps, oj_dn, EDBOUT) ; + *str_ps->ps_ptr = 0 ; + ps_free(str_ps) ; + + new_AV = AttrV_cpy(str2AttrV(str_buffer, str2syntax("DN"))) ; + new_avs = avs_comp_new(AttrV_cpy(new_AV)) ; + emnew->em_what = as_comp_new(AttrT_new("seeAlso"), new_avs, NULLACL_INFO) ; + } + emnew->em_next = NULLMOD ; + mod_arg.mea_object = aoj_dn; + mod_arg.mea_changes = emnew ; + + if (rebind () != OK) + return ; + +/* + * If this operation is time-stamped, it may have expired while the user + * was editing the entry. Re-calculate the time-stamp. Modify is the only + * dish command where this needs to be done. + */ + + if ((mod_arg.mea_common.ca_security != (struct security_parms *) 0) + && (mod_arg.mea_common.ca_security->sp_time != NULLCP)) + { + char *new_version(); + + free(mod_arg.mea_common.ca_security->sp_time); + mod_arg.mea_common.ca_security->sp_time = new_version(); + } + +/* If security parameters are present, take this to mean that strong + * authentication is required. This disallows 'parms + no signature' + * (pointless) and 'signature + no parms' (security risk). + */ + if (mod_arg.mea_common.ca_security != (struct security_parms *) 0) + { + int encode_DAS_ModifyEntryArgumentData(); + struct signature *sign_operation(); + mod_arg.mea_common.ca_sig = + sign_operation((caddr_t)&mod_arg, + encode_DAS_ModifyEntryArgumentData); + } + + while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK) + { + if (dish_error (OPT, &mod_error) == 0) + { + ps_print(OPT, "Unable to modify ") ; + dn_print(OPT, aoj_dn, EDBOUT) ; + ps_print(OPT, "\n") ; + return ; + } + mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + ps_print (RPS, "Modified "); + dn_print (RPS, aoj_dn, EDBOUT); + ps_print (RPS, "\n"); + delete_cache (aoj_dn); /* re-cache when next read */ + + dn_free(dn) ; + dn = dn_cpy(save_dn) ; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/manage/alias_chk.c b/usr/src/contrib/isode/others/quipu/uips/manage/alias_chk.c new file mode 100644 index 0000000000..9ae731172d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/manage/alias_chk.c @@ -0,0 +1,528 @@ +/* alias_chk.c - checks aliases from position provided downwards. */ +/* A management tool - probably best to run this as a manager. */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/manage/RCS/alias_chk.c,v 7.1 91/02/22 09:32:02 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/manage/RCS/alias_chk.c,v 7.1 90/07/27 08:4 + * + * + * $Log: alias_chk.c,v $ + * Revision 7.1 91/02/22 09:32:02 mrose + * Interim 6.8 + * + * Revision 7.0 91/01/24 14:43:41 mrose + * *** empty log message *** + * + * Revision 7.1 90/07/27 08:47:16 mrose + * update + * + * Revision 7.0 90/06/26 14:52:31 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "quipu/entry.h" +#include "quipu/util.h" +#include "quipu/compare.h" +#include "quipu/ds_search.h" +#include "quipu/read.h" + +#define ORG_PERSON "thornPerson & quipuObject" + /* this should probably go elsewhere !!! */ + +extern DN dn; +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt; +extern PS rps; +extern Entry current_entry; +extern DN sequence_dn(); +extern DN str2dn_aux(); +extern Filter get_filter(); + char **NULLARGV = (char **) 0; + +call_alias_chk(argc, argv) +int argc ; +char **argv ; +{ + struct ds_search_arg search_arg; + struct DSError search_error; + struct ds_search_result search_result; + DN save_dn, tmp_dn = NULLDN; + char alias = FALSE ; + char verify_alias() ; + EntryInfo *ptr ; + + if (argc > 2) + { + ps_print(OPT, "Error, too many arguments..\n") ; + return(NOTOK) ; + } + + if (argc == 2) + { + /* Convert arg 2 to a DN for future use. */ + + /* Turn a sequence number back into a DN */ + if (*argv[1] >= '0' && *argv[1] <= '9') + { + /* First convert the number into a dn */ + tmp_dn = dn_cpy(sequence_dn(atoi(argv[1]))) ; + } + else + { + if (*argv[1] == '.') + { + ps_print(OPT, "..@ gives me a headache. Ambiguous. Aborting.\n") ; + return(NOTOK) ; + } + + if (*argv[1] == '@') + { + tmp_dn = dn_cpy(str2dn(argv[1] + 1)) ; + } + else + { + save_dn = dn_cpy(str2dn_aux(argv[1], &alias)) ; + if (save_dn != NULLDN) + { + if (alias) + { + tmp_dn = dn_cpy(save_dn); + } + else + { + if (dn == NULLDN) + { + tmp_dn = dn_cpy(save_dn) ; + } + else + { + tmp_dn = dn_cpy(dn) ; + dn_append(tmp_dn, dn_cpy(save_dn)); + } + } + dn_free(save_dn) ; + } + } + } + } + + /* We now have the start location in tmp_dn */ + if (tmp_dn != NULLDN) + { + save_dn = dn_cpy(dn) ; /* save start location for later restore */ + dn_free(dn) ; + dn = dn_cpy(tmp_dn) ; + dn_free(tmp_dn) ; + } + + /* dn should be set to a: either current location, or + b: 2nd arg if specified. */ + + /* Is dn a leaf or a non_leaf? */ + { + struct ds_compare_arg compare_arg; + struct DSError compare_error; + struct ds_compare_result compare_result; + + if ((argc = service_control (OPT, argc, argv, &compare_arg.cma_common)) == -1) + return(NOTOK) ; + + compare_arg.cma_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS ; + compare_arg.cma_object = dn; + if (get_ava (&compare_arg.cma_purported, "objectClass", "quipuNonLeafObject") != OK) + { + ps_print(OPT, "Oops, 'objectClass=quipuNonLeafObject' is a bad attribute!\n") ; + ps_print(OPT, "This is very bad...\n") ; + return(NOTOK) ; + } + + if (compare_arg.cma_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + int encode_DAS_CompareArgumentData(); + + compare_arg.cma_common.ca_sig = + sign_operation((caddr_t)&compare_arg, encode_DAS_CompareArgumentData) ; + } + + if (rebind () != OK) + return(NOTOK) ; + + while (ds_compare (&compare_arg, &compare_error, &compare_result) != DS_OK) + { + if (dish_error (OPT, &compare_error) == 0) + { + return(NOTOK) ; + } + compare_arg.cma_object = compare_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + /* If the object is a leaf then check it out and exit... */ + if ( compare_result.cmr_matched == FALSE ) + { + struct DSError read_error; + struct ds_read_result read_result; + struct ds_read_arg read_arg; + + read_arg.rda_eis.eis_allattributes = TRUE ; + read_arg.rda_eis.eis_select = NULLATTR ; + read_arg.rda_eis.eis_infotypes = TRUE ; + + if (service_control (OPT, argc, argv, &read_arg.rda_common) == -1) + { + return(-1) ; + } + read_arg.rda_common.ca_servicecontrol.svc_options + |= SVC_OPT_DONTDEREFERENCEALIAS ; + read_arg.rda_object = dn; + + /* Strong authentication */ + if (read_arg.rda_common.ca_security != + (struct security_parms *) 0) + { + struct signature *sign_operation(); + int encode_DAS_ReadArgumentData(); + + read_arg.rda_common.ca_sig = + sign_operation((caddr_t)&read_arg, + encode_DAS_ReadArgumentData); + } + while (ds_read (&read_arg, &read_error, &read_result) != DS_OK) { + if (dish_error (OPT, &read_error) == 0) + return (-2); + read_arg.rda_object = read_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + if ( verify_alias(&read_result.rdr_entry) != OK ) + { + ps_print(OPT, "Bad Alias.\n") ; + } + return(OK) ; + } + } + + /* Else search the subtree below this current + * position for ALL aliases, and check each one. */ + + /* Sort out the search filter for this. */ + search_arg.sra_baseobject = dn ; + search_arg.sra_subset = SRA_WHOLESUBTREE ; + search_arg.sra_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT ; + search_arg.sra_searchaliases = FALSE ; + search_arg.sra_filter = NULLFILTER ; + + if ((argc = service_control (OPT, argc, argv, &search_arg.sra_common)) == -1) + return(NOTOK); + + if ((search_arg.sra_filter = get_filter("objectClass=alias")) == NULLFILTER) + { + ps_printf (OPT,"Very bad... Filter wrong. Aborting...\n"); + return(NOTOK) ; + } + ps_print(OPT, "Searching... please wait...\n") ; + + if (rebind () != OK) + return(NOTOK); + + /* Strong authentication */ + if (search_arg.sra_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + int encode_DAS_SearchArgumentData(); + + search_arg.sra_common.ca_sig = sign_operation((caddr_t)&search_arg, encode_DAS_SearchArgumentData); + } + + while (ds_search (&search_arg, &search_error, &search_result) != DS_OK) + { + if (dish_error (OPT, &search_error) == 0) + return(NOTOK); + search_arg.sra_baseobject = search_error.ERR_REFERRAL.DSE_ref_candidates->cr_name ; + } + + correlate_search_results (&search_result); + + if (search_result.CSR_entries == NULLENTRYINFO) + { + ps_printf(OPT, "No aliases found...\n"); + return(OK) ; + } + + for (ptr = search_result.CSR_entries; ptr != NULLENTRYINFO; ptr = ptr->ent_next) + { + /* decode it immediately so we only have to do it once. */ + cache_entry (ptr, TRUE, TRUE) ; + if ( verify_alias(ptr) != OK ) + { + ps_print(OPT, "Bad Alias.\n") ; + } + } + + handle_problems (RPS, search_result.CSR_cr,search_result.CSR_limitproblem, TRUE); + filter_free (search_arg.sra_filter); + dn_free(dn) ; + dn = dn_cpy(save_dn) ; + dn_free(save_dn) ; + return(OK) ; +} + +char +verify_alias(alias_entry) +EntryInfo *alias_entry ; +{ + static char *nvec[2] = {"search"}; + struct DSError read_error; + struct ds_read_result read_result; + struct ds_read_arg read_arg; + struct attrcomp *tmp_ent_attr ; + AttributeType at_ojc ; + AttributeType at_aoj ; + AttributeType at_acl ; + AttributeType at_sa ; + AttributeType at_lmt ; + AttributeType at_lmb ; + AttributeType at_trs ; + AttributeType at_c ; + AttributeType at_o ; + AttributeType at_ou ; + AttributeType at_cn ; + + AV_Sequence object_class_of_object ; + AV_Sequence tree_strAVS = NULLAV ; + DN dn_above_alias, trail, dnptr ; + char Name=FALSE, Acl=FALSE, ObjClass=FALSE, AlObjNam=FALSE ; + char BackReference=FALSE ; + char GoodAlias = OK ; + + at_ojc = AttrT_new("objectClass") ; /* objectClass */ + at_aoj = AttrT_new("aliasedObjectName") ; + at_acl = AttrT_new("acl") ; + at_sa = AttrT_new("seeAlso") ; + at_lmt = AttrT_new("lastModifiedTime") ; + at_lmb = AttrT_new("lastModifiedBy") ; + at_trs = AttrT_new("treeStructure") ; + at_c = AttrT_new("countryName") ; + at_o = AttrT_new("organizationName") ; + at_ou = AttrT_new("organizationalUnitName") ; + at_cn = AttrT_new("commonName") ; + nvec[1] = "-compact"; + read_arg.rda_object = NULLDN ; + + ps_print(OPT, "\nFound alias:") ; + dn_print(OPT, alias_entry->ent_dn, EDBOUT) ; + ps_print(OPT, "\n") ; + + /* We now have ourselves an entrystruct which is an alias, and we + * have to check various features!! + * 1: only the allowed objects. + * 2: the seeAlso attribute is correct (ie points to a real entry). + * 3: The objectClass of the real entry fits under where the alias + * lives. + */ + + /* Does the alias have the allowed objects and only the allowed? */ + + for (tmp_ent_attr = alias_entry->ent_attr; tmp_ent_attr != NULL; tmp_ent_attr = tmp_ent_attr->attr_link) + { + if (AttrT_cmp(tmp_ent_attr->attr_type, at_ojc) == 0) + { + ObjClass = TRUE ; + } else + if (AttrT_cmp(tmp_ent_attr->attr_type, at_aoj) == 0) + { + read_arg.rda_object = dn_cpy ((DN) tmp_ent_attr->attr_value->avseq_av.av_struct); + AlObjNam = TRUE ; + } else + if (AttrT_cmp(tmp_ent_attr->attr_type, at_acl) == 0) + { + Acl = TRUE ; + } + else + if (AttrT_cmp(tmp_ent_attr->attr_type, at_lmt) == 0) + { + ; + } + else + if (AttrT_cmp(tmp_ent_attr->attr_type, at_lmb) == 0) + { + ; + } + else + if (AttrT_cmp(tmp_ent_attr->attr_type, at_c) == 0 || + AttrT_cmp(tmp_ent_attr->attr_type, at_o) == 0 || + AttrT_cmp(tmp_ent_attr->attr_type, at_ou) == 0 || + AttrT_cmp(tmp_ent_attr->attr_type, at_cn) == 0) + { + Name = TRUE ; + } + else + { + ps_print(OPT, "Illegal attribute type: ") ; + AttrT_print (OPT, tmp_ent_attr->attr_type, EDBOUT) ; + ps_print(OPT, "\n") ; + GoodAlias = NOTOK; + } + } + + if (read_arg.rda_object == NULLDN ) + { + ps_print(OPT, "Malformed alias. No alias object name present!\n" ) ; + return (NOTOK) ; + } + + if (ObjClass == FALSE) + { + ps_print(OPT, "Object Class missing.\n") ; + } + if (AlObjNam == FALSE) + { + ps_print(OPT, "Alias Object name missing.\n") ; + } + if (Acl == FALSE) + { + ps_print(OPT, "ACL missing.\n") ; + } + if (Name == FALSE) + { + ps_print(OPT, "Name of alias is missing.\n") ; + } + + GoodAlias = ((ObjClass && AlObjNam && Acl && Name) ? OK : NOTOK) ; + /* Read the entry that the alias points to.... */ + read_arg.rda_eis.eis_allattributes = TRUE ; + read_arg.rda_eis.eis_select = NULLATTR ; + read_arg.rda_eis.eis_infotypes = TRUE ; + + if (service_control (OPT, 0, NULLARGV, &read_arg.rda_common) == -1) + { + return(-1) ; + } + read_arg.rda_common.ca_servicecontrol.svc_options + |= SVC_OPT_DONTDEREFERENCEALIAS ; + + /* Strong authentication */ + if (read_arg.rda_common.ca_security != + (struct security_parms *) 0) + { + struct signature *sign_operation(); + int encode_DAS_ReadArgumentData(); + + read_arg.rda_common.ca_sig = + sign_operation((caddr_t)&read_arg, + encode_DAS_ReadArgumentData); + } + while (ds_read (&read_arg, &read_error, &read_result) != DS_OK) { + if (dish_error (OPT, &read_error) == 0) + { + ps_print(OPT, "Can't read ") ; + dn_print(OPT, read_arg.rda_object, EDBOUT) ; + ps_print(OPT, "\n") ; + return (GoodAlias); + } + read_arg.rda_object = read_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + /* and see if it points back to this alias. + * It should do, but doesn't have to. While we are at it, + * collect the objectClass of this entry. + */ + for (tmp_ent_attr = read_result.rdr_entry.ent_attr; tmp_ent_attr != NULL; + tmp_ent_attr = tmp_ent_attr->attr_link) + { + if (AttrT_cmp(tmp_ent_attr->attr_type, at_sa) == 0) + { + AV_Sequence tmp_avs = tmp_ent_attr->attr_value; + + for (; tmp_avs != NULL; tmp_avs = tmp_avs->avseq_next) + { + if (dn_cmp((DN) tmp_avs->avseq_av.av_struct, alias_entry->ent_dn)) + { + ps_print(OPT, "Alias object correctly points back to alias itself.\n") ; + BackReference = TRUE ; + } + } + } + else + if (AttrT_cmp(tmp_ent_attr->attr_type, at_ojc) == 0) + { + object_class_of_object = avs_cpy(tmp_ent_attr->attr_value) ; + } + } + if (BackReference == FALSE) + { + ps_print(OPT, "Alias object should point back to alias.\n") ; + } + + if (object_class_of_object == NULLAV) + { + ps_print(OPT, "Can't find object class of aliased object\n. Assuming OK\n") ; + return(GoodAlias) ; + } + /* Move above the alias in order to find the treeStructure. */ + dn_above_alias = dn_cpy(alias_entry->ent_dn) ; + for (dnptr = dn_above_alias; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + trail = dnptr; + dn_comp_free (dnptr); + trail->dn_parent = NULLDN; + + /* Now read it... */ + read_arg.rda_object = dn_cpy(dn_above_alias) ; + /* Strong authentication */ + if (read_arg.rda_common.ca_security != + (struct security_parms *) 0) + { + struct signature *sign_operation(); + int encode_DAS_ReadArgumentData(); + + read_arg.rda_common.ca_sig = + sign_operation((caddr_t)&read_arg, + encode_DAS_ReadArgumentData); + } + while (ds_read (&read_arg, &read_error, &read_result) != DS_OK) { + if (dish_error (OPT, &read_error) == 0) + return (-2); + read_arg.rda_object = read_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + for (tmp_ent_attr = read_result.rdr_entry.ent_attr; tmp_ent_attr != NULL; + tmp_ent_attr = tmp_ent_attr->attr_link) + { + if (AttrT_cmp(tmp_ent_attr->attr_type, at_trs) == 0) + { + tree_strAVS = avs_cpy(tmp_ent_attr->attr_value) ; + } + } + + if (tree_strAVS == NULLAV) + { + ps_print(OPT, "Tree structure missing - assuming validity.\n") ; + } + else + if (test_schema(tree_strAVS, object_class_of_object) != OK) + { + ps_print(OPT, "Tree structure bad...\n") ; + GoodAlias = NOTOK ; + } + return (GoodAlias) ; +} + +shadow_entry() +{ + ; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/manage/del_alias.c b/usr/src/contrib/isode/others/quipu/uips/manage/del_alias.c new file mode 100644 index 0000000000..e406430dc1 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/manage/del_alias.c @@ -0,0 +1,425 @@ +/* del_alias.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/manage/RCS/del_alias.c,v 7.3 91/02/22 09:32:03 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/manage/RCS/del_alias.c,v 7.3 91/02/22 09:32:03 mrose Interim $ + * + * + * $Log: del_alias.c,v $ + * Revision 7.3 91/02/22 09:32:03 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/24 14:43:14 mrose + * update + * + * Revision 7.1 90/07/27 08:47:19 mrose + * update + * + * Revision 7.0 90/06/26 14:52:33 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/remove.h" +#include "quipu/compare.h" +#include "quipu/modify.h" + +extern DN dn; +extern char frompipe; +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern PS opt; +extern PS rps; +extern Entry current_entry ; + +call_del_alias (argc, argv) +int argc; +char **argv; +{ + DN dnptr, aoj_dn, oj_dn, save_dn; + DN trail = NULLDN ; +extern DN str2dn_aux() ; +extern DN sequence_dn () ; + PS str_ps ; + char *str_buffer ; + char alias = FALSE ; + int mod_failed = 0 ; + AV_Sequence aliObjNameAVS ; + struct entrymod *emnew ; + struct DSError compare_error; + struct ds_compare_result compare_result; + struct ds_compare_arg compare_arg; + struct ds_removeentry_arg remove_arg; + struct ds_modifyentry_arg mod_arg; + struct DSError mod_error; + struct DSError error; + char objectname[80] ; + char *contact_compare[6] ; + char *contact_showentry[6] ; + char *contact_modify[1] ; + contact_compare[0] = "compare" ; + contact_compare[1] = ""; + contact_compare[2] = "-attribute"; + contact_compare[4] = "-noprint"; + contact_compare[5] = "-dontdereferencealias" ; + contact_showentry[0] = "showentry"; + contact_showentry[1] = "-noshow" ; + contact_showentry[2] = "-all" ; + contact_showentry[3] = "-nokey" ; + contact_showentry[4] = "-dontdereferencealias"; + contact_modify[0] = "modify" ; + + emnew = em_alloc() ; + str_buffer = (char *) malloc ((unsigned)1000) ; + contact_showentry[5] = (char *) malloc ((unsigned)strlen(argv[1])) ; + (void)strcpy(contact_showentry[5], argv[1]+1) ; + + contact_compare[3] = (char *) malloc ((unsigned)strlen("objectClass=alias.")) ; + (void)strcpy(contact_compare[3], "objectClass=alias") ; + + if ((argc = service_control (OPT, argc, argv, &remove_arg.rma_common)) == -1) + return ; + + if (argc > 2) + { + ps_printf (OPT,"Too many arguments. Aborting...\n"); + Usage (argv[0]); + return ; + } + + if (argc == 1) + { + ps_printf (OPT,"Delete what???\n") ; + Usage (argv[0]) ; + return ; + } + + (void)strcpy(objectname,argv[1]) ; + contact_compare[1] = argv[1] ; + + if (service_control (OPT, 6, contact_compare, &compare_arg.cma_common) == -1) + { + ps_print(OPT, "Problems with compare service control flags.\n") ; + return ; + } + + /* Turn a sequence number back into a DN */ + if (*objectname >= '0' && *objectname <= '9') + { + /* First convert the number into a dn */ + oj_dn = dn_cpy(sequence_dn(atoi(objectname))) ; + } + else + { + if (*objectname == '.') + { + ps_print(OPT, "..@ gives me a headache. Ambiguous. Aborting.\n") ; + return ; + } + if (*objectname == '@') + { + oj_dn = dn_cpy(str2dn(objectname + 1)) ; + } + else + { + /*oj_dn = dn_cpy(dn) ; + *dn_append(oj_dn, dn_cpy(str2dn(objectname))) ; + */ + save_dn = str2dn_aux(objectname,&alias) ; + if (save_dn != NULLDN) + { + if (alias) + { + oj_dn = dn_cpy(save_dn); + } + else + { + if (dn == NULLDN) + { + oj_dn = dn_cpy(save_dn) ; + } + else + { + oj_dn = dn_cpy(dn) ; + dn_append (oj_dn,dn_cpy(save_dn)); + } + } + } + dn_free(save_dn) ; + } + } + + if (get_ava (&compare_arg.cma_purported, "objectClass", "alias") != OK) + { + ps_print(OPT, "Oops, 'objectClass=alias' is a bad attribute!\n") ; + ps_print(OPT, "This is very bad...\n") ; + return ; + } + + save_dn = dn_cpy(dn) ; + dn = dn_cpy(oj_dn) ; + compare_arg.cma_object = oj_dn; + + if (rebind () != OK) + return ; + + /* Strong authentication */ + if (compare_arg.cma_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + int encode_DAS_CompareArgumentData(); + + compare_arg.cma_common.ca_sig = + sign_operation((caddr_t)&compare_arg, encode_DAS_CompareArgumentData) ; + } + + while (ds_compare (&compare_arg, &compare_error, &compare_result) != DS_OK) + { + if (dish_error (OPT, &compare_error) == 0) + { + return ; + } + compare_arg.cma_object = compare_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + if (compare_result.cmr_matched == FALSE) + { + ps_printf(OPT, "Sorry, object is not an alias. Aborting.\n") ; + return ; + } + + call_showentry(5, contact_showentry) ; + + if (current_entry == NULLENTRY) + { + (void)fprintf(stderr, "we have no current entry. No wonder!\n") ; + } + else + { + Attr_Sequence eptr ; + AttributeType a_t = AttrT_new("aliasedObjectName") ; + + for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link) + { + if ( AttrT_cmp (eptr->attr_type, a_t) == 0 ) + { + aliObjNameAVS = avs_cpy(eptr->attr_value); + } + } + } + if (aliObjNameAVS == NULLAV) + { + ps_print(OPT, "Can't find 'aliasedObjectName' attribute type.\n") ; + ps_print(OPT, "Are you sure that this is an alias? Aborting.\n") ; + return ; + } + + /* Now we have the other end of the alias in AttrValue format, + * convert it into a DN, so we can modify it. + */ + + if ((str_ps = ps_alloc(str_open)) == NULLPS) + { + ps_printf(OPT, "Ps alloc for your string failed.\n") ; + return ; + } + if (str_setup (str_ps, str_buffer, 998, 1) == NOTOK) + { + ps_printf (OPT, "str_setup: %s", ps_error (str_ps -> ps_errno)); + ps_free (str_ps); + return ; + } + + avs_print(str_ps, aliObjNameAVS, EDBOUT) ; + *str_ps->ps_ptr = 0 ; + ps_free (str_ps) ; + { + char *ptr_local = str_buffer ; + while(*ptr_local !=0 && *ptr_local != '\n') + ptr_local++ ; + *ptr_local = '\0' ; + } + aoj_dn = str2dn(str_buffer) ; + + /* We now have converted a string to DN and we now have to form the + * attribute "seeAlso=", put it into the modify attributes + * and delete that attribute from the other end of the alias. + */ + + if (service_control(OPT, 1, contact_modify, &mod_arg.mea_common) == -1) + { + ps_printf(OPT, "Del_alias: Badly wrong. Service controls for modify in error...\n") ; + return ; + } + + dn_free(dn) ; + dn = dn_cpy(aoj_dn) ; + contact_showentry[1] = ( char *) malloc ((unsigned)strlen("-noshow") + 1) ; + (void)strcpy(contact_showentry[1], "-noshow") ; + contact_showentry[2] = ( char *) malloc ((unsigned)strlen("-all") + 1) ; + (void)strcpy(contact_showentry[2], "-all") ; + contact_showentry[3] = ( char *) malloc ((unsigned)strlen("-nokey") + 1) ; + (void)strcpy(contact_showentry[3], "-nokey") ; + contact_showentry[4] = ( char *) malloc ((unsigned)strlen("-dontdereferencealias") + 1) ; + (void)strcpy(contact_showentry[4], "-dontdereferencealias") ; + + call_showentry(5, contact_showentry) ; + if (current_entry == NULLENTRY) + { + (void)fprintf(stderr, "we have no current entry. No wonder!\n") ; + } + else + { + Attr_Sequence eptr ; + AttributeType a_t = AttrT_new("seeAlso") ; + + emnew->em_type = -1 ; + for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link) + { + if ( AttrT_cmp (eptr->attr_type, a_t) == 0 ) + { + if (emnew->em_type == -1) + { + emnew->em_type = EM_REMOVEATTRIBUTE ; + } + else + { + emnew->em_type = EM_REMOVEVALUES ; + } + } + } + if (emnew->em_type == -1) + { + ps_print(OPT, "INVALID set of entries for the alias object\n") ; + ps_print(OPT, "Aborting...\n") ; + return ; + } + } + + { + AV_Sequence new_avs = avs_comp_alloc() ; + AttributeValue new_AV = AttrV_alloc() ; + + str_buffer = (char *) malloc ((unsigned)1000) ; + if ((str_ps = ps_alloc(str_open)) == NULLPS) + { + ps_printf(OPT, "Ps alloc for your string failed.\n") ; + return ; + } + if (str_setup (str_ps, str_buffer, 998, 1) == NOTOK) + { + ps_printf (OPT, "str_setup: %s", ps_error (str_ps -> ps_errno)); + ps_free (str_ps); + return ; + } + + dn_print(str_ps, oj_dn, EDBOUT) ; + *str_ps->ps_ptr = 0 ; + ps_free(str_ps) ; + + new_AV = AttrV_cpy(str2AttrV(str_buffer, str2syntax("DN"))) ; + new_avs = avs_comp_new(AttrV_cpy(new_AV)) ; + emnew->em_what = as_comp_new(AttrT_new("seeAlso"), new_avs, NULLACL_INFO) ; + } + emnew->em_next = NULLMOD ; + mod_arg.mea_object = aoj_dn; + mod_arg.mea_changes = emnew ; + + if (rebind () != OK) + return ; + +/* + * If this operation is time-stamped, it may have expired while the user + * was editing the entry. Re-calculate the time-stamp. Modify is the only + * dish command where this needs to be done. + */ + + if ((mod_arg.mea_common.ca_security != (struct security_parms *) 0) + && (mod_arg.mea_common.ca_security->sp_time != NULLCP)) + { + char *new_version(); + + free(mod_arg.mea_common.ca_security->sp_time); + mod_arg.mea_common.ca_security->sp_time = new_version(); + } + +/* If security parameters are present, take this to mean that strong + * authentication is required. This disallows 'parms + no signature' + * (pointless) and 'signature + no parms' (security risk). + */ + if (mod_arg.mea_common.ca_security != (struct security_parms *) 0) + { + int encode_DAS_ModifyEntryArgumentData(); + struct signature *sign_operation(); + mod_arg.mea_common.ca_sig = + sign_operation((caddr_t)&mod_arg, + encode_DAS_ModifyEntryArgumentData); + } + + while (ds_modifyentry (&mod_arg, &mod_error) != DS_OK) + { + if (dish_error (OPT, &mod_error) == 0) + { + ps_print(OPT, "Unable to modify ") ; + dn_print(OPT, aoj_dn, EDBOUT) ; + ps_print(OPT, "\nContinuing to delete alias...") ; + mod_failed = 1 ; + } + mod_arg.mea_object = mod_error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + if (!mod_failed) + { + ps_print (RPS, "Modified "); + dn_print (RPS, aoj_dn, EDBOUT); + ps_print (RPS, "\n"); + delete_cache (aoj_dn); /* re-cache when next read */ + } + + dn_free(dn) ; + dn = dn_cpy(save_dn) ; + + if (move (objectname) == OK) + argc--; + + remove_arg.rma_object = dn; + + if (rebind () != OK) + return ; + + while (ds_removeentry (&remove_arg, &error) != DS_OK) + { + if (dish_error (OPT, &error) == 0) + return ; + remove_arg.rma_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + ps_print (RPS, "Removed "); + dn_print (RPS, dn, EDBOUT); + delete_cache (dn); + for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + trail = dnptr; + + if (trail != NULLDN) + trail->dn_parent = NULLDN; + else + dn = NULLDN; + + dn_comp_free (dnptr); + ps_print (RPS, "\n"); +} diff --git a/usr/src/contrib/isode/others/quipu/uips/manage/make b/usr/src/contrib/isode/others/quipu/uips/manage/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/manage/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/Makefile b/usr/src/contrib/isode/others/quipu/uips/pod/Makefile new file mode 100644 index 0000000000..c1c0da4413 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/Makefile @@ -0,0 +1,405 @@ +############################################################################### +# +# $Header: /f/osi/others/quipu/uips/pod/RCS/Makefile,v 7.4 91/02/22 09:31:18 mrose Interim $ +# +############################################################################### + +#X app-defaults directory. +APPDEFDIR = /usr/lib/X11/app-defaults + +#yacc flags +YFLAGS = -d + + +############################################################################### +# +# Files and libraries. +# +############################################################################### + +ISOLIBS = $(TOPDIR)libdsap.a $(TOPDIR)libisode.a \ + $(TOPDIR)others/quipu/photo/libphoto.a + +XLIBS = -lXaw -lXmu -lXt -lX11 -lXext + +LIBES = $(ISOLIBS) $(XLIBS) +LLIBS = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode + +CFILES = y.tab.c calls.c main.c pod.c filt.c sequence.c \ + photo.c list.c read.c search.c modify.c dir_entry.c util.c +OFILES = y.tab.o calls.o main.o pod.o filt.o sequence.o \ + photo.o list.o read.o search.o modify.o dir_entry.o util.o +TESTOFILES = y.tab.o testcalls.o main.o pod.o filt.o sequence.o \ + photo.o list.o read.o search.o modify.o dir_entry.o util.o + +YFILES = conf_read.y + +############################################################################### +# Here it is... +############################################################################### + +all: xpod +inst-all: inst-pod manuals help appdefs config +install: inst-all clean +lint: l-pod + + +############################################################################## +# pod +############################################################################## + + +inst-pod: $(BINDIR)pod + -mkdir $(ETCDIR)xd + +$(BINDIR)pod: xpod + -cp $@ zxpod + -rm -f $@ + cp xpod $@ + -@ls -gls $@ + -@echo "" + +xpod: $(OFILES) $(ISOLIBS) + $(LDCC) $(LDFLAGS) -o $@ $(OFILES) \ + $(LIBDSAP) $(TOPDIR)others/quipu/photo/libphoto.a $(LIBISODE) \ + $(XLIBS) $(LSOCKET) + +l-pod: $(CFILES) + $(LINT) $(LFLAGS) $(LLIBS) $(CFILES) \ + | grep -v "warning: possible pointer alignment problem" + +#testpod: $(TESTOFILES) +# $(LDCC) $(LDFLAGS) -o $@ $(TESTOFILES) $(LIBES) + +#testcalls.o: +# $(CC) $(CFLAGS) -DTESTPOD -c calls.c -o testcalls.o + +y.tab.c: conf_read.y + yacc $(YFLAGS) conf_read.y + +############################################################################### +# config files +############################################################################### + +config:; -mkdir $(ETCDIR)xd/duaconfig + -cp -r Xd/duaconfig/* $(ETCDIR)xd/duaconfig + -@echo "" + +############################################################################### +# app-defaults +############################################################################### + +appdefs:; -cp Pod.ad $(APPDEFDIR)/Pod + +############################################################################### +# manual pages +############################################################################### + +MANUALS = pod.1c + +manuals:; + @$(UTILDIR)inst-man.sh $(MANOPTS) pod.1c + @$(UTILDIR)inst-man.sh $(MANOPTS) pod.5 + -@echo "" + +############################################################################### +# help +############################################################################### + +help:; -mkdir $(ETCDIR)xd/podHelpdir + cp Xd/podHelpdir/* $(ETCDIR)xd/podHelpdir + -@ls -gls $(ETCDIR)xd/podHelpdir + -@echo "" + + +############################################################################### +# clean +############################################################################### + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig \ + core $(CLEANSTRINGS) y.tab.c y.tab.h + +grind:; iprint Makefile + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; + +# DO NOT DELETE BELOW THIS LINE +# Dependencies follow +calls.o: ../../../../h/config.h +calls.o: ../../../../h/general.h +calls.o: ../../../../h/isoaddrs.h +calls.o: ../../../../h/logger.h +calls.o: ../../../../h/manifest.h +calls.o: ../../../../h/psap.h +calls.o: ../../../../h/quipu/abandon.h +calls.o: ../../../../h/quipu/add.h +calls.o: ../../../../h/quipu/attr.h +calls.o: ../../../../h/quipu/attrvalue.h +calls.o: ../../../../h/quipu/authen.h +calls.o: ../../../../h/quipu/bind.h +calls.o: ../../../../h/quipu/common.h +calls.o: ../../../../h/quipu/commonarg.h +calls.o: ../../../../h/quipu/compare.h +calls.o: ../../../../h/quipu/config.h +calls.o: ../../../../h/quipu/dap.h +calls.o: ../../../../h/quipu/ds_error.h +calls.o: ../../../../h/quipu/ds_search.h +calls.o: ../../../../h/quipu/dsp.h +calls.o: ../../../../h/quipu/entry.h +calls.o: ../../../../h/quipu/list.h +calls.o: ../../../../h/quipu/modify.h +calls.o: ../../../../h/quipu/modifyrdn.h +calls.o: ../../../../h/quipu/name.h +calls.o: ../../../../h/quipu/oid.h +calls.o: ../../../../h/quipu/read.h +calls.o: ../../../../h/quipu/remove.h +calls.o: ../../../../h/quipu/util.h +calls.o: ../../../../h/tailor.h +calls.o: ../../../../h/usr.dirent.h +calls.o: ./defs.h +calls.o: ./filt.h +calls.o: ./sequence.h +calls.o: ./util.h +dir_entry.o: ./defs.h +dir_entry.o: ./dir_entry.h +filt.o: ../../../../h/config.h +filt.o: ../../../../h/general.h +filt.o: ../../../../h/isoaddrs.h +filt.o: ../../../../h/logger.h +filt.o: ../../../../h/manifest.h +filt.o: ../../../../h/psap.h +filt.o: ../../../../h/quipu/abandon.h +filt.o: ../../../../h/quipu/add.h +filt.o: ../../../../h/quipu/attr.h +filt.o: ../../../../h/quipu/attrvalue.h +filt.o: ../../../../h/quipu/authen.h +filt.o: ../../../../h/quipu/bind.h +filt.o: ../../../../h/quipu/common.h +filt.o: ../../../../h/quipu/commonarg.h +filt.o: ../../../../h/quipu/compare.h +filt.o: ../../../../h/quipu/config.h +filt.o: ../../../../h/quipu/dap.h +filt.o: ../../../../h/quipu/ds_error.h +filt.o: ../../../../h/quipu/ds_search.h +filt.o: ../../../../h/quipu/dsp.h +filt.o: ../../../../h/quipu/entry.h +filt.o: ../../../../h/quipu/list.h +filt.o: ../../../../h/quipu/modify.h +filt.o: ../../../../h/quipu/modifyrdn.h +filt.o: ../../../../h/quipu/name.h +filt.o: ../../../../h/quipu/oid.h +filt.o: ../../../../h/quipu/read.h +filt.o: ../../../../h/quipu/remove.h +filt.o: ../../../../h/quipu/util.h +filt.o: ./defs.h +filt.o: ./filt.h +filt.o: ./y.tab.h +list.o: ../../../../h/config.h +list.o: ../../../../h/general.h +list.o: ../../../../h/isoaddrs.h +list.o: ../../../../h/logger.h +list.o: ../../../../h/manifest.h +list.o: ../../../../h/psap.h +list.o: ../../../../h/quipu/abandon.h +list.o: ../../../../h/quipu/add.h +list.o: ../../../../h/quipu/attr.h +list.o: ../../../../h/quipu/attrvalue.h +list.o: ../../../../h/quipu/authen.h +list.o: ../../../../h/quipu/bind.h +list.o: ../../../../h/quipu/common.h +list.o: ../../../../h/quipu/commonarg.h +list.o: ../../../../h/quipu/compare.h +list.o: ../../../../h/quipu/config.h +list.o: ../../../../h/quipu/dap.h +list.o: ../../../../h/quipu/ds_error.h +list.o: ../../../../h/quipu/ds_search.h +list.o: ../../../../h/quipu/dsp.h +list.o: ../../../../h/quipu/entry.h +list.o: ../../../../h/quipu/list.h +list.o: ../../../../h/quipu/modify.h +list.o: ../../../../h/quipu/modifyrdn.h +list.o: ../../../../h/quipu/name.h +list.o: ../../../../h/quipu/oid.h +list.o: ../../../../h/quipu/read.h +list.o: ../../../../h/quipu/remove.h +list.o: ../../../../h/quipu/util.h +list.o: ./defs.h +list.o: ./filt.h +list.o: ./sequence.h +main.o: ../../../../h/config.h +main.o: ../../../../h/general.h +main.o: ../../../../h/isoaddrs.h +main.o: ../../../../h/logger.h +main.o: ../../../../h/manifest.h +main.o: ../../../../h/psap.h +main.o: ../../../../h/quipu/abandon.h +main.o: ../../../../h/quipu/add.h +main.o: ../../../../h/quipu/attr.h +main.o: ../../../../h/quipu/attrvalue.h +main.o: ../../../../h/quipu/authen.h +main.o: ../../../../h/quipu/bind.h +main.o: ../../../../h/quipu/common.h +main.o: ../../../../h/quipu/commonarg.h +main.o: ../../../../h/quipu/compare.h +main.o: ../../../../h/quipu/config.h +main.o: ../../../../h/quipu/dap.h +main.o: ../../../../h/quipu/ds_error.h +main.o: ../../../../h/quipu/ds_search.h +main.o: ../../../../h/quipu/dsp.h +main.o: ../../../../h/quipu/dua.h +main.o: ../../../../h/quipu/entry.h +main.o: ../../../../h/quipu/list.h +main.o: ../../../../h/quipu/modify.h +main.o: ../../../../h/quipu/modifyrdn.h +main.o: ../../../../h/quipu/name.h +main.o: ../../../../h/quipu/oid.h +main.o: ../../../../h/quipu/photo.h +main.o: ../../../../h/quipu/read.h +main.o: ../../../../h/quipu/remove.h +main.o: ../../../../h/quipu/util.h +main.o: ./defs.h +main.o: ./pod.h +main.o: ./sequence.h +modify.o: ../../../../h/config.h +modify.o: ../../../../h/general.h +modify.o: ../../../../h/isoaddrs.h +modify.o: ../../../../h/logger.h +modify.o: ../../../../h/manifest.h +modify.o: ../../../../h/psap.h +modify.o: ../../../../h/quipu/abandon.h +modify.o: ../../../../h/quipu/add.h +modify.o: ../../../../h/quipu/attr.h +modify.o: ../../../../h/quipu/attrvalue.h +modify.o: ../../../../h/quipu/authen.h +modify.o: ../../../../h/quipu/bind.h +modify.o: ../../../../h/quipu/common.h +modify.o: ../../../../h/quipu/commonarg.h +modify.o: ../../../../h/quipu/compare.h +modify.o: ../../../../h/quipu/config.h +modify.o: ../../../../h/quipu/dap.h +modify.o: ../../../../h/quipu/ds_error.h +modify.o: ../../../../h/quipu/ds_search.h +modify.o: ../../../../h/quipu/dsp.h +modify.o: ../../../../h/quipu/entry.h +modify.o: ../../../../h/quipu/list.h +modify.o: ../../../../h/quipu/modify.h +modify.o: ../../../../h/quipu/modifyrdn.h +modify.o: ../../../../h/quipu/name.h +modify.o: ../../../../h/quipu/oid.h +modify.o: ../../../../h/quipu/read.h +modify.o: ../../../../h/quipu/remove.h +modify.o: ../../../../h/quipu/util.h +modify.o: ./defs.h +modify.o: ./dir_entry.h +modify.o: ./sequence.h +modify.o: ./util.h +photo.o: ../../../../h/quipu/photo.h +photo.o: ./defs.h +photo.o: ./pod.h +photo.o: ./sequence.h +pod.o: ../../../../h/config.h +pod.o: ../../../../h/general.h +pod.o: ../../../../h/manifest.h +pod.o: ./bitmap +pod.o: ./bitmaps/About +pod.o: ./bitmaps/AboutPress +pod.o: ./bitmaps/Close +pod.o: ./bitmaps/ClosePress +pod.o: ./bitmaps/Help +pod.o: ./bitmaps/HelpPress +pod.o: ./bitmaps/History +pod.o: ./bitmaps/HistoryPress +pod.o: ./bitmaps/Keep +pod.o: ./bitmaps/KeepPress +pod.o: ./bitmaps/Kept +pod.o: ./bitmaps/List +pod.o: ./bitmaps/ListPress +pod.o: ./bitmaps/Modify +pod.o: ./bitmaps/ModifyPress +pod.o: ./bitmaps/Okay +pod.o: ./bitmaps/OkayPress +pod.o: ./bitmaps/Quit +pod.o: ./bitmaps/QuitPress +pod.o: ./bitmaps/Search +pod.o: ./bitmaps/SearchPress +pod.o: ./bitmaps/ShowAll +pod.o: ./bitmaps/ShowAllPress +pod.o: ./bitmaps/icon +pod.o: ./bitmaps/menuicon +pod.o: ./defs.h +pod.o: ./dir_entry.h +pod.o: ./pod.h +pod.o: ./sequence.h +read.o: ../../../../h/config.h +read.o: ../../../../h/general.h +read.o: ../../../../h/isoaddrs.h +read.o: ../../../../h/logger.h +read.o: ../../../../h/manifest.h +read.o: ../../../../h/psap.h +read.o: ../../../../h/quipu/abandon.h +read.o: ../../../../h/quipu/add.h +read.o: ../../../../h/quipu/attr.h +read.o: ../../../../h/quipu/attrvalue.h +read.o: ../../../../h/quipu/authen.h +read.o: ../../../../h/quipu/bind.h +read.o: ../../../../h/quipu/common.h +read.o: ../../../../h/quipu/commonarg.h +read.o: ../../../../h/quipu/compare.h +read.o: ../../../../h/quipu/config.h +read.o: ../../../../h/quipu/dap.h +read.o: ../../../../h/quipu/ds_error.h +read.o: ../../../../h/quipu/ds_search.h +read.o: ../../../../h/quipu/dsp.h +read.o: ../../../../h/quipu/entry.h +read.o: ../../../../h/quipu/list.h +read.o: ../../../../h/quipu/modify.h +read.o: ../../../../h/quipu/modifyrdn.h +read.o: ../../../../h/quipu/name.h +read.o: ../../../../h/quipu/oid.h +read.o: ../../../../h/quipu/read.h +read.o: ../../../../h/quipu/remove.h +read.o: ../../../../h/quipu/util.h +read.o: ./defs.h +read.o: ./sequence.h +read.o: ./util.h +search.o: ../../../../h/config.h +search.o: ../../../../h/general.h +search.o: ../../../../h/isoaddrs.h +search.o: ../../../../h/logger.h +search.o: ../../../../h/manifest.h +search.o: ../../../../h/psap.h +search.o: ../../../../h/quipu/abandon.h +search.o: ../../../../h/quipu/add.h +search.o: ../../../../h/quipu/attr.h +search.o: ../../../../h/quipu/attrvalue.h +search.o: ../../../../h/quipu/authen.h +search.o: ../../../../h/quipu/bind.h +search.o: ../../../../h/quipu/common.h +search.o: ../../../../h/quipu/commonarg.h +search.o: ../../../../h/quipu/compare.h +search.o: ../../../../h/quipu/config.h +search.o: ../../../../h/quipu/dap.h +search.o: ../../../../h/quipu/ds_error.h +search.o: ../../../../h/quipu/ds_search.h +search.o: ../../../../h/quipu/dsp.h +search.o: ../../../../h/quipu/entry.h +search.o: ../../../../h/quipu/list.h +search.o: ../../../../h/quipu/modify.h +search.o: ../../../../h/quipu/modifyrdn.h +search.o: ../../../../h/quipu/name.h +search.o: ../../../../h/quipu/oid.h +search.o: ../../../../h/quipu/read.h +search.o: ../../../../h/quipu/remove.h +search.o: ../../../../h/quipu/util.h +search.o: ./defs.h +search.o: ./filt.h +search.o: ./sequence.h +sequence.o: ./defs.h +sequence.o: ./sequence.h +util.o: ./util.h +y.tab.o: ./filt.h diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/Pod.ad b/usr/src/contrib/isode/others/quipu/uips/pod/Pod.ad new file mode 100644 index 0000000000..87772e7812 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/Pod.ad @@ -0,0 +1,415 @@ +/* $Header: /f/osi/others/quipu/uips/pod/RCS/Pod.ad,v 7.2 91/02/22 09:31:20 mrose Interim $ */ + +Pod*PosTitle.font: -*-helvetica-*-*-*-*-11-* +Pod*ReadTitle.font: -*-helvetica-*-*-*-*-11-* +Pod*ListTitle.font: -*-helvetica-*-*-*-*-11-* +Pod*HistoryTitle.font: -*-helvetica-*-*-*-*-11-* +Pod*MenuButton*font: -*-helvetica-*-r-*-*-11-* +Pod*standby*font: -*-helvetica-bold-r-*-*-14-* +Pod*error_popup*font: -*-helvetica-bold-r-*-*-14-* +Pod*popup_help_form*font: -*-helvetica-medium-r-*-*-11-* +Pod*font: -*-helvetica-medium-r-*-*-11-* + +#ifdef COLOR + +Pod*foreground: Black + +Pod*MainButtonForm*background: LemonChiffon4 +Pod*MainButtonForm.background: LemonChiffon4 + +Pod*ReadButtonForm*background: LemonChiffon4 +Pod*ReadButtonForm.background: LemonChiffon4 + +Pod*ModifyButtonForm*background: LemonChiffon4 +Pod*ModifyButtonForm.background: LemonChiffon4 + +Pod*PosForm.background: LemonChiffon4 +Pod*ReadForm.background: LemonChiffon4 +Pod*outer.background: LemonChiffon4 +Pod*TypeForm.background: LemonChiffon4 +Pod*ListForm.background: LemonChiffon4 +Pod*HistoryForm.background: LemonChiffon4 +Pod*modifyForm.background: LemonChiffon4 +Pod*popup_help_form.background: LemonChiffon4 + +#endif COLOR + +Pod*SearchVal.cursor: question_arrow +Pod*Command.cursor: hand2 +Pod*MenuButton.cursor: hand2 + +Pod*defaultDistance: 10 +Pod*MainButtonForm.defaultDistance: 12 + +Pod*TypeForm.fromVert: PosForm +Pod*MainButtonForm.fromVert: TypeForm + +Pod*MainButtonForm.Command.label: +Pod*ReadButtonForm.Command.label: +Pod*ListForm.Command.label: +Pod*ModifyButtonForm.Command.label: + +Pod*MainButtonForm.resizable: TRUE +Pod*MainButtonForm.top: ChainBottom +Pod*MainButtonForm.bottom: ChainBottom +Pod*MainButtonForm.left: ChainLeft +Pod*MainButtonForm.right: ChainRight + +Pod*PosScrolledWindow.width: 424 +Pod*PosScrolledWindow.height: 100 +Pod*PosForm.resizable: FALSE + +Pod*PosForm.left: ChainLeft +Pod*PosForm.right: ChainRight +Pod*PosForm.top: ChainTop +Pod*PosForm.bottom: ChainBottom + +Pod*PosForm*Command.left: ChainLeft +Pod*PosForm*Command.right: ChainRight +Pod*PosForm*Command.top: ChainTop +Pod*PosForm*Command.bottom: ChainTop + +Pod*ReadButtonForm.height: 280 +Pod*ReadButtonForm.left: ChainLeft +Pod*ReadButtonForm.right: ChainLeft +Pod*ReadButtonForm.top: ChainTop +Pod*ReadButtonForm.bottom: ChainTop + +Pod*ReadTitle.width: 400 +Pod*ReadTitle.fromHoriz: ReadButtonForm +Pod*ReadTitle.left: ChainLeft +Pod*ReadTitle.right: ChainRight +Pod*ReadTitle.top: ChainTop +Pod*ReadTitle.bottom: ChainTop + +Pod*TextScrolledWindow.width: 400 +Pod*TextScrolledWindow.height: 280 + +Pod*TextScrolledWindow.fromVert: ReadTitle +Pod*TextScrolledWindow.fromHoriz: ReadButtonForm + +Pod*TextScrolledWindow.left: ChainLeft +Pod*TextScrolledWindow.right: ChainRight +Pod*TextScrolledWindow.top: ChainTop +Pod*TextScrolledWindow.bottom: ChainBottom + +Pod*List.defaultColumns: 1 +Pod*List.forceColums: TRUE +Pod*List.rowSpacing: 0 + +Pod*AttrWindow.right: ChainLeft +Pod*AttrWindow.left: ChainLeft +Pod*AttrWindow.top: ChainTop +Pod*AttrWindow.bottom: ChainTop + +Pod*SepWindow.right: ChainRight +Pod*SepWindow.left: ChainLeft +Pod*SepWindow.top: ChainTop +Pod*SepWindow.bottom: ChainTop + +Pod*ValWindow.right: ChainRight +Pod*ValWindow.left: ChainLeft +Pod*ValWindow.top: ChainTop +Pod*ValWindow.bottom: ChainTop + +Pod*SepWindow.fromHoriz: AttrWindow +Pod*ValWindow.fromHoriz: SepWindow + +Pod*TextScrolledWindow.borderWidth: 1 +Pod*TextScrolledWindow.borderColor: black +Pod*PosForm*borderWidth: 1 +Pod*PosForm*borderColor: black + +Pod*TypeForm.width: 410 +Pod*TypeForm.right: ChainRight +Pod*TypeForm.left: ChainLeft +Pod*TypeForm.top: ChainBottom +Pod*TypeForm.bottom: ChainBottom + +Pod*SearchVal.fromHoriz: SearchValLabel +Pod*TypeButton.fromHoriz: SearchVal +Pod*SearchVal.width: 200 + +Pod*ModifyButtonForm.borderWidth: 1 +Pod*ModifyButtonForm*Command.top: ChainTop +Pod*ModifyButtonForm*Command.bottom: ChainTop +Pod*ModifyButtonForm*Command.right: ChainLeft +Pod*ModifyButtonForm*Command.left: ChainLeft + +Pod*helpButton.fromHoriz: quitButton +Pod*searchButton.fromHoriz: helpButton +Pod*listButton.fromHoriz: searchButton +Pod*historyButton.fromHoriz: listButton + +Pod*helpButton.horizDistance: 19 +Pod*searchButton.horizDistance: 19 +Pod*listButton.horizDistance: 19 +Pod*historyButton.horizDistance: 19 + +Pod*Viewport.useBottom: TRUE +Pod*Viewport.useRight: TRUE +Pod*Viewport.allowHoriz: TRUE +Pod*Viewport.allowVert: TRUE +Pod*Viewport.forceBars: TRUE + +Pod*vertical.width: 9 +Pod*horizontal.height: 9 + +Pod*PhotoWindow.fromVert: AttrWindow +Pod*PhotoWindow.borderWidth: 1 +Pod*PhotoWindow.borderColor: black +Pod*PhotoWindow.top: ChainTop +Pod*PhotoWindow.bottom: ChainTop +Pod*PhotoWindow.left: ChainLeft +Pod*PhotoWindow.right: ChainLeft + +Pod*TextForm*displayCaret: FALSE +Pod*TextForm*borderWidth: 0 +Pod*TextForm*borderColor: white + +Pod*ReadForm*keepButton.fromVert: closeButton +Pod*ReadForm*showAllButton.fromVert: keepButton +Pod*ReadForm*modifyButton.fromVert: showAllButton + +Pod*PosForm*defaultDistance: 0 +Pod*PosForm.borderWidth: 0 + +Pod*PosTitle.borderWidth: 0 +Pod*PosTitle.width: 424 +Pod*PosTitle.label: Current Directory Position +Pod*PosTitle.resizable: FALSE +Pod*PosTitle.left: ChainLeft +Pod*PosTitle.right: ChainRight +Pod*PosTitle.top: ChainTop +Pod*PosTitle.bottom: ChainTop + +Pod*PosWindow.borderWidth: 0 +Pod*PosWindow.borderColor: white +Pod*PosScrolledWindow.fromVert: PosTitle +Pod*PosScrolledWindow.borderWidth: 0 +Pod*PosScrolledWindow.borderColor: white +Pod*PosScrolledWindow.resizable: FALSE +Pod*PosScrolledWindow.left: ChainLeft +Pod*PosScrolledWindow.right: ChainRight +Pod*PosScrolledWindow.top: ChainTop +Pod*PosScrolledWindow.bottom: ChainBottom +Pod*PosScrolledWindow*defaultDistance: 0 + +Pod*Command.highlightThickness: 0 +Pod*Command.borderWidth: 1 + +Pod*TypeMenu.borderWidth: 1 + +Pod*standby.borderWidth: 2 +Pod*standby.borderColor: black + +Pod*Session History*Form.width: 460 +Pod*Session History*Form.height: 500 + +Pod*ListWindow*defaultDistance: 0 +Pod*ListWindow.borderColor: white +Pod*ListWindow.borderWidth: 0 +Pod*ListWindow*resizable: TRUE +Pod*ListWindow*top: ChainTop +Pod*ListWindow*bottom: ChainTop + +Pod*closeButton.label: +Pod*ListForm.defaultDistance: 10 + +Pod*Session History*HistoryTitle.fromHoriz: closeButton +Pod*ListTitle.fromHoriz: keepButton + +Pod*ListForm*keepButton.fromHoriz: closeButton + +Pod*ListScrolledWindow.fromVert: closeButton +Pod*ListMessage.fromVert: ListScrolledWindow + +Pod*ListForm*Command.top: ChainTop +Pod*ListForm*Command.bottom: ChainTop +Pod*ListForm*Command.right: ChainLeft +Pod*ListForm*Command.left: ChainLeft + +Pod*ListTitle.width: 300 +Pod*ListTitle.right: ChainRight +Pod*ListTitle.left: ChainLeft +Pod*ListTitle.top: ChainTop +Pod*ListTitle.bottom: ChainTop + +Pod*Session History.Form*HistoryTitle.width: 350 +Pod*Session History.Form*HistoryTitle.right: ChainRight +Pod*Session History.Form*HistoryTitle.left: ChainLeft +Pod*Session History.Form*HistoryTitle.top: ChainTop +Pod*Session History.Form*HistoryTitle.bottom: ChainTop + +Pod*ListScrolledWindow.borderWidth: 0 +Pod*ListScrolledWindow.borderColor: white +Pod*ListScrolledWindow.height: 360 +Pod*ListScrolledWindow.width: 450 +Pod*ListScrolledWindow.left: ChainLeft +Pod*ListScrolledWindow.top: ChainTop +Pod*ListScrolledWindow.bottom: ChainBottom +Pod*ListScrolledWindow.right: ChainRight + +Pod*ListMessage.width: 450 +Pod*ListMessage.bottom: ChainBottom +Pod*ListMessage.top: ChainBottom +Pod*ListMessage.right: ChainRight +Pod*ListMessageleft: ChainLeft + +Pod*popup_help_general.label: +Pod*popup_help_quit.label: + +Pod*popup_help_general.fromHoriz: popup_help_quit +Pod*popup_help_scrolwin.fromVert: popup_help_quit + +Pod*popup_help_form.Command.left: ChainLeft +Pod*popup_help_form.Command.right: ChainLeft +Pod*popup_help_form.Command.top: ChainTop +Pod*popup_help_form.Command.bottom: ChainTop + +Pod*popup_help_scrolwin.left: ChainLeft +Pod*popup_help_scrolwin.right: ChainRight +Pod*popup_help_scrolwin.top: ChainTop +Pod*popup_help_scrolwin.bottom: ChainBottom + +Pod*popup_help_scrolwin.width: 350 +Pod*popup_help_scrolwin.height: 300 +Pod*popup_scrolwin.borderWidth: 0 +Pod*popup_scrolwin.borderColor: white +Pod*popup_help_text*resize: textResizeBoth +Pod*popup_help_text*borderColor: white +Pod*popup_help_text*borderWidth: 0 +Pod*popup_help_text*displayCaret: FALSE + +Pod*ModifyButtonForm.left: ChainLeft +Pod*ModifyButtonForm.right: ChainLeft +Pod*ModifyButtonForm.top: ChainTop +Pod*ModifyButtonForm.bottom: ChainBottom + +Pod*ModifyButtonForm*keepButton.fromVert: closeButton +Pod*ModifyButtonForm*modifyButton.fromVert: keepButton +Pod*modifyScrolledWindow.fromHoriz: ModifyButtonForm +Pod*modifyScrolledWindow.left: ChainLeft +Pod*modifyScrolledWindow.right: ChainRight +Pod*modifyScrolledWindow.top: ChainTop +Pod*modifyScrolledWindow.bottom: ChainBottom +Pod*modifyScrolledWindow.width: 500 +Pod*modifyScrolledWindow.height: 350 +Pod*modifyScrolledWindow*defaultDistance: 2 + +Pod*attrLabel.borderWidth: 1 +Pod*attrLabel.borderColor: white +Pod*attrLabel.highlightThickness: 1 +Pod*modValMenu.highlightThickness: 0 +Pod*modValMenu.borderWidth: 0 +Pod*modValMenu.label: +Pod*valText.resize: textResizeBoth + +Pod*attrLabel.left: ChainLeft +Pod*attrLabel.right: ChainLeft +Pod*attrLabel.top: ChainTop +Pod*attrLabel.bottom: ChainTop + +Pod*modValMenu.left: ChainLeft +Pod*modValMenu.right: ChainLeft +Pod*modValMenu.top: ChainTop +Pod*modValMenu.bottom: ChainTop + +Pod*valText.left: ChainLeft +Pod*valText.right: ChainLeft +Pod*valText.top: ChainTop +Pod*valText.bottom: ChainTop + +Pod*modMessage.fromVert: modifyScrolledWindow +Pod*modMessage.fromHoriz: ModifyButtonForm +Pod*modMessage.width: 500 +Pod*modMessage.right: ChainRight +Pod*modMessage.left: ChainLeft +Pod*modMessage.bottom: ChainBottom +Pod*modMessage.top: ChainBottom + +/* + * Don't touch these! + */ + +Pod*attrLabel.translations: #override \ + : ChangeHelp(attr_menu) + +Pod*modValMenu.translations: #override \ + : ChangeHelp(val_menu) + +Pod*valText.translations: #override \ + : ChangeHelp(mod_val) + +Pod*popup_help_quit.translations: \ + : buttonPress(close) \n\ + : ChangeHelp(close) + +Pod*TypeForm.translations: \ + : ChangeHelp(search_popup) \n\ + +Pod*closeButton.translations: \ + : buttonPress(close) \n\ + : ChangeHelp(close) + +Pod*cancelButton.translations: \ + : buttonPress(close) \n\ + : ChangeHelp(close) + +Pod*okButton.translations: \ + : buttonPress(okay) + +Pod*quitButton.translations: \ + : ChangeHelp(quit) \n\ + : buttonPress(quit) + +Pod*helpButton.translations: \ + : ChangeHelp(help) \n\ + : buttonPress(help) + +Pod*searchButton.translations: \ + : ChangeHelp(search) \n\ + : buttonPress(search) + +Pod*listButton.translations: \ + : ChangeHelp(list) \n\ + : buttonPress(list) + +Pod*popup_help_general.translations: \ + : buttonPress(about) + +Pod*historyButton.translations: \ + : ChangeHelp(history) \n\ + : buttonPress(history) + +Pod*keepButton.translations: \ + : ChangeHelp(keep) \n\ + : buttonPress(keep) + +Pod*showAllButton.translations: \ + : ChangeHelp(show_all) \n\ + : buttonPress(show_all) + +Pod*ReadForm*modifyButton.translations: \ + : ChangeHelp(modify) \n\ + : buttonPress(modify) + +Pod*modifyForm*modifyButton.translations: \ + : ChangeHelp(submit_modify) \n\ + : buttonPress(submit_modify) + +Pod*TextScrolledWindow.translations: \ + : ChangeHelp(read_window) + +Pod*PosScrolledWindow.translations: \ + : ChangeHelp(curr_pos) + +Pod*ListForm.translations: \ + : ChangeHelp(list_popup) + +Pod*HistoryForm.translations: \ + : ChangeHelp(history_popup) + + + + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/READ-ME b/usr/src/contrib/isode/others/quipu/uips/pod/READ-ME new file mode 100644 index 0000000000..644a0b86f4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/READ-ME @@ -0,0 +1,75 @@ +Pod version 2 +~~~~~~~~~~~~~~~ + + POD is a prototype X-windows based directory user agent (DUA). + It is intended for novice users, and, as such, has limited + functionality. There are no facilities to add entries or to modify + the RDNs of entries, though most other entry modifications are + permitted. + +INFO +~~~~ + The 'pod' directory has been to designed to fit directly into the + 'isode' source tree. Specifically, in the directory + + 'others/quipu/uips'. + + POD requires X11r4 and the associated X toolkit and Athena + widget libraries. + + Two Postscript documents are provided, `pod.man.ps' a user manual, + and `pod.guide.ps' an introductory user guide. + +COMPILATION +~~~~~~~~~~~ + To compile type + + ./make + + This should build 'xpod'. To test run , + + xpod -test + + which runs POD and tells it to read it's config files from the + source directory. + +INSTALLATION +~~~~~~~~~~~~ + Modify the Makefile to suit your system. The location of the + 'app-defaults' directory (described by APPDEFDIR) might require + modification. Installation of POD can be performed by typing + + ./make inst-all + + This will install 'pod' and any supporting files/directories, these + being configuration directories, help directories and the system + manual pages. + + if you want to install and clean up the source directory type + + ./make install + +Bug reports and comments. +~~~~~~~~~~~~~~~~~~~~~~~~~~ + + All bug reports and other requests to 'X500@brunel.ac.uk'. + If there are any comments/criticisms you would like to make + about POD, send them to the above address also as these can + and (gasp!) often will be fused into the design for further DUAs + (new designs are currently being implemented under X using the + Athena widgets and for MS-DOS using Windows 286/386, with + a planned version for X using the Motif widget set). + + +Andrew Findlay +Damanjit Mahl +Stefan Nahajski + + + + + + + + + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/bitmap b/usr/src/contrib/isode/others/quipu/uips/pod/bitmap new file mode 100644 index 0000000000..75edb0ec1c --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/bitmap @@ -0,0 +1,24 @@ +#include "bitmaps/Search" +#include "bitmaps/SearchPress" +#include "bitmaps/List" +#include "bitmaps/ListPress" +#include "bitmaps/History" +#include "bitmaps/HistoryPress" +#include "bitmaps/Close" +#include "bitmaps/ClosePress" +#include "bitmaps/Quit" +#include "bitmaps/QuitPress" +#include "bitmaps/Help" +#include "bitmaps/HelpPress" +#include "bitmaps/About" +#include "bitmaps/AboutPress" +#include "bitmaps/Keep" +#include "bitmaps/KeepPress" +#include "bitmaps/Kept" +#include "bitmaps/Modify" +#include "bitmaps/ModifyPress" +#include "bitmaps/ShowAll" +#include "bitmaps/ShowAllPress" +#include "bitmaps/icon" +#include "bitmaps/menuicon" +#include diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/calls.c b/usr/src/contrib/isode/others/quipu/uips/pod/calls.c new file mode 100644 index 0000000000..ab6d081eaa --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/calls.c @@ -0,0 +1,877 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/calls.c,v 7.2 91/02/22 09:31:23 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/calls.c,v 7.2 91/02/22 09:31:23 mrose Interim $ + */ + +#include +#include +#include +#include + +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/entry.h" +#include "quipu/name.h" +#include "quipu/list.h" + +#include "usr.dirent.h" +#include "tailor.h" +#include "sequence.h" +#include "filt.h" +#include "defs.h" +#include "util.h" + +extern mailtype mailformat; +extern Attr_Sequence read_types, read_types2, oclass; +extern bool photo_on; + +int typetoggled = 0; + +int dn_print(), rdn_print(), as_print(); +char *TidyString(); +Attr_Sequence get_sorted_attrs(); + +void set_default_type(), make_friendly(); +void quit(); + +str_seq dnseq = NULLDS, backseq = NULLDS, showseq = NULLDS; +int entry_number, back_buf_num, dn_number, histlimit = 50; +bool read_all_flag = TRUE; +bool testing = FALSE; + +char goto_path[STRINGLEN]; /* Used by the 'G:goto' command*/ +char base_path[STRINGLEN]; /* Used by all DS operations */ +char friendly_base_path[STRINGLEN]; +char namestr[STRINGLEN]; +char bindpass [STRINGLEN]; +char mvalue [STRINGLEN]; +char passwd[STRINGLEN]; + +unsigned int curr_filt = 0; +unsigned int filt_num = 0; +unsigned int typeindx = 0; +filt_struct *filt_arr[MAXTYPES]; +char *filtvalue[MAXTYPES]; +char *filttype[MAXTYPES]; + +int default_num; +int *av_typeindx; +int *available_types[MAXTYPES]; +char *levels[MAXTYPES]; +int defaults[MAXTYPES]; + +typedef struct friendlyName { + str_seq names; + char fname[256]; +} *fName; + +unsigned int fname_num = 0; +fName name_map[MAXTYPES]; + +#ifndef NO_STATS +extern LLog *log_stat; +#endif + +extern int sizelimit; +extern char *local_dit; + +DN user_name; + +char * addobj = NULLCP; +Filter search_filter; +FILE *config_file; +char *file_names[MAXTYPES]; +char dua_help_dir[SMALLSTRING]; + +char *get_strioid(ptr) + register char *ptr; +{ + register char *end_ptr; + + while(*ptr == '"') ptr++; + while(*ptr != '"') ptr++; + + while(*ptr > '9' || *ptr < '0') ptr++; + + end_ptr = ptr; + while(*end_ptr != '\n') end_ptr++; + + *end_ptr = '\0'; + return ptr; +} + +void user_tailor() +{ + char *part1, *part2; + char *getenv(), *TidyString(), *SkipSpace(); + char *config_dir = "/.duaconfig", + *type_dir = "/filterTypes", + *readTypes = "/readTypes", + *friendlyNames = "/friendlyNames", + *options = "/.duarc", + *typeDefaults = "/typeDefaults"; + + char user_path[BUFSIZ], read_path[BUFSIZ], + type_path[BUFSIZ], options_path[BUFSIZ], + friendly_path[BUFSIZ], type_defaults_path[BUFSIZ], + dua_config_dir[BUFSIZ]; + + char stroid_buf[BUFSIZ]; + char Read_in_Stuff[STRINGLEN]; + + register char *str, *sptr, *p, *end; + char save; + + DIR *config_directory; + struct dirent *dir_ent; + + int count, n, num; + int tempints[MAXTYPES]; + +#ifndef NO_STATS + ll_hdinit (log_stat,"pod"); +#endif + + (void) strcpy(dua_config_dir, isodefile("xd", 0)); + (void) strcpy(dua_help_dir, dua_config_dir); + + (void) strcat(dua_config_dir, "/duaconfig"); + (void) strcat(dua_help_dir, "/podHelpdir"); + + (void) strcpy (user_path, getenv("HOME")); + (void) strcpy(read_path, user_path); + (void) strcpy(type_path, user_path); + (void) strcpy(friendly_path, user_path); + (void) strcpy(type_defaults_path, user_path); + (void) strcpy(options_path, user_path); + + (void) strcat(options_path, options); + (void) strcat(read_path, config_dir); + (void) strcat(read_path, readTypes); + (void) strcat(type_path, config_dir); + (void) strcat(type_path, type_dir); + (void) strcat(friendly_path, config_dir); + (void) strcat(friendly_path, friendlyNames); + (void) strcat(type_defaults_path, config_dir); + (void) strcat(type_defaults_path, typeDefaults); + + if (testing) { + (void) strcpy(type_path, "./Xd/duaconfig/"); + (void) strcat(type_path, type_dir); + if (!(config_directory = opendir(type_path))) { + (void) fprintf(stderr, "File error! Test pod should be run from source directory!\n"); + quit(1); + } + } else { + if (!(config_directory = opendir(type_path))) { + (void) strcpy(type_path, dua_config_dir); + (void) strcat(type_path, type_dir); + if(!(config_directory = opendir(type_path))) { + (void) fprintf(stderr, "Can't find directory %s!\n", type_dir); + quit(1); + } + } + } + + rewinddir(config_directory); + filt_num = 0; + while(dir_ent = readdir(config_directory)) { + if (!(strncmp(dir_ent->d_name, "Type_", 5))) { + file_names[filt_num] = + (char *) malloc((unsigned int) + (strlen(dir_ent->d_name) + + strlen(type_path) + 2)); + (void) strcpy(file_names[filt_num], type_path); + (void) strcat(file_names[filt_num], "/"); + (void) strcat(file_names[filt_num], dir_ent->d_name); + filt_num++; + } + } + (void) closedir(config_directory); + + if ((config_file = fopen (options_path, "r")) == 0); + else { + while (fgets (Read_in_Stuff, STRINGLEN, config_file) != 0) { + p = SkipSpace (Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; /* ignore comments and blanks */ + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) + continue; /* ignore it */ + + *part2++ = '\0'; + part2 = TidyString(part2); + + if ((lexequ(part1, "username") == 0) && *namestr == '\0') + (void) strcpy (namestr, part2); + else if ((lexequ(part1, "password") == 0) && *passwd == '\0') + (void) strcpy (passwd, part2); + else if (lexequ(part1, "prefergreybook") == 0) + mailformat = greybook; + else if (lexequ (part1, "dsap") == 0) + (void) tai_string (part2); + else if (lexequ (part1, "isode") == 0) { + char *split; + if ((split = index (part2,' ')) != NULLCP) { + *split++ = 0; + (void) isodesetvar (part2, split, 0); + } + } else if (lexequ(part1, "service") == 0) + new_service (part2); + else if (lexequ(part1, "history") == 0) { + (void) sscanf(part2, "%d", &histlimit); + if (histlimit < 1) histlimit = 1; + } else if (lexequ(part1, "readnonleaf") == 0) { + if (lexequ(part2, "TRUE") == 0) read_all_flag = TRUE; + else read_all_flag = FALSE; + } + } + isodexport (NULLCP); + (void) fclose(config_file); + } + + if (testing) { + (void) strcpy(read_path, "./Xd/duaconfig/"); + (void) strcat(read_path, readTypes); + if (!(config_file = fopen(read_path, "r"))) { + (void) fprintf(stderr, "File error! Test pod must be run from source directory!\n"); + quit(1); + } + } else { + if (!(config_file = fopen(read_path, "r"))) { + (void) strcpy(read_path, dua_config_dir); + (void) strcat(read_path, readTypes); + if (!(config_file = fopen(read_path, "r"))) { + (void) fprintf(stderr, "Can't find read file (%s)!\n", read_path); + quit(1); + } + } + } + + while(fgets(Read_in_Stuff, STRINGLEN, config_file) != 0) { + (void) strcpy(stroid_buf, get_strioid(Read_in_Stuff)); + if (*stroid_buf) { + if (!read_types) + read_types = as_comp_new(AttrT_new(stroid_buf), NULLAV, NULLACL_INFO); + else { + read_types2 = as_comp_new(AttrT_new(stroid_buf), NULLAV, NULLACL_INFO); + read_types = as_merge(read_types, read_types2); + } + } + } + (void) fclose(config_file); + + if (testing) { + (void) strcpy(friendly_path, "./Xd/duaconfig/"); + (void) strcat(friendly_path, friendlyNames); + if (!(config_file = fopen(friendly_path, "r"))) { + (void) fprintf(stderr, "File error! Test pod must be run from source directory!\n"); + quit(1); + } + } else { + if (!(config_file = fopen(friendly_path, "r"))) { + (void) strcpy(friendly_path, dua_config_dir); + (void) strcat(friendly_path, friendlyNames); + if (!(config_file = fopen(friendly_path, "r"))) { + (void) fprintf(stderr, "Can't find read file (%s)!\n", friendly_path); + quit(1); + } + } + } + + name_map[fname_num] = 0; + while(fgets(Read_in_Stuff, STRINGLEN, config_file) != 0) { + if (*Read_in_Stuff != '#') { + sptr = str = Read_in_Stuff; + while (*sptr != ':' && !isspace(*sptr) && sptr != '\0') { + while (!isalnum(*sptr)) sptr++; + str = sptr; + while (*str != ' ' && *str != ',' && *str != ':') str++; + save = *str; + *str = '\0'; + + if (!name_map[fname_num]) { + name_map[fname_num] = (fName) malloc(sizeof(struct friendlyName)); + name_map[fname_num]->names = 0; + } + + add_seq(&name_map[fname_num]->names, sptr); + *str = save; + sptr = str; + while (*sptr != ',' && *sptr != ':') sptr++; + } + + while (!isalpha(*sptr) && *sptr != '\0') sptr++; + + str = sptr; + while (*str != '\0' && *str != '\n') str++; + *str = '\0'; + + if (name_map[fname_num]) { + (void) strcpy(name_map[fname_num]->fname, sptr); + fname_num++; + name_map[fname_num] = 0; + } + } + } + + for (curr_filt = 0; curr_filt < filt_num; curr_filt++) { + if (!(config_file = fopen(file_names[curr_filt], "r"))) { + (void) fprintf(stderr, "Can't find file %s!\n", file_names[curr_filt]); + quit(1); + } + filt_arr[curr_filt] = (filt_struct *) 0; + filtvalue[curr_filt] = (char *) malloc(STRINGLEN); + *filtvalue[curr_filt] = '\0'; + + (void) yyparse(); + (void) fclose(config_file); + } + + filttype[curr_filt] = NULLCP; + for (count = 0; count < filt_num; count++) + free(file_names[count]); + + if (testing) { + (void) strcpy(type_defaults_path, "./Xd/duaconfig/"); + (void) strcat(type_defaults_path, typeDefaults); + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) fprintf(stderr, "File error! Test pod must be run from source directory.\n"); + quit(1); + } + } else { + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) strcpy(type_defaults_path, dua_config_dir); + (void) strcat(type_defaults_path, typeDefaults); + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) fprintf(stderr, "File error! Can't find typeDefaults file.\n"); + quit(1); + } + } + } + + default_num = 0; + while (fgets (Read_in_Stuff, STRINGLEN, config_file) != 0) { + p = SkipSpace(Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) + continue; + + end = part2 - 1; + while (isspace(*end)) end--; + *++end = '\0'; + + *part2++ = '\0'; + + while (isspace(*part2)) part2++; + end = part2; + + while (!isspace(*end) && *end != ',' && *end != ':') end++; + + count = 0; + while (*part2 != ':') { + n = 0; + while (n < filt_num && strncmp(filttype[n], + part2, (int) (end - part2))) n++; + + if (n == filt_num) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } else { + tempints[count] = n; + count++; + part2 = end; + while (!isalpha(*part2) && *part2 != ':' && part2 != '\0') part2++; + + if (*part2 == '\0') { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } + + if (*part2 != ':') { + while (!isalpha(*part2)) part2++; + end = part2; + while (!isspace(*end) && *end != ',' && + *end != ':' && *end != '\0') end++; + if (*end == '\0') { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } + } else end = part2; + } + } + + if (*end == ':') { + while(isspace(*++end)); + p = end; + while(!isspace(*++end)); + *end = '\0'; + + n = 0; + while (n < filt_num && strcmp(filttype[n], p)) n++; + + if (n == filt_num) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } else { + num = 0; + while (num < count && n != tempints[num]) num++; + if (num == count) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } + } + + defaults[default_num] = n; + + levels[default_num] = malloc((unsigned int) (strlen(part1) + 1)); + (void) strcpy(levels[default_num], part1); + available_types[default_num] = + (int *) malloc((unsigned int) (sizeof(int) * (count+1))); + + for (n = 0; n < count; n++) + available_types[default_num][n] = tempints[n]; + + available_types[default_num][n] = -1; + default_num++; + } + } + + (void) fclose(config_file); +} + +char *cnnct_bind() +{ + struct ds_bind_arg bindarg; + struct ds_bind_arg bindresult; + struct ds_bind_error binderr; + extern char * dsa_address, + * myname; + extern char * tailfile; + FILE * fp; + char buf[BUFSIZ]; + + if (*passwd != 0) + (void) strcpy(bindpass, "******"); + else + bindpass[0] = '\0'; + + /* set dsa_address */ + dsa_address = NULLCP; + /* read tailor file to get address */ + if( (fp = fopen(isodefile(tailfile,0), "r")) == (FILE *) NULL) { + return("Cannot open `dsaptailor' file.\nClick on this window to continue."); + } + while(fgets(buf, sizeof(buf), fp) != NULLCP) + if ( (*buf != '#') && (*buf != '\n') ) + (void) tai_string (buf); + + (void) fclose(fp); + + if (dsa_address == NULLCP) + dsa_address = myname; + + /* set password */ + if (bindpass[0] != 0) { + if (strcmp (bindpass,"******") != 0) + (void) strcpy (passwd,bindpass); + } else + passwd[0] = 0; + + /* now bind */ + bindarg.dba_version = DBA_VERSION_V1988; + if (passwd[0] == 0) { + bindarg.dba_passwd_len = 0; + bindarg.dba_passwd [0] = '\0'; + } else { + bindarg.dba_passwd_len = strlen(passwd); + (void) strcpy (bindarg.dba_passwd, passwd); + } + + bindarg.dba_dn = (*namestr == 0? NULLDN: str2dn(namestr)); + + if (ds_bind (&bindarg, &binderr, &bindresult) != DS_OK) { + return(binderr.dbe_type == DBE_TYPE_SECURITY? + "Security error - Check name and pasword.\nClick on this window to exit.": + "Service error - Can't connect to directory!\nClick on thi window to exit."); + } else { + user_name = bindarg.dba_dn; + + if(local_dit && *local_dit) + (void) strcpy(base_path, local_dit); + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("bound ('%s' to '%s')",namestr,dsa_address)); +#endif +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("pod bound to directory")); +#endif + + make_friendly(friendly_base_path, base_path); + + set_default_type(); + check_known_oids(); + oclass = as_comp_new(AttrT_new("2.5.4.0"), NULLAV, NULLACL_INFO); + } + dn_number = 0; + back_buf_num = 0; + backseq = dnseq = NULLDS; + return NULLCP; +} + +void set_default_type() +{ + int count; + register DN base_name; + DN d_name; + + if (*base_path != '\0') { + base_name = d_name = str2dn(base_path); + + while (base_name && base_name->dn_parent) base_name = base_name->dn_parent; + for (count = 0; + count < default_num && base_name && + strcmp(levels[count], + base_name->dn_rdn->rdn_at-> + oa_ot.ot_stroid); + count++); + dn_free(d_name); + + if (count < default_num) { + av_typeindx = available_types[count]; + typeindx = defaults[count]; + } else { + av_typeindx = available_types[0]; + typeindx = defaults[0]; + } + } else { + for(count = 0; count < default_num && strcmp(levels[count], "@"); count++); + if (count < default_num) { + av_typeindx = available_types[count]; + typeindx = defaults[count]; + } else { + av_typeindx = available_types[0]; + typeindx = defaults[0]; + } + } + typetoggled = 0; +} + +void dn2buf (ptr,cptr) + caddr_t ptr; + char * cptr; +{ + PS ps; + char buffer [RESBUF]; + + if((ps = ps_alloc(str_open)) == NULLPS) return ; + + if(str_setup(ps, buffer, RESBUF, 1) == NOTOK) return ; + + dn_print(ps, (DN) ptr, EDBOUT); + *ps->ps_ptr = 0; + + ps_free (ps); + + (void) strcpy(cptr, buffer); +} + +void make_friendly(fstr, str) + char *fstr, *str; +{ + register char *end, *start; + char *string, *rdn_start; + char save; + int count, seqnum = 0, mapped; + + *fstr = '\0'; + if (*str == '\0') { + *fstr = '\0'; + return; + } + + end = str; + while (*end != '\0') { + if (*end == ',') *end = ' '; + end++; + } + start = end; + + while (1) { + /* First check the attribute type alias*/ + while (*start != '=') start--; + while (!isalnum(*start)) start--; + + end = start + 1; + + save = *end; + *end = '\0'; + + while (isalnum(*start) && start > str) start--; + if (start > str) start++; + + mapped = FALSE; + for (count = 0; count < fname_num && !mapped; count++) { + seqnum = 0; + while (!mapped && + (string = get_from_seq(seqnum++, name_map[count]->names))) + if (!strcmp(string, start)) { + (void) strcat(fstr, name_map[count]->fname); + mapped = TRUE; + } + } + + if (!mapped) { + (void) strcat(fstr, str); + (void) strcat(fstr, " = "); + } else { + if (*name_map[--count]->fname != '\0') (void) strcat(fstr, " = "); + } + + *end = save; + + /* Now get the attribute value*/ + rdn_start = start; + start = end; + while (!(isalnum(*start))) start++; + + end = start; + while (*end != '@' && *end != '\0') end++; + + save = *end; + *end = '\0'; + (void) strcat(fstr, start); + *end = save; + + start = rdn_start; + if (start <= str) break; + + while (*start != '@' && start > str) start--; + (void) strcat(fstr, ", "); + } +} + +make_friendly_rdn(friendly, object, base) + char *friendly; + char *object, *base; +{ + register char *front; + int count; + + *friendly = '\0'; + + front = base; + count = 0; + + if (showseq != backseq) { + while (*front != '\0') { + if (*front == '=') count++; + front++; + } + } else + count = 0; + + front = object; + + while (count && *front != '\0') { + if (*front == '=') count--; + front++; + } + + if (front != object) { + while (*front != '\0' && *front != '@') front++; + while (!isalpha(*front) && *front != '\0') front++; + } + make_friendly(friendly, front); +} + +goto_addr() +{ + char *str; + int count = 0; + void add_to_history(); + + set_default_type(); + + make_friendly(friendly_base_path, base_path); + + str = get_from_seq(count+1, backseq); + while (count < back_buf_num && strcmp(str, base_path)){ + count++; + str = get_from_seq(count+1, backseq); + } + + if (count == back_buf_num) { + add_seq(&backseq, base_path); + back_buf_num++; + add_to_history(back_buf_num); + } +} + +clear_dnseq() +{ + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; +} + +int isleafnode(name) + char *name; +{ + struct ds_list_arg list_arg; + struct ds_list_result list_result; + struct list_cache *cached_list; + + struct ds_read_arg read_arg; + struct ds_read_result read_result; + Entry read_entry; + Attr_Sequence object_class; + + struct DSError list_error, read_error; + + char entry_str[STRINGLEN]; + + if (get_default_service (&read_arg.rda_common) != 0) return(1); + read_arg.rda_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + read_arg.rda_eis.eis_allattributes = FALSE; + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + read_arg.rda_eis.eis_select = oclass; + + read_arg.rda_object = (*name? str2dn(name): NULLDN); + + if ((read_entry = local_find_entry(read_arg.rda_object, FALSE)) + != NULLENTRY && + read_entry->e_data != E_TYPE_CONSTRUCTOR) { + object_class = get_sorted_attrs(read_entry->e_attributes, + oclass); + entry2str((caddr_t) object_class, entry_str, STRINGLEN); + as_free(object_class); + if (issubstr(entry_str, "NonLeaf")) return(0); + } else if (ds_read(&read_arg, &read_error, &read_result) == DS_OK) { + if (read_result.rdr_entry.ent_attr == NULLATTR) return(0); + entry2str((caddr_t) read_result.rdr_entry.ent_attr, entry_str, STRINGLEN); + entryinfo_comp_free(&read_result.rdr_entry, 0); + if (issubstr(entry_str, "NonLeaf")) return(0); + } + + dn_free(read_arg.rda_object); + ds_error_free(&read_error); + + if (get_default_service (&list_arg.lsa_common) != 0) return(1); + list_arg.lsa_common.ca_servicecontrol.svc_sizelimit = 1; + list_arg.lsa_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + list_arg.lsa_object = (*name? str2dn(name): NULLDN); + + if ((cached_list = find_list_cache(list_arg.lsa_object, 1)) != NULL) { + if (cached_list->list_sub_top) return(0); + else return(1); + } else if (ds_list (&list_arg, &list_error, &list_result) == DS_OK) { + cache_list(list_result.lsr_subordinates, 0, list_arg.lsa_object, 1); + dn_free(list_arg.lsa_object); + if (list_result.lsr_subordinates) return(0); + else return(1); + } else { + dn_free(list_arg.lsa_object); + ds_error_free(&list_error); + return (1); + } +} + +char *GetSurname(name) + register char *name; +{ + while (*name != '\0') name++; + while (*name != ' ' && *name != '=') name--; + return ++name; +} + +char *GetWholeRelName(name) + register char *name; +{ + while (*name!= '\0') name++; + while (*name != '=') name--; + while (!isalpha(*name)) name++; + return name; +} + +str_seq SortList(list) + str_seq list; +{ + register str_seq currEntry, lastSortedEntry , currSortedEntry; + str_seq sortedList; + char *sortedName, *currName; + register DN curr_dn; + DN dn; + + if (!list) return 0; + + currEntry = list; + sortedList = 0; + + while (currEntry) { + dn = curr_dn = str2dn(currEntry->dname); + + while (curr_dn && curr_dn->dn_parent != NULLDN) + curr_dn = curr_dn->dn_parent; + + if (!strcmp(curr_dn->dn_rdn->rdn_at->oa_ot.ot_stroid, "2.5.4.3")) + currName = GetSurname(currEntry->dname); + else + currName = GetWholeRelName(currEntry->dname); + + dn_free(dn); + + if (!sortedList) { + sortedList = currEntry; + currEntry = currEntry->next; + sortedList->next = 0; + } else { + lastSortedEntry = 0; + currSortedEntry = sortedList; + + while (currSortedEntry != 0) { + dn = curr_dn = str2dn(currSortedEntry->dname); + + while (curr_dn && curr_dn->dn_parent != NULLDN) + curr_dn = curr_dn->dn_parent; + + if (!strcmp(curr_dn->dn_rdn->rdn_at->oa_ot.ot_stroid, "2.5.4.3")) + sortedName = GetSurname(currSortedEntry->dname); + else + sortedName = GetWholeRelName(currSortedEntry->dname); + + dn_free(dn); + + if (strcmp(currName, sortedName) <= 0) { + if (lastSortedEntry) { + lastSortedEntry->next = currEntry; + currEntry = currEntry->next; + lastSortedEntry->next->next = currSortedEntry; + } else { + sortedList = currEntry; + currEntry = currEntry->next; + sortedList->next = currSortedEntry; + } + currSortedEntry = 0; + } else { + lastSortedEntry = currSortedEntry; + currSortedEntry = currSortedEntry->next; + if (!currSortedEntry) { + lastSortedEntry->next = currEntry; + currEntry = currEntry->next; + lastSortedEntry->next->next = 0; + currSortedEntry = 0; + } + } + } + } + } + return sortedList; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/conf_read.y b/usr/src/contrib/isode/others/quipu/uips/pod/conf_read.y new file mode 100644 index 0000000000..10f1eaa025 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/conf_read.y @@ -0,0 +1,225 @@ +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/conf_read.y,v 7.2 91/02/22 09:31:26 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/conf_read.y,v 7.2 91/02/22 09:31:26 mrose Interim $ + */ + + +#include +#include +#include +#include "filt.h" + +int make_type(); +filt_struct *make_item_filter(); +filt_struct *link_filters(); +filt_struct *make_parent_filter(); + +extern FILE *config_file; +extern unsigned int curr_filt; +extern char *file_names[], *filttype[]; +extern filt_struct *filt_arr[]; +%} +%start type_spec + +%union { + filt_struct *filt; + char strval[255]; + int symbol; +} + +%token NUMBER NAME DEFAULT STRING OID AND OR NOT APPROX EQUAL ITEM + +%type filter filter_list assertion filter_item +%type filt_type match +%token NOT AND OR APPROX EQUAL SUBSTRING +%token '"' ':' '(' ')' +%token STRING OID +%type name default + +%% + type_spec : name filter {make_type($1, $2);} + ; + + name : NAME ':' STRING {(void) strcpy($$, $3);} + ; + + default : DEFAULT ':' STRING {(void) strcpy($$, $3);} + | {(void) strcpy($$, "\0");} + ; + + assertion : '(' filt_type filter filter filter_list ')' {$$ = make_parent_filter($2, $3, $4, $5);} + | '(' NOT filter ')' {$$ = make_parent_filter($2, $3, (filt_struct *) 0,(filt_struct *) 0);} + | filter_item {$$ = $1;} + ; + + filter_list : filter filter_list {$$ = link_filters($1, $2);} + | filter {$$ = $1;} + | {$$ = (filt_struct *) 0;} + ; + + filter : filter_item {$$ = $1;} + | assertion {$$ = $1;} + ; + + filter_item : '(' OID match STRING ')' {$$ = make_item_filter($2, $3, $4);} + ; + + match : APPROX {$$ = $1;} + | EQUAL {$$ = $1;} + | SUBSTRING {$$ = $1;} + ; + + filt_type : AND {$$ = $1;} + | OR {$$ = $1;} + ; +%% + +yylex() +{ + int c, count = 0; + char lexeme[255]; + + while(isspace(c = getc(config_file))) + if (c == EOF) return(0); + + lexeme[count++] = c; + + switch(c) { + case '#': + while (getc(config_file) != '\n'); + return(yylex()); + case '"': + count = 0; + while ((c = getc(config_file)) != '"') + lexeme[count++] = c; + lexeme[count] = '\0'; + (void) strcpy(yylval.strval, lexeme); + return STRING; + case '(': + return (int) c; + case ')': + return (int) c; + case ':': + return (int) c; + case '&': + yylval.symbol = AND; + return AND; + case '|': + yylval.symbol = OR; + return OR; + case '!': + yylval.symbol = NOT; + return NOT; + case '*': + lexeme[count] = '\0'; + (void) strcpy(yylval.strval, lexeme); + return STRING; + case '~': + if((lexeme[count] = getc(config_file)) == '=') { + yylval.symbol = APPROX; + return APPROX; + } + break; + case '%': + if((lexeme[count] = getc(config_file)) == '=') { + yylval.symbol = SUBSTRING; + return SUBSTRING; + } + break; + case '=': + yylval.symbol = EQUAL; + return EQUAL; + } + + while(!isspace(c = getc(config_file)) && c != '\0' && !issymbol(c)) + if (c != EOF) + lexeme[count++] = c; + else + return(0); + + (void) fseek(config_file,(long) -1, 1); + + lexeme[count] = '\0'; + switch(*lexeme) { + case 'd': + case 'D': + if(!strcmp(lexeme, "default") || !strcmp(lexeme, "DEFAULT")) + return DEFAULT; + else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + case 'n': + case 'N': + if(!strcmp(lexeme, "name") || !strcmp(lexeme, "NAME")) + return NAME; + else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + count = 0; + while (isdigit(lexeme[count]) || lexeme[count] == '.') count++; + if (lexeme[count] == '\0') { + (void) strcpy(yylval.strval, lexeme); + return OID; + } else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + default: + (void) strcpy(yylval.strval, lexeme); + return STRING; + } +} + +/* ARGSUSED */ +yyerror(err) + char *err; +{ + (void) fprintf(stderr, + "Parse error in '%s'. Exiting.\n", + (char *) file_names[curr_filt]); + if (filttype[curr_filt]) { + free(filttype[curr_filt]); + filttype[curr_filt] = (char *) 0; + } + + if (filt_arr[curr_filt]) free_filt(filt_arr[curr_filt]); + exit(1); +} + +int issymbol(c) +char c; +{ + switch(c) { + case '#': + case '"': + case '(': + case ')': + case ':': + case '&': + case '|': + case '!': + case '*': + case '~': + case '=': + case '%': + return 1; + } + return 0; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/cpr b/usr/src/contrib/isode/others/quipu/uips/pod/cpr new file mode 100644 index 0000000000..56fcbd84f2 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/cpr @@ -0,0 +1,92 @@ +#! /bin/sh + +# cp-r +# +# Implements recursive copy for machines which do not have the -R option on cp +# +# Andrew.Findlay@brunel.ac.uk +# +# Derived from: +# +# lndir - create shadow link tree +# +# Time stamp <89/11/28 18:56:54 gildea> +# By Stephen Gildea based on +# XConsortium: lndir.sh,v 1.1 88/10/20 17:37:16 jim Exp + + +USAGE="Usage: $0 fromdir [todir]" + +if [ $# -lt 1 -o $# -gt 2 ] +then + echo "$USAGE" + exit 1 +fi + +DIRFROM=$1 + +if [ $# -eq 2 ]; +then + DIRTO=$2 +else + DIRTO=. +fi + +if [ ! -d $DIRTO ] +then + echo "$0: $DIRTO is not a directory" + echo "$USAGE" + exit 2 +fi + +case "$DIRFROM" in + /*) ;; + *) DIRFROM=`pwd`/$DIRFROM ;; +esac + +cd $DIRTO + +if [ ! -d $DIRFROM ] +then + echo "$0: $DIRFROM is not a directory" + echo "$USAGE" + exit 2 +fi + +pwd=`pwd` + +if [ `(cd $DIRFROM; pwd)` = $pwd ] +then + echo "$pwd: FROM and TO are identical!" + exit 1 +fi + +for file in `ls -a $DIRFROM` +do + if [ ! -d $DIRFROM/$file ] + then + #ln -s $DIRFROM/$file . + cp $DIRFROM/$file . + else + if [ \( $file != RCS \) \ + -a \( $file != . \) \ + -a \( $file != .. \) ] + then + #echo $file: + mkdir $file + (cd $file + pwd=`pwd` + case "$DIRFROM" in + /*) ;; + *) DIRFROM=../$DIRFROM ;; + esac + if [ `(cd $DIRFROM/$file; pwd)` = $pwd ] + then + echo "$pwd: FROM and TO are identical!" + exit 1 + fi + $0 $DIRFROM/$file + ) + fi + fi +done diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/defs.h b/usr/src/contrib/isode/others/quipu/uips/pod/defs.h new file mode 100644 index 0000000000..c8b51d7c07 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/defs.h @@ -0,0 +1,43 @@ +/* $Header: /f/osi/others/quipu/uips/pod/RCS/defs.h,v 7.1 91/02/22 09:31:28 mrose Interim $ */ + +#ifndef PODDEFS +#define PODDEFS + +#ifndef NULLCP +#define NULLCP (char *) 0 +#endif + +typedef short bool; + +typedef enum {rfc822, greybook} mailtype; + +typedef enum { + Okay, + timelimit, + timelimit_w_partial, + listsizelimit, + adminlimit, + adminlimit_w_partial, + nothingfound, + localdsaerror, + remotedsaerror, + duaerror, + attributerror, + namerror, + security, + updaterror, + serviceerror + } dsEnqError; + +typedef struct dsErrorStruct { + dsEnqError error; + char *err_mess; +} dsErrorStruct; + +#define RESBUF 10000 +#define MAXARGS 20 +#define STRINGLEN 1000 +#define SMALLSTRING 255 +#define MAXTYPES 255 + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.c b/usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.c new file mode 100644 index 0000000000..dd83be6c19 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.c @@ -0,0 +1,33 @@ +#include "dir_entry.h" + +int free_dir_entry(entry) + dirEntry entry; +{ + if (entry->entry_name) free(entry->entry_name); + (void) free_ent_attrs(entry->attrs); + free((char *) entry); +} + +int free_ent_attrs(attrs) + dirAttrs attrs; +{ + dirAttrs last_attr = 0; + for (; attrs; attrs = attrs->next) { + if (attrs->val_seq) free_mod_vals(attrs->val_seq); + if (attrs->attr_name) free(attrs->attr_name); + if (last_attr) free((char *) last_attr); + last_attr = attrs; + } +} + +int free_mod_vals(vals) + modVals vals; +{ + modVals last_val = 0; + for (; vals; vals = vals->next) { + if (vals->value) free(vals->value); + if (vals->new_value) free(vals->new_value); + if (last_val) free((char *)last_val); + last_val = vals; + } +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.h b/usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.h new file mode 100644 index 0000000000..e840797d8d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/dir_entry.h @@ -0,0 +1,46 @@ +#ifndef ENTRYSEQ +#define ENTRYSEQ + +#include +#include +#include "defs.h" + +#ifdef QUIPU_MALLOC + +#else +extern char * malloc (); +extern char * smalloc (); +#endif + +typedef struct mod_vals { + char *value; + char *new_value; + Widget text_widg; + bool mod_flag; + struct dir_attrs *attr; + struct mod_vals *next; +} mod_vals, *modVals; + +typedef struct dir_attrs { + char *attr_name; + modVals val_seq; + bool mod_flag; + bool in_flag; + bool hidden_flag; + struct dir_attrs *next; +} dir_attrs, *dirAttrs; + +typedef struct dir_entry { + char *entry_name; + dirAttrs attrs; + bool mod_flag; +} dir_entry, *dirEntry; + +#define NULLDIRENTRY ((dirEntry) 0) + +int free_dir_entry(); +int free_ent_attrs(); +int free_mod_vals(); + +#endif + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/filt.c b/usr/src/contrib/isode/others/quipu/uips/pod/filt.c new file mode 100644 index 0000000000..8f9e032abe --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/filt.c @@ -0,0 +1,500 @@ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/filt.c,v 7.2 91/02/22 09:31:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/filt.c,v 7.2 91/02/22 09:31:31 mrose Interim $ + */ + +#include +#include +#include + +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/entry.h" + +#include "filt.h" +#include "y.tab.h" +#include "defs.h" + +extern unsigned int curr_filt; +extern unsigned int filt_num; +extern unsigned int typeindx; +extern filt_struct *filt_arr[]; +extern char *filtvalue[]; +extern char *filttype[]; +extern char *default_arr[]; + +extern char mvalue[]; + +make_type(name_val, filt) + char * name_val; + filt_struct * filt; +{ + filttype[curr_filt] = (char *) malloc((unsigned int) (strlen(name_val) + 1)); + (void) strcpy(filttype[curr_filt], name_val); + + filt_arr[curr_filt] = filt; +} + +filt_struct *make_item_filter(oid, match, value) + char *oid; + int match; + char *value; +{ + register filt_struct * filt = (filt_struct *) malloc(sizeof(filt_struct)); + + filt->flt_type = ITEM; + filt->next = 0; + + filt->fu_cont.item.fi_type = match; + filt->fu_cont.item.stroid = + (char *) malloc((unsigned int) (strlen(oid) + 1)); + (void) strcpy(filt->fu_cont.item.stroid, oid); + + if (*value == '*') filt->fu_cont.item.name = (char *) 0; + else { + filt->fu_cont.item.name = + (char *) malloc((unsigned int) (strlen(value) + 1)); + (void) strcpy(filt->fu_cont.item.name, value); + } + return filt; +} + +filt_struct *link_filters(filt1, filt2) + filt_struct *filt1, *filt2; +{ + filt1->next = filt2; + return filt1; +} + +filt_struct *make_parent_filter(filt_type, filt1, filt2, filt3) + int filt_type; + filt_struct *filt1, *filt2, *filt3; +{ + filt_struct * parent = (filt_struct *) malloc(sizeof(filt_struct)); + + switch (filt_type) { + + case NOT: + parent->flt_type = NOT; + parent->fu_cont.sub_filt = filt1; + parent->next = 0; + break; + + case AND: + parent->flt_type = AND; + parent->fu_cont.sub_filt = filt1; + filt1->next = filt2; + filt2->next = filt3; + parent->next = 0; + break; + + default: + parent->flt_type = OR; + parent->fu_cont.sub_filt = filt1; + filt1->next = filt2; + filt2->next = filt3; + parent->next = 0; + break; + } + + return parent; +} + +free_filt(filt) + filt_struct *filt; +{ + if (filt) { + free_filt(filt->next); + + if (filt->flt_type = ITEM) { + free(filt->fu_cont.item.stroid); + if (filt->fu_cont.item.name) free(filt->fu_cont.item.name); + } else + free_filt(filt->fu_cont.sub_filt); + + free((char *) filt); + } else + return; +} + +Filter make_attr_filter() +{ + int match_type; + char attr_name[STRINGLEN], + attr_val[STRINGLEN], sub_val_initial[STRINGLEN], + sub_val_final[STRINGLEN], sub_val_any[STRINGLEN]; + register char *end, *start, *next; + char save; + Filter sfilt = filter_alloc(); + + sfilt->flt_type = FILTER_ITEM; + sfilt->flt_next = NULLFILTER; + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = NULLAttrV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = NULLAttrT; + + if (end = index(mvalue, '~')) match_type = APPROX; + else if (end = index(mvalue, '*')) match_type = SUBSTRING; + else match_type = EQUAL; + + start = mvalue; + while (isspace(*start) && *start != '\0') start++; + end = start; + while (!isspace(*end) && *end != '=' && *end != '~' + && *end != '*' && *end != '\0') end++; + save = *end; + *end = '\0'; + (void) strcpy(attr_name, start); + *end = save; + + if (attr_name [0] == '\0') { + (void) fprintf (stderr, + "Error: Cannot search, invalid syntax on filter '%s'.\n", + mvalue); + filter_free(sfilt); + return NULLFILTER; + } + + start = end + 1; + if (match_type != SUBSTRING) { + while (!isalnum(*start) && *start != '\0') start++; + + end = start; + + while (*end != '\0') end++; + while (!isalnum(*end) && end > start) end--; + if (*end != '\0') end++; + + save = *end; + *end = '\0'; + (void) strcpy(attr_val, start); + *end = save; + + if (attr_val[0] == '\0') { + (void) fprintf (stderr, + "Error: Cannot search, invalid syntax on filter '%s'.\n", + mvalue); + filter_free(sfilt); + return NULLFILTER; + } + } else { + while (!isalnum(*start) && *start != '*' && *start != '\0') start++; + + if (*start == '\0') { + (void) fprintf (stderr, + "Error: Cannot search, invalid syntax on filter '%s'.\n", + mvalue); + filter_free(sfilt); + return NULLFILTER; + } + + if (*start == '*') { + sub_val_initial[0] = '*'; + ++start; + while (isspace(*start) && *start != '\0') start++; + + if (*start == '\0' || !isalnum(*start)) { + (void) fprintf (stderr, + "Error: Cannot search, invalid syntax on filter '%s'.\n", + mvalue); + filter_free(sfilt); + return NULLFILTER; + } + + end = start; + while (isalnum(*end) && *end != '\0') end++; + + if (*end == '\0') { + (void) strcpy (sub_val_final, start); + sub_val_any[0] = '*'; + } else { + next = end; + + while (*next != '*' && *next != '\0') next++; + + if (*next == '*') { + sub_val_final[0] = '*'; + + save = *end; + *end = '\0'; + (void) strcpy(sub_val_any, start); + *end = save; + } else { + sub_val_any[0] = '*'; + + save = *end; + *end = '\0'; + (void) strcpy(sub_val_final, start); + *end = save; + } + } + } else if (isalnum(*start)) { + end = start; + while (!isspace(*end) && *end != '\0') end++; + + if (*end == '\0') { + (void) fprintf (stderr, + "Error: Cannot search, invalid syntax on filter '%s'.\n", + mvalue); + filter_free(sfilt); + return NULLFILTER; + } + + save = *end; + *end = '\0'; + + if (index ((char *) (end + 1), '*') == NULLCP) { + (void) fprintf (stderr, + "Error: Cannot search, invalid syntax on filter '%s'.\n", + mvalue); + filter_free(sfilt); + return NULLFILTER; + } else { + (void) strcpy(sub_val_initial, start); + sub_val_any[0] = sub_val_final[0] = '*'; + } + } + } + + switch (match_type) { + case APPROX: + case EQUAL: + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = AttrT_new(attr_name); + + if (match_type == EQUAL) + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; + else + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; + + if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax + == 0) { + (void) fprintf (stderr, + "Error: Cannot search, invalid attribute type '%s'.\n", + attr_name); + sfilt->flt_next = NULLFILTER; + filter_free(sfilt); + return NULLFILTER; + } + + if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = + str2AttrV(attr_val, + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type + ->oa_syntax)) == NULL) { + (void) fprintf (stderr, + "Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", + attr_val, attr_name); + filter_free(sfilt); + return NULLFILTER; + } + return sfilt; + + case SUBSTRING: + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_SUBSTRINGS; + + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = NULLAV; + + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_type = + AttrT_new(attr_name); + + if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type->oa_syntax + == 0) { + (void) fprintf (stderr, + "Error: Cannot search, invalid attribute type '%s'.\n", + attr_name); + filter_free(sfilt); + return NULLFILTER; + } + + if (sub_val_initial[0] != '*') + if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = + avs_comp_new(str2AttrV(sub_val_initial, + sfilt->flt_un.flt_un_item.fi_un. + fi_un_substrings.fi_sub_type + ->oa_syntax))) + == NULLAV) { + (void) fprintf (stderr, + "Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", + sub_val_initial, attr_name); + filter_free(sfilt); + return NULLFILTER; + } + + if (sub_val_any[0] != '*') + if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = + avs_comp_new(str2AttrV(sub_val_any, + sfilt->flt_un.flt_un_item.fi_un. + fi_un_substrings.fi_sub_type-> + oa_syntax))) + == NULLAV) { + (void) fprintf (stderr, + "Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", + sub_val_any, attr_name); + filter_free(sfilt); + return NULLFILTER; + } + + if (sub_val_final[0] != '*') + if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = + avs_comp_new(str2AttrV(sub_val_final, + sfilt->flt_un.flt_un_item.fi_un. + fi_un_substrings.fi_sub_type-> + oa_syntax))) + == NULLAV) { + (void) fprintf (stderr, + "Error: Cannot search, invalid value '%s' for attribute type '%s'.\n", + sub_val_final, attr_name); + filter_free(sfilt); + return NULLFILTER; + } + return sfilt; + default: + return NULLFILTER; + } +} + +Filter make_filter(filt) + filt_struct *filt; +{ + int type; + char svalue[STRINGLEN]; + Filter rfilt, sfilt; + + if (!filt) return NULLFILTER; + + if (index(mvalue, '=')) return make_attr_filter(); + + sfilt = filter_alloc(); + + switch(filt->flt_type) { + case ITEM: + sfilt->flt_type = FILTER_ITEM; + sfilt->flt_next = make_filter(filt->next); + + (void) strcpy(svalue, (filt->fu_cont.item.name? + filt->fu_cont.item.name: + mvalue)); + + type = filt->fu_cont.item.fi_type; + + switch(type) { + case APPROX: + case EQUAL: + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = + AttrT_new(filt->fu_cont.item.stroid); + + if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax == 0) { + rfilt = sfilt->flt_next; + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = NULLAttrV; + sfilt->flt_next = NULLFILTER; + filter_free(sfilt); + return rfilt; + } + + if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = + str2AttrV(svalue, + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax)) == NULLAttrV) { + rfilt = sfilt->flt_next; + sfilt->flt_next = NULLFILTER; + filter_free(sfilt); + return rfilt; + } + + if (type == EQUAL) + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; + else + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; + + break; + + case SUBSTRING: + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_SUBSTRINGS; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_type = + AttrT_new(filt->fu_cont.item.stroid); + + if (!sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type || + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax == 0) { + rfilt = sfilt->flt_next; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = + NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = + NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = + NULLAV; + sfilt->flt_next = NULLFILTER; + filter_free(sfilt); + return rfilt; + } + + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = + NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = + NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = + avs_comp_new(str2AttrV(svalue, + sfilt->flt_un.flt_un_item.fi_un. + fi_un_substrings.fi_sub_type-> + oa_syntax)); + if (sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any == + NULLAV) { + rfilt = sfilt->flt_next; + sfilt->flt_next = NULLFILTER; + filter_free(sfilt); + return rfilt; + } + + break; + + default: + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; + break; + } + return sfilt; + + case AND: + sfilt->flt_type = FILTER_AND; + sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); + sfilt->flt_next = make_filter(filt->next); + return sfilt; + + case OR: + sfilt->flt_type = FILTER_OR; + sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); + sfilt->flt_next = make_filter(filt->next); + return sfilt; + + case NOT: + sfilt->flt_type = FILTER_NOT; + sfilt->flt_next = make_filter(filt->next); + sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); + return sfilt; + + default: + return NULLFILTER; + } +} + + + + + + + + + + + + + + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/filt.h b/usr/src/contrib/isode/others/quipu/uips/pod/filt.h new file mode 100644 index 0000000000..496d336c5a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/filt.h @@ -0,0 +1,24 @@ +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/filt.h,v 7.2 91/02/22 09:31:32 mrose Interim $ + */ + + +#ifndef FILT +#define FILT + +typedef struct stroid_list { + int fi_type; + char *stroid; + char *name; +} filt_item; + +typedef struct filter_struct { + int flt_type; + union ftype { + filt_item item; + struct filter_struct *sub_filt; + } fu_cont; + struct filter_struct *next; +} filt_struct; + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/list.c b/usr/src/contrib/isode/others/quipu/uips/pod/list.c new file mode 100644 index 0000000000..77741e3073 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/list.c @@ -0,0 +1,163 @@ +#include + +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/entry.h" +#include "quipu/name.h" + +#include "sequence.h" +#include "filt.h" +#include "defs.h" + +extern str_seq dnseq, backseq, showseq; +extern int entry_number, back_buf_num, dn_number; + +#ifndef NO_STATS +extern LLog *log_stat; +#endif + +extern char goto_path[], base_path[], friendly_base_path[], mvalue []; + +str_seq SortList(); +void dn2buf(); + +dsEnqError list_start() +{ + struct ds_search_arg search_arg; + struct ds_search_result result; + struct DSError error; + dsEnqError return_error; + + return_error = Okay; + + if (get_default_service (&search_arg.sra_common) != 0) { + return localdsaerror; + } + + search_arg.sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + + search_arg.sra_baseobject = (*base_path != 'T'? + str2dn (base_path): + NULLDN); + + search_arg.sra_eis.eis_allattributes = FALSE; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTETYPESONLY; + search_arg.sra_eis.eis_select = 0; + + search_arg.sra_searchaliases = TRUE; + search_arg.sra_subset = SRA_ONELEVEL; + + search_arg.sra_filter = filter_alloc(); + search_arg.sra_filter->flt_type = FILTER_NOT; + search_arg.sra_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_un.flt_un_filter = filter_alloc(); + search_arg.sra_filter->flt_un.flt_un_filter->flt_type = FILTER_ITEM; + search_arg.sra_filter->flt_un.flt_un_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_type + = FILTERITEM_EQUALITY; + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un. + fi_un_ava.ava_type = AttrT_new("2.5.4.0"); + + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un. + fi_un_ava.ava_value = + str2AttrV("dsa", search_arg.sra_filter->flt_un.flt_un_filter-> + flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax); + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("search +%s,extent %d, val objectClass != dsa", + base_path,search_arg.sra_subset)); +#endif + + if (search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item. + fi_un.fi_un_ava.ava_value == NULLAttrV) { + return_error = localdsaerror; + } else if (ds_search (&search_arg, &error, &result) != DS_OK) { + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; + log_ds_error(&error); + ds_error_free(&error); + switch (error.dse_type) { + case DSE_LOCALERROR: + return_error = duaerror; + break; + case DSE_REMOTEERROR: + return_error = localdsaerror; + break; + case DSE_ATTRIBUTEERROR: + return_error = attributerror; + break; + case DSE_REFERRAL: + case DSE_DSAREFERRAL: + return_error = remotedsaerror; + break; + case DSE_SECURITYERROR: + return_error = security; + break; + case DSE_NAMEERROR: + return_error = namerror; + break; + case DSE_SERVICEERROR: + return_error = serviceerror; + break; + default: + return_error = localdsaerror; + break; + } + } else { + dn_number = 0; + if (result.CSR_entries != NULLENTRYINFO) { + register EntryInfo *ptr; + + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; + + for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; + ptr = ptr->ent_next) { + dn_number++; + dn2buf ((caddr_t)ptr->ent_dn, goto_path); + add_seq (&dnseq, goto_path); + } + + if (dn_number) dnseq = SortList(dnseq); + } else if (result.CSR_limitproblem == LSR_NOLIMITPROBLEM) { + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; + return_error = nothingfound; + } + + if (result.CSR_limitproblem != LSR_NOLIMITPROBLEM) { + switch (result.CSR_limitproblem) { + case LSR_TIMELIMITEXCEEDED: + if (dn_number > 0) return_error = timelimit_w_partial; + else { + free_seq(dnseq); + dnseq = NULLDS; + return_error = timelimit; + } + break; + case LSR_SIZELIMITEXCEEDED: + return_error = listsizelimit; + break; + case LSR_ADMINSIZEEXCEEDED: + if (dn_number > 0) return_error = adminlimit_w_partial; + else { + free_seq(dnseq); + dnseq = NULLDS; + return_error = adminlimit; + } + break; + } + } + if (result.CSR_entries) entryinfo_free(result.CSR_entries, 0); + } + entry_number = dn_number; + filter_free(search_arg.sra_filter); + dn_free(search_arg.sra_baseobject); + ds_error_free(&error); + return return_error; +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/main.c b/usr/src/contrib/isode/others/quipu/uips/pod/main.c new file mode 100644 index 0000000000..3a27426ab0 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/main.c @@ -0,0 +1,146 @@ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/main.c,v 7.2 91/02/22 09:31:34 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/main.c,v 7.2 91/02/22 09:31:34 mrose Interim $ + */ + +#include "quipu/util.h" +#include "quipu/photo.h" +#include "quipu/common.h" +#include "quipu/entry.h" +#include "quipu/dua.h" +#include "pod.h" + +#include + +extern int print_parse_errors; +extern char *oidtable, *tailfile, *myname; +extern char namestr[], passwd[]; +extern Widget toplevel; +extern bool testing; + +int podphoto(), quipu_pe_cmp(); +void CreateWidgets(), PodLoop(), displayStartupError(); +char *cnnct_bind(); +void kill_message(), message(); + +void user_tailor(); +void read_args(), quit(); + +main (argc, argv) + unsigned int argc; + char **argv; +{ + char *mess; + + print_parse_errors = FALSE; + quipu_syntaxes(); + want_oc_hierarchy(); + + namestr[0] = '\0'; + passwd[0] = '\0'; + + toplevel = XtInitialize("X-Directory", "Pod", NULL, 0, + &argc, argv); + + read_args(&argc, &argv); + dsap_init((int *) 0, &argv); + + user_tailor(); + + CreateWidgets(); + message("Connecting to Directory. Please Wait..."); + + if ((mess = cnnct_bind()) != NULLCP) { + kill_message(); + displayStartupError(mess); + XtMainLoop(); + quit(1); + } + + set_attribute_syntax (str2syntax("photo"), + (IFP)pe_cpy, NULLIFP, + NULLIFP, podphoto, + (IFP)pe_cpy, quipu_pe_cmp, + pe_free, NULLCP, + NULLIFP, TRUE ); + + kill_message(); + PodLoop(); + + return 0; +} + +void read_args(acptr, avptr) + unsigned int *acptr; + char ***avptr; +{ + register char *cp; + char **av; + int count; + + if (acptr == (unsigned int *) NULL) return; + if (*acptr <= 1) return; + + av = *avptr; + av++, count = 1; + + while ((cp = *av) && (*cp == '-')) { + switch (*++cp) { + case 'u': + if (*++av != NULLCP) (void) strcpy(namestr, *av); + count++; + break; + case 'p': + if (*++av != NULLCP) (void) strcpy(passwd, *av); + count++; + break; + case 'T': + if (*++av != NULLCP) oidtable = *av; + count++; + break; + case 'c': + if (*++av != NULLCP) myname = *av; + count++; + break; + case 't': + if (lexequ(*av, "-test") != 0) { + if (*++av != NULLCP) tailfile = *av; + count++; + } else { + testing = TRUE; + } + break; + } + av++; + count++; + } + *acptr -= count; + *avptr = av; +} + +void quit(sig) + int sig; +{ + (void) ds_unbind(); + exit(sig); +} + + +advise (va_alist) + va_dcl +{ + int code; + va_list ap; + extern LLog * log_dsap; + + va_start (ap); + + code = va_arg (ap, int); + (void) _ll_log (log_dsap, code, ap); + + va_end (ap); +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/make b/usr/src/contrib/isode/others/quipu/uips/pod/make new file mode 100644 index 0000000000..e7c3dd3b5c --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/make @@ -0,0 +1,8 @@ +: run this script through /bin/sh +: $Header: /f/osi/others/quipu/uips/pod/RCS/make,v 7.1 91/02/22 09:31:35 mrose Interim $ +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/modify.c b/usr/src/contrib/isode/others/quipu/uips/pod/modify.c new file mode 100644 index 0000000000..3a68efaa2f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/modify.c @@ -0,0 +1,742 @@ +#include +#include +#include +#include + +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/entry.h" +#include "quipu/modify.h" +#include "quipu/name.h" + +#include "sequence.h" +#include "dir_entry.h" +#include "defs.h" +#include "util.h" + +#define AS_SYNTAX(attrSeq) attrSeq->attr_type->oa_syntax +#define AS_STROID(attrSeq) attrSeq->attr_type->oa_ot.ot_stroid +#define FOREACH(a) for (eptr = a; eptr != NULLATTR; eptr=eptr->attr_link) + +extern bool photo_on; + +char *modify_error(); +Attr_Sequence as_sort(); +void char_map(), char_unmap(); + +static Attr_Sequence eptr; + +#ifndef NO_STATS +extern LLog *log_stat; +#endif + +struct entrymod * ems_append (a,b) + struct entrymod *a; + struct entrymod *b; +{ + struct entrymod *ptr; + + if ((ptr = a) == NULLMOD) + return b; + + for ( ; ptr->em_next != NULLMOD; ptr = ptr->em_next) + ; + + ptr->em_next = b; + return a; +} + + +dsErrorStruct modify_entry(mods) + dirEntry mods; +{ + struct ds_modifyentry_arg mod_arg; + dsErrorStruct mod_error; + struct DSError error; + struct entrymod *curr_mod = 0, *entrymods = 0; + AttributeType attr_type = 0; + AttributeValue attr_val = 0; + AV_Sequence attrVal_seq = 0; + register modVals curr_val; + dirAttrs attrs; + char err_buf[STRINGLEN], attr_val_buf[STRINGLEN]; + short attr_removed; + + if (get_default_service(&mod_arg.mea_common) != 0) { + mod_error.error = serviceerror; + mod_error.err_mess = strdup("Directory Service Error!\n"); + } + + mod_arg.mea_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + mod_arg.mea_object = str2dn(mods->entry_name); + + for (attrs = mods->attrs; attrs; attrs = attrs->next) { + if (attrs->mod_flag) { + attr_type = str2AttrT(attrs->attr_name); + + for (curr_val = attrs->val_seq; + curr_val && curr_val->mod_flag; + curr_val = curr_val->next) + ; + + if (!curr_val) { + if (attrs->in_flag) { + curr_mod = em_alloc(); + curr_mod->em_next = NULLMOD; + curr_mod->em_type = EM_REMOVEATTRIBUTE; + curr_mod->em_what = NULLATTR; + + curr_mod->em_what = as_comp_new(attr_type, NULLAV, NULLACL_INFO); + entrymods = ems_append(entrymods, curr_mod); + } + + curr_mod = em_alloc(); + curr_mod->em_next = NULLMOD; + curr_mod->em_type = EM_ADDATTRIBUTE; + curr_mod->em_what = NULLATTR; + + for (curr_val = attrs->val_seq; curr_val; curr_val = curr_val->next) { + char_unmap(attr_val_buf, curr_val->new_value); + if (attr_val_buf[0] != '\0') { + attr_val = str2AttrV(attr_val_buf, attr_type->oa_syntax); + if (attr_val) { + if (attrVal_seq) + attrVal_seq = avs_merge(attrVal_seq, avs_comp_new(attr_val)); + else + attrVal_seq = avs_comp_new(attr_val); + } else { + if (entrymods) ems_free(entrymods); + AttrT_free(attr_type); + mod_error.error = attributerror; + (void) sprintf(err_buf, + "Attribute Error!\nInvalid syntax for value %s type %s.", + curr_val->new_value, attrs->attr_name); + mod_error.err_mess = strdup(err_buf); + return mod_error; + } + } + } + + if (attrVal_seq) { + curr_mod->em_what = as_comp_new(AttrT_cpy(attr_type), + attrVal_seq, + NULLACL_INFO); + entrymods = ems_append(entrymods, curr_mod); + attrVal_seq = 0; + curr_mod = 0; + AttrT_free(attr_type); + } + } else { + if (attrs->in_flag) { + for (curr_val = attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + char_unmap(attr_val_buf, curr_val->value); + if (curr_val->mod_flag && attr_val_buf[0] != '\0') { + attrVal_seq = avs_comp_new(str2AttrV(attr_val_buf, + attr_type-> + oa_syntax)); + curr_mod = em_alloc(); + curr_mod->em_next = NULLMOD; + curr_mod->em_type = EM_REMOVEVALUES; + curr_mod->em_what = as_comp_new(AttrT_cpy(attr_type), + attrVal_seq, + NULLACL_INFO); + entrymods = ems_append(entrymods, curr_mod); + } + } + + for (curr_val = attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + char_unmap(attr_val_buf, curr_val->new_value); + if (curr_val->mod_flag && attr_val_buf[0] != '\0') { + attr_val = str2AttrV(attr_val_buf, + attr_type->oa_syntax); + if (attr_val) { + if (attrVal_seq) + attrVal_seq = avs_merge(attrVal_seq, + avs_comp_new(attr_val)); + else + attrVal_seq = avs_comp_new(attr_val); + } else { + if (entrymods) ems_free(entrymods); + AttrT_free(attr_type); + mod_error.error = attributerror; + (void) sprintf(err_buf, + "Attribute Error!\nInvalid syntax for value %s type %s.", + curr_val->new_value, attrs->attr_name); + mod_error.err_mess = strdup(err_buf); + return mod_error; + } + + curr_mod = em_alloc(); + curr_mod->em_next = NULLMOD; + curr_mod->em_type = EM_ADDVALUES; + curr_mod->em_what = as_comp_new(AttrT_cpy(attr_type), + attrVal_seq, + NULLACL_INFO); + entrymods = ems_append(entrymods, curr_mod); + } + } + } else { + curr_mod = em_alloc(); + curr_mod->em_next = NULLMOD; + curr_mod->em_type = EM_ADDATTRIBUTE; + + for (curr_val = attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + char_unmap(attr_val_buf, curr_val->new_value); + if (attr_val_buf[0] != '\0') { + attr_val = str2AttrV(attr_val_buf, + attr_type->oa_syntax); + if (attr_val) { + if (attrVal_seq) + attrVal_seq = avs_merge(attrVal_seq, + avs_comp_new(attr_val)); + else + attrVal_seq = avs_comp_new(attr_val); + } else { + if (entrymods) ems_free(entrymods); + AttrT_free(attr_type); + mod_error.error = attributerror; + (void) sprintf(err_buf, + "Attribute Error!\nInvalid syntax for value %s type %s.", + curr_val->new_value, attrs->attr_name); + mod_error.err_mess = strdup(err_buf); + return mod_error; + } + } + } + + if (attrVal_seq) { + curr_mod->em_what = as_comp_new(AttrT_cpy(attr_type), + attrVal_seq, + NULLACL_INFO); + entrymods = ems_append(entrymods, curr_mod); + attrVal_seq = 0; + curr_mod = 0; + AttrT_free(attr_type); + } + } + } + } + } + + if (entrymods) { + mod_arg.mea_changes = entrymods; + if (ds_modifyentry(&mod_arg, &error) != DS_OK) { + mod_error.err_mess = modify_error(&error); + + switch (error.dse_type) { + case DSE_LOCALERROR: + mod_error.error = duaerror; + if (!mod_error.err_mess) { + mod_error.err_mess = + strdup("Internal Error, No modifications made. Sorry!"); + } + break; + + case DSE_REMOTEERROR: + mod_error.error = localdsaerror; + break; + + case DSE_ATTRIBUTEERROR: + mod_error.error = attributerror; + if (!mod_error.err_mess) { + mod_error.err_mess = + strdup("Attribute Error! No Modifications made."); + } + break; + + case DSE_REFERRAL: + case DSE_DSAREFERRAL: + mod_error.error = remotedsaerror; + if (!mod_error.err_mess) { + mod_error.err_mess = + strdup("Referral Error! No Modifications made."); + } + break; + + case DSE_SECURITYERROR: + mod_error.error = security; + if (!mod_error.err_mess) { + mod_error.err_mess = strdup("Security Error! Check access rights."); + } + break; + + case DSE_NAMEERROR: + mod_error.error = namerror; + if (!mod_error.err_mess) { + switch (error.dse_un.dse_un_name.DSE_na_problem) { + case DSE_NA_NOSUCHOBJECT: + mod_error.err_mess = + strdup("Name Error! No such object."); + break; + case DSE_NA_ALIASPROBLEM: + case DSE_NA_ALIASDEREFERENCE: + mod_error.err_mess = strdup("Error! Alias problem."); + break; + case DSE_NA_INVALIDATTRIBUTESYNTAX: + mod_error.err_mess = + strdup("Name Error! Invalid attribute syntax."); + break; + } + } + break; + + case DSE_SERVICEERROR: + mod_error.error = serviceerror; + break; + + case DSE_UPDATEERROR: + mod_error.error = updaterror; + break; + + default: + mod_error.error = localdsaerror; + break; + } + ds_error_free(&error); + dn_free(mod_arg.mea_object); + return mod_error; + } else { + ems_free(entrymods); + delete_cache(mod_arg.mea_object); + } + } else { + mod_error.error = updaterror; + mod_error.err_mess = strdup("No modifications to make!"); + dn_free(mod_arg.mea_object); + return mod_error; + } + + for (attrs = mods->attrs; attrs; attrs = attrs->next) { + if (attrs->mod_flag == TRUE && attrs->in_flag == FALSE) + attrs->in_flag = TRUE; + attrs->mod_flag = FALSE; + + attr_removed = TRUE; + for (curr_val = attrs->val_seq; curr_val; curr_val = curr_val->next) { + if (curr_val->new_value != NULLCP) { + if (curr_val->value != NULLCP) free(curr_val->value); + curr_val->value = curr_val->new_value; + curr_val->new_value = NULLCP; + attr_removed = FALSE; + } + + if (curr_val->value && *curr_val->value != '\0' && !curr_val->mod_flag) + attr_removed = FALSE; + + curr_val->mod_flag = FALSE; + } + if (attr_removed) attrs->in_flag = FALSE; + } + mod_error.error = Okay; + dn_free(mod_arg.mea_object); + return mod_error; +} + + +void make_template(entry_name, attrs) + char *entry_name; + dirAttrs *attrs; +{ + static char buffer[RESBUF]; + PS ps; + extern AttributeType at_objectclass; + struct ds_read_arg read_arg; + struct ds_read_result result; + struct DSError error; + Entry read_entry; + Attr_Sequence as, read_attrs; + Attr_Sequence nas = 0, tas = 0, templ_as, make_template_as(); + + buffer[0] = '\0'; + *attrs = 0; + + if (*entry_name == '\0') return; + + if ((ps = ps_alloc(str_open)) == NULLPS) return; + if (str_setup(ps, buffer, RESBUF, 1) == NOTOK) return; + + if (get_default_service (&read_arg.rda_common) != 0) return; + + read_arg.rda_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + read_arg.rda_eis.eis_allattributes = TRUE; + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + + read_arg.rda_object = str2dn(entry_name); + + photo_on = FALSE; + + if ((read_entry = local_find_entry(read_arg.rda_object, FALSE)) + != NULLENTRY && + read_entry->e_data != E_TYPE_CONSTRUCTOR) { + read_attrs = read_entry->e_attributes; + } else { + if (ds_read(&read_arg, &error, &result) != DS_OK) { + photo_on = TRUE; + return; + } + if (result.rdr_entry.ent_attr == NULLATTR) { + photo_on = TRUE; + return; + } + + read_attrs = result.rdr_entry.ent_attr; + } + + for (as = read_attrs; as != NULLATTR; as = as->attr_link) + if (as->attr_type == at_objectclass) + break; + + templ_as = make_template_as(as->attr_value); + + for (as = read_attrs; + as != NULLATTR; + as = as->attr_link) + if (!(AS_SYNTAX(as) == str2syntax("schema") || + AS_SYNTAX(as) == str2syntax("objectclass") || + AS_SYNTAX(as) == str2syntax("acl") || + AS_SYNTAX(as) == str2syntax("edbinfo") || + AS_SYNTAX(as) == str2syntax("octetstring") || + !strcmp(AS_STROID(as), "0.9.2342.19200300.100.1.23") || + !strcmp(AS_STROID(as), "0.9.2342.19200300.100.1.24"))) { + nas = as_comp_new(AttrT_cpy(as->attr_type), + avs_cpy(as->attr_value), + NULLACL_INFO); + if (tas) tas = as_merge(tas, nas); + else tas = nas; + } + + as = templ_as; + nas = templ_as = 0; + for (; as != NULLATTR; as = as->attr_link) + if (!(AS_SYNTAX(as) == str2syntax("schema") || + AS_SYNTAX(as) == str2syntax("objectclass") || + AS_SYNTAX(as) == str2syntax("acl") || + AS_SYNTAX(as) == str2syntax("edbinfo") || + AS_SYNTAX(as) == str2syntax("octetstring") || + !strcmp(AS_STROID(as), "0.9.2342.19200300.100.1.23") || + !strcmp(AS_STROID(as), "0.9.2342.19200300.100.1.24"))) { + nas = as_comp_new(AttrT_cpy(as->attr_type), NULLAV, NULLACL_INFO); + if (templ_as) templ_as = as_merge(templ_as, nas); + else templ_as = nas; + } + + as = as_merge(tas, templ_as); + as = as_sort(as); + + my_as_print(ps, as, READOUT); + *--ps->ps_ptr = NULL, ps->ps_cnt++; + + photo_on = TRUE; + + ps_free(ps); + as_free(as); + + make_attr_sequence(buffer, attrs); +} + +make_attr_sequence(entry_string, attrs) + char *entry_string; + dirAttrs *attrs; +{ + register char *str, *sptr; + char save, buffer[RESBUF]; + modVals curr_val = 0; + dirAttrs curr_attr = 0; + AttributeType curr_attr_type; + int count = 0; + + str = sptr = entry_string; + while (1) { + str = index(sptr, '-'); + if (!str || str == sptr) return; + while (!isalpha(*str)) { + if (str < sptr) return; + else --str; + } + str++; + + save = *str; + *str = '\0'; + + if (curr_attr) { + if (strcmp(curr_attr->attr_name, sptr)) { + curr_val = 0; + curr_attr->next = (dirAttrs) malloc(sizeof(dir_attrs)); + curr_attr = curr_attr->next; + + curr_attr->next = 0; + curr_attr->val_seq = 0; + curr_attr->mod_flag = FALSE; + curr_attr->in_flag = TRUE; + + curr_attr->attr_name = strdup(sptr); + + curr_attr_type = str2AttrT(curr_attr->attr_name); + if (!strcmp(curr_attr_type->oa_ot.ot_stroid, "2.5.4.35")) + curr_attr->hidden_flag = TRUE; + else + curr_attr->hidden_flag = FALSE; + AttrT_free(curr_attr_type); + } + } else { + curr_attr = (dirAttrs) malloc(sizeof(dir_attrs)); + *attrs = curr_attr; + + curr_attr->next = 0; + curr_attr->val_seq = (modVals) 0; + curr_attr->mod_flag = FALSE; + curr_attr->in_flag = TRUE; + + curr_attr->attr_name = strdup(sptr); + + curr_attr_type = str2AttrT(curr_attr->attr_name); + if (!strcmp(curr_attr_type->oa_ot.ot_stroid, "2.5.4.35")) + curr_attr->hidden_flag = TRUE; + else + curr_attr->hidden_flag = FALSE; + AttrT_free(curr_attr_type); + } + + *str = save; + while ((isspace(*str) || (*str == '-')) && *str != '\n' && *str != '\0') + str++; + + sptr = str; + count = 0; + + while (1) { + while (*str != '\n' && *str != '\0') { + buffer[count++] = *str; + str++; + } + if (*str != '\0' && *(str + 1) == '\t') { + buffer[count++] = '\n'; + while (isspace(*str)) str++; + } else break; + } + + buffer[count] = '\0'; + save = *str; + *str = '\0'; + + if (curr_val) { + curr_val->next = (modVals) malloc(sizeof(struct mod_vals)); + curr_val = curr_val->next; + } else { + curr_val = (modVals) malloc(sizeof(struct mod_vals)); + curr_attr->val_seq = curr_val; + + if (!count) curr_attr->in_flag = FALSE; + } + curr_val->attr = curr_attr; + curr_val->next = 0; + curr_val->mod_flag = FALSE; + curr_val->new_value = 0; + curr_val->text_widg = 0; + + curr_val->value = strdup(buffer); + char_map(buffer, curr_val->value); + free(curr_val->value); + curr_val->value = strdup(buffer); + + *str = save; + if (*str == '\0' || *++str == '\0') return; + sptr = str; + } +} + +void char_map(buffer, value) + char *buffer, *value; +{ + if (value != NULLCP && *value != '\0') { + while (*value != '\0') { + switch (*value) { + case '$': + *buffer = '\n'; + break; + case '\\': + if (*((char *) (value + 1)) == '4' && + *((char *) (value + 2)) == '0') { + *buffer = '@'; + value += 2; + } + break; + default: + *buffer = *value; + } + value++; + buffer++; + } + } + + *buffer = '\0'; +} + +void char_unmap(buffer, value) + char *buffer, *value; +{ + if (value != NULLCP && *value != '\0') { + while (*value != '\0') { + switch (*value) { + case '\n': + *buffer = '$'; + break; + default: + *buffer = *value; + } + value++; + buffer++; + } + } + + *buffer = '\0'; +} + + +Attr_Sequence make_template_as(oc) + AV_Sequence oc; +{ + AV_Sequence avs; + Attr_Sequence newas; + Attr_Sequence as = NULLATTR; + table_seq optr; + AttributeType at; + objectclass * ocp; + + for (avs = oc; avs != NULLAV; avs = avs->avseq_next) { + ocp = (objectclass *) avs->avseq_av.av_struct; + for (optr = ocp->oc_must; optr != NULLTABLE_SEQ; optr = optr->ts_next) { + at = optr->ts_oa; + newas = as_comp_new(at, NULLAV, NULLACL_INFO); + as = as_merge(as, newas); + } + } + + for (avs = oc; avs != NULLAV; avs = avs->avseq_next) { + ocp = (objectclass *) avs->avseq_av.av_struct; + for (optr = ocp->oc_may; optr != NULLTABLE_SEQ; optr = optr->ts_next) { + at = optr->ts_oa; + newas = as_comp_new(at, NULLAV, NULLACL_INFO); + as = as_merge(as, newas); + } + } + return(as); +} + +/*Big Bodge!*/ +char *modify_error(error) + struct DSError *error; +{ + PS ps; + char buffer[RESBUF]; + char *str, *message; + + if ((ps = ps_alloc(str_open)) == NULLPS) { + return NULLCP; + } + + if (str_setup(ps, buffer, RESBUF, 1) == NOTOK) { + return NULLCP; + } + + ds_error(ps, error); + *ps->ps_ptr = 0; + ps_free(ps); + + str = buffer; + + if (*str != '\0') { + message = strdup(str); + } else message = NULLCP; + + return message; +} + + +my_as_comp_print (ps,as,format) + PS ps; + Attr_Sequence as; + int format; +{ + AV_Sequence avs; + char buffer[RESBUF]; + extern int oidformat; + + if (as!=NULLATTR) { + if (format == READOUT) + (void) sprintf(buffer,"%s",attr2name (as->attr_type, 1)); + else + (void) sprintf (buffer,"%s",attr2name_aux (as->attr_type)); + + if (split_attr (as)) { + if ((as->attr_value == NULLAV) && (format != READOUT)) + ps_printf (ps, "%s=\n", buffer); + else { + if (as->attr_value == NULLAV) { + ps_printf(ps, "%-21s - \n", buffer); + } else { + for (avs = as->attr_value; avs != NULLAV; avs = avs->avseq_next) { + if (format == READOUT) + ps_printf (ps, "%-21s - ", buffer); + else + ps_printf (ps, "%s= ", buffer); + avs_comp_print (ps, avs, EDBOUT); + ps_print (ps, "\n"); + } + } + } + } else { + if (format == READOUT) + ps_printf (ps, "%-21s - ", buffer); + else + ps_printf (ps, "%s= ", buffer); + avs_print (ps, as->attr_value, format); + } + } +} + +my_as_print (ps,as,format) +Attr_Sequence as; +PS ps; +int format; +{ + if (as != NULLATTR) + FOREACH(as) + my_as_comp_print(ps,eptr,format); +} + +Attr_Sequence as_sort(as) + Attr_Sequence as; +{ + Attr_Sequence with_vals = NULLATTR, without_vals = NULLATTR, next_as; + + if (as == NULLATTR) return as; + + while (as != NULLATTR) { + next_as = as->attr_link; + as->attr_link = NULLATTR; + + if (as->attr_value) with_vals = as_merge(with_vals, as); + else without_vals = as_merge(without_vals, as); + + as = next_as; + } + + as = with_vals; + + if (as != NULLATTR) + for (; as->attr_link != NULLATTR; as = as->attr_link) + ; + else return without_vals; + + as->attr_link = without_vals; + return with_vals; +} + + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/photo.c b/usr/src/contrib/isode/others/quipu/uips/pod/photo.c new file mode 100644 index 0000000000..06b861dc39 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/photo.c @@ -0,0 +1,128 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/photo.c,v 7.2 91/02/22 09:31:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/photo.c,v 7.2 91/02/22 09:31:38 mrose Interim $ + */ + + +#include "quipu/photo.h" +#include "pod.h" + +extern Widget toplevel; +extern Widget PhotoWindow; + +GC XCreateGC(); +void make_photo_widget(); + +GC gc; +char photo_name[1024]; +Pixmap photo_pixmap = 0; +Display *dpy; +Screen *scr; +int winX, winY, winW, winH; +extern int NUMLINES,PIC_LINESIZE; +extern unsigned position; +unsigned long XorVal; + +static int passno = 1; +static int x, y; +int px, py, maxx; +int two_passes; + +/*ARGSUSED*/ +int photo_start(name) + char *name; +{ + x = y = 0; + if (passno == 1) + maxx = 0, two_passes = 1; + return 0; +} + +int photo_end(name) + char *name; +{ + if (passno == 1) { + passno = 2; + px = x = maxx; + py = --y; + + make_photo_widget(); + + dpy = XtDisplay(toplevel); + scr = DefaultScreenOfDisplay(dpy); + + winW = x; + winH = y; + + photo_pixmap = XCreatePixmap(dpy, XtWindow(PhotoWindow), + (Dimension) x, (Dimension) y, + DefaultDepthOfScreen(scr)); + gc = XCreateGC(dpy, photo_pixmap, 0, NULL); + + XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel); + XSetFunction(dpy, gc, GXclear); + + XSetBackground(dpy, gc, WhitePixelOfScreen(scr)); + XSetForeground(dpy, gc, BlackPixelOfScreen(scr)); + + XFillRectangle(dpy, photo_pixmap, gc, 0, 0, winW,winH); + + XSetFunction(dpy, gc, GXcopy); + + XSetForeground(dpy, gc, BlackPixelOfScreen(scr)); + XSetBackground(dpy, gc, WhitePixelOfScreen(scr)); + + XFillRectangle(dpy, photo_pixmap, gc, 0, 0, winW,winH); + XSetFunction(dpy, gc, GXclear); + + return 0; + } + if (name && *name) (void) strcpy(photo_name, name); + passno = 1; + x = y = maxx = 0; + return 0; +} + +/*ARGSUSED*/ +int photo_line_end(line) + bit_string *line; +{ + /* the end of a line has been reached */ + /* A bit string is stored in line->dbuf_top */ + + if (passno == 1 && x > maxx) + maxx = x; + x = 0, y++; + + return 0; +} + +int photo_black(length) + int length; +{ + if (passno == 1) { + x += length; + return 0; + } + /* draw a black line of 'length' pixels */ + return 0; +} + +int photo_white(length) + int length; +{ + if (passno == 1) { + x += length; + return 0; + } + + /* draw a white line of 'length' pixels */ + XDrawLine (dpy, photo_pixmap, gc, position, + NUMLINES, length+position-1, NUMLINES); + + return 0; +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/pod.1c b/usr/src/contrib/isode/others/quipu/uips/pod/pod.1c new file mode 100644 index 0000000000..e920b9f024 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/pod.1c @@ -0,0 +1,109 @@ +.\"$Header: /f/osi/others/quipu/uips/pod/RCS/pod.1c,v 7.2 91/02/22 09:31:39 mrose Interim $" +.TH Pod 1C "16 Jan 1909" +.SH NAME +Pod \- X-windows based directory user agent. +.SH SYNOPSIS +.B pod +[ OPTIONS ] +.SH DESCRIPTION +.PP +\fIPod\fR is an x-windows interface to +the Quipu implementation of the X500 directory intended for +novice users. +.PP +X500 is a worldwide directory service providing +information on people, places and organizations. +As yet it is still in it's infancy and thus the amount +of information contained in the directory is limited. +The directory can be thought of as an `electronic phonebook'. +Like a phonebook, +a geographic structure is imposed on the data; +no phonebook lists all people in the world in a single alphabetic sequence. +It is necessary to have some idea of where a person might be before starting +to search for them. +The directory is similar; +information is held in a hierarchical structure, +with data on countries held at the top level of the hierarchy +and information on organizations, +and the entities contained therein +(people, +departments etc.), +held below this. +.PP +\fIPod\fR relies heavily on the concept of the user 'navigating' +around the directory database, +'visiting' entries. +At any one time the user occupies a single position in the +directory, +where this position corresponds to some directory entry, +e.g. the country Great Britain. +The name of the currently visited entry +is shown in the upper right window of +\fIpod\fR's main screen. +This name has a form similar to that of a postal address, +as shown in the example below. +.sp +.in +.5i +.nf +The World +.br +GB +.br +Brunel University +.fi +.in -.5i +.sp +The user can browse below the current position using +the search and list functions, +details of which can be found using the on-line help +system. +Information on entries visited is displayed automatically +in the lower right window of the main screen. +.br +.SH "OPTIONS" +Pod supports the command line options listed below. +.TP 12 +.BI \-c +Bind to named directory system agent. +Pod binds to your local dsa, +if not otherwise requested. +.TP +.BI \-u +Bind as the specified user. +This name must be a quoted distinguished name. +.TP +.BI \-p +The password to bind against. +.TP +.BI \-fn +Use named font. +The default font is helvetica, +with point size 11. +.TP +.BI \-display +Run pod on named display. +As with all other X applications, +pod looks for the environment variable 'DISPLAY' +or else runs on 'unix:0.0'. +.TP +.BI \-fg +Set foreground colour. +.TP +.BI \-bg +Set background colour. +.SH "SEE ALSO" +dish(1c) sd(1c) xd(1c) sd(5) +.br +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594: +\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory\fR +.SH AUTHORS +Damanjit.Mahl@brunel.ac.uk +.br +Andrew.Findlay@brunel.ac.uk +.br +Stefan.Nahajski@brunel.ac.uk +.br + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/pod.5 b/usr/src/contrib/isode/others/quipu/uips/pod/pod.5 new file mode 100644 index 0000000000..41e209443f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/pod.5 @@ -0,0 +1,174 @@ +.TH POD 5 "16 May 1990" +.SH NAME +pod \- X-windows based directory user agent. +.SH SYNOPSIS +.B pod +.SH DESCRIPTION +.PP +Read and search calls to the directory in \fIpod\fR are carried out +using parameters specified in configuration files contained +in a configuration directory. +This directory can be held on a per-user basis, +and will otherwise default to a system-wide default directory +held in the ETCDIR defined during isode installation. +These directories are called \*(lq$(HOME)/.duaconfig\*(rq and +\*(lq$(ETCDIR)/xd/duaconfig\*(rq respectively. +.PP +Configuration is trivial in the case of reads, +requiring a list of numeric OIDs +(one on each line), +specifying the attribute types to be read. +A sample section of the default configuration file +(called readTypes and held in one of the above configuration directories) +is, +.sp +.in +.5i +.nf +"alias" 2.5.6.1 +"c" 2.5.4.6 +"l" 2.5.4.7 +.fi +.in -.5i +.sp +where the quoted sections +(required but always ignored) +state the actual name of the type specified and the numeric +sections equate to their actual OIDs. +.PP +Configuration of search is more complicated +and is best illustrated by describing the search mechanism used by \fIpod\fR +(for information on how to use \fIpod\fR consult section 1c of the manual). +Each attribute type in an \fIpod\fR search consists of a +complex filter, +that may make use of a number of actual primitive attribute types. +Thus a search using the \fIpod\fR type \*(lqPerson\*(rq, +as provided in the default configuration set-up, +actually corresponds to the filter, +.sp +.in +.5i +.nf +objectClass=person AND ( commonName ~= * + OR surname~= * + OR title~= *) +.fi +.in -.5i +.sp +where '*' means the value supplied at +search-time, '~=' means approximately matches, '%=' means substring matches +and '=' means exactly matches. +Each of the types used by \fIpod\fR is described in a separate +file called \*(lq/filterTypes/Type_*\*(rq under +one of the configuration directories described above +(note that each file name must have the prefix \*(lqType_\*(rq). +The set of filter-types provided +(Person, +Place, +Department, +Organization) +can thus be added to or modified as wished. +The precise syntax that must be used is shown in the +follwing example, +.sp +.in +.5i +.nf +#Composition of type Place +name:"Place" +( & ( | (2.5.4.0 = "country") #"objectClass" + (2.5.4.0 = "room") # ditto + (2.5.4.0 = "locality")) # ditto + ( | (2.5.4.7 ~= *) #"l" - locality + (2.5.4.8 ~= *) #"stateOrProvinceName" + (2.5.4.6 ~= *) #"c" - country + (0.9.2342.19200300.100.1.6 ~= *) #"roomNumber" + (2.5.4.3 ~= *))) #"cn" - "commonName" +.fi +.in -.5i +.sp +The first thing to note is that comments begin with a '#'. +The rest of the line following a '#' is ignored. +The name used by \fIpod\fR to denote the type is +specified using the syntax +.sp +.in +.5i +.nf +name:"STRING". +.fi +.in -.5i +.sp +The following lines describe the filter that the type +is composed of. +It has a lisp-like syntax and uses symbols that correspond +to those used in \fIdish\fR. +The points to note are; +.sp +.in +.5i +.nf +(1) Each filter or filter-item must be enclosed in brackets. +(2) Hard-wired values (as in 2.5.4.0 = "country" above) + must be enclosed in quotes. +(3) '*' denotes a value supplied at search time. +.fi +.in -.5i +.sp +.PP +Additions to the search types will make modification to the +\*(lqtypeDefaults\*(rq file necassary. +This describes the set of types, +chosen from those specified as above, +that are available to search with when +a specific level of the DIT, +e.g. country level, +is occupied by the user. +In addition it specifies the default type at any level. +A typical \*(lqtypeDefaults\*(rq file is shown below, +.sp +.in +.5i +.nf +# +# Format is: +# OID of RDN: Types available at this level: Default type +# +2.5.4.10:Person, Place, Department: Person +2.5.4.11:Person, Place, Department: Person +2.5.4.6:Place, Organization:Organization +2.5.4.7:Place, Organization, Department: Organization +@: Place: Place +.fi +.in -.5i +.sp +Each line, +composed of three colon separated fields, +specifies defaults for one level of the DIT. +The first field contains the numeric OID of an attribute that may be used +as an RDN. +The root entry, +though, +is specified by an \*(lq@\*(rq character, +as can be seen in the lowermost line. +The first line contains the OID for \*(lqorganizationName\*(rq. +The second field describes the types that are available to the user +when occupying the specified level of the DIT. +The third field, +which must also be a member of the second field, +states the default type available at this level. +Thus the first line says that the types Person, +Place and Department are available at the orgainzational level, +and that the default type given to the user is Person. +.PP +To view the list of OID's used in the directory, use the 'oiddump' tool +provided with isode. +(held in 'ISODE/others/quipu/tools'). +.SH "SEE ALSO" +xd(1c) sd(1c) dish(1c) pod(1c) +.br +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594:\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory\fR +.SH AUTHOR +Andrew.Findlay@brunel.ac.uk +.br +Damanjit.Mahl@brunel.ac.uk +.br +Stefan.Nahajski@brunel.ac.uk + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/pod.c b/usr/src/contrib/isode/others/quipu/uips/pod/pod.c new file mode 100644 index 0000000000..2c651e1047 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/pod.c @@ -0,0 +1,3456 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/pod.c,v 7.2 91/02/22 09:31:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/pod.c,v 7.2 91/02/22 09:31:41 mrose Interim $ + */ + +#include "bitmap" +#include "pod.h" +#include "defs.h" +#include "dir_entry.h" + +#include +#include + +dsEnqError srch_start(), read_config_types(), list_start(), read_all(); +dsErrorStruct modify_entry(); + +void make_friendly(), make_template(); +void quit(); + +extern bool read_all_flag; + +extern char base_path[]; +extern char friendly_base_path[]; +extern char mvalue[]; + +extern unsigned int filt_num, typeindx; +extern int *av_typeindx; + +extern char *filtvalue[]; +extern char *filttype[]; + +extern char dua_help_dir[]; + +extern int NUMLINES; +extern int px, py, maxx; +extern Pixmap photo_pixmap; +extern bool photo_on; + +Widget PhotoWindow; +Pixmap icon; + +extern int sizelimit, histlimit; + +char curr_help[STRINGLEN]; +char curr_selection[STRINGLEN]; +char help_string[RESBUF]; + +static Widget standby = 0, error_popup = 0, + curr_read_popup = 0, curr_list_popup = 0, + curr_modify_popup = 0; + +static Display *dpy; +static Screen *screen; +static int scr; + +extern str_seq showseq, dnseq, backseq; +extern int entry_number, dn_number, back_buf_num; + +int element_number = 0; +int rdn_number = 0; +int help_up = 0; + +static void CreateCurrPosWindow(), CreateSearchWindow(), CreateMessagePopup(); +static void CreateErrorPopup(), CreateHelpPopup(), CreateHistoryPopup(); +static void CreateCommandForm(); +static dirEntry createModifyTemplate(); +static Widget createModifyPopup(), createReadPopup(); +static Widget createTypeMenu(); +static void Quit(), QuitFromHelp(), InsertHelp(); +static void List(), ListDestroy(), Close(); +static void AddNewList(), ListSelect(), destroyList(), keepList(); +static void Move(), DnMoveRead(), DnMove(); +static void SetType(), Read(), Help(), ReadAll(); +static void TSearch(), ClearSearchArea(), StartSearch(); +static void createList(); +static void createHistoryPopup(), popupHistory(), popdownHistory(); +static void displayReadPopup(), readDestroy(), keepRead(); +static void submitModif(), closeModify(), modifyEntry(), addValField(); +static void UndoValChanges(), UndoAttrChanges(), modUpdate(), keepModify(); +static void killError(), doError(); +static void ChangeHelp(); +static void buttonPress(); +static void SetBorder(), UnSetBorder(); +static void freeEntry(), freeSpace(), CutString(); +static void ListSelectList(), DnList(); +static void ListSelectMove(); + +static bool ConvSel(); +static int GetTextWidth(), GetTextHeight(); +static void PopupMessage(); +static void entry_print(); +static void displayModMessage(); +static void kill_error(); +void kill_message(), message(); + +void CreateBackgroundPixmap(); +void displayError(); +void print_photo(), kill_photo(), make_photo_widget(); + +Widget toplevel, outer; + +static XtActionsRec buttonActionsTable[] = { + {"ChangeHelp", (XtActionProc) ChangeHelp}, + {"buttonPress", (XtActionProc) buttonPress}, +}; + +static XtActionsRec borderActionsTable[] = { + {"SetBorder", (XtActionProc) SetBorder}, + {"UnSetBorder", (XtActionProc) UnSetBorder}, +}; + +static XtActionsRec listActionsTable[] = { + {"ListSelectList", (XtActionProc) ListSelectList}, + {"ListSelectMove", (XtActionProc) ListSelectMove}, +}; + +static XtActionsRec currPosActionsTable[] = { + {"DnList", (XtActionProc) DnList}, + {"DnMove", (XtActionProc) DnMove}, +}; + +void CreateWidgets() +{ + int count; + Arg args[MAXARGS]; + + count = 0; + outer = XtCreateManagedWidget("outer", formWidgetClass, toplevel, + args, count); + + dpy = XtDisplay(toplevel); + scr = DefaultScreen(dpy); + screen = XtScreen(toplevel); + + XtAddActions(buttonActionsTable, XtNumber(buttonActionsTable)); + XtAddActions(borderActionsTable, XtNumber(borderActionsTable)); + XtAddActions(listActionsTable, XtNumber(listActionsTable)); + XtAddActions(currPosActionsTable, XtNumber(currPosActionsTable)); + + curr_help[0] = '\0'; + CreateCurrPosWindow(outer); + CreateSearchWindow(outer); + CreateCommandForm(outer); + CreateHistoryPopup(backseq, ""); + CreateHelpPopup(); + CreateMessagePopup(); + CreateErrorPopup(); +} + +void PodLoop() +{ + Widget PosWindow; + XSizeHints hints; + + XtRealizeWidget(toplevel); + + icon = XCreatePixmapFromBitmapData(dpy, XtWindow(toplevel), + icon_bits, icon_width, icon_height, + BlackPixelOfScreen(screen), + WhitePixelOfScreen(screen), + DefaultDepthOfScreen(screen)); + + hints.flags = 0; + XSetStandardProperties(dpy, XtWindow(toplevel), "Pod", "Directory", + icon, (char **) 0, (int) 0, &hints); + + PosWindow = XtNameToWidget(outer, + "PosForm.PosScrolledWindow.PosWindow"); + print_search_area(PosWindow); + + if (DefaultDepthOfScreen(screen) == 1) { + CreateBackgroundPixmap(XtNameToWidget(outer, "MainButtonForm"), + gray_bits, gray_width, gray_height); + + CreateBackgroundPixmap(outer, gray_bits, gray_width, gray_height); + CreateBackgroundPixmap(XtNameToWidget(outer, "TypeForm"), + gray_bits, gray_width, gray_height); + } + + CreateBackgroundPixmap(XtNameToWidget(outer, "MainButtonForm.searchButton"), + Search_bits, Search_width, Search_height); + + CreateBackgroundPixmap(XtNameToWidget(outer, "MainButtonForm.listButton"), + List_bits, List_width, List_height); + + CreateBackgroundPixmap(XtNameToWidget(outer, "MainButtonForm.historyButton"), + History_bits, History_width, History_height); + + CreateBackgroundPixmap(XtNameToWidget(outer, "MainButtonForm.quitButton"), + Quit_bits, Quit_width, Quit_height); + + CreateBackgroundPixmap(XtNameToWidget(outer, "MainButtonForm.helpButton"), + Help_bits, Help_width, Help_height); + + goto_addr(); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + + XtMainLoop(); +} + +void make_photo_widget() +{ + int count; + Arg args[MAXARGS]; + Widget TextForm, TextWindow; + + TextForm = XtNameToWidget(curr_read_popup, + "ReadForm.TextScrolledWindow.TextForm"); + TextWindow = XtNameToWidget(curr_read_popup, + "ReadForm.TextScrolledWindow.TextForm.AttrWindow"); + + count = 0; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNforeground, WhitePixelOfScreen(screen)); count++; + XtSetArg(args[count], XtNbackground, BlackPixelOfScreen(screen)); count++; + XtSetArg(args[count], XtNwidth, (Dimension) maxx); count++; + XtSetArg(args[count], XtNheight, (Dimension) py); count++; + XtSetArg(args[count], XtNlabel, ""); count++; + XtSetArg(args[count], XtNfromVert, TextWindow); count++; + PhotoWindow = XtCreateManagedWidget("PhotoWindow", + labelWidgetClass, + TextForm, args, count); +} + +void kill_photo() +{ + if (PhotoWindow != NULL) { + XtUnmanageChild(PhotoWindow); + XtDestroyWidget(PhotoWindow); + PhotoWindow = (Widget) 0; + } +} + +void print_photo() +{ + int count; + Arg args[MAXARGS]; + + count = 0; + if (photo_pixmap) { + XtSetArg(args[count], XtNbackgroundPixmap, photo_pixmap); count++; + } + XtSetArg(args[count], XtNresizable, FALSE); count++; + XtSetValues(PhotoWindow, args, count); + + photo_pixmap = (Pixmap) 0; +} + +static void createList(list_seq, top_mess, lower_mess) + str_seq list_seq; + char *top_mess, *lower_mess; +{ + int count = 0; + Widget shell, swindow, ListForm, ListWindow, + closeButton, keepButton; + Arg args[MAXARGS]; + + if (curr_list_popup) { + if (!XtIsManaged(curr_list_popup)) XtManageChild(curr_list_popup); + shell = curr_list_popup; + + ListForm = XtNameToWidget(shell, "ListForm"); + swindow = XtNameToWidget(shell, + "ListForm.ListScrolledWindow"); + ListWindow = XtNameToWidget(shell, + "ListForm.ListScrolledWindow.ListWindow"); + + XawFormDoLayout(ListForm, FALSE); + + XtUnmanageChild(ListWindow); + XtDestroyWidget(ListWindow); + + count = 0; + ListWindow = XtCreateWidget("ListWindow", formWidgetClass, + swindow, args, count); + + AddNewList(ListWindow, list_seq, (unsigned) entry_number); + XtRealizeWidget(ListWindow); + XtManageChild(ListWindow); + + XawFormDoLayout(ListForm, TRUE); + + count = 0; + XtSetArg(args[count], XtNlabel, top_mess); count++; + XtSetValues(XtNameToWidget(shell, "ListForm.ListTitle"), + args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, lower_mess); count++; + XtSetValues(XtNameToWidget(shell, "ListForm.ListMessage"), + args, count); + + XRaiseWindow(dpy, XtWindow(shell)); + return; + } + + count = 0; + shell = XtCreatePopupShell("ListOutput", topLevelShellWidgetClass, + toplevel, args, 0); + count = 0; + ListForm = XtCreateManagedWidget("ListForm", formWidgetClass, + shell, args, count); + + count = 0; + XtSetArg(args[count], XtNheight, Close_height); count++; + XtSetArg(args[count], XtNwidth, Close_width); count++; + closeButton = XtCreateManagedWidget("closeButton", + commandWidgetClass, + ListForm, args, count); + + XtAddCallback(closeButton, XtNcallback, + (XtCallbackProc) destroyList, (XtPointer) shell); + + count = 0; + XtSetArg(args[count], XtNheight, Keep_height); count++; + XtSetArg(args[count], XtNwidth, Keep_width); count++; + keepButton = XtCreateManagedWidget("keepButton", + commandWidgetClass, + ListForm, args, count); + + XtAddCallback(keepButton, XtNcallback, + (XtCallbackProc) keepList, (XtPointer) shell); + + count = 0; + XtSetArg(args[count], XtNlabel, top_mess); count++; + (void) XtCreateManagedWidget("ListTitle", labelWidgetClass, + ListForm, args, count); + + count = 0; + swindow = XtCreateManagedWidget("ListScrolledWindow", viewportWidgetClass, + ListForm, args, count); + + count = 0; + ListWindow = XtCreateManagedWidget("ListWindow", formWidgetClass, + swindow, args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, lower_mess); count++; + (void) XtCreateManagedWidget("ListMessage", labelWidgetClass, + ListForm, args, count); + + XtAddCallback(ListWindow, XtNdestroyCallback, + ListDestroy, (XtPointer) list_seq); + + AddNewList(ListWindow, list_seq, (unsigned) entry_number); + + XtRealizeWidget(shell); + XtPopup(shell, XtGrabNone); + + curr_list_popup = shell; + + CreateBackgroundPixmap(closeButton, Close_bits, Close_width, Close_height); + CreateBackgroundPixmap(keepButton, Keep_bits, Keep_width, Keep_height); + if (DefaultDepthOfScreen(screen) == 1) + CreateBackgroundPixmap(ListForm, gray_bits, gray_width, gray_height); +} + +static void CreateCurrPosWindow(parent) + Widget parent; +{ + int count; + Widget PosForm, swindow, title; + Arg args[MAXARGS]; + + count = 0; + PosForm = XtCreateManagedWidget("PosForm", formWidgetClass, + parent, args, count); + count = 0; + title = XtCreateManagedWidget("PosTitle", commandWidgetClass, PosForm, + args, count); + + XtAddCallback(title, XtNcallback, CutString, (XtPointer) base_path); + + count = 0; + swindow = XtCreateManagedWidget("PosScrolledWindow", viewportWidgetClass, + PosForm, args, count); + + count = 0; + (void) XtCreateManagedWidget("PosWindow", formWidgetClass, + swindow, args, count); +} + +static XtActionsRec actionsTable[] = { + {"TSearch", (XtActionProc) TSearch}, + {"ClearSearchArea", (XtActionProc) ClearSearchArea}, +}; + +static char defaultTranslations[] = + "Return: TSearch() \n\ + CtrlM: TSearch() \n\ + CtrlO: TSearch() \n\ + CtrlJ: TSearch() \n\ + CtrlU: ClearSearchArea()"; + +static void CreateSearchWindow(parent) + Widget parent; +{ + int count; + Arg args[MAXARGS]; + Widget TypeForm, SearchVal; + XtTranslations trans_table; + XFontStruct *font; + Dimension height; + + count = 0; + TypeForm = XtCreateManagedWidget("TypeForm", formWidgetClass, + parent, args, count); + + + count = 0; + XtSetArg(args[count], XtNlabel, "Searching For "); count++; + (void) XtCreateManagedWidget("SearchValLabel", labelWidgetClass, + TypeForm, args, count); + + count = 0; + XtSetArg(args[count], XtNeditType, XawtextEdit); count++; + SearchVal = XtCreateManagedWidget("SearchVal", + asciiTextWidgetClass, + TypeForm, args, count); + + count = 0; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(SearchVal, args, count); + + height = FONTHEIGHT(font); + height += 8; + + count = 0; + XtSetArg(args[count], XtNheight, height); count++; + XtSetValues(SearchVal, args, count); + count = 0; + + XtSetArg(args[count], XtNlabel, " "); count++; + (void) XtCreateManagedWidget("TypeButton", menuButtonWidgetClass, + TypeForm, args, count); + + XtSetKeyboardFocus(parent, SearchVal); + + XtAddActions(actionsTable, XtNumber(actionsTable)); + trans_table = XtParseTranslationTable(defaultTranslations); + XtOverrideTranslations(SearchVal, trans_table); +} + +void add_to_history(seqnum) + int seqnum; +{ + int count; + char curr_base[STRINGLEN]; + Widget history_form, history_display, scrolwin; + Arg args[MAXARGS]; + str_seq first; + + history_form = XtNameToWidget(toplevel, "Session History.HistoryForm"); + + history_display = XtNameToWidget(history_form, + "ListScrolledWindow.ListWindow"); + scrolwin = XtParent(history_display); + + XawFormDoLayout(history_form, FALSE); + + XtUnmanageChild(history_display); + XtDestroyWidget(history_display); + + count = 0; + history_display = XtCreateWidget("ListWindow", formWidgetClass, + scrolwin, args, count); + + if (seqnum > histlimit) { + first = backseq; + backseq = backseq->next; + first->next = NULLDS; + free_seq(first); + back_buf_num--; + } + + (void) strcpy(curr_base, base_path); + base_path[0] = '\0'; + + AddNewList(history_display, backseq, (unsigned) back_buf_num); + + XtRealizeWidget(history_display); + XtManageChild(history_display); + + (void) strcpy(base_path, curr_base); + XawFormDoLayout(history_form, TRUE); + +} + +print_search_area(PosWindow) + Widget PosWindow; +{ + char *str, *end, save, name_array[STRINGLEN]; + char *trans_start_btn2 = ": DnList(", + *trans_start_btn3 = ": DnMove(", + translations[STRINGLEN], + trans_buf[SMALLSTRING]; + Dimension width; + int count; + Arg args[MAXARGS]; + Widget rdn_window, last_rdn = 0; + XtTranslations trans_table; + + count = 0; + XtSetArg(args[count], XtNwidth, &width); count++; + XtGetValues(PosWindow, args, count); + + width -= 24; + + count = 0; + XtSetArg(args[count], XtNlabel, ("The World")); count++; + XtSetArg(args[count], XtNborderWidth, 0); count++; + XtSetArg(args[count], XtNborderColor, WhitePixelOfScreen(screen)); count++; + XtSetArg(args[count], XtNhighlightThickness, 1); count++; + XtSetArg(args[count], XtNjustify, XtJustifyLeft); count++; + XtSetArg(args[count], XtNwidth, width); count++; + rdn_window = XtCreateManagedWidget("x", commandWidgetClass, + PosWindow, args, count); + XtAddCallback(rdn_window, XtNcallback, DnMoveRead, (XtPointer) 0); + + (void) sprintf(trans_buf, "%d", 0); + + (void) strcpy(translations, trans_start_btn2); + (void) strcat(translations, trans_buf); + (void) strcat(translations, ") \n\ "); + (void) strcat(translations, trans_start_btn3); + (void) strcat(translations, trans_buf); + (void) strcat(translations, ")"); + + trans_table = XtParseTranslationTable(translations); + XtOverrideTranslations(rdn_window, trans_table); + + last_rdn = rdn_window; + + rdn_number = 1; + + (void) strcpy (name_array, "xx"); + + make_friendly(friendly_base_path, base_path); + end = friendly_base_path; + + while (*end != '\0') end++; + str = end; + + while (str > (char *) friendly_base_path) { + while (*str != ',' && str > (char *) friendly_base_path) str--; + while (!isalnum(*str)) str++; + + save = *end; + *end = '\0'; + + count = 0; + XtSetArg(args[count], XtNlabel, (*str? str: "ahem")); count++; + XtSetArg(args[count], XtNborderWidth, 0); count++; + XtSetArg(args[count], XtNborderColor, WhitePixelOfScreen(screen)); count++; + XtSetArg(args[count], XtNhighlightThickness, 1); count++; + XtSetArg(args[count], XtNjustify, XtJustifyLeft); count++; + XtSetArg(args[count], XtNwidth, width); count++; + XtSetArg(args[count], XtNfromVert, last_rdn); count++; + rdn_window = XtCreateManagedWidget((String) name_array, commandWidgetClass, + PosWindow, args, count); + last_rdn = rdn_window; + XtAddCallback(rdn_window, XtNcallback, DnMoveRead, (XtPointer) rdn_number); + + (void) sprintf(trans_buf, "%d", (strlen(name_array) - 1)); + + (void) strcpy(translations, trans_start_btn2); + (void) strcat(translations, trans_buf); + (void) strcat(translations, ") \n\ "); + (void) strcat(translations, trans_start_btn3); + (void) strcat(translations, trans_buf); + (void) strcat(translations, ")"); + + trans_table = XtParseTranslationTable(translations); + XtOverrideTranslations(rdn_window, trans_table); + + (void) strcat(name_array, "x"); + rdn_number++; + + *end = save; + + if (str > (char *) friendly_base_path) { + while (*str != ',' && str > (char *) friendly_base_path) str--; + end = str; + if (*str == ',') str--; + } + } +} + +/*ARGSUSED*/ +static void StartSearch(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Arg args[MAXARGS]; + int count, indx; + Widget text; + char entry[STRINGLEN], string[STRINGLEN], mess[STRINGLEN]; + char *value; + dsEnqError status; + Cursor time_cur = XCreateFontCursor(dpy, XC_watch); + Cursor normal_cur = XCreateFontCursor(dpy, XC_left_ptr); + + message("Please Stand By........"); + + text = XtNameToWidget(outer, + "TypeForm.SearchVal"); + + count = 0; + XtSetArg(args[count], XtNstring, &value); count++; + XtGetValues(text, args, count); + (void) strcpy(mvalue, value); + + if (mvalue[0] == '\0') { + kill_message(); + displayError("You have not specified a search value!\nClick on this window to continue"); + return; + } + + XDefineCursor(dpy, XtWindow(outer), time_cur); + XFlush(dpy); + + status = srch_start(); + + XDefineCursor(dpy, XtWindow(outer), normal_cur); + XFlush(dpy); + + kill_message(); + + switch(status) { + case Okay: + if (entry_number == 1) { + (void) strcpy(entry, (get_from_seq(1, dnseq))); + if (!isleafnode(entry)) { + (void) strcpy(base_path, entry); + make_friendly(friendly_base_path, base_path); + set_search_area(XtNameToWidget + (outer, "PosForm.PosScrolledWindow.PosWindow")); + goto_addr(); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + XFlush(dpy); + + if (curr_read_popup == 0) curr_read_popup = createReadPopup(); + + status = read_config_types(); + + if (status == Okay) + displayReadPopup(); + else + doError(status); + } else { + (void) strcpy(string, base_path); + (void) strcpy(base_path, entry); + make_friendly(friendly_base_path, base_path); + XFlush(dpy); + + if (curr_read_popup == 0) curr_read_popup = createReadPopup(); + + status = read_config_types(); + displayReadPopup(); + + if (status == Okay) { + (void) strcpy(base_path, string); + make_friendly(friendly_base_path, base_path); + } else + doError(status); + } + clear_dnseq(); + entry_number = 0; + } else if (entry_number > 0) { + (void) strcpy(mess, "Results of search under "); + + if (strlen(base_path) > 3) { + indx = 0; + while (friendly_base_path[indx] != ',' && + friendly_base_path[indx] != '\0') indx++; + friendly_base_path[indx] = '\0'; + (void) strcat(mess, (char *) (friendly_base_path+indx)); + } else { + (void) strcat(mess, "The World"); + indx = 0; + } + + createList(dnseq, mess, ""); + dnseq = 0; + break; + case listsizelimit: + case adminlimit_w_partial: + case timelimit_w_partial: + (void) strcpy(mess, "Results of search under "); + + if (strlen(base_path) > 3) { + indx = 0; + while (friendly_base_path[indx] != ',' && + friendly_base_path[indx] != '\0') indx++; + friendly_base_path[indx] = '\0'; + (void) strcat(mess, (char *) (friendly_base_path+indx)); + } else { + (void) strcat(mess, "The World"); + indx = 0; + } + + switch (status) { + case timelimit_w_partial: + (void) sprintf(string, + "%s. %s. %d %s.", + "Time limit reached", + "Partial results only", + entry_number, + "items displayed"); + break; + case adminlimit_w_partial: + (void) sprintf(string, + "%s. %s. %d %s.", + "Administrative limit reached", + "Partial results only", + entry_number, + "items displayed"); + break; + case listsizelimit: + (void) sprintf(string, + "List size limit exceeded. Only %d items displayed.", + entry_number); + break; + } + + createList(dnseq, mess, string); + dnseq = 0; + break; + default: + doError(status); + } + } + + ClearSearchArea(XtNameToWidget(outer, "TypeForm.SearchVal"), + (XEvent *) 0, (String *) 0, (Cardinal *) 0); +} + +static Widget createTypeMenu(parent) + Widget parent; +{ + Widget menu_mgr, button; + Arg args[MAXARGS]; + int count = 0, n; + + menu_mgr = XtCreatePopupShell("menu", simpleMenuWidgetClass, + parent, args, 0 ); + + n = 0; + while (av_typeindx[n] != -1) { + count = 0; + XtSetArg(args[count], XtNlabel, (String) filttype[av_typeindx[n]]);count++; + button = XtCreateManagedWidget((String) filttype[av_typeindx[n]], + smeBSBObjectClass, + menu_mgr, args, count); + XtAddCallback(button, XtNcallback, SetType, (XtPointer) av_typeindx[n]); + n++; + } + return menu_mgr; +} + +/*ARGSUSED*/ +static void SetType(w, indx, calldata) + Widget w; + XtPointer indx, calldata; +{ + Widget menu, menuButton; + int count = 0; + Arg args[MAXARGS]; + char label[1024]; + + menuButton = XtNameToWidget(outer, "TypeForm.TypeButton"); + + if ((int) indx < 0 || (int) indx >= (int) filt_num) return; + + if ((menu = XtNameToWidget(outer, "TypeForm.TypeButton.menu"))) + XtDestroyWidget(menu); + + (void) createTypeMenu(menuButton); + + (void) strcpy(label, filttype[(int) indx]); + + count = 0; + XtSetArg(args[count], XtNlabel, label); count++; + XtSetValues(menuButton, args, count); + + typeindx = (int) indx; +} + +static void CreateCommandForm(parent) + Widget parent; +{ + Widget form, quitButton, helpButton, + searchButton, listButton, historyButton; + Arg args[MAXARGS]; + int count; + + count = 0; + form = XtCreateManagedWidget("MainButtonForm", formWidgetClass, parent, + args, count); + + count = 0; + XtSetArg(args[count], XtNheight, Quit_height); count++; + XtSetArg(args[count], XtNwidth, Quit_width); count++; + quitButton = XtCreateManagedWidget("quitButton", + commandWidgetClass, + form, args, count); + + XtAddCallback(quitButton, XtNcallback, + (XtCallbackProc) Quit, (XtPointer) 0); + + count = 0; + XtSetArg(args[count], XtNheight, Help_height); count++; + XtSetArg(args[count], XtNwidth, Help_width); count++; + helpButton = XtCreateManagedWidget("helpButton", + commandWidgetClass, + form, args, count); + + XtAddCallback(helpButton, XtNcallback, + (XtCallbackProc) Help, (XtPointer) 0); + + count = 0; + XtSetArg(args[count], XtNheight, Search_height); count++; + XtSetArg(args[count], XtNwidth, Search_width); count++; + searchButton = XtCreateManagedWidget("searchButton", + commandWidgetClass, + form, args, count); + + XtAddCallback(searchButton, XtNcallback, + (XtCallbackProc) StartSearch, (XtPointer) 0); + + count = 0; + XtSetArg(args[count], XtNheight, List_height); count++; + XtSetArg(args[count], XtNwidth, List_width); count++; + listButton = XtCreateManagedWidget("listButton", + commandWidgetClass, + form, args, count); + + XtAddCallback(listButton, XtNcallback, + (XtCallbackProc) List, (XtPointer) 0); + + count = 0; + XtSetArg(args[count], XtNheight, History_height); count++; + XtSetArg(args[count], XtNwidth, History_width); count++; + historyButton = XtCreateManagedWidget("historyButton", + commandWidgetClass, + form, args, count); + + XtAddCallback(historyButton, XtNcallback, + (XtCallbackProc) popupHistory, (XtPointer) 0); + +} + +static void displayReadPopup() +{ + if (curr_read_popup) { + XtPopup(curr_read_popup, XtGrabNone); + XRaiseWindow(dpy, XtWindow(curr_read_popup)); + } +} + +void setReadEntryName(entry_name) + char *entry_name; +{ + Widget title, modifyButton, showAllButton; + int count = 0; + Arg args[MAXARGS]; + char *object, friendly_name[STRINGLEN]; + + make_friendly(friendly_name, entry_name); + + if (curr_read_popup) { + object = strdup(entry_name); + + title = XtNameToWidget(curr_read_popup, "ReadForm.ReadTitle"); + modifyButton = XtNameToWidget(curr_read_popup, + "ReadForm.ReadButtonForm.modifyButton"); + showAllButton = XtNameToWidget(XtParent(modifyButton), "showAllButton"); + + if (*friendly_name == '\0') { + XtSetArg(args[count], XtNlabel, "The World"); count++; + } else { + XtSetArg(args[count], XtNlabel, friendly_name); count++; + } + XtSetValues(title, args, count); + + if (XtHasCallbacks(title, XtNcallback) == XtCallbackHasSome) + XtRemoveAllCallbacks(title, XtNcallback); + + XtAddCallback(title, XtNcallback, CutString, (XtPointer) object); + + if (XtHasCallbacks(showAllButton, XtNcallback) == XtCallbackHasSome) + XtRemoveAllCallbacks(showAllButton, XtNcallback); + + XtAddCallback(showAllButton, XtNcallback, ReadAll, (XtPointer) object); + + if (XtHasCallbacks(modifyButton, XtNdestroyCallback) == XtCallbackHasSome) + XtRemoveAllCallbacks(modifyButton, XtNdestroyCallback); + + if (XtHasCallbacks(modifyButton, XtNcallback) == XtCallbackHasSome) + XtRemoveAllCallbacks(modifyButton, XtNcallback); + + XtAddCallback(modifyButton, XtNcallback, modifyEntry, (XtPointer) object); + XtAddCallback(modifyButton, XtNdestroyCallback, + freeSpace, (XtPointer) object); + } +} + +static XawTextSelectType select_types[] = {XawselectLine, XawselectNull}; + +static Widget createReadPopup() +{ + Arg args[MAXARGS]; + int count = 0; + Widget closeButton, keepButton, modifyButton, showAllButton, + TextScrolledWindow, AttrWindow, + TextForm, ReadPopup, ReadForm, ButtonForm; + + ReadPopup = XtCreatePopupShell("Directory Entry", topLevelShellWidgetClass, + toplevel, args , 0); + + /* Top of popup form. */ + ReadForm = XtCreateWidget("ReadForm", formWidgetClass, + ReadPopup, args, 0); + + /* Buttons */ + ButtonForm = XtCreateManagedWidget("ReadButtonForm", formWidgetClass, + ReadForm, args, 0); + + count = 0; + XtSetArg(args[count], XtNheight, Close_height); count++; + XtSetArg(args[count], XtNwidth, Close_width); count++; + closeButton = XtCreateManagedWidget("closeButton", commandWidgetClass, + ButtonForm, args, count); + + XtAddCallback(closeButton, XtNcallback, readDestroy, (XtPointer) ReadPopup); + + count = 0; + XtSetArg(args[count], XtNheight, Keep_height); count++; + XtSetArg(args[count], XtNwidth, Keep_width); count++; + keepButton = XtCreateManagedWidget("keepButton", commandWidgetClass, + ButtonForm, args, count); + + XtAddCallback(keepButton, XtNcallback, keepRead, (XtPointer) ReadPopup); + + count = 0; + XtSetArg(args[count], XtNheight, ShowAll_height); count++; + XtSetArg(args[count], XtNwidth, ShowAll_width); count++; + showAllButton = XtCreateManagedWidget("showAllButton", commandWidgetClass, + ButtonForm, args, count); + + count = 0; + XtSetArg(args[count], XtNheight, Modify_height); count++; + XtSetArg(args[count], XtNwidth, Modify_width); count++; + modifyButton = XtCreateManagedWidget("modifyButton", commandWidgetClass, + ButtonForm, args, count); + + /* End of buttons */ + count = 0; + + XtSetArg(args[count], XtNlabel, friendly_base_path); count++; + (void) XtCreateManagedWidget("ReadTitle", commandWidgetClass, + ReadForm, args, count); + + count = 0; + TextScrolledWindow = XtCreateManagedWidget("TextScrolledWindow", + viewportWidgetClass, + ReadForm, args, count); + + count = 0; + XtSetArg(args[count], XtNborderWidth, 0); count++; + TextForm = XtCreateManagedWidget("TextForm", formWidgetClass, + TextScrolledWindow, args, count); + + count = 0; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNstring, ""); count++; + AttrWindow = XtCreateManagedWidget("AttrWindow", asciiTextWidgetClass, + TextForm, args, count); + + XawTextSetSelectionArray(AttrWindow, select_types); + + count = 0; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNstring, ""); count++; + (void) XtCreateManagedWidget("SepWindow", asciiTextWidgetClass, + TextForm, args, count); + + count = 0; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNstring, ""); count++; + (void) XtCreateManagedWidget("ValWindow", asciiTextWidgetClass, + TextForm, args, count); + + XawFormDoLayout(TextForm, FALSE); + + /* End of text layout */ + XFlush(dpy); + XtManageChild(ReadForm); + XtRealizeWidget(ReadPopup); + + CreateBackgroundPixmap(closeButton, Close_bits, Close_width, Close_height); + + CreateBackgroundPixmap(keepButton, Keep_bits, + Keep_width, Keep_height); + + CreateBackgroundPixmap(showAllButton, ShowAll_bits, + ShowAll_width, ShowAll_height); + + CreateBackgroundPixmap(modifyButton, Modify_bits, + Modify_width, Modify_height); + + if (DefaultDepthOfScreen(screen) == 1) { + CreateBackgroundPixmap(ReadForm, gray_bits, + gray_width, gray_height); + + CreateBackgroundPixmap(ButtonForm, gray_bits, + gray_width, gray_height); + } + + PhotoWindow = 0; + return ReadPopup; +} + + +static void AddNewList(list_widget, list_seq, list_size) + Widget list_widget; + str_seq list_seq; + unsigned int list_size; +{ + Arg args[MAXARGS]; + Widget element, scrolwin; + int count = 0, n; + char name[STRINGLEN], friendly_rdn[STRINGLEN]; + char *prev, *object; + Dimension width, rwidth; + char *trans_start_btn2 = ": ListSelectList(", + *trans_start_btn3 = ": ListSelectMove(", + translations[STRINGLEN]; + XtTranslations trans_table; + + scrolwin = (Widget) XtParent(list_widget); + + count = 0; + XtSetArg(args[count], XtNwidth, &width); count++; + XtGetValues(scrolwin, args, count); + + width -= 15; + + element_number = list_size; + + *name = '\0'; + for (n = 0; n < element_number; n++) { + (void) strcat(name, "X"); + + object = get_from_seq(n+1, list_seq); + make_friendly_rdn(friendly_rdn, object, base_path); + count = 0; + XtSetArg(args[count], XtNlabel, (*friendly_rdn? + friendly_rdn: "The World")); count++; + XtSetArg(args[count], XtNborderWidth, 0);count++; + XtSetArg(args[count], XtNborderColor, WhitePixelOfScreen(screen)); count++; + XtSetArg(args[count], XtNhighlightThickness, 1); count++; + XtSetArg(args[count], XtNjustify, XtJustifyLeft); count++; + if (strlen(name) > 1) { + prev = (char *) name + 1; + XtSetArg(args[count], XtNfromVert, XtNameToWidget(list_widget, prev)); + count++; + } + element = XtCreateManagedWidget((String) name, + commandWidgetClass, + list_widget, args, count); + + XtAddCallback(element, XtNcallback, ListSelect, (XtPointer) object); + + (void) strcpy(translations, trans_start_btn2); + (void) strcat(translations,"\""); + (void) strcat(translations, object); + (void) strcat(translations,"\""); + (void) strcat(translations, ") \n\ "); + (void) strcat(translations, trans_start_btn3); + (void) strcat(translations,"\""); + (void) strcat(translations, object); + (void) strcat(translations,"\""); + (void) strcat(translations, ")"); + + trans_table = XtParseTranslationTable(translations); + XtOverrideTranslations(element, trans_table); + + count = 0; + XtSetArg(args[count], XtNwidth, &rwidth); count++; + XtGetValues(element, args, count); + + if (rwidth < width) { + count = 0; + XtSetArg(args[count], XtNwidth, width); count++; + XtSetValues(element, args, count); + } + } +} + +void readEntryPrint(entry) + char *entry; +{ + Widget entry_form = 0; + + if (curr_read_popup) { + entry_form = XtNameToWidget(curr_read_popup, + "ReadForm.TextScrolledWindow.TextForm"); + entry_print(entry_form, entry); + } +} + +static void entry_print(entry_form, entry) + Widget entry_form; + char *entry; +{ + Widget attr_list, val_list, sep_list; + Arg args[MAXARGS]; + int count = 0, attr_count = 0; + register char *str_start, *str_end; + char save, vals[RESBUF], attrs[RESBUF], seps[RESBUF]; + Dimension attr_width = 0, max_attr_width = 0; + Dimension val_width = 0, max_val_width = 0; + Dimension sep_width; + Dimension height; + XFontStruct *font; + + XawFormDoLayout(entry_form, FALSE); + + (void) strcpy(vals, ""); + (void) strcpy(attrs, ""); + (void) strcpy(seps, ""); + + attr_list = XtNameToWidget(entry_form, "AttrWindow"); + val_list = XtNameToWidget(entry_form, "ValWindow"); + sep_list = XtNameToWidget(entry_form, "SepWindow"); + + XawTextDisableRedisplay(attr_list); + XawTextDisableRedisplay(val_list); + XawTextDisableRedisplay(sep_list); + + count = 0; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(attr_list, args, count); + + str_start = str_end = entry; + while (*str_end != '\0') { + attr_count++; + if (*str_end == '\t') { + while (isspace(*str_end)) str_end++; + str_start = str_end; + + while (*str_end != '\n' && *str_end != '\0') str_end++; + + save = *str_end; + *str_end = '\0'; + + (void) strcat(attrs, "\n"); + (void) strcat(vals, "\n"); + (void) strcat(vals, str_start); + (void) strcat(seps, "\n"); + + val_width = XTextWidth(font, str_start, strlen(str_start))+ + FONTWIDTH(font); + + if (val_width > max_val_width) max_val_width = val_width; + + if (save == '\0') str_end--; + } else { + while (!isspace(*str_end)) str_end++; + + save = *str_end; + *str_end = '\0'; + + (void) strcat(attrs, "\n"); + (void) strcat(attrs, str_start); + + attr_width = XTextWidth(font, str_start, strlen(str_start)) + + FONTWIDTH(font); + + if (attr_width > max_attr_width) max_attr_width = attr_width; + + *str_end = save; + while (*str_end != '-') str_end++; + str_end++; + + while (isspace(*str_end)) str_end++; + + str_start = str_end; + while (*str_end != '\n' && *str_end != '\0') str_end++; + + save = *str_end; + *str_end = '\0'; + + (void) strcat(seps, "-\n"); + (void) strcat(vals, "\n"); + (void) strcat(vals, str_start); + + val_width = XTextWidth(font, str_start, strlen(str_start))+ + FONTWIDTH(font); + + if (val_width > max_val_width) max_val_width = val_width; + if (save == '\0') str_end--; + } + str_start = ++str_end; + } + + max_attr_width += FONTWIDTH(font); + max_val_width += FONTWIDTH(font); + height = ++attr_count * FONTHEIGHT(font); + sep_width = FONTWIDTH(font); + + count = 0; + XtSetArg(args[count], XtNstring, (attrs+1)); count++; + XtSetArg(args[count], XtNwidth, max_attr_width); count++; + XtSetArg(args[count], XtNheight, height); count++; + XtSetValues(attr_list, args, count); + + count = 0; + XtSetArg(args[count], XtNstring, (vals+1)); count++; + XtSetArg(args[count], XtNwidth, max_val_width); count++; + XtSetArg(args[count], XtNheight, height); count++; + XtSetValues(val_list, args, count); + + count = 0; + XtSetArg(args[count], XtNstring, seps); count++; + XtSetArg(args[count], XtNwidth, sep_width); count++; + XtSetArg(args[count], XtNheight, height); count++; + XtSetValues(sep_list, args, count); + + XawTextEnableRedisplay(attr_list); + XawTextEnableRedisplay(val_list); + XawTextEnableRedisplay(sep_list); + + if (PhotoWindow != NULL && photo_on == TRUE) { + XtRealizeWidget(PhotoWindow); + print_photo(); + } + + XawFormDoLayout(entry_form, TRUE); +} + +/*ARGSUSED*/ +static void Quit(widget, closure, callData) + Widget widget; + XtPointer closure, callData; +{ + XtDestroyWidget(toplevel); + quit(0); +} + +/*ARGSUSED*/ +static void TSearch(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + StartSearch((Widget) 0, (XtPointer) 0, (XtPointer) 0); +} + +/*ARGSUSED*/ +static void ClearSearchArea(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + Arg args[MAXARGS]; + int count= 0; + XtSetArg(args[count], XtNstring, "\0"); count++; + XtSetValues(w, args, count); +} + +/*ARGSUSED*/ +static void ReadAll(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + dsEnqError status; + Widget temp_read_popup; + char current_path[STRINGLEN]; + char *object = (char *) closure; + + (void) strcpy(current_path, base_path); + (void) strcpy(base_path, object); + + temp_read_popup = curr_read_popup; + + curr_read_popup = XtParent(XtParent(XtParent(w))); + + status = read_all(); + + if (status != Okay) + doError(status); + else + displayReadPopup(); + + (void) strcpy(base_path, current_path); + curr_read_popup = temp_read_popup; +} + +/*ARGSUSED*/ +static void Read(w, data, calldata) + Widget w; + XtPointer data, calldata; +{ + dsEnqError status; + + if (curr_read_popup == 0) curr_read_popup = createReadPopup(); + + XFlush(dpy); + status = read_config_types(); + + if (status != Okay) + doError(status); + else + displayReadPopup(); +} + +set_search_area(search_area) + Widget search_area; +{ + WidgetList wlist; + char name[STRINGLEN]; + int count = 0, n; + + wlist = (WidgetList) XtMalloc((rdn_number + 1) * sizeof(Widget)); + + name[0] = '\0'; + + for (n = 0; n < rdn_number; n++) { + (void) strcat(name, "x"); + wlist[n] = XtNameToWidget(search_area, name); + count++; + } + XtUnmanageChildren(wlist, count); + + for (n = 0; n < count; n++) + XtDestroyWidget(wlist[n]); + + XtFree(wlist); + print_search_area(search_area); +} + +/*ARGSUSED*/ +static void List(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + int indx; + char string[1024], mess[1024]; + dsEnqError status; + Cursor time_cur = XCreateFontCursor(dpy, XC_watch); + Cursor normal_cur = XCreateFontCursor(dpy, XC_left_ptr); + + message("Please Stand By......"); + XFlush(dpy); + + XDefineCursor(dpy, XtWindow(outer), time_cur); + XFlush(dpy); + + status = list_start(); + + XDefineCursor(dpy, XtWindow(outer), normal_cur); + XFlush(dpy); + + kill_message(); + + make_friendly(friendly_base_path, base_path); + + switch(status) { + case listsizelimit: + case adminlimit_w_partial: + case timelimit_w_partial: + (void) strcpy(mess, "Results of list under "); + + if (strlen(base_path) > 3) { + indx = 0; + while (friendly_base_path[indx] != ',' && + friendly_base_path[indx] != '\0') indx++; + friendly_base_path[indx] = '\0'; + (void) strcat(mess, (char *) friendly_base_path); + } else + (void) strcat(mess, "The World"); + + switch (status) { + case listsizelimit: + (void) sprintf(string, + "List size limit exceeded. Only %d items displayed.", + entry_number); + break; + case adminlimit_w_partial: + (void) sprintf(string, + "%s. %s. %d %s.", + "Administrative limit reached", + "Partial results only", + entry_number, + "items displayed"); + break; + case timelimit_w_partial: + (void) sprintf (string, + "%s. %s. %d %s.", + "Time limit reached", + "Partial results only", + entry_number, + "items displayed"); + break; + } + createList(dnseq, mess, string); + dnseq = 0; + break; + case Okay: + (void) strcpy(mess, "Results of list under "); + + if (strlen(base_path) > 3) { + indx = 0; + while (friendly_base_path[indx] != ',' && + friendly_base_path[indx] != '\0') indx++; + friendly_base_path[indx] = '\0'; + (void) strcat(mess, (char *) friendly_base_path); + } else + (void) strcat(mess, "The World"); + + createList(dnseq, mess, ""); + dnseq = 0; + break; + default: + dnseq = 0; + entry_number = 0; + doError(status); + } +} + +/*ARGSUSED*/ +static void ListSelect(w, object, calldata) + Widget w; + XtPointer object, calldata; +{ + char *entry_name, parent[STRINGLEN]; + + (void) XtNameToWidget(outer, "PosForm.PosScrolledWindow.PosWindow"); + + entry_name = (char *) object; + + (void) strcpy(parent, base_path); + (void) strcpy(base_path, entry_name); + make_friendly(friendly_base_path, base_path); + + if (!isleafnode(entry_name)) { + if (read_all_flag == TRUE) { + Read((Widget) 0, (XtPointer) 0, (XtPointer) 0); + } + Move((Widget) 0, (XtPointer) entry_name, (XtPointer) 0); + } else { + Read((Widget) 0, (XtPointer) 0, (XtPointer) 0); + (void) strcpy(base_path, parent); + } +} + +/*ARGSUSED*/ +static void ListSelectMove(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + char temp_path[STRINGLEN]; + Widget search_area = XtNameToWidget(outer, + "PosForm.PosScrolledWindow.PosWindow"); + (void) strcpy(temp_path, base_path); + (void) strcpy(base_path, params[0]); + + if (!isleafnode(base_path)) { + goto_addr(); + set_search_area(search_area); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + XFlush(dpy); + } else { + (void) strcpy(base_path, temp_path); + displayError("Cannot move to a leaf entry!\nClick on this window to continue"); + } +} + +/*ARGSUSED*/ +static void ListSelectList(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + Widget search_area = XtNameToWidget(outer, + "PosForm.PosScrolledWindow.PosWindow"); + char temp_path[STRINGLEN]; + + (void) strcpy(temp_path, base_path); + (void) strcpy(base_path, params[0]); + + if (!isleafnode(base_path)) { + List((Widget) 0, (XtPointer) 0, (XtPointer) 0); + + goto_addr(); + set_search_area(search_area); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + XFlush(dpy); + } else { + (void) strcpy(base_path, temp_path); + displayError("Cannot list under a leaf entry!\nClick on this window to continue"); + } +} + +/*ARGSUSED*/ +static void DnList(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + Widget search_area = XtNameToWidget(outer, + "PosForm.PosScrolledWindow.PosWindow"); + register char *end = base_path; + int rdnlevel = atoi(params[0]); + + if (rdnlevel == 0) *base_path = '\0'; + else if (rdn_number > (int) (rdnlevel+1)) { + while (rdnlevel) { + while (*end != '@') end++; + if (*end == '@') end++; + rdnlevel--; + } + *--end = '\0'; + } + + List((Widget) 0, (XtPointer) 0, (XtPointer) 0); + goto_addr(); + set_search_area(search_area); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + XFlush(dpy); +} + +/*ARGSUSED*/ +static void DnMove(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + register char *end; + Widget search_area = XtNameToWidget(outer, + "PosForm.PosScrolledWindow.PosWindow"); + int rdnlevel = atoi(params[0]); + + end = base_path; + + if (rdnlevel == 0) *base_path = '\0'; + else if (rdn_number > (int) (rdnlevel+1)) { + while (rdnlevel) { + while (*end != '@') end++; + if (*end == '@') end++; + rdnlevel--; + } + *--end = '\0'; + } + + goto_addr(); + set_search_area(search_area); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + XFlush(dpy); +} + +/*ARGSUSED*/ +static void DnMoveRead(w, rdnlevel, calldata) + Widget w; + XtPointer rdnlevel, calldata; +{ + Widget search_area; + char *end; + dsEnqError status; + + search_area = XtNameToWidget(outer, "PosForm.PosScrolledWindow.PosWindow"); + + end = base_path; + if (rdnlevel == 0) *base_path = '\0'; + else if (rdn_number > (int) (rdnlevel+1)) { + while (rdnlevel) { + while (*end != '@') end++; + if (*end == '@') end++; + rdnlevel--; + } + *--end = '\0'; + } + + goto_addr(); + set_search_area(search_area); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); + XFlush(dpy); + + if (read_all_flag == TRUE) { + if (curr_read_popup == 0) curr_read_popup = createReadPopup(); + status = read_config_types(); + + if (status != Okay) + doError(status); + else { + displayReadPopup(); + } + } +} + +/*ARGSUSED*/ +static void Move(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget search_area; + char *new_base; + + search_area = XtNameToWidget(outer, "PosForm.PosScrolledWindow.PosWindow"); + + new_base = (char *) closure; + (void) strcpy(base_path, new_base); + + make_friendly(friendly_base_path, new_base); + set_search_area(search_area); + goto_addr(); + SetType((Widget) 0, (XtPointer) typeindx, (XtPointer) 0); +} + +static void CreateMessagePopup() +{ + int count; + Arg args[MAXARGS]; + + count = 0; + standby = XtCreatePopupShell("POD: Working.", + transientShellWidgetClass, + toplevel, args, count); + + count = 0; + XtSetArg(args[count], XtNresize, FALSE); count++; + (void) XtCreateManagedWidget("standby", labelWidgetClass, + standby, args, count); + + XtRealizeWidget(standby); +} + +static void CreateErrorPopup() +{ + Widget text; + int count; + Arg args[MAXARGS]; + + count = 0; + error_popup = XtCreatePopupShell("POD: ", + transientShellWidgetClass, + toplevel, args, count); + + count = 0; + XtSetArg(args[count], XtNresize, FALSE); count++; + text = XtCreateManagedWidget("error_popup", commandWidgetClass, + error_popup, args, count); + + XtAddCallback(text, XtNcallback, killError, (XtPointer) 0); + + XtRealizeWidget(error_popup); +} + +static void doError(status) + dsEnqError status; +{ + switch(status) { + case timelimit: + entry_number = 0; + displayError("Time limit reached.\nClick on this window to continue"); + break; + case adminlimit: + entry_number = 0; + displayError + ("Administrative limit reached.\nClick on this window to continue"); + break; + case nothingfound: + dnseq = 0; + entry_number = 0; + displayError("Nothing found!\nClick on this window to continue"); + break; + case localdsaerror: + dnseq = 0; + entry_number = 0; + displayError("Problem with remote directory server.\nClick on this window to continue"); + break; + case remotedsaerror: + dnseq = 0; + entry_number = 0; + displayError("Requested data unavailable at present.\nClick on this window to continue"); + break; + case duaerror: + dnseq = 0; + entry_number = 0; + displayError("Internal error. Sorry!\nClick on this window to continue"); + break; + case security: + dnseq = 0; + entry_number = 0; + displayError("You do not have the access privileges required\nto make this request!\nClick on this window to continue"); + break; + case namerror: + dnseq = 0; + entry_number = 0; + displayError("Invalid directory position!\nClick on this window to continue"); + break; + case attributerror: + dnseq = 0; + entry_number = 0; + displayError("Faulty data found in database!\nClick on this window to continue"); + break; + case serviceerror: + dnseq = 0; + entry_number = 0; + displayError("Directory Service Error!\nClick on this window to continue"); + break; + case updaterror: + dnseq = 0; + entry_number = 0; + displayError("Update Error!\nClick on this window to continue"); + break; + } +} + +void displayError(mess) + String mess; +{ + Arg args[MAXARGS]; + int count; + Widget text; + + text = XtNameToWidget(error_popup, "error_popup"); + + count = 0; + XtSetArg(args[count], XtNlabel, mess); count++; + XtSetValues(text, args, count); + + PopupMessage(error_popup, text, mess, XtGrabExclusive); + + XBell(dpy, 100); +} + +void displayStartupError(mess) + String mess; +{ + Arg args[MAXARGS]; + int count; + Widget text; + + text = XtNameToWidget(error_popup, "error_popup"); + + XtRemoveAllCallbacks(text, XtNcallback); + XtAddCallback(text, XtNcallback, Quit, (XtPointer) 0); + + count = 0; + XtSetArg(args[count], XtNlabel, mess); count++; + XtSetValues(text, args, count); + + PopupMessage(error_popup, text, mess, XtGrabExclusive); +} + +/*ARGSUSED*/ +static void killError(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + kill_error(); +} + +static void kill_error() +{ + Arg args[MAXARGS]; + int count; + Pixmap pixmap_resource; + + Widget text = XtNameToWidget(error_popup, "error_popup"); + + XtPopdown(error_popup); + + count = 0; + XtSetArg(args[count], XtNbackgroundPixmap, &pixmap_resource); count++; + XtGetValues(text, args, count); + + count = 0; + XtSetArg(args[count], XtNbackgroundPixmap, XtUnspecifiedPixmap); count++; + XtSetValues(text, args, count); + + if (pixmap_resource != XtUnspecifiedPixmap) + XFreePixmap(dpy, pixmap_resource); +} + +void message(mess) + char *mess; +{ + Arg args[MAXARGS]; + int count; + Widget text; + XEvent event; + + text = XtNameToWidget(standby, "standby"); + + count = 0; + XtSetArg(args[count], XtNlabel, mess); count++; + XtSetValues(text, args, count); + + PopupMessage(standby, text, mess, XtGrabNonexclusive); + + while (!XCheckTypedWindowEvent(dpy, XtWindow(text), Expose, &event)); + XtDispatchEvent(&event); + + XFlush(dpy); +} + +void kill_message() +{ + Arg args[MAXARGS]; + int count; + Pixmap pixmap_resource; + + Widget text = XtNameToWidget(standby, "standby"); + + XtPopdown(standby); + + count = 0; + XtSetArg(args[count], XtNbackgroundPixmap, &pixmap_resource); count++; + XtGetValues(text, args, count); + + count = 0; + XtSetArg(args[count], XtNbackgroundPixmap, XtUnspecifiedPixmap); count++; + XtSetValues(text, args, count); + + if (pixmap_resource != XtUnspecifiedPixmap) + XFreePixmap(dpy, pixmap_resource); +} + +static void CreateHelpPopup() +{ + Widget popup_help, popup_help_button, popup_quit_button, + popup_help_form, popup_help_scrolwin; + + Arg args[MAXARGS]; + int count; + + count = 0; + popup_help = XtCreatePopupShell("Pod Help Screen", topLevelShellWidgetClass, + toplevel, args, count); + + count = 0; + popup_help_form = XtCreateManagedWidget("popup_help_form", formWidgetClass, + popup_help, args, count); + + count = 0; + XtSetArg(args[count], XtNheight, Close_height); count++; + XtSetArg(args[count], XtNwidth, Close_width); count++; + popup_quit_button = XtCreateManagedWidget("popup_help_quit", + commandWidgetClass, + popup_help_form, args, count); + + XtAddCallback(popup_quit_button, XtNcallback, QuitFromHelp, (XtPointer) 0); + + count = 0; + XtSetArg(args[count], XtNheight, About_height); count++; + XtSetArg(args[count], XtNwidth, About_width); count++; + popup_help_button = XtCreateManagedWidget("popup_help_general", + commandWidgetClass, + popup_help_form, args, count); + + XtAddCallback(popup_help_button, XtNcallback, InsertHelp, + (XtPointer) "general"); + + count = 0; + popup_help_scrolwin = XtCreateManagedWidget("popup_help_scrolwin", + viewportWidgetClass, + popup_help_form, args, count); + + count = 0; + (void) XtCreateManagedWidget("popup_help_text", + asciiTextWidgetClass, + popup_help_scrolwin, args, count); + XtRealizeWidget(popup_help); + + CreateBackgroundPixmap(popup_help_button, About_bits, + About_width, About_height); + + CreateBackgroundPixmap(popup_quit_button, Close_bits, + Close_width, Close_height); + + if (DefaultDepthOfScreen(screen) == 1) { + CreateBackgroundPixmap(popup_help_form, gray_bits, + gray_width, gray_height); + } +} + +/*ARGSUSED*/ +static void Help(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget help_popup; + + help_popup = XtNameToWidget(toplevel, "Pod Help Screen"); + + XtPopup(help_popup, XtGrabNone); + InsertHelp((Widget) 0, (XtPointer) "help", (XtPointer) 0); + XFlush(dpy); + help_up = TRUE; +} + +/*ARGSUSED*/ +static void QuitFromHelp(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget help_popup; + + help_up = FALSE; + help_popup = XtNameToWidget(toplevel, "Pod Help Screen"); + XtPopdown(help_popup); +} + +/*ARGSUSED*/ +static void InsertHelp(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget text, scrolwin; + FILE *file; + char filename[STRINGLEN], help_buf[RESBUF]; + int count; + Arg args[MAXARGS]; + Dimension width, height; + XFontStruct *font; + + scrolwin = XtNameToWidget(toplevel, + "Pod Help Screen.popup_help_form.popup_help_scrolwin"); + + text = XtNameToWidget(scrolwin, "popup_help_text"); + + count = 0; + XtSetArg(args[count], XtNwidth, &width); count++; + XtGetValues(scrolwin, args, count); + + (void) strcpy(filename, dua_help_dir); + (void) strcat(filename, (String) closure); + + count = 0; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(text, args, count); + + height = FONTHEIGHT(font); + count = 0; + XtSetArg(args[count], XtNheight, height); count++; + XtSetValues(text, args, count); + + height = 0; + if (!(file = fopen(filename, "r"))) { + (void) strcpy(filename, "./Xd/podHelpdir/"); + (void) strcat(filename, (String) closure); + if (!(file = fopen(filename, "r"))) (void) fprintf(stderr, + "Helpfile not found\n"); + } + + if (file) { + (void) strcpy(help_buf, "\0"); + while (fgets(help_string, STRINGLEN - 1, file)) { + height += (FONTHEIGHT(font)); + (void) strcat(help_buf, help_string); + } + + (void) fclose(file); + count = 0; + XtSetArg(args[count], XtNstring, ""); count++; + XtSetValues(text, args, count); + + count = 0; + XtSetArg(args[count], XtNwidth, width - 18); count++; + XtSetArg(args[count], XtNheight, height); count++; + XtSetArg(args[count], XtNstring, help_buf); count++; + XtSetValues(text, args, count); + } +} + +void CreateBackgroundPixmap(widget, bits, width, height) + Widget widget; + char bits[]; + Cardinal width, height; +{ + Arg args[MAXARGS]; + int count; + Pixmap bitmap; + + bitmap = XCreatePixmapFromBitmapData(dpy, + XtWindow(widget), bits, + width, height, + BlackPixelOfScreen(screen), + WhitePixelOfScreen(screen), + DefaultDepthOfScreen(screen)); + + count = 0; + XtSetArg(args[count], XtNheight, height); count++; + XtSetArg(args[count], XtNwidth, width); count++; + XtSetArg(args[count], XtNbackgroundPixmap, bitmap); count++; + XtSetArg(args[count], XtNresizable, FALSE); count++; + XtSetValues(widget, args, count); +} + +/*ARGSUSED*/ +static void ListDestroy(w, list_seq, calldata) + Widget w; + XtPointer calldata, list_seq; +{ + free_seq((str_seq) list_seq); +} + +/*ARGSUSED*/ +static void destroyList(w, shellwidget, calldata) + Widget w; + XtPointer shellwidget, calldata; +{ + if (curr_list_popup == (Widget) shellwidget) curr_list_popup = 0; + + XtPopdown((Widget) shellwidget); + XtUnmanageChild((Widget) shellwidget); + XtDestroyWidget((Widget) shellwidget); + XFlush(dpy); +} + +/*ARGSUSED*/ +static void keepList(w, shellwidget, calldata) + Widget w; + XtPointer calldata, shellwidget; +{ + if (curr_list_popup == (Widget) shellwidget) curr_list_popup = 0; +} + +static void CreateHistoryPopup(list_seq, mess) + str_seq list_seq; + char *mess; +{ + int count = 0; + Widget shell, swindow, HistoryForm, ListWindow, closeButton; + Arg args[MAXARGS]; + + count = 0; + shell = XtCreatePopupShell("Session History", topLevelShellWidgetClass, + toplevel, args, 0); + count = 0; + HistoryForm = XtCreateManagedWidget("HistoryForm", formWidgetClass, + shell, args, count); + + count = 0; + XtSetArg(args[count], XtNheight, Close_height); count++; + XtSetArg(args[count], XtNwidth, Close_width); count++; + closeButton = XtCreateManagedWidget("closeButton", + commandWidgetClass, + HistoryForm, args, count); + + XtAddCallback(closeButton, XtNcallback, + (XtCallbackProc) popdownHistory, (XtPointer) shell); + + count = 0; + XtSetArg(args[count], XtNlabel, "History Window"); count++; + (void) XtCreateManagedWidget("HistoryTitle", labelWidgetClass, + HistoryForm, args, count); + + count = 0; + swindow = XtCreateManagedWidget("ListScrolledWindow", viewportWidgetClass, + HistoryForm, args, count); + + count = 0; + ListWindow = XtCreateManagedWidget("ListWindow", formWidgetClass, + swindow, args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, mess); count++; + (void) XtCreateManagedWidget("ListMessage", labelWidgetClass, + HistoryForm, args, count); + + XtAddCallback(ListWindow, XtNdestroyCallback, + ListDestroy, (XtPointer) list_seq); + + AddNewList(ListWindow, list_seq, (unsigned) entry_number); + XtRealizeWidget(shell); + + CreateBackgroundPixmap(closeButton, Close_bits, Close_width, Close_height); + if (DefaultDepthOfScreen(screen) == 1) + CreateBackgroundPixmap(HistoryForm, gray_bits, gray_width, gray_height); +} + +/*ARGSUSED*/ +static void popupHistory(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget history_popup; + + history_popup = XtNameToWidget(toplevel, "Session History"); + XtPopup(history_popup, XtGrabNone); +} + +/*ARGSUSED*/ +static void popdownHistory(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget history_popup; + + history_popup = XtNameToWidget(toplevel, "Session History"); + XtPopdown(history_popup); +} + + +/*ARGSUSED*/ +static void ChangeHelp(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + if ((help_up) && strcmp(params[0], curr_help)) { + InsertHelp((Widget) 0, (XtPointer) params[0], (XtPointer) 0); + (void) strcpy(curr_help, params[0]); + } +} + +/*ARGSUSED*/ +static void buttonPress(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + char *buttonName = params[0]; + + if (!strcmp(buttonName, "search")) + CreateBackgroundPixmap(w, SearchPress_bits, + SearchPress_width, SearchPress_height); + else if (!strcmp(buttonName, "help")) + CreateBackgroundPixmap(w, HelpPress_bits, + HelpPress_width, HelpPress_height); + else if (!strcmp(buttonName, "quit")) + CreateBackgroundPixmap(w, QuitPress_bits, + QuitPress_width, QuitPress_height); + else if (!strcmp(buttonName, "list")) + CreateBackgroundPixmap(w, ListPress_bits, + ListPress_width, ListPress_height); + else if (!strcmp(buttonName, "history")) + CreateBackgroundPixmap(w, HistoryPress_bits, + HistoryPress_width, HistoryPress_height); + else if (!strcmp(buttonName, "close")) + CreateBackgroundPixmap(w, ClosePress_bits, + ClosePress_width, ClosePress_height); + else if (!strcmp(buttonName, "about")) + CreateBackgroundPixmap(w, AboutPress_bits, + AboutPress_width, AboutPress_height); + else if (!strcmp(buttonName, "keep")) + CreateBackgroundPixmap(w, KeepPress_bits, + KeepPress_width, KeepPress_height); + else if (!strcmp(buttonName, "modify")) + CreateBackgroundPixmap(w, ModifyPress_bits, + ModifyPress_width, ModifyPress_height); + else if (!strcmp(buttonName, "show_all")) + CreateBackgroundPixmap(w, ShowAllPress_bits, + ShowAllPress_width, ShowAllPress_height); + else if (!strcmp(buttonName, "submit_modify")) + CreateBackgroundPixmap(w, ModifyPress_bits, + ModifyPress_width, ModifyPress_height); + + XFlush(dpy); + XtCallCallbacks(w, XtNcallback, NULL); + XFlush(dpy); + + if (!strcmp(buttonName, "search")) + CreateBackgroundPixmap(w, Search_bits, + Search_width, Search_height); + else if (!strcmp(buttonName, "help")) + CreateBackgroundPixmap(w, Help_bits, + Help_width, Help_height); + else if (!strcmp(buttonName, "quit")) + CreateBackgroundPixmap(w, Quit_bits, + Quit_width, Quit_height); + else if (!strcmp(buttonName, "list")) + CreateBackgroundPixmap(w, List_bits, + List_width, List_height); + else if (!strcmp(buttonName, "history")) + CreateBackgroundPixmap(w, History_bits, + History_width, History_height); + else if (!strcmp(buttonName, "close")) + CreateBackgroundPixmap(w, Close_bits, + Close_width, Close_height); + else if (!strcmp(buttonName, "about")) + CreateBackgroundPixmap(w, About_bits, + About_width, About_height); + else if (!strcmp(buttonName, "keep")) + CreateBackgroundPixmap(w, Kept_bits, + Kept_width, Kept_height); + else if (!strcmp(buttonName, "modify")) + CreateBackgroundPixmap(w, Modify_bits, + Modify_width, Modify_height); + else if (!strcmp(buttonName, "show_all")) + CreateBackgroundPixmap(w, ShowAll_bits, + ShowAll_width, ShowAll_height); + else if (!strcmp(buttonName, "submit_modify")) + CreateBackgroundPixmap(w, Modify_bits, + Modify_width, Modify_height); + + XFlush(dpy); +} + +/*ARGSUSED*/ +static void readDestroy(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Widget readForm = XtNameToWidget((Widget) closure, "ReadForm"); + PhotoWindow = XtNameToWidget(readForm, + "TextScrolledWindow.TextForm.PhotoWindow"); + + if (PhotoWindow != (Widget) 0) kill_photo(); + + if (curr_read_popup == (Widget) closure) { + XtPopdown(curr_read_popup); + return; + } + + if (curr_read_popup == (Widget) 0) { + Widget keepButton = XtNameToWidget((Widget) closure, + "ReadForm.ReadButtonForm.keepButton"); + CreateBackgroundPixmap(keepButton, Keep_bits, Keep_width, Keep_height); + XtPopdown((Widget) closure); + curr_read_popup = (Widget) closure; + return; + } + + XtPopdown((Widget) closure); + + XtUnmanageChild(readForm); + XtDestroyWidget(readForm); + + XtUnmanageChild((Widget) closure); + XtDestroyWidget((Widget) closure); +} + +/*ARGSUSED*/ +static void keepRead(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + if (curr_read_popup == (Widget) closure) { + PhotoWindow = 0; + curr_read_popup = 0; + } +} + +/*ARGSUSED*/ +static void modifyEntry(w, object, calldata) + Widget w; + XtPointer object, calldata; +{ + if (!curr_modify_popup) + curr_modify_popup = createModifyPopup((char *) object); + else { + Widget modify_form = XtNameToWidget(curr_modify_popup, "modifyForm"); + XawFormDoLayout(modify_form, FALSE); + (void) createModifyTemplate(curr_modify_popup, (char *) object); + XawFormDoLayout(modify_form, TRUE); + XtPopup(curr_modify_popup, XtGrabNone); + XRaiseWindow(dpy, XtWindow(curr_modify_popup)); + } +} + + +/*ARGSUSED*/ +static void closeModify(w, clientdata, calldata) + Widget w; + XtPointer clientdata, calldata; +{ + Widget modifyPopup = (Widget) clientdata; + Widget modifyForm = XtNameToWidget(modifyPopup, "modifyForm"); + Widget modifyButtonForm = XtNameToWidget(modifyForm, "ModifyButtonForm"); + Widget modifyScrolledWindow = XtNameToWidget(modifyForm, + "modifyScrolledWindow"); + Widget modMessage = XtNameToWidget(modifyForm, "modMessage"); + + XtPopdown(modifyPopup); + + if (modifyPopup == curr_modify_popup) return; + + if (curr_read_popup == (Widget) 0) { + Widget keepButton = XtNameToWidget(modifyButtonForm, "keepButton"); + CreateBackgroundPixmap(keepButton, Keep_bits, Keep_width, Keep_height); + return; + } + + XtUnmanageChild (modifyButtonForm); + XtDestroyWidget(modifyButtonForm); + + XtUnmanageChild(modifyScrolledWindow); + XtDestroyWidget(modifyScrolledWindow); + + XtUnmanageChild(modMessage); + XtDestroyWidget(modMessage); + + XtUnmanageChild(modifyForm); + XtDestroyWidget(modifyForm); + + XtUnmanageChild(modifyPopup); + XtDestroyWidget(modifyPopup); + + if (modifyPopup == curr_modify_popup) curr_modify_popup = (Widget) 0; +} + +/*ARGSUSED*/ +static void keepModify(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + if (curr_modify_popup == (Widget) closure) { + curr_modify_popup = 0; + } +} + +/*ARGSUSED*/ +static void modUpdate(w, attrValue, calldata) + Widget w; + XtPointer attrValue, calldata; +{ + Widget form = XtParent(XtParent(XtParent(XtParent(w)))); + + modVals val = (modVals) attrValue; + val->mod_flag = TRUE; + val->attr->mod_flag = TRUE; + displayModMessage(form, ""); +} + + +/*ARGSUSED*/ +static void submitModif(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + dirEntry mods = (dirEntry) closure; + dirAttrs attrs; + modVals vals; + int curr_mod_num = 0; + int count; + Arg args[MAXARGS]; + char *string; + dsErrorStruct mod_error; + + for (attrs = mods->attrs; attrs; attrs = attrs->next) + if (attrs->mod_flag) { + for (vals = attrs->val_seq; vals; vals = vals->next) + if (vals->mod_flag) { + if (vals->text_widg) { + count = 0; + XtSetArg(args[count], XtNstring, &string); count++; + XtGetValues(vals->text_widg, args, count); + + if (!(*string == '\0' && (!vals->value || *vals->value == '\0'))) { + vals->new_value = (*string == '\0'? NULLCP: strdup(string)); + curr_mod_num++; + } else { + vals->mod_flag = FALSE; + } + } else { + if (vals->value && *vals->value != '\0') { + vals->new_value = 0; + curr_mod_num++; + } else { + vals->mod_flag = FALSE; + } + } + } + if (curr_mod_num == 0) attrs->mod_flag = 0; + curr_mod_num = 0; + } + mod_error = modify_entry(mods); + + switch (mod_error.error) { + case Okay: + displayModMessage(XtParent(XtParent(w)), "Modifications made"); + break; + default: + displayModMessage(XtParent(XtParent(w)), mod_error.err_mess); + free(mod_error.err_mess); + } +} + +static void displayModMessage(form, err_mess) + Widget form; + char *err_mess; +{ + Widget messageWidg = XtNameToWidget(form, "modMessage"); + int count = 0; + Arg args[MAXARGS]; + + count = 0; + XtSetArg(args[count], XtNlabel, (err_mess? err_mess: "")); count++; + XtSetValues(messageWidg, args, count); +} + +XtCallbackRec modCallbacks[] = { + {modUpdate, (XtPointer) NULL}, + {(XtCallbackProc) NULL, (XtPointer) NULL}, +}; + +/*ARGSUSED*/ +static void deleteVal(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + modVals this_val = (modVals) closure, curr_val; + dirAttrs this_attr = (dirAttrs) this_val->attr, curr_attr; + Widget valWidg, menuWidg, nextValWidg, nextValMenuWidg, + nextAttrWidg = 0, fromVertWidg, form; + int count, vertDistance; + Arg args[MAXARGS]; + + valWidg = this_val->text_widg; + if (!valWidg) return; + + form = XtParent(valWidg); + XawFormDoLayout(form, FALSE); + + count = 0; + XtSetArg(args[count], XtNfromVert, &fromVertWidg); count++; + XtSetArg(args[count], XtNfromHoriz, &menuWidg); count++; + XtGetValues(valWidg, args, count); + + curr_val = this_attr->val_seq; + while (curr_val && curr_val != this_val && !(curr_val->text_widg)) + curr_val = curr_val->next; + + if (curr_val == this_val) vertDistance = 10; + else vertDistance = 2; + + curr_val = this_val->next; + while (curr_val && !(nextValWidg = curr_val->text_widg)) + curr_val = curr_val->next; + + if (curr_val && nextValWidg) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &nextValMenuWidg); count++; + XtGetValues(nextValWidg, args, count); + + this_val->text_widg = 0; + nextAttrWidg = 0; + + XtUnmanageChild(valWidg); + XtDestroyWidget(valWidg); + XtUnmanageChild(menuWidg); + XtDestroyWidget(menuWidg); + } else { + curr_attr = this_attr->next; + + if (curr_attr) { + vertDistance = 10; + + curr_val = curr_attr->val_seq; + while (!(nextValWidg = curr_val->text_widg)) curr_val = curr_val->next; + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &nextValMenuWidg); count++; + XtGetValues(nextValWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &nextAttrWidg); count++; + XtGetValues(nextValMenuWidg, args, count); + } else + nextValWidg = nextValMenuWidg = nextAttrWidg = 0; + + curr_val = this_attr->val_seq; + while (curr_val && !curr_val->text_widg) curr_val = curr_val->next; + + if (this_val == curr_val) { + count = 0; + XtSetArg(args[count], XtNstring, ""); count++; + XtSetValues(valWidg, args, count); + + nextValWidg = nextValMenuWidg = nextAttrWidg = 0; + } else { + this_val->text_widg = 0; + + XtUnmanageChild(valWidg); + XtDestroyWidget(valWidg); + XtUnmanageChild(menuWidg); + XtDestroyWidget(menuWidg); + } + } + + if (nextValWidg) { + count = 0; + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNfromVert, fromVertWidg); count++; + + XtSetValues(nextValMenuWidg, args, count); + XtSetValues(nextValWidg, args, count); + + if (nextAttrWidg) XtSetValues(nextAttrWidg, args, count); + } + + this_val->mod_flag = TRUE; + this_attr->mod_flag = TRUE; + if (this_val->new_value) { + free(this_val->new_value); + this_val->new_value = 0; + } + + XawFormDoLayout(form, TRUE); +} + +/*ARGSUSED*/ +static void addValField(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + dirAttrs attr = (dirAttrs) closure; + modVals first_val = attr->val_seq, new_val; + Widget newValWidg, firstValWidg = first_val->text_widg, fromVertWidg, form, + modValButton, modValMenu, modValMenuButton, firstValButton; + int count; + Arg args[MAXARGS]; + XFontStruct *font = 0; + Dimension height; + + new_val = (modVals) malloc(sizeof(struct mod_vals)); + new_val->next = first_val; + new_val->mod_flag = FALSE; + new_val->new_value = 0; + new_val->value = 0; + new_val->attr = attr; + + attr->val_seq = new_val; + + form = XtParent(XtParent(XtParent(w))); + XawFormDoLayout(form, FALSE); + + while (first_val && !(firstValWidg = first_val->text_widg)) + first_val = first_val->next; + + firstValWidg = first_val->text_widg; + + count = 0; + XtSetArg(args[count], XtNfromVert, &fromVertWidg); count++; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(firstValWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, XtParent(XtParent(w))); count++; + XtSetArg(args[count], XtNfromVert, fromVertWidg); count++; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNwidth, menuicon_width); count++; + XtSetArg(args[count], XtNheight, menuicon_height); count++; + XtSetArg(args[count], XtNvertDistance, 10); count++; + modValButton = XtCreateWidget("modValMenu", + menuButtonWidgetClass, + form, args, count); + + count = 0; + modValMenu = XtCreatePopupShell("menu", simpleMenuWidgetClass, + modValButton, args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, "Delete this value"); count++; + modValMenuButton = XtCreateManagedWidget("delValMenuButton", + smeBSBObjectClass, + modValMenu, args, count); + + XtAddCallback(modValMenuButton, XtNcallback, + deleteVal, (XtPointer) new_val); + + count = 0; + XtSetArg(args[count], XtNlabel, "Undo changes to this value"); count++; + modValMenuButton = XtCreateManagedWidget("undoValMenuButton", + smeBSBObjectClass, + modValMenu, args, count); + + XtAddCallback(modValMenuButton, XtNcallback, + UndoValChanges, (XtPointer) new_val); + + height = FONTHEIGHT(font) + font->ascent; + + modCallbacks[0].closure = (XtPointer) new_val; + count = 0; + XtSetArg(args[count], XtNfromHoriz, modValButton); count++; + XtSetArg(args[count], XtNeditType, XawtextEdit); count++; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNresize, XawtextResizeBoth); count++; + XtSetArg(args[count], XtNstring, ""); count++; + XtSetArg(args[count], XtNcallback, modCallbacks); count++; + XtSetArg(args[count], XtNheight, height); count++; + XtSetArg(args[count], XtNfromVert, fromVertWidg); count++; + XtSetArg(args[count], XtNvertDistance, 10); count++; + newValWidg = XtCreateWidget("valText", asciiTextWidgetClass, + form, args, count); + new_val->text_widg = newValWidg; + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &firstValButton); count++; + XtGetValues(firstValWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromVert, newValWidg); count++; + XtSetArg(args[count], XtNvertDistance, 2); count++; + XtSetValues(firstValWidg, args, count); + XtSetValues(firstValButton, args, count); + + XFlush(dpy); + + XtManageChild(modValButton); + XtManageChild(newValWidg); + + CreateBackgroundPixmap(modValButton, menuicon_bits, + menuicon_width, menuicon_height); + + XawFormDoLayout(form, TRUE); +} + +/*ARGSUSED*/ +static void UndoAttrChanges(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + dirAttrs this_attr = (dirAttrs) closure; + modVals this_val = this_attr->val_seq; + Widget form = XtParent(XtParent(XtParent(w))); + + this_attr->mod_flag = FALSE; + + XawFormDoLayout(form, FALSE); + while (this_val) { + UndoValChanges(w, (XtPointer) this_val, (XtPointer) w); + this_val = this_val->next; + } + XawFormDoLayout(form, TRUE); + XFlush(dpy); +} + +/*ARGSUSED*/ +static void UndoValChanges(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + int count; + Arg args[MAXARGS]; + Widget thisValWidg, thisValMenuWidg, thisAttrWidg, + prevValWidg, prevValMenuWidg, + nextValWidg, nextValMenuWidg, nextAttrWidg, + modValMenu, modValMenuButton, form; + int vertDistance; + modVals this_val = (modVals) closure, next_val, prev_val; + dirAttrs this_attr = this_val->attr, next_attr; + + if (!this_val->mod_flag && this_val->value) return; + + if (w != (Widget) calldata) { + form = XtParent(XtParent(XtParent(w))); + XawFormDoLayout(form, FALSE); + } + + this_val->mod_flag = FALSE; + thisValWidg = this_val->text_widg; + + if (this_val->new_value) { + free(this_val->new_value); + this_val->new_value = NULLCP; + } + + if (this_val->value && *this_val->value != '\0') { + if (!thisValWidg) { + prevValWidg = 0; + prev_val = this_attr->val_seq; + while (prev_val && prev_val != this_val) { + if (prev_val->text_widg) prevValWidg = prev_val->text_widg; + prev_val = prev_val->next; + } + + nextValWidg = 0; + if (!prevValWidg) { + next_val = this_val->next; + while (next_val && !(next_val->text_widg)) next_val = next_val->next; + + if (!next_val) { + if (w != (Widget) calldata) XawFormDoLayout(form, TRUE); + return; + } + + nextValWidg = next_val->text_widg; + + count = 0; + XtSetArg(args[count], XtNfromVert, &prevValWidg); count++; + XtGetValues(nextValWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &prevValMenuWidg); count++; + XtGetValues(nextValWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &thisAttrWidg); count++; + XtGetValues(prevValMenuWidg, args, count); + + vertDistance = 10; + } else { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &prevValMenuWidg); count++; + XtGetValues(prevValWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &thisAttrWidg); count++; + XtGetValues(prevValMenuWidg, args, count); + + vertDistance = 2; + } + + count = 0; + XtSetArg(args[count], XtNfromHoriz, thisAttrWidg); count++; + XtSetArg(args[count], XtNfromVert, prevValWidg); count++; + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNwidth, menuicon_width); count++; + XtSetArg(args[count], XtNheight, menuicon_height); count++; + thisValMenuWidg = XtCreateWidget("modValMenu", + menuButtonWidgetClass, + XtParent(thisAttrWidg), args, count); + + count = 0; + modValMenu = XtCreatePopupShell("menu", simpleMenuWidgetClass, + thisValMenuWidg, args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, "Delete this value"); count++; + modValMenuButton = XtCreateManagedWidget("delValMenuButton", + smeBSBObjectClass, + modValMenu, args, count); + + XtAddCallback(modValMenuButton, XtNcallback, + deleteVal, (XtPointer) this_val); + + count = 0; + XtSetArg(args[count], XtNlabel, "Undo changes to this value"); count++; + modValMenuButton = XtCreateManagedWidget("undoValMenuButton", + smeBSBObjectClass, + modValMenu, args, count); + + XtAddCallback(modValMenuButton, XtNcallback, + UndoValChanges, (XtPointer) this_val); + + modCallbacks[0].closure = (XtPointer) this_val; + + count = 0; + XtSetArg(args[count], + XtNwidth, + GetTextWidth(prevValWidg, this_val->value)); count++; + XtSetArg(args[count], + XtNheight, + GetTextHeight(prevValWidg, this_val->value)); count++; + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNfromVert, prevValWidg); count++; + XtSetArg(args[count], XtNfromHoriz, thisValMenuWidg); count++; + XtSetArg(args[count], XtNstring, this_val->value); count++; + XtSetArg(args[count], XtNeditType, XawtextEdit); count++; + XtSetArg(args[count], XtNresize, XawtextResizeBoth); count++; + XtSetArg(args[count], XtNcallback, modCallbacks); count++; + XtSetArg(args[count], XtNresizable, TRUE); count++; + thisValWidg = XtCreateWidget("valText", asciiTextWidgetClass, + XtParent(thisAttrWidg), args, count); + + this_val->text_widg = thisValWidg; + + next_attr = 0; + next_val = this_val->next; + while (next_val && !(next_val->text_widg)) next_val = next_val->next; + + if (next_val) nextValWidg = next_val->text_widg; + else { + next_attr = this_attr->next; + if (!next_attr) nextValWidg = 0; + else { + next_val = next_attr->val_seq; + while (!(next_val->text_widg)) next_val = next_val->next; + + nextValWidg = next_val->text_widg; + } + } + + if (nextValWidg) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &nextValMenuWidg); count++; + XtGetValues(nextValWidg, args, count); + + if (next_attr) { + vertDistance = 10; + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &nextAttrWidg); count++; + XtGetValues(nextValMenuWidg, args, count); + } else { + vertDistance = 2; + nextAttrWidg = 0; + } + + count = 0; + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNfromVert, thisValWidg); count++; + + XtSetValues(nextValWidg, args, count); + XtSetValues(nextValMenuWidg, args, count); + + if (nextAttrWidg) XtSetValues(nextAttrWidg, args, count); + } + + XtManageChild(thisValMenuWidg); + XtManageChild(thisValWidg); + + CreateBackgroundPixmap(thisValMenuWidg, menuicon_bits, + menuicon_width, menuicon_height); + } else { + count = 0; + XtSetArg(args[count], + XtNwidth, + GetTextWidth(thisValWidg, this_val->value)); count++; + XtSetArg(args[count], + XtNheight, + GetTextHeight(thisValWidg, this_val->value)); count++; + XtSetArg(args[count], XtNstring, this_val->value); count++; + XtSetValues(thisValWidg, args, count); + } + } else { + deleteVal(thisValWidg, (XtPointer) this_val, (XtPointer) 0); + } + if (w != (Widget) calldata) XawFormDoLayout(form, TRUE); +} + +static dirEntry createModifyTemplate(modify_form, entry_name) + Widget modify_form; + char *entry_name; +{ + Widget modifyViewForm, modAttrMenu, attrName, lastVal, + modAttrMenuButton, modValButton, modValMenu, modifyScrolledWindow, + valName, modValMenuButton, modifyButton; + dirEntry entry; + dirAttrs attrs, curr_attrs; + modVals curr_val; + Dimension text_width, text_height, max_width; + Arg args[MAXARGS]; + int count, vertDistance; + + make_template(entry_name, &attrs); + + entry = (dirEntry) malloc(sizeof(dir_entry)); + entry->entry_name = malloc((unsigned) strlen(entry_name) + 1); + (void) strcpy(entry->entry_name, entry_name); + entry->attrs = attrs; + + modifyViewForm = XtNameToWidget(modify_form, + "modifyForm.modifyScrolledWindow.modifyViewForm"); + modifyScrolledWindow = XtNameToWidget(modify_form, + "modifyForm.modifyScrolledWindow"); + + if (modifyViewForm != 0) { + XtUnmanageChild(modifyViewForm); + XtDestroyWidget(modifyViewForm); + } + + count = 0; + modifyViewForm = XtCreateWidget("modifyViewForm", formWidgetClass, + modifyScrolledWindow, args, count); + + lastVal = (Widget) 0; + for (curr_attrs = entry->attrs; curr_attrs; curr_attrs = curr_attrs->next) { + vertDistance = 10; + + count = 0; + if (lastVal) {XtSetArg(args[count], XtNfromVert, lastVal); count++;} + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNlabel, ""); count++; + XtSetArg(args[count], XtNjustify, XtJustifyLeft); count++; + XtSetArg(args[count], XtNresizable, TRUE); count++; + attrName = XtCreateWidget("attrLabel", menuButtonWidgetClass, + modifyViewForm, args, count); + + text_width = GetTextWidth(attrName, curr_attrs->attr_name); + + count = 0; + modAttrMenu = XtCreatePopupShell("menu", simpleMenuWidgetClass, + attrName, args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, "Add value field"); count++; + modAttrMenuButton = XtCreateManagedWidget("addValMenuButton", + smeBSBObjectClass, + modAttrMenu, args, count); + + XtAddCallback(modAttrMenuButton, XtNcallback, + addValField, (XtPointer) curr_attrs); + + count = 0; + XtSetArg(args[count], XtNlabel, "Undo ALL changes"); count++; + modAttrMenuButton = XtCreateManagedWidget("undoMenuButton", + smeBSBObjectClass, + modAttrMenu, args, count); + + XtAddCallback(modAttrMenuButton, XtNcallback, + UndoAttrChanges, (XtPointer) curr_attrs); + + count = 0; + XtSetArg(args[count], XtNlabel, curr_attrs->attr_name); count++; + XtSetArg(args[count], XtNwidth, text_width); count++; + XtSetValues(attrName, args, count); + + for (curr_val = curr_attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, attrName); count++; + if (lastVal) {XtSetArg(args[count], XtNfromVert, lastVal); count++;} + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNwidth, menuicon_width); count++; + XtSetArg(args[count], XtNheight, menuicon_height); count++; + modValButton = XtCreateWidget("modValMenu", + menuButtonWidgetClass, + modifyViewForm, args, count); + + count = 0; + modValMenu = XtCreatePopupShell("menu", simpleMenuWidgetClass, + modValButton, args, count); + + count = 0; + XtSetArg(args[count], XtNlabel, "Delete this value"); count++; + modValMenuButton = XtCreateManagedWidget("delValMenuButton", + smeBSBObjectClass, + modValMenu, args, count); + + XtAddCallback(modValMenuButton, XtNcallback, + deleteVal, (XtPointer) curr_val); + + count = 0; + XtSetArg(args[count], XtNlabel, "Undo changes to this value"); count++; + modValMenuButton = XtCreateManagedWidget("undoValMenuButton", + smeBSBObjectClass, + modValMenu, args, count); + + XtAddCallback(modValMenuButton, XtNcallback, + UndoValChanges, (XtPointer) curr_val); + + modCallbacks[0].closure = (XtPointer) curr_val; + count = 0; + if (curr_val->value) + if (!curr_attrs->hidden_flag) { + XtSetArg(args[count], XtNstring, curr_val->value); count++; + } else { + XtSetArg(args[count], XtNstring, "HIDDEN"); count++; + } + + if (lastVal) { + XtSetArg(args[count], XtNfromVert, lastVal); count++; + } + + XtSetArg(args[count], XtNfromHoriz, modValButton); count++; + XtSetArg(args[count], XtNvertDistance, vertDistance); count++; + XtSetArg(args[count], XtNeditType, XawtextEdit); count++; + XtSetArg(args[count], XtNresize, XawtextResizeBoth); count++; + XtSetArg(args[count], XtNresizable, TRUE); count++; + XtSetArg(args[count], XtNcallback, modCallbacks); count++; + valName = XtCreateWidget("valText", asciiTextWidgetClass, + modifyViewForm, args, count); + + text_height = text_width = 0; + if (!attrs->hidden_flag) { + text_height = GetTextHeight(valName, curr_val->value); + text_width = GetTextWidth(valName, curr_val->value); + } else { + text_height = GetTextHeight(valName, "HIDDEN"); + text_width = GetTextWidth(valName, "HIDDEN"); + } + + count = 0; + if (text_height && text_width) { + XtSetArg(args[count], XtNwidth, text_width); count++; + XtSetArg(args[count], XtNheight, text_height); count++; + XtSetValues(valName, args, count); + } + + curr_val->text_widg = valName; + + lastVal = valName; + vertDistance = 2; + } + } + + if (curr_modify_popup) { + for (max_width = 0, curr_attrs = entry->attrs; + curr_attrs; + curr_attrs = curr_attrs->next) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + XtGetValues(curr_attrs->val_seq->text_widg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &attrName); count++; + XtGetValues(modValButton, args, count); + + count = 0; + XtSetArg(args[count], XtNwidth, &text_width); count++; + XtGetValues(attrName, args, count); + + max_width = (text_width > max_width? text_width: max_width); + } + + for(curr_attrs = entry->attrs; curr_attrs; curr_attrs = curr_attrs->next) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + XtGetValues(curr_attrs->val_seq->text_widg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &attrName); count++; + XtGetValues(modValButton, args, count); + + count = 0; + XtSetArg(args[count], XtNwidth, max_width); count++; + XtSetValues(attrName, args, count); + + XtManageChild(attrName); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + + for (curr_val = curr_attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + valName = curr_val->text_widg; + XtGetValues(valName, args, count); + XtManageChild(modValButton); + XtManageChild(valName); + } + } + + XtManageChild(modifyViewForm); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + + for(curr_attrs = entry->attrs; curr_attrs; curr_attrs = curr_attrs->next) { + for (curr_val = curr_attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + valName = curr_val->text_widg; + XtGetValues(valName, args, count); + CreateBackgroundPixmap(modValButton, menuicon_bits, + menuicon_width, menuicon_height); + } + } + + modifyButton = XtNameToWidget(modify_form, + "modifyForm.ModifyButtonForm.modifyButton"); + +/* XtCallCallbacks(modifyButton, XtNdestroyCallback, NULL); + XtRemoveAllCallbacks(modifyButton, XtNdestroyCallback);*/ + + if (XtHasCallbacks(modifyButton, XtNcallback) == XtCallbackHasSome) + XtRemoveAllCallbacks(modifyButton, XtNcallback); + + XtAddCallback(modifyButton, XtNcallback, submitModif, (XtPointer) entry); + XtAddCallback(modifyButton, XtNdestroyCallback, + freeEntry, (XtPointer) entry); + + } else XtManageChild(modifyViewForm); + return entry; +} + +static Widget createModifyPopup(entry_name) + char *entry_name; +{ + Widget modifyPopup, modifyForm, modifyButton, closeButton, keepButton, + attrName, valName, ButtonForm, modMessage, modValButton; + dirEntry entry; + dirAttrs curr_attrs; + modVals curr_val; + Dimension text_width, text_height, max_width; + XFontStruct *font = 0; + Arg args[MAXARGS]; + int count; + + modifyPopup = XtCreatePopupShell("Modify Entry", topLevelShellWidgetClass, + toplevel, args, 0); + + count = 0; + modifyForm = XtCreateManagedWidget("modifyForm", formWidgetClass, + modifyPopup, args, count); + + count = 0; + ButtonForm = XtCreateManagedWidget("ModifyButtonForm", formWidgetClass, + modifyForm, args, count); + + count = 0; + XtSetArg(args[count], XtNheight, Close_height); count++; + XtSetArg(args[count], XtNwidth, Close_width); count++; + closeButton = XtCreateManagedWidget("closeButton", commandWidgetClass, + ButtonForm, args, count); + + XtAddCallback(closeButton, XtNcallback, closeModify, + (XtPointer) modifyPopup); + + count = 0; + XtSetArg(args[count], XtNheight, Keep_height); count++; + XtSetArg(args[count], XtNwidth, Keep_width); count++; + keepButton = XtCreateManagedWidget("keepButton", commandWidgetClass, + ButtonForm, args, count); + + XtAddCallback(keepButton, XtNcallback, keepModify, (XtPointer) modifyPopup); + + count = 0; + XtSetArg(args[count], XtNheight, Modify_height); count++; + XtSetArg(args[count], XtNwidth, Modify_width); count++; + modifyButton = XtCreateManagedWidget("modifyButton", commandWidgetClass, + ButtonForm, args, count); + + count = 0; + (void) XtCreateManagedWidget("modifyScrolledWindow", + viewportWidgetClass, modifyForm, + args, count); + + entry = createModifyTemplate(modifyPopup, entry_name); + + XtAddCallback(modifyButton, XtNcallback, submitModif, (XtPointer) entry); + XtAddCallback(modifyButton, XtNdestroyCallback, + freeEntry, (XtPointer) entry); + + count = 0; + XtSetArg(args[count], XtNlabel, ""); count++; + modMessage = XtCreateManagedWidget("modMessage", labelWidgetClass, + modifyForm, args, count); + + count = 0; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(modMessage, args, count); + + text_height = 5 * FONTHEIGHT(font); + count = 0; + XtSetArg(args[count], XtNheight, text_height); count++; + XtSetValues(modMessage, args, count); + + XtRealizeWidget(modifyPopup); + + for (max_width = 0, curr_attrs = entry->attrs; + curr_attrs; + curr_attrs = curr_attrs->next) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + XtGetValues(curr_attrs->val_seq->text_widg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &attrName); count++; + XtGetValues(modValButton, args, count); + + count = 0; + XtSetArg(args[count], XtNwidth, &text_width); count++; + XtGetValues(attrName, args, count); + + max_width = (text_width > max_width? text_width: max_width); + } + + for(curr_attrs = entry->attrs; curr_attrs; curr_attrs = curr_attrs->next) { + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + XtGetValues(curr_attrs->val_seq->text_widg, args, count); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &attrName); count++; + XtGetValues(modValButton, args, count); + + count = 0; + XtSetArg(args[count], XtNwidth, max_width); count++; + XtSetValues(attrName, args, count); + + XtManageChild(attrName); + + count = 0; + XtSetArg(args[count], XtNfromHoriz, &modValButton); count++; + + for (curr_val = curr_attrs->val_seq; + curr_val; + curr_val = curr_val->next) { + valName = curr_val->text_widg; + XtGetValues(valName, args, count); + XtManageChild(modValButton); + XtManageChild(valName); + CreateBackgroundPixmap(modValButton, menuicon_bits, + menuicon_width, menuicon_height); + } + } + + CreateBackgroundPixmap(modifyButton, Modify_bits, + Modify_width, Modify_height); + CreateBackgroundPixmap(closeButton, Close_bits, + Close_width, Close_height); + CreateBackgroundPixmap(keepButton, Keep_bits, + Keep_width, Keep_height); + + if (DefaultDepthOfScreen(screen) == 1) { + CreateBackgroundPixmap(ButtonForm, gray_bits, + gray_width, gray_height); + CreateBackgroundPixmap(modifyForm, gray_bits, + gray_width, gray_height); + } + + XtPopup(modifyPopup, XtGrabNone); + XRaiseWindow(dpy, XtWindow(modifyPopup)); + XFlush(dpy); + + return(modifyPopup); +} + + +/*ARGSUSED*/ +static void freeEntry(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + free_dir_entry((dirEntry) closure); +} + +/*ARGSUSED*/ +static void freeSpace(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + free(closure); +} + +/*ARGSUSED*/ +static void SetBorder(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + int count = 0; + Arg args[MAXARGS]; + + XtSetArg(args[count], XtNborderColor, BlackPixelOfScreen(screen)); count++; + XtSetValues(w, args, count); + + XFlush(dpy); +} + +/*ARGSUSED*/ +static void UnSetBorder(w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + int num_params; +{ + int count = 0; + Arg args[MAXARGS]; + + XtSetArg(args[count], XtNborderColor, WhitePixelOfScreen(screen)); count++; + XtSetValues(w, args, count); + + XFlush(dpy); +} + + +static int GetTextWidth(widget, string) + Widget widget; + char *string; +{ + int count; + Arg args[MAXARGS]; + XFontStruct *font; + int max_width, text_width; + register char *sptr, *str; + + if (!widget) return 0; + + count = 0; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(widget, args, count); + + if (!string || *string == '\0') return (FONTWIDTH(font)); + + max_width = 0; + sptr = str = string; + while (str && *str != '\0') { + if (*str == '\n') { + *str = '\0'; + text_width = XTextWidth(font, sptr, strlen(sptr)); + if (text_width > max_width) max_width = text_width; + *str = '\n'; + sptr = ++str; + } else str++; + } + + if (sptr) { + text_width = XTextWidth(font, sptr, strlen(sptr)); + if (text_width > max_width) max_width = text_width; + } + + return (max_width + FONTWIDTH(font)); +} + + +static int GetTextHeight(widget, string) + Widget widget; + char *string; +{ + int count; + Arg args[MAXARGS]; + XFontStruct *font; + int lines; + register char *str; + + if (!widget) return 0; + + count = 0; + XtSetArg(args[count], XtNfont, &font); count++; + XtGetValues(widget, args, count); + + if (!string || *string == '\0') return (FONTHEIGHT(font) + font->ascent); + + lines = 1; + str = string; + while (str && *str != '\0') { + if (*str == '\n') lines++; + str++; + } + + return ((FONTHEIGHT(font) * lines) + font->ascent); +} + +/*ARGSUSED*/ +static bool ConvSel(w, selection, target, type, value, length, format) + Widget w; + Atom *selection, *target, *type; + XtPointer *value; + unsigned long *length; + int *format; +{ + if (XmuConvertStandardSelection(w, selection, target, + type, value, length, format)) + return TRUE; + + if (*target == XA_STRING) { + *type = XA_STRING; + *value = strdup(curr_selection); + *length = strlen(*value); + *format = 8; + return TRUE; + } else + return FALSE; +} + +/*ARGSUSED*/ +static void CutString(w, closure, calldata) + Widget w; + XtPointer closure, calldata; +{ + Time time = XtLastTimestampProcessed(dpy); + char *string = (char *) closure; + + (void) strcpy(curr_selection, "@"); + (void) strcat(curr_selection, string); + XtOwnSelection(w, XA_PRIMARY, time, ConvSel, NULL, NULL); +} + +static void PopupMessage(shell, label_widget, label, grab_kind) + Widget shell, label_widget; + char *label; + XtGrabKind grab_kind; +{ + int count; + Arg args[MAXARGS]; + Dimension width, height; + Pixmap border_pixmap; + GC gc; + char dash_list[2]; + Position x, y; + + dash_list[0] = dash_list[1] = 1; + + width = GetTextWidth(label_widget, label) + 8; + height = GetTextHeight(label_widget, label) + 8; + + count = 0; + XtSetArg(args[count], XtNlabel, label); count++; + XtSetValues(label_widget, args, count); + + if (!XtIsRealized(outer)) XtMoveWidget(shell, 0, 0); + else { + count = 0; + XtSetArg(args[count], XtNx, &x); count++; + XtSetArg(args[count], XtNy, &y); count++; + XtGetValues(outer, args, count); + + XtTranslateCoords(outer, x, y, &x, &y); + + XtMoveWidget(shell, x, y); + } + + XtMakeResizeRequest(shell, width, height, NULL, NULL); + XtResizeWidget(label_widget, width, height, (Dimension) 1); + + XtPopup(shell, grab_kind); + XRaiseWindow(dpy, XtWindow(shell)); + + border_pixmap = XCreatePixmap(dpy, XtWindow(label_widget), + width, height, DefaultDepthOfScreen(screen)); + + gc = XCreateGC(dpy, XtWindow(label_widget), 0, NULL); + + XSetFunction(dpy, gc, GXcopy); + + XSetBackground(dpy, gc, WhitePixelOfScreen(screen)); + XSetForeground(dpy, gc, WhitePixelOfScreen(screen)); + + XFillRectangle(dpy, border_pixmap, gc, 0, 0, width, height); + + XSetForeground(dpy, gc, BlackPixelOfScreen(screen)); + + XSetDashes(dpy, gc, 0, dash_list, 2); + XSetLineAttributes(dpy, gc, 0, LineOnOffDash, CapButt, JoinBevel); + + XDrawLine(dpy, border_pixmap, gc, 0, 0, width - 1, 0); + XDrawLine(dpy, border_pixmap, gc, 1, 1, width - 2, 1); + XDrawLine(dpy, border_pixmap, gc, 2, 2, width - 3, 2); + XDrawLine(dpy, border_pixmap, gc, 3, 3, width - 4, 3); + + XDrawLine(dpy, border_pixmap, gc, 0, 0, 0, height - 1); + XDrawLine(dpy, border_pixmap, gc, 1, 1, 1, height - 2); + XDrawLine(dpy, border_pixmap, gc, 2, 2, 2, height - 3); + XDrawLine(dpy, border_pixmap, gc, 3, 3, 3, height - 4); + + XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel); + + XDrawLine(dpy, border_pixmap, gc, 0, height - 1, width - 1, height - 1); + XDrawLine(dpy, border_pixmap, gc, 1, height - 2, width - 2, height - 2); + XDrawLine(dpy, border_pixmap, gc, 2, height - 3, width - 3, height - 3); + XDrawLine(dpy, border_pixmap, gc, 3, height - 4, width - 4, height - 4); + + XDrawLine(dpy, border_pixmap, gc, width - 1, 0, width - 1, height - 1); + XDrawLine(dpy, border_pixmap, gc, width - 2, 1, width - 2, height - 2); + XDrawLine(dpy, border_pixmap, gc, width - 3, 2, width - 3, height - 3); + XDrawLine(dpy, border_pixmap, gc, width - 4, 3, width - 4, height - 4); + + count = 0; + XtSetArg(args[count], XtNbackgroundPixmap, border_pixmap); count++; + XtSetValues(label_widget, args, count); +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/pod.h b/usr/src/contrib/isode/others/quipu/uips/pod/pod.h new file mode 100644 index 0000000000..9913cfb1ce --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/pod.h @@ -0,0 +1,45 @@ +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/pod.h,v 7.1 91/02/22 09:31:50 mrose Interim $ + */ + +#include +#include "sequence.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define FONTHEIGHT(f) ((f)->max_bounds.ascent + \ + (f)->max_bounds.descent ) + + +#define FONTWIDTH(f) ((f)->max_bounds.width) + + + + + + + + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/search.c b/usr/src/contrib/isode/others/quipu/uips/pod/search.c new file mode 100644 index 0000000000..820aba9445 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/search.c @@ -0,0 +1,167 @@ +#include + +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/entry.h" +#include "quipu/name.h" + +#include "sequence.h" +#include "filt.h" +#include "defs.h" + +extern str_seq dnseq, backseq, showseq; +extern int entry_number, back_buf_num, dn_number; +extern int sizelimit; +extern unsigned int typeindx; +extern filt_struct *filt_arr[]; +extern char *filttype[]; + +#ifndef NO_STATS +extern LLog *log_stat; +#endif + +extern char goto_path[], base_path[], friendly_base_path[], mvalue[]; + +str_seq SortList(); +dsEnqError list_start(); +void dn2buf(); + +dsEnqError srch_start() +{ + struct ds_search_arg search_arg; + struct ds_search_result result; + struct DSError error; + dsEnqError return_error; + extern Filter make_filter(); + DN curr_rdn; + + if (*mvalue == '\0') { + return list_start(); + } + + if (get_default_service (&search_arg.sra_common) != 0) { + return nothingfound; + } + + search_arg.sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + + curr_rdn = search_arg.sra_baseobject = (*base_path != 'T'? + str2dn (base_path): + NULLDN); + + search_arg.sra_eis.eis_allattributes = FALSE; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTETYPESONLY; + search_arg.sra_eis.eis_select = 0; + search_arg.sra_searchaliases = TRUE; + + search_arg.sra_subset = SRA_ONELEVEL; + while (curr_rdn != NULLDN) { + if (!strcmp(curr_rdn->dn_rdn->rdn_at->oa_ot.ot_stroid, + "2.5.4.10")) { + search_arg.sra_subset = SRA_WHOLESUBTREE; + break; + } + curr_rdn = curr_rdn->dn_parent; + } + + if ((search_arg.sra_filter = make_filter(filt_arr[typeindx])) == NULLFILTER) + return duaerror; + +#ifndef NO_STATS + LLOG (log_stat, LLOG_NOTICE, ("search +%s, extent %d, val %s", + base_path,search_arg.sra_subset, mvalue)); +#endif + + if(ds_search (&search_arg, &error, &result) != DS_OK) { + /* deal with error */ + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; + log_ds_error(&error); + ds_error_free(&error); + switch (error.dse_type) { + case DSE_LOCALERROR: + return_error = duaerror; + break; + case DSE_REMOTEERROR: + return_error = localdsaerror; + break; + case DSE_ATTRIBUTEERROR: + return_error = attributerror; + break; + case DSE_REFERRAL: + case DSE_DSAREFERRAL: + return_error = remotedsaerror; + break; + case DSE_SECURITYERROR: + return_error = security; + break; + case DSE_NAMEERROR: + return_error = namerror; + break; + case DSE_SERVICEERROR: + return_error = serviceerror; + break; + default: + return_error = localdsaerror; + break; + } + } else { + correlate_search_results (&result); + dn_number = 0; + + if (result.CSR_entries != NULLENTRYINFO) { + register EntryInfo *ptr; + + return_error = Okay; + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; + + for (ptr = result.CSR_entries; + ptr != NULLENTRYINFO; + ptr = ptr->ent_next){ + dn_number++; + dn2buf((caddr_t) ptr->ent_dn, goto_path); + add_seq(&dnseq, goto_path); + } + + if (dn_number) dnseq = SortList(dnseq); + } else if (result.CSR_limitproblem == LSR_NOLIMITPROBLEM) { + free_seq(dnseq); + dnseq = NULLDS; + dn_number = 0; + return_error = nothingfound; + } + + if(result.CSR_limitproblem != LSR_NOLIMITPROBLEM) { + switch (result.CSR_limitproblem) { + case LSR_TIMELIMITEXCEEDED: + if (dn_number > 0) return_error = timelimit_w_partial; + else { + free_seq(dnseq); + dnseq = NULLDS; + return_error = timelimit; + } + break; + case LSR_SIZELIMITEXCEEDED: + return_error = listsizelimit; + break; + case LSR_ADMINSIZEEXCEEDED: + if (dn_number > 0) return_error = adminlimit_w_partial; + else { + free_seq(dnseq); + dnseq = NULLDS; + return_error = adminlimit; + } + break; + } + entryinfo_free(result.CSR_entries, 0); + } + } + entry_number = dn_number; + filter_free(search_arg.sra_filter); + dn_free(search_arg.sra_baseobject); + ds_error_free(&error); + return return_error; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/sequence.c b/usr/src/contrib/isode/others/quipu/uips/pod/sequence.c new file mode 100644 index 0000000000..936810b25d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/sequence.c @@ -0,0 +1,60 @@ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/pod/RCS/sequence.c,v 7.1 91/02/22 09:31:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/sequence.c,v 7.1 91/02/22 09:31:53 mrose Interim $ + */ + + +#include +#include + +#include "sequence.h" + +void add_seq (seq, str) + str_seq *seq; + char *str; +{ + str_seq curr; + + if (*seq) { + for (curr = *seq; curr->next; curr = curr->next) {} + curr->next = (struct str_seq *) malloc (sizeof (struct str_seq)); + curr = curr->next; + curr->strlen = strlen (str); + curr->dname = malloc ((curr->strlen)+5); + (void) strcpy(curr->dname, str); + curr->next = 0; + } else { + curr = (struct str_seq *) malloc (sizeof (struct str_seq)); + curr->strlen = strlen (str); + curr->dname = malloc ((curr->strlen)+5); + (void) strcpy(curr->dname, str); + curr->next = 0; + *seq = curr; + } +} + +char *get_from_seq (seq_num, seq_ptr) + int seq_num; + str_seq seq_ptr; +{ + for (; seq_num > 1 && seq_ptr; seq_ptr = seq_ptr->next, seq_num--) {} + if (seq_ptr) return seq_ptr->dname; + else return 0; +} + +void free_seq (seq_ptr) + str_seq seq_ptr; +{ + str_seq next_seq; + + while (seq_ptr) { + free((char *) (seq_ptr->dname)); + next_seq = seq_ptr->next; + free((char *) seq_ptr); + seq_ptr = next_seq; + } +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/sequence.h b/usr/src/contrib/isode/others/quipu/uips/pod/sequence.h new file mode 100644 index 0000000000..3e2f852ae9 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/sequence.h @@ -0,0 +1,29 @@ +/* + * $Header: /f/osi/others/quipu/uips/pod/RCS/sequence.h,v 7.1 91/02/22 09:31:54 mrose Interim $ + */ + +#ifndef SEQ +#define SEQ + +#include +#include "defs.h" + +#ifdef QUIPU_MALLOC + +#else +extern char * malloc (); +extern char * smalloc (); +#endif + +typedef struct str_seq { + char *dname; + unsigned strlen; + struct str_seq *next; +} strSeq, *str_seq; + +#define NULLDS ((str_seq) 0) +char *get_from_seq(); +void add_seq(); +void free_seq(); +#endif + diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/util.c b/usr/src/contrib/isode/others/quipu/uips/pod/util.c new file mode 100644 index 0000000000..00897804da --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/util.c @@ -0,0 +1,54 @@ +#include "util.h" + +int issubstr(str, substr) + char *str; + char *substr; +{ + register char *sptr; + char c; + int substrlen = strlen(substr); + int count; + + if (*substr == '\0' || *str == '\0') return(0); + + sptr = str; + c = *substr; + + while (1) { + while (*sptr != '\0' && *sptr != c) sptr++; + if (*sptr == '\0') return(0); + for (count = 0; count < substrlen; count++) { + if (sptr[count] == '\0') return(0); + else if (substr[count] != sptr[count]) break; + } + if (count == substrlen) return(1); + sptr++; + } +} + +int indexstring(string, substring) + char *string, *substring; +{ + register char *sub, *str; + char c, s; + int indx = 0; + + while (1) { + str = string + indx;; + if (*str == '\0') return(-1); + sub = substring; + + if (*str == *sub) { + s = *str; + c = *sub; + while(c == s && c != '\0') { + c = *++sub; + s = *++str; + } + + if (c == '\0') return((int) indx); + else if(s == '\0') return(-1); + } + indx++; + } +} diff --git a/usr/src/contrib/isode/others/quipu/uips/pod/util.h b/usr/src/contrib/isode/others/quipu/uips/pod/util.h new file mode 100644 index 0000000000..0c9f087c07 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/pod/util.h @@ -0,0 +1,4 @@ +#include + +int issubstr(); +int indexstring(); diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/READ-ME b/usr/src/contrib/isode/others/quipu/uips/sd/READ-ME new file mode 100644 index 0000000000..83ddc5d7bb --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/READ-ME @@ -0,0 +1,27 @@ +This directory contains an OSI directory interface called "sd", derived +from the "widget" interface released with isode-5.0). + +It is "full screen" style interface based on the curses library. To +generate sd you should: + + ./make + +To test 'sd' enter the following command, + + xsd -test + +To install you should: + + ./make install + +from this directory. If you do not want to clean up after the install +you can issue the following command instead: + + ./make inst-all + +The directory 'x29' contains files that allow sd to be set up as +a public-access service. + + +Bug reports and comments (gratefully recieved!) to x500@brunel.ac.uk + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/calls.c b/usr/src/contrib/isode/others/quipu/uips/sd/calls.c new file mode 100644 index 0000000000..af9e50283a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/calls.c @@ -0,0 +1,1627 @@ +/* calls.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/calls.c,v 7.4 91/02/22 09:32:09 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/calls.c,v 7.4 91/02/22 09:32:09 mrose Interim $ + */ + +#include "calls.h" + +#define RESBUF 10000 + +typedef enum {rfc822, greybook} mailtype; +mailtype mailformat = rfc822; + +int scrollize; +PS opt; +Attr_Sequence read_types = 0, read_types2 = 0, oclass = 0; + +str_seq curr_dnseq, textseq, back_seq; + +int current_entry, entry_number, display_entry; +int back_buf_num; + +int dn_print (), rdn_print(), as_print(); +void quit(), int_quit(); +void help_back(), help_list(), help_up(), help_number(), help_srch(), + help_cncs(); +void setwidgets(); + +char bound = FALSE; /* indication of wether bound */ +char * TidyString(); + +/* hack to get isode/curses compatability */ +#define WINDOW char + +#include "widget.h" +#include "wdgtdefs.h" + +extern text_height; +int text_state; +int histlimit = 20; +char testing = FALSE; + +#define DN_LIST 0 +#define TEXT 1 +#define BACK_LIST 3 + +/* These are common operation variables */ +#define STRINGLEN 1000 +#define SMALLSTRING 255 +#define MAXTYPES 255 + +char goto_path[STRINGLEN]; /* Used by the 'G:goto' command*/ +char base_path[STRINGLEN]; /* Used by all DS operations */ +char friendly_base_path[STRINGLEN]; +char friendly_name[STRINGLEN]; +char namestr[STRINGLEN]; +char cache [STRINGLEN]; +char bindpass [STRINGLEN]; +char srchvalue[STRINGLEN]; /* Used by search */ +char mvalue [STRINGLEN]; + +unsigned int curr_filt = 0; +unsigned int filt_num = 0; +unsigned int typeindx = 0; +filt_struct *filt_arr[MAXTYPES]; +char *filtvalue[MAXTYPES]; +char *filttype[MAXTYPES]; + +int default_num; +int *av_typeindx; +int *available_types[MAXTYPES]; +char *levels[MAXTYPES]; +int defaults[MAXTYPES]; + +#ifndef NO_STATS +extern LLog *log_stat; +#endif + +/* These are used as the data for the binding connection */ +char passwd[STRINGLEN]; +extern char * myname; + +extern int sizelimit; +extern char *local_dit; +DN user_name; + +char * addobj = NULLCP; + +Filter search_filter; + +FILE *config_file; +char *file_names[MAXTYPES]; + +char *get_strioid(ptr) +register char *ptr; +{ + register char *end_ptr; + + while(*ptr == '"') ptr++; + while(*ptr != '"') ptr++; + + while(*ptr > '9' || *ptr < '0') ptr++; + + end_ptr = ptr; + while(*end_ptr != '\n') end_ptr++; + + *end_ptr = '\0'; + return ptr; +} + +void user_tailor() +{ + char *part1; + char *part2; + char *getenv (); + char *ptr = "/.duarc"; + char *config_dir = "/.duaconfig/"; + char *isode_config_dir = "sd/duaconfig/"; + char *type_dir = "filterTypes/"; + char *readTypes = "readTypes"; + char *typeDefaults = "typeDefaults"; + + char user_home[BUFSIZ]; + char read_path[BUFSIZ]; + char type_path[BUFSIZ]; + char type_defaults_path[BUFSIZ]; + + char stroid_buf[BUFSIZ]; + + DIR *config_directory; + + struct dirent *dir_ent; + + char Read_in_Stuff[STRINGLEN]; + char *p, + *TidyString(), + *SkipSpace(), + *end; + + int count, n, num; + int tempints[MAXTYPES]; + +#ifndef NO_STATS + ll_hdinit (log_stat,"sd"); +#endif + + if ((opt = ps_alloc (std_open)) == NULLPS) + fatal (-1,"ps_alloc failed"); + if (std_setup (opt,stdout) == NOTOK) + fatal (-1,"std_setup failed"); + + cache[0] = '\0'; + + (void) strcpy (user_home, getenv ("HOME")); + (void) strcpy(read_path, user_home); + (void) strcpy(type_path, user_home); + (void) strcpy(type_defaults_path, user_home); + + (void) strcat(user_home, ptr); + (void) strcat(read_path, config_dir); + (void) strcat(read_path, readTypes); + (void) strcat(type_path, config_dir); + (void) strcat(type_path, type_dir); + (void) strcat(type_defaults_path, config_dir); + (void) strcat(type_defaults_path, typeDefaults); + + if (testing) { + (void) strcpy(type_path, "./sd/duaconfig/"); + (void) strcat(type_path, type_dir); + if (!(config_directory = opendir(type_path))) { + (void) fprintf(stderr, "File error! Test sd should be run from source directory!\n"); + int_quit(1); + } + } else { + if (!(config_directory = opendir(type_path))) { + (void) strcpy(type_path, isodefile(isode_config_dir,0)); + (void) strcat(type_path, type_dir); + if(!(config_directory = opendir(type_path))) { + quit("Can't find directory filterTypes.\n", 1); + } + } + } + + rewinddir(config_directory); + filt_num = 0; + while(dir_ent = readdir(config_directory)) { + if (!(strncmp(dir_ent->d_name, "Type_", 5))) { + file_names[filt_num] = + (char *) malloc((unsigned) + (strlen(dir_ent->d_name) + strlen(type_path) + 2)); + (void) strcpy(file_names[filt_num], type_path); + (void) strcat(file_names[filt_num], dir_ent->d_name); + filt_num++; + } + } + (void) closedir(config_directory); + + if ((config_file = fopen (user_home, "r")) == 0); + else { + while (fgets (Read_in_Stuff, STRINGLEN, config_file) != 0) { + p = SkipSpace (Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; /* ignore comments and blanks */ + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) + continue; /* ignore it */ + + *part2++ = '\0'; + part2 = TidyString(part2); + + if ((lexequ(part1, "username") == 0) && namestr[0] == '\0') + (void) strcpy (namestr, part2); + else if ((lexequ(part1, "password") == 0) && passwd[0] == '\0') + (void) strcpy (passwd, part2); + else if (lexequ(part1, "prefergreybook") == 0) + mailformat = greybook; + else if (lexequ(part1, "dsap") == 0) + (void) tai_string (part2); + else if (lexequ(part1, "isode") == 0) { + char * split; + if ((split = index(part2,' ')) != NULLCP) { + *split++ = 0; + (void) isodesetvar(part2,split,0); + } + } else if(strcmp (part1, "service") == 0) + new_service (part2); + else if (lexequ(part1, "history") == 0) { + (void) sscanf(part2, "%d", &histlimit); + if (histlimit < 1) histlimit = 1; + } + } + isodexport (); + (void) fclose(config_file); + } + + if (testing) { + (void) strcpy(read_path, "./sd/duaconfig/"); + (void) strcat(read_path, readTypes); + if (!(config_file = fopen(read_path, "r"))) { + (void) fprintf(stderr, "File error! Test sd must be run from source directory!\n"); + int_quit(1); + } + } else { + if (!(config_file = fopen(read_path, "r"))) { + (void) strcpy(read_path, isodefile(isode_config_dir,0)); + (void) strcat(read_path, readTypes); + if (!(config_file = fopen(read_path, "r"))) { + quit("Can't find file readTypes.\n", 1); + } + } + } + +/* load_oid_table("oidtable");*/ + + while(fgets(Read_in_Stuff, STRINGLEN, config_file) != 0) { + (void) strcpy(stroid_buf, get_strioid(Read_in_Stuff)); + if (*stroid_buf) { + if (!read_types) + read_types = as_comp_new(AttrT_new(stroid_buf), NULLAV, NULLACL_INFO); + else { + read_types2 = as_comp_new(AttrT_new(stroid_buf) ,NULLAV, NULLACL_INFO); + read_types = as_merge(read_types, read_types2); + } + } + } + (void) fclose(config_file); + + for (curr_filt = 0; curr_filt < filt_num; curr_filt++) { + if (!(config_file = fopen(file_names[curr_filt], "r"))) { + quit("Can't find filter template file\n", 1); + } + filtvalue[curr_filt] = (char *) malloc(STRINGLEN); + *filtvalue[curr_filt] = '\0'; + + (void) yyparse(); + (void) fclose(config_file); + } + filttype[curr_filt] = NULLCP; + for (count = 0; count < filt_num; count++) + free(file_names[count]); + + if (testing) { + (void) strcpy(type_defaults_path, "./sd/duaconfig/"); + (void) strcat(type_defaults_path, typeDefaults); + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) fprintf(stderr, "File error! Test sd must be run from source directory.\n"); + int_quit(1); + } + } else { + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) strcpy(type_defaults_path, isodefile(isode_config_dir,0)); + (void) strcat(type_defaults_path, typeDefaults); + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) strcpy(type_defaults_path, "./sd/duaconfig/"); + (void) strcat(type_defaults_path, typeDefaults); + if (!(config_file = fopen(type_defaults_path, "r"))) { + (void) fprintf(stderr, "Can't open typeDefaults file\n"); + int_quit(1); + } + } + } + } + + default_num = 0; + while (fgets (Read_in_Stuff, STRINGLEN, config_file) != 0) { + p = SkipSpace(Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) + continue; + + end = part2 - 1; + while (isspace(*end)) end--; + *++end = '\0'; + + *part2++ = '\0'; + + while (isspace(*part2)) part2++; + end = part2; + + while (!isspace(*end) && *end != ',' && *end != ':') end++; + + count = 0; + while (*part2 != ':') { + n = 0; + while (n < filt_num && strncmp(filttype[n], part2, + (int) (end - part2))) n++; + + if (n == filt_num) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + int_quit(1); + } else { + tempints[count] = n; + count++; + part2 = end; + while (!isalpha(*part2) && *part2 != ':' && part2 != '\0') part2++; + + if (*part2 == '\0') { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + int_quit(1); + } + + if (*part2 != ':') { + while (!isalpha(*part2)) part2++; + end = part2; + while (!isspace(*end) && *end != ',' && + *end != ':' && *end != '\0') end++; + if (*end == '\0') { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + int_quit(1); + } + } else end = part2; + } + } + if (*end == ':') { + while(isspace(*++end)); + p = end; + while(!isspace(*++end)); + *end = '\0'; + + n = 0; + while (n < filt_num && strcmp(filttype[n], p)) n++; + + if (n == filt_num) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + int_quit(1); + } else { + num = 0; + while (num < count && n != tempints[num]) num++; + if (num == count) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + int_quit(1); + } + } + + defaults[default_num] = n; + + levels[default_num] = strdup(part1); + available_types[default_num] = (int *) malloc((unsigned) + sizeof(int) * (count+1)); + + for (n = 0; n < count; n++) + available_types[default_num][n] = tempints[n]; + + available_types[default_num][n] = -1; + default_num++; + } + } + (void) fclose(config_file); +} + +void main_help() +{ + cleartext(); + killwidgets(mainwdgts); + setwidgets(dethelpwdgts,-1); + help_cncs(); +} + +void main_bind() +{ + cleartext(); + if (*passwd != 0) + (void) strcpy(bindpass,"******"); + else + bindpass[0] = '\0'; +} + +void cnnct_quit () +{ + quit("Exiting sd.\n", 0); +} + +void cnnct_bind() +{ + struct ds_bind_arg bindarg; + struct ds_bind_arg bindresult; + struct ds_bind_error binderr; + extern char * dsa_address, + * myname; + extern char * tailfile; + FILE * fp; + char buf [BUFSIZ]; + + /* set dsa_address */ + dsa_address = NULLCP; + /* read tailor file to get address */ + if( (fp = fopen(isodefile(tailfile,0), "r")) == (FILE *)NULL) { + tprint ("Cannot open tailor file %s\n",isodefile(tailfile,0)); + return; + } + while(fgets(buf, sizeof(buf), fp) != NULLCP) + if ( (*buf != '#') && (*buf != '\n') ) + (void) tai_string(buf); + + (void) fclose(fp); + + if (dsa_address == NULLCP) + dsa_address = myname; + + /* set password */ + if (bindpass[0] != 0) { + if (strcmp (bindpass,"******") != 0) + (void) strcpy (passwd,bindpass); + } else + passwd[0] = 0; + + /* now bind */ + bindarg.dba_version = DBA_VERSION_V1988; + if (passwd[0] == 0) { + bindarg.dba_passwd_len = 0; + bindarg.dba_passwd [0] = '\0'; + } else { + bindarg.dba_passwd_len = strlen(passwd); + (void) strcpy (bindarg.dba_passwd, passwd); + } + + bindarg.dba_dn = (*namestr == 0? NULLDN: str2dn(namestr)); + + if (ds_bind (&bindarg,&binderr,&bindresult) != DS_OK) { + if (binderr.dbe_type == DBE_TYPE_SECURITY) + quit("Bind security error - Check name and pasword.\n", 0); + else + quit("Bind service error - Can't contact DSA!\n", 1); + } else { + setdialogstr(getwidget(mainwdgts, '\0'), friendly_base_path, STRINGLEN); + setdialogstr(getwidget(mainwdgts, 's'), mvalue, STRINGLEN); + setdialogstr(getwidget(mainwdgts, '*'), srchvalue, 6); + settogglstrs(getwidget(mainwdgts, 't'), filttype, 0); + setwidgets (mainwdgts,-1); + user_name = bindarg.dba_dn; + + if(local_dit && *local_dit) + (void) strcpy(base_path, local_dit); + else + (void) strcpy(base_path, "The World"); + + oclass = as_comp_new(AttrT_new("objectClass"), NULLAV, NULLACL_INFO); + make_friendly(friendly_base_path, base_path); + printdialog(getwidget(mainwdgts,'\0')); + set_default_type(); + + (void) strcpy (buf, "TERM"); + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("bound ('%s' to '%s')",namestr,dsa_address)); +#endif +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("sd called from a ('%s')", getenv(buf))); +#endif + } + display_entry = current_entry = 1; + entry_number = 0; + back_buf_num = 0; + textseq = back_seq = curr_dnseq = NULLDS; + text_state = TEXT; +} + +void rd_start() +{ + struct ds_read_arg read_arg; + struct ds_read_result result; + struct DSError error; + Entry read_entry; + + cleartext(); + if (*friendly_base_path == 'T') { + free_seq(textseq); + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = textseq = NULLDS; + text_state = TEXT; + entry_number = 0; + return; + } + + xprint("Reading data on "); + xprint(friendly_base_path); + xprint(".\n"); + tprint("Working. Please wait....."); + + if ( get_default_service (&read_arg.rda_common) != 0) { + xprint ("Default service error -> check your .quipurc\n"); + return ; + } + + read_arg.rda_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + read_arg.rda_eis.eis_allattributes = FALSE; + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + read_arg.rda_eis.eis_select = read_types; + + read_arg.rda_object = (*friendly_base_path != 'T'? + str2dn(base_path): + NULLDN); + if ((read_entry = local_find_entry(read_arg.rda_object, FALSE)) + != NULLENTRY && + read_entry->e_data != E_TYPE_CONSTRUCTOR) { + read_entry->e_attributes = sort_attrs(read_entry->e_attributes); + read_print (as_print, (caddr_t) read_entry->e_attributes); + return; + } + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("read +%s",base_path)); +#endif + + if (ds_read (&read_arg,&error,&result) != DS_OK) { + /* deal with error */ + cleartext(); + quipu_error(&error); + } else { + /* use data */ + if (result.rdr_entry.ent_attr == NULLATTR) { + free_seq(textseq); + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = textseq = NULLDS; + entry_number = 0; + text_state = TEXT; + xprint("No attributes"); + return; + } + xprint("Result of look up ...\n"); + if (result.rdr_common.cr_aliasdereferenced) + xprint("Alias dereferenced)\n"); + + result.rdr_entry.ent_attr = sort_attrs(result.rdr_entry.ent_attr); + cache_entry(&(result.rdr_entry), FALSE, TRUE); + read_print(as_print, (caddr_t) result.rdr_entry.ent_attr); + } +} + +void back_start() +{ + if (!back_buf_num) { + cleartext(); + tprint("History Buffer Empty!\n"); + sleep(3); + scrollbar('\0'); + return; + } + + if (text_state == DN_LIST) free_seq(curr_dnseq); + + free_seq(textseq); + textseq = NULLDS; + curr_dnseq = back_seq; + text_state = BACK_LIST; + entry_number = back_buf_num; + current_entry = display_entry = 1; + scrollbar('\0'); +} + +void widen() +{ + register char *str, *sptr; + int count = 0; + str_seq first; + + str = get_from_seq(count+1, back_seq); + while (count < back_buf_num && strcmp(str, base_path)){ + count++; + str = get_from_seq(count+1, back_seq); + } + if (count == back_buf_num) { + add_seq(&back_seq, base_path); + if (++back_buf_num > histlimit) { + first = back_seq; + back_seq = back_seq->next; + first->next = 0; + free_seq(first); + } + } + + str = base_path; + if (*str != 'T') { + + for (sptr = str; *sptr != '\0'; sptr++) + if (*sptr == '@') str = sptr; + + sptr = str; + typetoggled = 0; + + if (str != base_path) { + if (*--sptr == ' ') + str = sptr; + *str = '\0'; + } else + (void) strcpy(base_path, "The World"); + + make_friendly(friendly_base_path, base_path); + set_default_type(); + printdialog(getwidget(mainwdgts, '\0')); + rd_start(); + } +} + +void set_default_type() +{ + int count, lastindx; + WIDGET *wdgt, *vwdgt; + DN base_name; + + wdgt = getwidget(mainwdgts,'t'); + vwdgt = getwidget(mainwdgts, 's'); + + if (av_typeindx) + lastindx = wdgt->tindx; + else + lastindx = 0; + + if (*base_path != 'T') { + if (!typetoggled) { + base_name = str2dn(base_path); + while (base_name->dn_parent) base_name = base_name->dn_parent; + for (count = 0; count < default_num && + strcmp(levels[count] ,base_name->dn_rdn->rdn_at-> + oa_ot.ot_stroid); + count++); + + if (count < default_num) { + av_typeindx = available_types[count]; + typeindx = defaults[count]; + } else { + av_typeindx = available_types[0]; + typeindx = defaults[0]; + } + count = typeindx; + + if (count < filt_num) { + if (lastindx) + (void) strcpy(filtvalue[lastindx], vwdgt->dstr); + wdgt->tindx = count; + (void) strcpy(vwdgt->dstr, filtvalue[wdgt->tindx]); + } + } + } else { + for(count = 0; count < default_num && strcmp(levels[count], "@"); count++); + if (count < default_num) { + av_typeindx = available_types[count]; + typeindx = defaults[count]; + } else { + av_typeindx = available_types[0]; + typeindx = defaults[0]; + } + count = typeindx; + if (count < filt_num) { + if (lastindx) + (void) strcpy(filtvalue[lastindx], vwdgt->dstr); + wdgt->tindx = count; + (void) strcpy(vwdgt->dstr, filtvalue[wdgt->tindx]); + } + } + + make_friendly(friendly_base_path, base_path); + typetoggled = 0; + printtoggle(wdgt); + printdialog(vwdgt); +} + +/* These are the functions called by the list level widgets */ + +void list_start() +{ + struct ds_search_arg search_arg; + struct ds_search_result result; + struct DSError error; + + cleartext(); + xprint("OK, listing.\n"); + tprint("Working. Please wait....."); + + if (get_default_service (&search_arg.sra_common) != 0) { + xprint ("Default service error -> check your .quipurc\n"); + return ; + } + + search_arg.sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + search_arg.sra_baseobject = (*base_path != 'T'? + str2dn (base_path): + NULLDN); + + search_arg.sra_eis.eis_allattributes = FALSE; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTETYPESONLY; + search_arg.sra_eis.eis_select = 0; + search_arg.sra_subset = SRA_ONELEVEL; + + search_arg.sra_filter = filter_alloc(); + search_arg.sra_filter->flt_type = FILTER_NOT; + search_arg.sra_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_un.flt_un_filter = filter_alloc(); + search_arg.sra_filter->flt_un.flt_un_filter->flt_type = FILTER_ITEM; + search_arg.sra_filter->flt_un.flt_un_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_type + = FILTERITEM_EQUALITY; + + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un. + fi_un_ava.ava_type = AttrT_new("2.5.4.0"); + + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un. + fi_un_ava.ava_value = + str2AttrV("dsa", search_arg.sra_filter->flt_un.flt_un_filter-> + flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax); + + if (search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item. + fi_un.fi_un_ava.ava_value == NULLAttrV) { + cleartext(); + xprint("Internal Error! Sorry."); + } else if (ds_search (&search_arg,&error,&result) != DS_OK) { + /* deal with error */ + free_seq(textseq); + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = textseq = NULLDS; + text_state = TEXT; + entry_number = 0; + cleartext(); + xprint("Search error!\n"); + quipu_error(&error); + } else { + cleartext(); + correlate_search_results (&result); + if (result.CSR_entries != NULLENTRYINFO) { + register EntryInfo *ptr; + + xprint ("Result of search ...\n"); + if (result.CSR_common.cr_aliasdereferenced) { + xprint ("(Alias dereferenced - object is "); + quipu_print (dn_print, (caddr_t) result.CSR_object); + dn_free (result.CSR_object); + xprint (")\n"); + } + + if (text_state == DN_LIST) free_seq(curr_dnseq); + free_seq(textseq); + curr_dnseq = textseq = NULLDS; + display_entry = current_entry = 1; + entry_number = 0; + text_state = DN_LIST; + + for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; + ptr = ptr->ent_next) { + entry_number++; + dn2buf ((caddr_t)ptr->ent_dn, goto_path); + add_seq (&curr_dnseq, goto_path); + } + + if (entry_number) curr_dnseq = SortList(curr_dnseq); + scrollbar('\0'); + } else if (result.CSR_limitproblem != LSR_TIMELIMITEXCEEDED) { + free_seq(textseq); + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = textseq = NULLDS; + entry_number = 0; + text_state = TEXT; + xprint("Nothing found<"); + } + + if(result.CSR_limitproblem != LSR_NOLIMITPROBLEM) { + switch (result.CSR_limitproblem) { + case LSR_TIMELIMITEXCEEDED: + if (entry_number > 0) + xprint("(Time limit exceeded. Partial results only.)"); + else { + free_seq(curr_dnseq); + curr_dnseq = NULLDS; + xprint("(Time limit exceeded.)"); + } + break; + case LSR_SIZELIMITEXCEEDED: + xprint("(Size limit exceeded)"); + break; + case LSR_ADMINSIZEEXCEEDED: + if (entry_number > 0) + xprint("(Administrative limit reached. Partial results only.)"); + else { + free_seq(curr_dnseq); + curr_dnseq = NULLDS; + xprint("(Administrative limit reached.)"); + } + break; + } + } + + entryinfo_free(result.CSR_entries, 0); + } + + filter_free(search_arg.sra_filter); +} + +void rdn2str(ptr,cptr) + caddr_t ptr; + char * cptr; +{ + PS ps; + char buffer [RESBUF]; + + if ((ps = ps_alloc(str_open)) == NULLPS) { + return ; + } + if (str_setup(ps, buffer, RESBUF, 1) == NOTOK) { + return ; + } + rdn_print(ps, (RDN) ptr, READOUT); + + ps_free(ps); + *ps->ps_ptr = 0; + + (void) strcpy(cptr, buffer); +} + +void srch_start() +{ + struct ds_search_arg search_arg; + struct ds_search_result result; + struct DSError error; + WIDGET *wdgt; + DN curr_rdn; + + if (*mvalue == '\0') { + list_start(); + return; + } + + cleartext(); + xprint("OK. Starting search.\n"); + tprint("Working. Please wait....."); + + wdgt = getwidget(mainwdgts,'t'); + + if (get_default_service (&search_arg.sra_common) != 0) { + xprint ("Default service error -> check your .quipurc\n"); + return ; + } + + search_arg.sra_common.ca_servicecontrol.svc_options = SVC_OPT_PREFERCHAIN; + curr_rdn = search_arg.sra_baseobject = (*base_path != 'T'? + str2dn (base_path): + NULLDN); + + search_arg.sra_eis.eis_allattributes = FALSE; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTETYPESONLY; + search_arg.sra_eis.eis_select = 0; + + search_arg.sra_subset = SRA_ONELEVEL; + while (curr_rdn != NULLDN) { + if (!strcmp(curr_rdn->dn_rdn->rdn_at->oa_ot.ot_stroid, + "2.5.4.10")) { + search_arg.sra_subset = SRA_WHOLESUBTREE; + break; + } + curr_rdn = curr_rdn->dn_parent; + } + + if ((search_arg.sra_filter = make_filter(filt_arr[gettogglindx(wdgt)])) + == NULLFILTER) { + (void) xprint("Invalid search filter!"); + return; + } + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("search +%s, extent %d, val %s", + base_path, search_arg.sra_subset, mvalue)); +#endif + + if(ds_search (&search_arg,&error,&result) != DS_OK) { + /* deal with error */ + free_seq(textseq); + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = textseq = NULLDS; + entry_number = 0; + text_state = TEXT; + cleartext(); + xprint(" Search error!\n "); + quipu_error(&error); + } else { + cleartext(); + correlate_search_results (&result); + + if (result.CSR_entries != NULLENTRYINFO) { + register EntryInfo *ptr; + + if (result.CSR_common.cr_aliasdereferenced) { + xprint (" (Alias dereferenced - object is "); + quipu_print (dn_print, (caddr_t) result.CSR_object); + dn_free (result.CSR_object); + xprint (")\n"); + } + + if (text_state == DN_LIST) free_seq(curr_dnseq); + free_seq(textseq); + curr_dnseq = textseq = NULLDS; + display_entry = current_entry = 1; + entry_number = 0; + text_state = DN_LIST; + + for (ptr = result.CSR_entries; + ptr != NULLENTRYINFO; ptr = ptr->ent_next){ + entry_number++; + dn2buf ((caddr_t) ptr->ent_dn, goto_path); + add_seq (&curr_dnseq, goto_path); + } + + if (entry_number > 1) curr_dnseq = SortList(curr_dnseq); + + if (entry_number != 1) + scrollbar('\0'); + else { + if (!isleafnode(goto_path)) { + get_listed_object('1', (WIDGET *) 0); + } else { + char temp[1024]; + (void) strcpy(temp, base_path); + (void) strcpy(base_path, goto_path); + rd_start(); + (void) strcpy(base_path, temp); + } + } + } else if(result.CSR_limitproblem != LSR_TIMELIMITEXCEEDED) { + free_seq(textseq); + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = textseq = NULLDS; + entry_number = 0; + text_state = TEXT; + xprint("Nothing found using current search parameters.\n"); + } + + if(result.CSR_limitproblem != LSR_NOLIMITPROBLEM) + switch (result.CSR_limitproblem) { + case LSR_TIMELIMITEXCEEDED: + if (entry_number > 0) + xprint("(Time limit exceeded. Partial results only.)"); + else { + free_seq(curr_dnseq); + curr_dnseq = NULLDS; + xprint("(Time limit exceeded.)"); + } + break; + case LSR_SIZELIMITEXCEEDED: + xprint("(Size limit exceeded)"); + break; + case LSR_ADMINSIZEEXCEEDED: + if (entry_number > 0) + xprint("(Administrative limit reached. Partial results only.)"); + else { + free_seq(curr_dnseq); + curr_dnseq = NULLDS; + xprint("(Administrative limit reached.)"); + } + break; + } + entryinfo_free(result.CSR_entries, 0); + } + + filter_free(search_arg.sra_filter); +} + +void dn2buf (ptr,cptr) + caddr_t ptr; + char * cptr; +{ + PS ps; + char buffer [RESBUF]; + + if((ps = ps_alloc(str_open)) == NULLPS) return ; + + if(str_setup(ps, buffer, RESBUF, 1) == NOTOK) return ; + + dn_print(ps, (DN) ptr, EDBOUT); + *ps->ps_ptr = 0; + + ps_free (ps); + + (void) strcpy(cptr, buffer); +} + + +void read_print(func,ptr) + int (*func) (); + caddr_t ptr; +{ + PS ps; + char buffer [RESBUF]; + char save; + int i, size; + register char *str, *sptr; + + if ((ps = ps_alloc (str_open)) == NULLPS) return ; + + if (str_setup (ps,buffer,RESBUF,1) == NOTOK) return ; + + (*func) (ps, ptr, READOUT); + *ps->ps_ptr = 0; + + ps_free(ps); + str = buffer ; + sptr = str; + size = strlen(buffer); + + if (text_state == DN_LIST) free_seq(curr_dnseq); + curr_dnseq = NULLDS; + free_seq(textseq); + textseq = NULLDS; + display_entry = current_entry = 1; + entry_number = 0; + text_state = TEXT; + + for (i = 0; i <= size; i++, sptr++) + if (*sptr == '\n' || *sptr == '\0') { + entry_number++; + save = *sptr ; + *sptr = '\0'; + + if (mailformat == greybook && indexstring(str, "rfc822") >= 0) + (void) rfc2jnt(str); + add_seq(&textseq, str); + + str = sptr+1; + *sptr = save; + } + + scrollbar('\0'); +} + +void quipu_print(func,ptr) + int (*func)(); /* assumes func (PS ,dataptr,(int) format); */ + caddr_t ptr; +{ + PS ps; + char buffer [RESBUF]; + int count; + register char *str, *sptr; + char save; + + if ((ps = ps_alloc (str_open)) == NULLPS) return ; + + if (str_setup (ps,buffer,RESBUF,1) == NOTOK) return ; + + (*func) (ps,ptr,READOUT); + *ps->ps_ptr = 0; + + ps_free (ps); + + /* print in blocks of 100 bytes-larger seems too much for curses*/ + str = buffer; + do { + for (count = 0, sptr = str; *sptr != '\0' && + count < 100; sptr++, count++); + save = *sptr; + *sptr = 0; + xprint (str); + *sptr = save; + str = sptr; + } while (*sptr != '\0'); +} + +void quipu_error(err) + struct DSError *err; +{ + switch(err->dse_type) { + case DSE_LOCALERROR: + xprint(" SD internal error!\n"); + break; + case DSE_REMOTEERROR: + xprint(" Problem with remote directory server!\n"); + break; + case DSE_ATTRIBUTEERROR: + xprint(" Faulty data found in database!\n"); + break; + case DSE_REFERRAL: + case DSE_DSAREFERRAL: + xprint(" Requested data unavailable at present.\n"); + break; + case DSE_SECURITYERROR: + xprint(" You do not have the privileges required\n to make this request!"); + break; + case DSE_NAMEERROR: + xprint(" Invalid directory position!\n"); + break; + case DSE_SERVICEERROR: + xprint(" Directory Service Error!\n"); + break; + default: + xprint(" Requested data unavailable at present.\n"); + } +} + +void returnmain() +{ + QUITFN(); + setwidgets (mainwdgts,-1); + rd_start(); + scrollbar('\0'); +} + +void get_listed_object(number, wdgt) + char number; + WIDGET *wdgt; +{ + int entrynum, count = 0; + char *sptr, *str; + char buffer[1024]; + + if (text_state != DN_LIST && text_state != BACK_LIST) { + *wdgt->dstr = '\0'; + printdialog(wdgt); + return; + } + + *srchvalue = number; + *(srchvalue+1) = '\0'; + + if (wdgt) { + printdialog(wdgt); + dialog(wdgt); + } + + entrynum = atoi(srchvalue); + + if (entrynum > entry_number) { + *wdgt->dstr = '\0'; + printdialog(wdgt); + return; + } + + if (sptr = get_from_seq (entrynum, curr_dnseq)) + if(!isleafnode(sptr)) { + cleartext(); + str = get_from_seq(count+1, back_seq); + + while (str && count < back_buf_num && strcmp(str, base_path)){ + count++; + str = get_from_seq(count+1, back_seq); + } + + if (count == back_buf_num) { + add_seq(&back_seq, base_path); + back_buf_num++; + } + + (void) strcpy(base_path, sptr); + make_friendly(friendly_base_path, base_path); + wdgt = getwidget(mainwdgts, '\0'); + printdialog(wdgt); + rd_start(); + typetoggled = 0; + set_default_type(); + } else { + (void) strcpy(buffer, base_path); + (void) strcpy(base_path, sptr); + make_friendly(friendly_base_path, base_path); + rd_start(); + (void) strcpy(base_path, buffer); + } + *srchvalue = '\0'; +} + +void scrollbar(command) + char command; +{ + register char *str; + char *base_rdn; + register int rdn_count = 0; + int lines, count = 0; + str_seq thisseq; + + if (!entry_number) + return; + + if(command == '[') { + if(display_entry >= entry_number) + return; + + for (count = 0; (display_entry + count) < entry_number && + count < text_height/2; count++); + + current_entry += count; + } else if(command == ']') { + + for (count = 0; (current_entry - count) > 1 && + count < text_height/2; count++); + + current_entry -= count; + } + + cleartext(); + + switch(text_state) { + + case BACK_LIST: + thisseq = back_seq; + break; + + case DN_LIST: + base_rdn = base_path; + while(*base_rdn != '\0') { + if(*base_rdn == '@') + rdn_count++; + base_rdn++; + } + if (*base_path != 'T') rdn_count++; + thisseq = curr_dnseq; + break; + + case TEXT: + thisseq = textseq; + break; + } + + if (current_entry > entry_number) + current_entry = 1; + + lines = linec()-2; + count = 0; + + for (display_entry = current_entry; display_entry <= entry_number + && gety() < lines; display_entry++) { + + if (text_state == DN_LIST || text_state == BACK_LIST) + xprintint(" %d ", display_entry) ; + + base_rdn = str = get_from_seq(display_entry, thisseq); + + if (text_state == DN_LIST && rdn_count) { + while (rdn_count) { + if (*str == '@') rdn_count--; + str++; + } + + while(*str == ' ') str++; + count = (int) (str - base_rdn); + + } else if (count) str += count; + + if (str) { + if (text_state != TEXT) { + make_friendly(friendly_name, str); + xprint(friendly_name); + } else + xprint(str); + xprint("\n"); + } + } + + if (text_state == DN_LIST) + if (current_entry >= entry_number) xprint(""); + else xprintint("", entry_number); + + printbar(entry_number, current_entry, display_entry-current_entry); + display_entry--; + return; +} + +void make_friendly(fstr, str) + char *fstr; + register char *str; +{ + register char *end_ptr; + char save; + + *fstr = '\0'; + if (!strcmp(str, "The World")) { + (void) strcpy(fstr, str); + return; + } + + while (*str != '\0') { + while (*str != '=') str++; + while (*str == ' ') str++; + + end_ptr = ++str; + while (*end_ptr != '@' && *end_ptr != '\0') end_ptr++; + save = *end_ptr; + *end_ptr = '\0'; + if (*fstr == '\0') + (void) strcpy(fstr, str); + else + (void) strcat(fstr, str); + *end_ptr = save; + str = end_ptr; + if (*str != '\0') + (void) strcat(fstr, ", "); + } +} + +void goto_addr() +{ + set_default_type(); + rd_start(); +} + +int isleafnode(name) + char *name; +{ + struct ds_list_arg list_arg; + struct ds_list_result list_result; + + struct ds_read_arg read_arg; + struct ds_read_result read_result; + + struct DSError list_error, read_error; + char entry_str[1024]; + + if (get_default_service (&read_arg.rda_common) != 0) return(1); + + read_arg.rda_common.ca_servicecontrol.svc_options = 1; + read_arg.rda_eis.eis_allattributes = FALSE; + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + read_arg.rda_eis.eis_select = oclass; + + read_arg.rda_object = (*name? str2dn(name): NULLDN); + if (ds_read (&read_arg,&read_error,&read_result) != DS_OK) return(1); + else { + if (read_result.rdr_entry.ent_attr == NULLATTR) return(0); + entry2str((caddr_t) read_result.rdr_entry.ent_attr, entry_str, 1024); + if (issubstr(entry_str, "NonLeaf")) return(0); + } + if (get_default_service (&list_arg.lsa_common) != 0) return(1); + + list_arg.lsa_common.ca_servicecontrol.svc_sizelimit = 1; + list_arg.lsa_common.ca_servicecontrol.svc_options = 1; + + if (*name) + list_arg.lsa_object = str2dn(name); + else + list_arg.lsa_object = NULLDN; + + if (ds_list (&list_arg,&list_error,&list_result) != DS_OK) + return (1); + else { + if (list_result.lsr_subordinates == NULLSUBORD) return(1); + else return(0); + } +} + +void entry2str(ptr, cptr, size) + caddr_t ptr; + char *cptr; + int size; +{ + PS ps; + + if ((ps = ps_alloc (str_open)) == NULLPS) return ; + if (str_setup (ps, cptr, size, 1) == NOTOK) return ; + + as_print(ps, (Attr_Sequence) ptr, READOUT); + *ps->ps_ptr = 0; + + ps_free(ps); +} + +int issubstr(str, substr) + char *str; + char *substr; +{ + register char *sptr; + char c; + int substrlen = strlen(substr); + int count; + + if (*substr == '\0' || *str == '\0') return(0); + + sptr = str; + c = *substr; + + while (1) { + while (*sptr != '\0' && *sptr != c) sptr++; + if (*sptr == '\0') return(0); + for (count = 0; count >= 0 && count < substrlen; count++) { + if (sptr[count] == '\0') return(0); + else if (substr[count] != sptr[count]) count = -2; + } + if (count == substrlen) return(1); + sptr++; + } +} + +int indexstring(string, substring) + char *string, *substring; +{ + register char *sub, *str; + char c, s; + int indx = 0; + + while (1) { + str = string + indx;; + if (*str == '\0') return(-1); + sub = substring; + + if (*str == *sub) { + s = *str; + c = *sub; + while(c == s && c != '\0') { + c = *++sub; + s = *++str; + } + if (c == '\0') return((int) indx); + else if(s == '\0') return(-1); + } + indx++; + } +} + +void rfc2jnt(string) + char *string; +{ + char reversed[STRINGLEN]; + char front[STRINGLEN]; + register char *part; + char *mailbox; + + mailbox = string; + while (*mailbox != '-') mailbox++; + + reversed[0] = '\0'; + part = string + strlen(string); + + if (*part != '\0') return; + + while(1) { + while (*part != '.' && *part != '@') --part; + + if (*part == '.') { + if (reversed[0] != '\0') (void) strcat(reversed, "."); + part++; + (void) strcat(reversed, part); + *--part = '\0'; + --part; + } else { + part++; + (void) strcat(reversed, "."); + (void) strcat(reversed, part); + *part-- = '\0'; + while (!isspace(*part)) --part; + ++part; + (void) strcpy(front, part); + (void) strcpy(string, "mailbox - "); + (void) strcat(string, front); + (void) strcat(string, reversed); + return; + } + } +} + +struct attrcomp *sort_attrs(entry_attrs) + struct attrcomp *entry_attrs; +{ + struct attrcomp *last, *next, *curr, *first, *firstn; + + first = curr = entry_attrs; + firstn = last = next = 0; + + while (curr) + if (!strcmp("2.5.4.3", curr->attr_type->oa_ot.ot_stroid) || + !strcmp("2.5.4.4", curr->attr_type->oa_ot.ot_stroid) || + !strcmp("0.9.2342.19200300.100.1.3", + curr->attr_type->oa_ot.ot_stroid) || + !strcmp("0.9.2342.19200300.100.1.2", + curr->attr_type->oa_ot.ot_stroid) || + !strcmp("2.5.4.20", curr->attr_type->oa_ot.ot_stroid)) { + + if (first == curr) first = curr->attr_link; + + if (next) + next->attr_link = curr; + else + firstn = curr; + + next = curr; + + if (last) + last->attr_link = curr->attr_link; + + curr = curr->attr_link; + next->attr_link = 0; + } else { + last = curr; + curr = curr->attr_link; + } + + if (next) { + next->attr_link = first; + return firstn; + } else + return first; +} + + +char *GetSurname(name) + register char *name; +{ + while (*name != '\0') name++; + while (*name != ' ' && *name != '=') name--; + return ++name; +} + +char *GetWholeRelName(name) + register char *name; +{ + while (*name!= '\0') name++; + while (*name != '=') name--; + while (!isalpha(*name)) name++; + return name; +} + +str_seq SortList(list) + str_seq list; +{ + register str_seq currEntry, lastSortedEntry , currSortedEntry; + str_seq sortedList; + char *sortedName, *currName; + register DN curr_dn; + DN dn; + + if (!list) return 0; + + currEntry = list; + sortedList = 0; + + while (currEntry) { + dn = curr_dn = str2dn(currEntry->dname); + + while (curr_dn && curr_dn->dn_parent != NULLDN) + curr_dn = curr_dn->dn_parent; + + if (!strcmp(curr_dn->dn_rdn->rdn_at->oa_ot.ot_stroid, "2.5.4.3")) + currName = GetSurname(currEntry->dname); + else + currName = GetWholeRelName(currEntry->dname); + + dn_free(dn); + + if (!sortedList) { + sortedList = currEntry; + currEntry = currEntry->next; + sortedList->next = 0; + } else { + lastSortedEntry = 0; + currSortedEntry = sortedList; + + while (currSortedEntry != 0) { + dn = curr_dn = str2dn(currSortedEntry->dname); + + while (curr_dn && curr_dn->dn_parent != NULLDN) + curr_dn = curr_dn->dn_parent; + + if (!strcmp(curr_dn->dn_rdn->rdn_at->oa_ot.ot_stroid, + "2.5.4.3")) + sortedName = GetSurname(currSortedEntry->dname); + else + sortedName = GetWholeRelName(currSortedEntry->dname); + + dn_free(dn); + + if (strcmp(currName, sortedName) <= 0) { + if (lastSortedEntry) { + lastSortedEntry->next = currEntry; + currEntry = currEntry->next; + lastSortedEntry->next->next = currSortedEntry; + } else { + sortedList = currEntry; + currEntry = currEntry->next; + sortedList->next = currSortedEntry; + } + currSortedEntry = 0; + } else { + lastSortedEntry = currSortedEntry; + currSortedEntry = currSortedEntry->next; + if (!currSortedEntry) { + lastSortedEntry->next = currEntry; + currEntry = currEntry->next; + lastSortedEntry->next->next = 0; + currSortedEntry = 0; + } + } + } + } + } + return sortedList; +} + + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/conf_read.y b/usr/src/contrib/isode/others/quipu/uips/sd/conf_read.y new file mode 100644 index 0000000000..78453b11af --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/conf_read.y @@ -0,0 +1,220 @@ +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/conf_read.y,v 7.2 91/02/22 09:32:14 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/conf_read.y,v 7.2 91/02/22 09:32:14 mrose Interim $ + */ + + +#include +#include +#include +#include "filt.h" + +void exit(); + +extern FILE *config_file; +extern unsigned int curr_filt; +extern char *file_names[], *filttype[]; +extern filt_struct *filt_arr[]; +%} +%start type_spec + +%union { + filt_struct *filt; + char strval[255]; + int symbol; +} + +%token NUMBER NAME DEFAULT STRING OID AND OR NOT APPROX EQUAL ITEM + +%type filter filter_list assertion filter_item +%type filt_type match +%token NOT AND OR APPROX EQUAL SUBSTRING +%token '"' ':' '(' ')' +%token STRING OID +%type name default + +%% + type_spec : name filter {make_type($1, $2);} + ; + + name : NAME ':' STRING {(void) strcpy($$, $3);} + ; + + default : DEFAULT ':' STRING {(void) strcpy($$, $3);} + | {(void) strcpy($$, "\0");} + ; + + assertion : '(' filt_type filter filter filter_list ')' {$$ = make_parent_filter($2, $3, $4, $5);} + | '(' NOT filter ')' {$$ = make_parent_filter($2, $3, (filt_struct *) 0,(filt_struct *) 0);} + | filter_item {$$ = $1;} + ; + + filter_list : filter filter_list {$$ = link_filters($1, $2);} + | filter {$$ = $1;} + | {$$ = (filt_struct *) 0;} + ; + + filter : filter_item {$$ = $1;} + | assertion {$$ = $1;} + ; + + filter_item : '(' OID match STRING ')' {$$ = make_item_filter($2, $3, $4);} + ; + + match : APPROX {$$ = $1;} + | EQUAL {$$ = $1;} + | SUBSTRING {$$ = $1;} + ; + + filt_type : AND {$$ = $1;} + | OR {$$ = $1;} + ; +%% + +yylex() +{ + register int c, count = 0; + char lexeme[255]; + + while(isspace(c = getc(config_file))) + if (c == EOF) return(0); + + lexeme[count++] = c; + + switch(c) { + case '#': + while (getc(config_file) != '\n'); + return(yylex()); + case '"': + count = 0; + while ((c = getc(config_file)) != '"') + lexeme[count++] = c; + lexeme[count] = '\0'; + (void) strcpy(yylval.strval, lexeme); + return STRING; + case '(': + return (int) c; + case ')': + return (int) c; + case ':': + return (int) c; + case '&': + yylval.symbol = AND; + return AND; + case '|': + yylval.symbol = OR; + return OR; + case '!': + yylval.symbol = NOT; + return NOT; + case '*': + lexeme[count] = '\0'; + (void) strcpy(yylval.strval, lexeme); + return STRING; + case '~': + if((lexeme[count] = getc(config_file)) == '=') { + yylval.symbol = APPROX; + return APPROX; + } + break; + case '%': + if((lexeme[count] = getc(config_file)) == '=') { + yylval.symbol = SUBSTRING; + return SUBSTRING; + } + break; + case '=': + yylval.symbol = EQUAL; + return EQUAL; + } + + while(!isspace(c = getc(config_file)) && c != '\0' && !issymbol(c)) + if (c != EOF) + lexeme[count++] = c; + else + return(0); + + (void) fseek(config_file,(long) -1, 1); + + lexeme[count] = '\0'; + switch(*lexeme) { + case 'd': + case 'D': + if(!strcmp(lexeme, "default") || !strcmp(lexeme, "DEFAULT")) + return DEFAULT; + else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + case 'n': + case 'N': + if(!strcmp(lexeme, "name") || !strcmp(lexeme, "NAME")) + return NAME; + else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + count = 0; + while (isdigit(lexeme[count]) || lexeme[count] == '.') count++; + if (lexeme[count] == '\0') { + (void) strcpy(yylval.strval, lexeme); + return OID; + } else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + default: + (void) strcpy(yylval.strval, lexeme); + return STRING; + } +} + +yyerror(err) + char *err; +{ + (void) fprintf(stderr, + "Parse error in '%s'. Exiting.\n", + (char *) file_names[curr_filt]); + if (filttype[curr_filt]) { + free(filttype[curr_filt]); + filttype[curr_filt] = (char *) 0; + } + + if (filt_arr[curr_filt]) free_filt(filt_arr[curr_filt]); + exit(1); +} + +int issymbol(c) + char c; +{ + switch(c) { + case '#': + case '"': + case '(': + case ')': + case ':': + case '&': + case '|': + case '!': + case '*': + case '~': + case '=': + case '%': + return 1; + } + return 0; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/filt.h b/usr/src/contrib/isode/others/quipu/uips/sd/filt.h new file mode 100644 index 0000000000..edfebe1445 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/filt.h @@ -0,0 +1,33 @@ +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/filt.h,v 7.2 91/02/22 09:32:15 mrose Interim $ + */ + +#ifndef FILT +#define FILT + +#include "quipu/ds_search.h" + +typedef struct stroid_list { + int fi_type; + char *stroid; + char *name; +} filt_item; + +typedef struct filter_struct { + int flt_type; + union ftype { + filt_item item; + struct filter_struct *sub_filt; + } fu_cont; + struct filter_struct *next; +} filt_struct; + +void make_type(); +filt_struct *make_item_filter(); +filt_struct *link_filters(); +filt_struct *make_parent_filter(); +Filter make_filter(); +Filter make_attr_filter(); +void free_filt(); + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/help.c b/usr/src/contrib/isode/others/quipu/uips/sd/help.c new file mode 100644 index 0000000000..9bdf42a05e --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/help.c @@ -0,0 +1,112 @@ +/* help.c - Display of assorted help texts */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/help.c,v 7.2 91/02/22 09:32:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/help.c,v 7.2 91/02/22 09:32:16 mrose Interim $ + */ + + +#include "sequence.h" +#include +#include "quipu/util.h" +#include "tailor.h" + +#define BUFLEN 1024 +#define TEXT 1 + +#ifdef lint +#define ETCDIR "/etc" +#endif + +#define HELPDIR "sd/helpdir/" + +extern str_seq textseq; +extern str_seq curr_dnseq; +extern int text_state; +extern int current_entry, entry_number, display_entry; + +void tprint(), scrollbar(); + +void get_help(); + +void help_cncs() +{ + get_help("help", " Press to get detailed help.\n"); +} + +void help_init() +{ + get_help("help", " SD X.500 Directory Agent - Concise Help\n"); +} + +void help_up() +{ + get_help("widen", " The \"Widen Area\" Function.\n"); +} + +void help_back() +{ + get_help("look", " The \"Look Back\" Function.\n"); +} + +void help_number() +{ + get_help("number", " The \"Go To Number\" Function.\n"); +} + +void help_srch() +{ + get_help("search", " The \"Search\" Function"); +} + +void help_list() +{ + get_help("list", " The \"List\" Function"); +} + +void get_help(filename, line) +char *filename, *line; +{ + FILE * helpfp; + char helpbuf[BUFLEN]; + char filebuf[BUFLEN]; + char *str; + + text_state = TEXT; + entry_number = 0; + display_entry = current_entry = 1; + free_seq(curr_dnseq); + free_seq(textseq); + curr_dnseq = 0; + textseq = 0; + + (void) strcpy(filebuf, HELPDIR); + (void) strcat(filebuf, filename); + (void) strcpy(helpbuf, isodefile(filebuf, 0)); + + if ((helpfp = fopen(helpbuf, "r")) == (FILE *)NULL ) { + tprint("Can't open help file '%s'.\n",helpbuf); + return; + } + + if (line) { + add_seq(&textseq, line); + entry_number++; + } + + while(fgets(filebuf, BUFLEN, helpfp) != (char *) NULL) { + str = filebuf; + while(*str != '\n' && *str != '\0') str++; + *str = '\0'; + add_seq(&textseq, filebuf); + entry_number++; + } + + (void) fclose(helpfp); + scrollbar('\0'); +} + + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/main.c b/usr/src/contrib/isode/others/quipu/uips/sd/main.c new file mode 100644 index 0000000000..cb98cb9bd1 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/main.c @@ -0,0 +1,150 @@ +/* main.c - widget */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/main.c,v 7.4 91/02/22 09:32:17 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/main.c,v 7.4 91/02/22 09:32:17 mrose Interim $ + */ + + +#include +#include +#define IP _IP +#include +#undef OK +#include + +#include "widget.h" +#include "quipu/util.h" + +extern char goto_path[], namestr[], passwd[]; +extern char *myname; +extern WINDOW *Text; +extern WIDGET mainwdgts[]; +extern WIDGET cnnctwdgts[]; +extern int print_parse_errors; +extern char *oidtable, *tailfile, *myname; +extern char testing; + +void quit(), die(), setsignals(), int_quit(), sd_quit(), read_args(); +void user_tailor(), main_bind(), cnnct_bind(), interact(), help_init(); + +void exit(); + +main(argc, argv) + unsigned int argc; + char *argv[]; +{ + print_parse_errors = FALSE; + quipu_syntaxes(); + + namestr[0] = '\0'; + passwd[0] = '\0'; + + read_args(argc, &argv); + dsap_init((int *) 0, &argv); + + initwidgets(); + setsignals(); + + user_tailor(); + main_bind(); + cnnct_bind(); + help_init(); + interact(); + return(0); +} + +void read_args(argc, avptr) + unsigned int argc; + char ***avptr; +{ + register char **av; + register char *cp; + + if (argc <= 1) return; + + av = *avptr; + av++; + + while ((cp = *av) && (*cp == '-')) { + switch (*++cp) { + case 'u': + if (*++av != NULLCP) (void) strcpy(namestr, *av); + break; + case 'p': + if (*++av != NULLCP) (void) strcpy(passwd, *av); + break; + case 'T': + if (*++av != NULLCP) oidtable = *av; + break; + case 'c': + if (*++av != NULLCP) myname = *av; + break; + case 't': + if (lexequ(*av, "-test") != 0) { + if (*++av != NULLCP) tailfile = *av; + } else { + testing = TRUE; + } + break; + } + av++; + } +} + +void setsignals() +{ + int i; + + for (i=0; i<18; i++) + (void) signal(i, SIG_DFL); +} + +void eprint(str) + char *str; +{ + tprint(str); +} + +void sd_quit() +{ + quit("\n", 0); +} + +void quit(error, sig) + char *error; + int sig; +{ + endwidgets(); + (void) ds_unbind(); + hide_picture(); + (void) printf(error); + exit(sig); +} + +void int_quit(sig) + int sig; +{ + quit("\n", sig); +} + + +advise (va_alist) + va_dcl +{ + int code; + va_list ap; + extern LLog * log_dsap; + + va_start (ap); + + code = va_arg (ap, int); + + (void) _ll_log (log_dsap, code, ap); + + va_end (ap); +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/make b/usr/src/contrib/isode/others/quipu/uips/sd/make new file mode 100644 index 0000000000..8f4d0bdc31 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/make @@ -0,0 +1,2 @@ +: run this script through /bin/sh +exec /bin/make TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/sd.1c b/usr/src/contrib/isode/others/quipu/uips/sd/sd.1c new file mode 100644 index 0000000000..c9ec444f99 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/sd.1c @@ -0,0 +1,115 @@ +.\"$Header: /f/osi/others/quipu/uips/sd/RCS/sd.1c,v 7.1 91/02/22 09:32:19 mrose Interim $" +.TH SD 1C "16 Jan 1909" +.SH NAME +sd \- Full-screen directory user agent. +.SH SYNOPSIS +.B sd +.SH DESCRIPTION +.PP +The \fIsd\fR program implements a simple window interface to +an X500 OSI directory. +It is derived from an original interface called "widget". +.PP + +\fISd\fR runs on most cursor-addressable terminals, providing a full-screen +character-driven interface suitable for novice users. +It is based on the notion of "widgets" as characterized by the +X-windows system and attempts to simulate button, +dialogue and text widgets. +Functions are invoked by pressing the initial letter of the +function name displayed in the widget. +.PP +List and Search operations within the directory are conducted relative +to an area displayed in the \fISearch Area\fR widget. +An instance of this could be, +.sp +.in +.5i +.nf +\*(lqGB, Brunel University.\*(rq +.fi +.in -.5i +.sp +.PP +List returns a list of entries held below the 'Search Area'. +In the above case, +a call to list would return a list of departments in Brunel University. +.PP +A search is performed on the basis of +a search value +(or attribute) +which describes some aspect of the +object +(i.e. it's name, +location etc.) +and a type, +which associates the object being searched +for with one of a given set of types +(i.e. Person, Place, Organization, Department). +The search value is displayed in the \fISearch For\fR field +and it's type is shown in the \fIType\fR field. +Any search will return a list of objects that match +the given search value within the current search area. +To display information on or move to a listed object the list number +of that object must be entered. +.PP +An example of a simple search is shown below. +Here the target is the directory object for +\*(lqProfessor Polonius Plum\*(rq +of Brunel University. +The search is initiated with +the search area set to \*(lqGB, Brunel University.\*(rq, +a value \*(lqPlum\*(rq and type \*(lqPerson\*(rq, +with the directory then returning, +.sp +.in +.5i +.nf +1 Computer Science, Polonius Plum +.br +2 Law, Plumley Farquarson +.fi +.in -.5i +.sp +Subsequently entering '1' would then give, +.sp +.in +.5i +.nf +commonName - Polonius Plum +.br +surname - Plum +.br +userClass - staff +.br +rfc822Mailbox - P.Plum@brunel.ac.uk +.br +description - "ruddy faced and gat toothed" +.fi +.in -.5i +.PP +A standard search strategy in \fIsd\fR, +and most other directory interfaces, +is to move to a suitable search area, +i.e. an \*(lqarea\*(rq in which the real world object is contained, +and to then search using an appropriate value and type. +.PP +In order to make \fIsd\fR simple to understand +there are no facilities for modifying entries. +.br +.SH "OPTIONS" +.TP 12 +.BI \-c +Bind to named directory system agent. +Pod binds to your local dsa, +if not otherwise requested. +.TP +.SH "SEE ALSO" +dish(1c) widget(1c) +.br +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594: +\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory\fR +.SH AUTHOR +Damanjit.Mahl@brunel.ac.uk +.br +Andrew.Findlay@brunel.ac.uk diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/sd.5 b/usr/src/contrib/isode/others/quipu/uips/sd/sd.5 new file mode 100644 index 0000000000..530caf91d9 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/sd.5 @@ -0,0 +1,172 @@ +.\"$Header: /f/osi/others/quipu/uips/sd/RCS/sd.5,v 7.2 91/02/22 09:32:23 mrose Interim $" +.TH SD 5 "16 Jan 1990" +.SH NAME +sd \- Full-screen directory user agent. +.SH SYNOPSIS +.B sd +.SH DESCRIPTION +.PP +Read and search calls to the directory in \fIsd\fR are carried out +using parameters specified in configuration files contained +in a configuration directory. +This directory can be held on a per-user basis, +and will otherwise default to a system-wide default directory +held in the ETCDIR defined during isode installation. +These directories are called \*(lq$(HOME)/.duaconfig\*(rq and +\*(lq$(ETCDIR)/sd/duaconfig\*(rq respectively. +.PP +Configuration is trivial in the case of reads, +requiring a list of numeric OIDs +(one on each line), +specifying the attribute types to be read. +A sample section of the default configuration file +(called readTypes and held in one of the above configuration directories) +is, +.sp +.in +.5i +.nf +"alias" 2.5.6.1 +"c" 2.5.4.6 +"l" 2.5.4.7 +.fi +.in -.5i +.sp +where the quoted sections +(required but always ignored) +state the actual name of the type specified and the numeric +sections equate to their actual OIDs. +.PP +Configuration of search is more complicated +and is best illustrated by describing the search mechanism used by \fIsd\fR +(for information on how to use \fIsd\fR consult section 1c of the manual). +Each attribute type in an \fIsd\fR search consists of a +complex filter, +that may make use of a number of actual primitive attribute types. +Thus a search using the \fIsd\fR type \*(lqPerson\*(rq, +as provided in the default configuration set-up, +actually corresponds to the filter, +.sp +.in +.5i +.nf +objectClass=person AND ( commonName ~= * + OR surname~= * + OR title~= *) +.fi +.in -.5i +.sp +where '*' means the value supplied at +search-time, '~=' means approximately matches, '%=' means substring matches +and '=' means exactly matches. +Each of the types used by \fIsd\fR is described in a separate +file called \*(lq/filterTypes/Type_whatever\*(rq under +one of the configuration directories described above +(note that each file name must have the prefix \*(lqType_\*(rq). +The set of filter-types provided +(Person, +Place, +Department, +Organization) +can thus be added to or modified as wished. +The precise syntax that must be used is shown in the +follwing example, +.sp +.in +.5i +.nf +#Composition of type Place +name:"Place" +( & ( | (2.5.4.0 = "country") #"objectClass" + (2.5.4.0 = "room") # ditto + (2.5.4.0 = "locality")) # ditto + ( | (2.5.4.7 ~= *) #"l" - locality + (2.5.4.8 ~= *) #"stateOrProvinceName" + (2.5.4.6 ~= *) #"c" - country + (0.9.2342.19200300.100.1.6 ~= *) #"roomNumber" + (2.5.4.3 ~= *))) #"cn" - "commonName" +.fi +.in -.5i +.sp +The first thing to note is that comments begin with a '#'. +The rest of the line following a '#' is ignored. +The name used by \fIsd\fR to denote the type is +specified using the syntax +.sp +.in +.5i +.nf +name:"STRING". +.fi +.in -.5i +.sp +The following lines describe the filter that the type +is composed of. +It has a lisp-like syntax and uses symbols that correspond +to those used in \fIdish\fR. +The points to note are; +.sp +.in +.5i +.nf +(1) Each filter or filter-item must be enclosed in brackets. +(2) Hard-wired values (as in 2.5.4.0 = "country" above) + must be enclosed in quotes. +(3) '*' denotes a value supplied at search time. +.fi +.in -.5i +.sp +.PP +Additions to the search types will make modification to the +\*(lqtypeDefaults\*(rq file necassary. +This describes the set of types, +chosen from those specified as above, +that are available to search with when +a specific level of the DIT, +e.g. country level, +is occupied by the user. +In addition it specifies the default type at any level. +A typical \*(lqtypeDefaults\*(rq file is shown below, +.sp +.in +.5i +.nf +# +# Format is: +# OID of RDN: Types available at this level: Default type +# +2.5.4.10:Person, Place, Department: Person +2.5.4.11:Person, Place, Department: Person +2.5.4.6:Place, Organization:Organization +2.5.4.7:Place, Organization, Department: Organization +@: Place: Place +.fi +.in -.5i +.sp +Each line, +composed of three colon separated fields, +specifies defaults for one level of the DIT. +The first field contains the numeric OID of an attribute that may be used +as an RDN. +The root entry, +though, +is specified by an \*(lq@\*(rq character, +as can be seen in the lowermost line. +The first line contains the OID for \*(lqorganizationName\*(rq. +The second field describes the types that are available to the user +when occupying the specified level of the DIT. +The third field, +which must also be a member of the second field, +states the default type available at this level. +Thus the first line says that the types Person, +Place and Department are available at the orgainzational level, +and that the default type given to the user is Person. +.PP +To view the list of OID's used in the directory, use the 'oiddump' tool +provided with isode. +(held in 'ISODE/others/quipu/tools'). +.SH "SEE ALSO" +sd(1c) dish(1c) pod(1c) xd(1c) +.br +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594:\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory\fR +.SH AUTHOR +Damanjit.Mahl@brunel.ac.uk +.br +Andrew.Findlay@brunel.ac.uk diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/sequence.c b/usr/src/contrib/isode/others/quipu/uips/sd/sequence.c new file mode 100644 index 0000000000..dc88b7e886 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/sequence.c @@ -0,0 +1,72 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/sequence.c,v 7.2 91/02/22 09:32:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/sequence.c,v 7.2 91/02/22 09:32:24 mrose Interim $ + */ + +/* This file was written by Damanjit Mahl @ Brunel University + * as part of the modifications made to + * the Quipu X.500 widget interface written by Paul Sharpe + * at GEC Research, Hirst Research Centre. + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "sequence.h" + +extern char * strdup (); + +void add_seq (seq, str) + str_seq *seq; + char *str; +{ + str_seq curr; + + if (*seq) { + for (curr = *seq; curr->next; curr = curr->next) {} + curr->next = (struct string_seq *) malloc (sizeof (struct string_seq)); + curr = curr->next; + } else { + curr = (struct string_seq *) malloc (sizeof (struct string_seq)); + *seq = curr; + } + + curr->strlen = strlen(str); + curr->dname = strdup(str); + curr->next = 0; +} + +char *get_from_seq (seq_num, seq_ptr) + int seq_num; + str_seq seq_ptr; +{ + for (; seq_num > 1 && seq_ptr; seq_ptr = seq_ptr->next, seq_num--) {} + if (seq_ptr) + return seq_ptr->dname; + else + return 0; +} + + +void free_seq (seq_ptr) + str_seq seq_ptr; +{ + str_seq next_seq; + + while (seq_ptr) { + free(seq_ptr->dname); + next_seq = seq_ptr->next; + free((char *) seq_ptr); + seq_ptr = next_seq; + } +} diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/sequence.h b/usr/src/contrib/isode/others/quipu/uips/sd/sequence.h new file mode 100644 index 0000000000..f342a5ac4b --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/sequence.h @@ -0,0 +1,48 @@ +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/sequence.h,v 7.2 91/02/22 09:32:25 mrose Interim $ + */ + +/* This file contains code to implement the list storage facilities + * in the modified widget program (renamed SD 5/1/90). + */ + +/* This file was written by Damanjit Mahl @ Brunel University + * as part of the modifications made to + * the Quipu X.500 widget interface written by Paul Sharpe + * at GEC Research, Hirst Research Centre. + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#ifndef STRINGSEQ +#define STRINGSEQ + +#include + +#ifdef QUIPU_MALLOC + +#else +extern char * malloc (); +extern char * smalloc (); +#endif + +typedef struct string_seq { + char *dname; + unsigned strlen; + int seq_num; + struct string_seq *next; +} string_seq, *str_seq; + +#define NULLDS ((str_seq) 0) +char *get_from_seq (); +void free_seq(), add_seq(); + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/symtab.c b/usr/src/contrib/isode/others/quipu/uips/sd/symtab.c new file mode 100644 index 0000000000..09e6e33b3a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/symtab.c @@ -0,0 +1,114 @@ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/symtab.c,v 7.2 91/02/22 09:32:26 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/symtab.c,v 7.2 91/02/22 09:32:26 mrose Interim $ + */ + +/* + * $Log: symtab.c,v $ + * Revision 7.2 91/02/22 09:32:26 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:49:58 mrose + * sync + * + * Revision 1.8 90/09/14 14:06:46 emsrdsm + * *** empty log message *** + * + * Revision 1.7 90/05/23 11:41:11 emsrdsm + * *** empty log message *** + * + * Revision 1.6 90/04/26 10:36:33 emsrdsm + * *** empty log message *** + * + * Revision 1.5 90/04/25 15:07:46 emsrdsm + * i) lint'ed + * + * Revision 1.4 90/04/20 17:58:02 emsrdsm + * i) no more freeing + * + * Revision 1.3 90/04/18 18:28:08 emsrdsm + * fixed i) does not move to leaves + * ii) added default mechanism described using "typeDefaults" file. + * iii) added 'sorting' to attribute display + * + * Revision 1.2 90/03/15 16:32:12 emsrdsm + * fixes i) Prints messages correctly on exit. + * ii) Added rfc822 to greybook mailbox conversion + * iii) Removed bug that caused crash if 'local_dit' undefined + * + * Revision 1.1 90/03/09 17:40:38 emsrdsm + * Initial revision + * + * Revision 1.1 90/03/09 13:37:47 emsrdsm + * Initial revision + * + */ + +#include +#include + +#include "symtab.h" + +put_symbol_value(table, name, val) +table_entry table; +char *name; +char *val; +{ + if (!name) return; + + while(table && strcmp(name, table->name)) { + table = table->next; + } + if (table) { + free(table->val); + if (val) { + table->val = + (char *) malloc((unsigned) strlen(val) + 1); + (void) strcpy(table->val, val); + } else + table->val = (char *) 0; + } else { + table = (table_entry) malloc(sizeof(table_entry)); + table->next = NULLSYM; + table->name = (char *) malloc((unsigned) strlen(name) + 1); + (void) strcpy(table->name, name); + if (val) { + table->val = + (char *) malloc((unsigned) strlen(val) + 1); + (void) strcpy(table->val, val); + } else + table->val = 0; + } +} + +char * +get_symbol_value(table, name) +table_entry table; +char *name; +{ + while(table && strcmp(name, table->name)) table = table->next; + if (table) + return table->val; + return (char *) 0; +} + + +free_table(table) +table_entry table; +{ + table_entry entry; + + while(table) { + if (table->val) + free(table->val); + free(table->name); + entry = table; + table = table->next; + free((char *) entry); + } +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/symtab.h b/usr/src/contrib/isode/others/quipu/uips/sd/symtab.h new file mode 100644 index 0000000000..848dde6bf6 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/symtab.h @@ -0,0 +1,56 @@ +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/symtab.h,v 7.2 91/02/22 09:32:27 mrose Interim $ + */ + +/* + * $Log: symtab.h,v $ + * Revision 7.2 91/02/22 09:32:27 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:49:59 mrose + * sync + * + * Revision 1.8 90/09/14 14:07:06 emsrdsm + * *** empty log message *** + * + * Revision 1.7 90/05/23 11:41:35 emsrdsm + * *** empty log message *** + * + * Revision 1.6 90/04/26 10:36:51 emsrdsm + * *** empty log message *** + * + * Revision 1.5 90/04/25 15:08:03 emsrdsm + * i) lint'ed + * + * Revision 1.4 90/04/20 17:58:14 emsrdsm + * i) no more freeing + * + * Revision 1.3 90/04/18 18:28:28 emsrdsm + * fixed i) does not move to leaves + * ii) added default mechanism described using "typeDefaults" file. + * iii) added 'sorting' to attribute display + * + * Revision 1.2 90/03/15 16:33:29 emsrdsm + * *** empty log message *** + * + * Revision 1.1 90/03/09 17:41:09 emsrdsm + * Initial revision + * + * Revision 1.1 90/03/09 13:39:03 emsrdsm + * Initial revision + * + */ + +#ifndef SYMTAB +#define SYMTAB + + +typedef struct tab_entry { + char *val; + char *name; + struct tab_entry *next; + } *table_entry; + +#define NULLSYM (table_entry) 0 + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/wdgtdefs.h b/usr/src/contrib/isode/others/quipu/uips/sd/wdgtdefs.h new file mode 100644 index 0000000000..16c5ead0a5 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/wdgtdefs.h @@ -0,0 +1,51 @@ +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/wdgtdefs.h,v 7.2 91/02/22 09:32:28 mrose Interim $ + */ + + +#include "widget.h" + +/* REMEMBER TO NULL-TERMINATE ALL OF THESE STRUCTURE ARRAYS */ +/*--------------------------------------------------------------*/ + +void main_help(); +void list_start(), back_start(); +void srch_start(), widen(); +void rd_start(); +void sd_quit(), cache_quit(); +void get_listed_object(), goto_addr(), scrollbar(); + +WIDGET mainwdgts[] = { +{LABEL," QUIPU X.500 Screen Directory. ",CENTRE,NULLFN,0,0,EXPAND ,0}, +{COMMAND, "q Quit ", 'q',sd_quit, 0,CRNL,0,0}, +{COMMAND, "h Help ", 'h',main_help, 0,0,0,0}, +{COMMAND, "l List ", 'l',list_start, 0,0,0,0}, +{COMMAND, "w Widen Search Area", 'w', widen, 0, 0, 0, 0}, +{COMMAND, "b History ", 'b', back_start, 0,0,0,0}, +{DIALOG, "Go To Number:", '*',get_listed_object,0,0,EXPAND,0}, +{DIALOG , "Search Area: ", '\0', goto_addr, 0,CRNL,EXPAND,0}, +{TOGGLE, "t Type: ", 't',TOGGLEFN, 0,0,0,0}, +{DIALOG, "s Search for: ", 's',srch_start, 0,0,EXPAND,0}, +{DUMMY, "Search", '\n', srch_start, 0,0,0,0}, +/* Scrollbar always last */ +{SCROLLBAR, "", '%', scrollbar, 0,0,3,0}, +{FINISH, "", 0,NULLFN} } ; + + +/*--------------------------------------------------------------*/ + +void help_read(), help_list(), help_srch(), help_back(), + help_number(), help_addr(), help_up(), returnmain(); + +WIDGET dethelpwdgts[] = { +{LABEL,"QUIPU X.500 Screen Directory: Help",CENTRE,NULLFN,0,0,EXPAND,0}, +{COMMAND, "q QUIT Help",'q',returnmain, 0,CRNL,0,0}, +{COMMAND, "s Search for",'s',help_srch, 0,0,0,0}, +{COMMAND, "b History ",'b', help_back, 0,0,0,0}, +{COMMAND, "w Widen Search Area",'w', help_up, 0,0,0,0}, +{COMMAND, "l List ",'l',help_list,0,0,0,0}, +{COMMAND, "n Number ",'n',help_number,0,0,0,0}, +/*scrollbar always last*/ +{SCROLLBAR, "", '%',scrollbar, 0,0,3,0}, +{FINISH, "", 0,NULLFN} } ; + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/widget.c b/usr/src/contrib/isode/others/quipu/uips/sd/widget.c new file mode 100644 index 0000000000..330a80ee88 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/widget.c @@ -0,0 +1,909 @@ +/* widget.c - Provides the screen and widget code */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/sd/RCS/widget.c,v 7.2 91/02/22 09:32:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/widget.c,v 7.2 91/02/22 09:32:29 mrose Interim $ + */ + + +/* This file has been modified by Damanjit Mahl @ Brunel University + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/*****************************************************************************/ +/* File: widget.c +/* Author: Paul Sharpe @ GEC Research, Hirst Research Centre. +/* Date: August 12, 1988. +/* Function: Provides the screen and widget code. +/* +/* DISCLAIMER: +/* This source file is deemed to be public domain: any person may use the +/* code in any way, on two simple provisos - +/* 1 - That this header remains in this file, +/* 2 - It is accepted that neither the author, nor the authors employees +/* accept any responsibility for the use, abuse or misuse of the +/* contained code. +/* No guarantee is made by the author to provide maintainance or up-grading +/* of this source. However, any adaptations made to this file will be viewed +/* at least with interest. +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "widget.h" + +extern char *filtvalue[]; +extern unsigned int typeindx; +extern int *av_typeindx; + +void get_listed_object(), scrollbar(); + +struct active { + int count; + WIDGET *widgets[MAXACTIVE]; + char lastindex[MAXACTIVE]; + WINDOW *text[MAXACTIVE]; +} activelist; + +char command; +WINDOW *Text; +int text_height; +jmp_buf env; + +void initwidgets() +{ + (void) initscr(); + (void) noecho(); + (void) crmode(); + Text = stdscr; + typetoggled = 0; + activelist.count = 0; +} + +void textfresh() +{ + (void) wrefresh (Text); +} + +void setwidgets(thesewdgts, y) + int y; + WIDGET *thesewdgts; +{ + currwidgets = thesewdgts; + lowy = posnwidgets(thesewdgts, y); + Text = newwin(LINES-1-lowy, COLS-3, lowy, 3); + text_height = LINES-1-lowy; + refresh(); + (void) scrollok(Text, FALSE); + (void) wrefresh(Text); + makewidgets(thesewdgts); + activewidget(thesewdgts, Text); + rfrshwidgets(thesewdgts); +} + +int linec() +{ + return (int) LINES; +} + +int gety() +{ + int y,x; + getyx(Text, y, x); + /* Get rid of lint warning */ + x = x + 1; + return y + lowy; +} + +/* Determine the positions of the widgets: return the lowest point */ +int posnwidgets(thesewdgts, starty) + int starty; + WIDGET thesewdgts[]; +{ + register int cnt = 0, x = 0, hght = WDGTHGHT; + +/* If no explicit position provided, put on the next level */ + if (starty < 0) + starty = lowesty(); + +/* Set the position of the widgets, as dynamically as possible */ + + while (thesewdgts[cnt].type != FINISH) { + + if (thesewdgts[cnt].type != DUMMY) { +/* If the widget is a scrollbar put on a new line */ + if (thesewdgts[cnt].type == SCROLLBAR) { + starty += WDGTHGHT; + hght = LINES - starty; + x = 0; + } else + +/* If the initial structure y-value is CRNL, put on a new line */ + if (thesewdgts[cnt].y == CRNL) { + starty += WDGTHGHT; + hght = WDGTHGHT; + x = 0; + } + +/* If we ain't got a width, make one based on the type/label-length */ + if (thesewdgts[cnt].wdth <= 0) + setwdgtwdth(&thesewdgts[cnt], x); + +/* If the widget won't fit, start a new line of widgets */ + if (x + thesewdgts[cnt].wdth > COLS) { + starty += WDGTHGHT; + x = 0; + } + thesewdgts[cnt].x = x; + thesewdgts[cnt].y = starty; + thesewdgts[cnt].hght = hght; + x += thesewdgts[cnt].wdth; + ++cnt; + } else + ++cnt; + } + return(starty); +} + +/* Create the widgets: return the number of widgets */ +void makewidgets(wdgts) + WIDGET wdgts[]; +{ + register int cnt = 0; + register WIDGET *wdgt; + +/* Now try to make, box and label the widget windows */ + while (wdgts[cnt].type != FINISH) { + if (wdgts[cnt].type != DUMMY) { + wdgt = &wdgts[cnt++]; + wdgt->wndw = newwin(wdgt->hght,wdgt->wdth,wdgt->y,wdgt->x); + boxwdgt(wdgt, '-', '|'); + printwdgt(wdgt); + } else ++cnt; + } +} + +/* Set a widgets width, based on the TYPE of widget and label length */ +void setwdgtwdth(wdgt, currx) + int currx; + WIDGET *wdgt; +{ + char expand; + register int len = -1, cnt = -1; + + if (expand = (wdgt->wdth == EXPAND)) + wdgt->wdth = COLS - currx; + + switch (wdgt->type) { + case LABEL: + len = strlen(wdgt->label) + 2; + if (wdgt->wdth < len) + if (expand) + wdgt->wdth = COLS; + else + wdgt->wdth = len; + break; + + case DIALOG: + len = strlen(wdgt->label) + 2; + if (wdgt->dstrlen > DIALOGLEN) + len += DIALOGLEN; + else + len += wdgt->dstrlen; + if (wdgt->wdth < len) { + if (expand) + wdgt->wdth = COLS; + else + wdgt->wdth = len; + } + break; + case TOGGLE: + if (wdgt->tvalues == (char **)NULL) + wdgt->wdth = strlen(wdgt->label) + 2; + else { + while(wdgt->tvalues[++cnt] != (char *)NULL) + if (strlen(wdgt->tvalues[cnt]) > len) + len = strlen(wdgt->tvalues[cnt]); + wdgt->wdth = strlen(wdgt->label) + len + 2; + } + break; + default: wdgt->wdth = strlen(wdgt->label) + 2; + break; + } +} + +/* Erase and remove the widgets, decrementing the activelist counter */ +void killwidgets(thesewdgts) + WIDGET *thesewdgts; +{ + register int cnt = 0; + + while (thesewdgts[cnt].type != FINISH) + if (thesewdgts[cnt].type != DUMMY) { + (void) wclear(thesewdgts[cnt].wndw); + (void) wrefresh(thesewdgts[cnt++].wndw); + } else ++cnt; + cnt = 0; + (void) wclear(Text); + (void) wrefresh(Text); + while (thesewdgts[cnt].type != FINISH) + if (thesewdgts[cnt].type != DUMMY) + delwin(thesewdgts[cnt++].wndw); + else ++cnt; + delwin(Text); + + deleteactive(); + + Text = activelist.text[activelist.count-1]; + if (Text != (WINDOW *)NULL) + (void) wrefresh(Text); +} + +/* THESE FUNCTIONS MANIPULATE THE ACTIVELIST ARRAY OF WIDGETS */ + +/* This should check that the number of active widgets is not excessive, or + * have the activelist really as a linked list. + */ +/* ARGSUSED */ +void activewidget(wdgts, text) + WIDGET wdgts[]; + WINDOW *text; +{ + activelist.widgets[activelist.count] = wdgts; + activelist.text[activelist.count] = Text; + ++(activelist.count); +} + +void deleteactive() +{ + if (activelist.count > 0) + --(activelist.count); +} + +void activeindex(indx) + char indx; +{ + activelist.lastindex[activelist.count - 1] = indx; +} + +/* Refresh each of the active widgets and the current text window */ +void redraw() +{ + register int i; + + clearok(curscr,TRUE); + for (i=0; iwndw, 0, 0, '.'); + for (x = 1; x < wdgt->wdth-1; x++) + (void) waddch(wdgt->wndw, xch); + (void) waddch(wdgt->wndw, '.'); + + mvwaddch(wdgt->wndw, 1, 0, ych); + for (y = 1; y < wdgt->hght-1; y++) { + (void) mvwaddch(wdgt->wndw, y, 0, ych); + (void) mvwaddch(wdgt->wndw, y, wdgt->wdth-1, ych); + } + + mvwaddch(wdgt->wndw, wdgt->hght-1, 0, '`'); + for (x = 1; x < wdgt->wdth-1; x++) + (void) waddch(wdgt->wndw, xch); + (void) waddch(wdgt->wndw, '\''); +} + +/* THESE ROUTINES PRINT THE INDIVIDUAL WIDGET BOXES */ + +/* Print a widgets label, dependant on the widget type */ +void printwdgt(wdgt) + WIDGET *wdgt; +{ + switch(wdgt->type) { + + case LABEL: + printlabel(wdgt); + break; + + case DIALOG: + printdialog(wdgt); + break; + + case TOGGLE: + printtoggle(wdgt); + break; + + default : + printcommand(wdgt); + break; + } +} + +void printbar(list_size, first, display_num) + int list_size, first, display_num; +{ + WIDGET * wdgt; + int cnt, bar_size, bar_pos=0, space_size; + + for(cnt = 0; currwidgets[cnt].type != SCROLLBAR; cnt++) ; + wdgt = &currwidgets[cnt]; + + (void) wclear(wdgt->wndw); + boxwdgt(wdgt, '-', '|'); + + space_size = wdgt->hght - 4; + + if(display_num == list_size) { + bar_size = space_size; + bar_pos = 1; + } else { + bar_size = (display_num*space_size)/(list_size+1); + bar_size = bar_size? bar_size: 1; + + while(!((list_size*bar_pos)/(first*(space_size+1)))) bar_pos++; + } + + while((bar_size + bar_pos - 1) > space_size) { + bar_size--; + } + + for(cnt = 0; cnt < bar_size; cnt++) + (void) mvwaddch(wdgt->wndw, cnt+1+bar_pos, 1, '*'); + + (void) mvwaddch(wdgt->wndw, 1, 1, ']'); + (void) mvwaddch(wdgt->wndw, wdgt->hght-2, 1, '['); + + (void) wrefresh(wdgt->wndw); +} + +/* Print a LABEL widgets label string, dependant on the justification char */ +void printlabel(wdgt) + WIDGET *wdgt; +{ + register int x, labellen, wdgtlen; + + labellen = strlen(wdgt->label); + wdgtlen = wdgt->wdth - 2; + + if (labellen > wdgtlen) + wdgt->label[wdgtlen] = '\0'; + + if (wdgt->callch & CENTRE) + x = (wdgtlen - labellen)/2; + else + if (wdgt->callch & LEFT) + x = 0; + else + if (wdgt->callch & RIGHT) x = wdgtlen - labellen; + + mvwaddstr(wdgt->wndw,1,1+x,wdgt->label); + (void) wrefresh(wdgt->wndw); +} + +/* Print a DIALOG widget label: if it don't all fit, show the last part */ +void printdialog(wdgt) + WIDGET *wdgt; +{ + register int length, maxlen; + register char *showptr; + + (void) wclear(wdgt->wndw); + boxwdgt(wdgt, '-', '|'); + if (wdgt->dstr != (char *)NULL) { + length = strlen(wdgt->dstr); + maxlen = wdgt->wdth - 4 - strlen(wdgt->label); + if (length > maxlen) + showptr = &(wdgt->dstr[length - maxlen]); + else + showptr = wdgt->dstr; + (void) mvwprintw(wdgt->wndw, 1, 1, "%s%c%s",wdgt->label, + (length > maxlen)?'<':' ',showptr); + } + (void) wrefresh(wdgt->wndw); +} + +/* Print a TOGGLE widget label, and the current toggle value */ +void printtoggle(wdgt) + WIDGET *wdgt; +{ + (void) wclear(wdgt->wndw); + boxwdgt(wdgt, '-', '|'); + if (wdgt->tvalues == (char **)NULL) + return; + mvwaddstr(wdgt->wndw,1,1,wdgt->label); + (void) waddstr(wdgt->wndw,wdgt->tvalues[wdgt->tindx]); + (void) wclrtoeol(wdgt->wndw); + (void) mvwaddch(wdgt->wndw,1,wdgt->wdth-1,'|'); + (void) wrefresh(wdgt->wndw); +} + +/* Print a COMMAND widget label */ +void printcommand(wdgt) + WIDGET *wdgt; +{ + mvwaddstr(wdgt->wndw,1,1,wdgt->label); + (void) wrefresh(wdgt->wndw); +} + +/* THESE ROUTINES GET AND REACT TO A USERS INPUT FROM THE KEYBOARD */ + +/* Loop forever, calling widget callback functions when activated */ +void interact() +{ + register int ch, indx; + void int_quit(), jumpback(); + + for (;;) { +/* Get a character input, and set the interrupt jump vector */ + (void) setjmp(env); + (void) signal(SIGINT, int_quit); + + move(0,0); + (void) wrefresh(Text); + refresh(); + ch = getchar(); + if (isupper(ch)) + ch = tolower(ch); + (void) signal(SIGINT, jumpback); + +/* Allow the user to refresh the entire screen, with a CTRL-L */ + if (ch == '\014') { + redraw(); + scrollbar('\0'); + continue; + } + +/* Search through the current widgets for one matching that required */ + command = ch; + indx = findactiveinput(ch); + if (indx >= 0) + docallback(indx); + ch = 0; + } +} + +/* Find a callback 'ch' from the currently active set of widgets */ +int findactiveinput(ch) + char ch; +{ + register int indx; + register WIDGET *wdgts; + + if (ch > 'z' || ch < 'a') { + switch (ch) { + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ch = '*'; + break; + case '[': + case ']': + ch = '%'; + break; + case '?': + ch = 'h'; + break; + } + } + +/* See whether the 'ch' exists in the currently active widgets */ + wdgts = activelist.widgets[activelist.count - 1]; + indx = getwidgetindex(wdgts, ch); + if (indx >= 0) + return(indx); + +/* If not, check the previously active widgets, if possible */ + if (activelist.count <= 1) + return(-1); + indx = getwidgetindex(activelist.widgets[activelist.count - 2], ch); + if (indx >= 0) { + killwidgets(activelist.widgets[activelist.count - 1]); + return(indx); + } + return(-1); +} + +void docallback(indx) + char indx; +{ + WIDGET *wdgts; + + activeindex(indx); + wdgts = activelist.widgets[activelist.count - 1]; + switch (wdgts[indx].type) { + + case DIALOG: + if (command >= '1' && command <= '9') + get_listed_object (command, &wdgts[indx]); + else { + dialog(&wdgts[indx]); + (*wdgts[indx].callfn)(); + } + break; + + case TOGGLE: + toggle(&wdgts[indx]); + (*wdgts[indx].callfn)(); + break; + + case SCROLLBAR : + scrollbar(command); + break; + + default: + (*wdgts[indx].callfn)(); + break; + } +} + +/* THESE ROUTINES SEARCH THE ACTIVE WIDGET SET FOR ONE SPECIFIED WIDGET */ + +/* Find a widget based on the call-back character */ +WIDGET *getwidget(wdgts, callch) + int callch; + WIDGET wdgts[]; +{ + register int indx; + + indx = getwidgetindex(wdgts, callch); + if (indx >= 0) return(&(wdgts[indx])); + + return((WIDGET *)NULL); +} + +int getwidgetindex(wdgts, callch) + int callch; + WIDGET wdgts[]; +{ + register int cnt = 0; + + while (wdgts[cnt].type != FINISH) { + if (callch == wdgts[cnt].callch) break; + ++cnt; + } + if (wdgts[cnt].type != FINISH) return(cnt); + + return(-1); +} + +/* THESE ROUTINES MANIPULATE THE DIALOG WIDGETS */ + +void dialog(wdgt) + WIDGET *wdgt; +{ + register int i, length, labellen, maxlen; + register char ch, *endptr, *showptr; + register char *blanks; + extern char *malloc(); + + labellen = strlen(wdgt->label); /* The length of the prompt string */ + length = strlen(wdgt->dstr); /* The length of the current string */ + + maxlen = wdgt->wdth - 4 - labellen; /* The maximum length of shown str */ + blanks = malloc((unsigned)(maxlen + 2)); + for (i=0; idstr[length]); /* The next character pos'n to fill */ + *endptr = '\0'; + + if (length > maxlen) + showptr = &(wdgt->dstr[length - maxlen]); + else + showptr = wdgt->dstr; + (void) mvwprintw(wdgt->wndw, 1, 1, "%s%c%s", wdgt->label, + (length > maxlen)? '<' : ' ', + showptr); + (void) wrefresh(wdgt->wndw); + + while ((ch = getchar() & 127) != '\n' && ch != '\r' && ch != '\f') { + if (ch == '\014') { /* Allow for redrawing */ + redraw(); + continue; + } + + if (ch == '\b' || ch == 127) { /* Delete a character, with wrapping */ + if (length == 0) + continue; + *(--endptr) = '\0'; /* Make the last character NULL */ + if (showptr > wdgt->dstr) /* We have parts of the string hidden */ + --showptr; + --length; + if (length < maxlen) { /* Only need to erase one character */ + (void) waddstr(wdgt->wndw,"\b \b"); + (void) wrefresh(wdgt->wndw); + continue; + } + /* We'll have to erase everything */ + (void) wprintw(wdgt->wndw, "\r|%s%c%s \b", wdgt->label, + (length <= maxlen)? ' ' : '<', + showptr); + (void) wrefresh(wdgt->wndw); + continue; + } + + if (ch == 21) { /* ^U to delete the entire line of text */ + length = 0; + endptr = wdgt->dstr; + *endptr = '\0'; + showptr = wdgt->dstr; + (void) wprintw(wdgt->wndw, "\r|%s %s\r|%s ", wdgt->label, blanks, + wdgt->label); + (void) wrefresh(wdgt->wndw); + continue; + } + +/* Otherwise, add the character if there is room and it ain't a control code */ + if (length == 1024 || ch < 32) + continue; + if (length == wdgt->dstrlen){ + *endptr++ = ch; + *endptr = '\0'; + setdialogstr(wdgt, showptr, wdgt->dstrlen); + continue; + } + *endptr++ = ch; + *endptr = '\0'; + if (++length <= maxlen) { /* Just add this character to the end */ + (void) waddch(wdgt->wndw, ch); + (void) wrefresh(wdgt->wndw); + continue; + } + ++showptr; + (void) wprintw(wdgt->wndw, "\r|%s<%s", wdgt->label, showptr); + (void) wrefresh(wdgt->wndw); + } + free(blanks); +} + + +void setdialogstr(wdgt, dstr, maxlen) + char *dstr; + WIDGET *wdgt; +int maxlen ; +{ + if (wdgt->type != DIALOG) return; + + wdgt->dstr = dstr; + wdgt->dstrlen = maxlen; +} + +int getdialogstr(wdgt, str) /* 'str' must be long enough... */ + char str[]; + WIDGET *wdgt; +{ + if (wdgt->type != DIALOG || wdgt->dstr == (char *)NULL) return(FALSE); + + (void) strcpy(str, wdgt->dstr); + return(TRUE); +} + +/* THESE ROUTINES MANIPULATE THE TOGGLE WIDGETS */ + +void toggle(wdgt) + WIDGET *wdgt; +{ + WIDGET *vwdgt; + int av_indx; + + if (wdgt->tvalues == (char **)NULL) + return; + + if (wdgt == getwidget(currwidgets, 't')) { + typetoggled = 1; + vwdgt = getwidget(currwidgets, 's'); + (void) strcpy(filtvalue[wdgt->tindx], vwdgt->dstr); + + av_indx = 0; + while (av_typeindx[av_indx] != wdgt->tindx && av_typeindx[av_indx] >= 0) + av_indx++; + + if (av_typeindx[av_indx] == wdgt->tindx) + av_indx++; + + if (av_typeindx[av_indx] < 0) + av_indx = 0; + + wdgt->tindx = av_typeindx[av_indx]; + + (void) strcpy(vwdgt->dstr, filtvalue[wdgt->tindx]); + typeindx = wdgt->tindx; + + printdialog(vwdgt); + } + + printtoggle(wdgt); +} + +void settogglstrs(wdgt, togglstrs, togglindx) + int togglindx; + char **togglstrs; + WIDGET *wdgt; +{ + if (wdgt->type != TOGGLE) + return; + wdgt->tvalues = togglstrs; + wdgt->tindx = togglindx; +} + +int settogglindx(wdgt, indx) + int indx; + WIDGET *wdgt; +{ + int i; + + if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) + return(FALSE); + for (i=0; itvalues[i] == (char *)NULL) + break; + if (i != indx) /* There ain't that many toggle strings */ + return(FALSE); + wdgt->tindx = indx; + return(TRUE); +} + +int gettogglindx(wdgt) + WIDGET *wdgt; +{ + if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) + return(-1); + return(wdgt->tindx); +} + +int gettogglstr(wdgt, str) /* 'str' must be long enough... */ + WIDGET *wdgt; + char str[]; +{ + if (wdgt->type != TOGGLE || wdgt->tvalues == (char **)NULL) + return(FALSE); + (void) strcpy(str, wdgt->tvalues[wdgt->tindx]); + return(TRUE); +} + +/* THESE ROUTINES MANIPULATE THE LABEL WIDGETS */ + +void setlabel(wdgt, label) + WIDGET *wdgt; + char *label; +{ + wdgt->label = label; +} + +void getlabel(wdgt, label) /* 'label' must be long enough... */ + WIDGET *wdgt; + char label[]; +{ + (void) strcpy(label, wdgt->label); +} + +/* MISCELLANEOUS FUNCTIONS */ + +/* Try to locate the bottom of the last set of widgets displayed */ +int lowesty() +{ + register int cnt = 0; + register WIDGET *wdgts; + + if (activelist.count <= 0) return(0); + + wdgts = activelist.widgets[activelist.count - 1]; + while (wdgts[cnt].type != FINISH) ++cnt; + + if (cnt == 0) return(0); + + return((wdgts[cnt-1].y) + WDGTHGHT); +} + +/* This satisfies the generalised printing structure */ +/* ARGSUSED */ +void wprint(here, fmt, a,b,c,d,e,f,g,h,i,j) + WINDOW *here; + char *fmt, *a,*b,*c,*d,*e,*f,*g,*h,*i,*j; +{ + (void) wprintw(Text,fmt,a,b,c,d,e,f,g,h,i,j); + (void) wrefresh(Text); +} + +/* This can be called as a way for an application to print text */ +/* VARARGS1 */ +void tprint(fmt, a,b,c,d,e,f,g,h,i,j) + char *fmt, *a,*b,*c,*d,*e,*f,*g,*h,*i,*j; +{ + (void) wprintw(Text,fmt,a,b,c,d,e,f,g,h,i,j); + (void) wrefresh(Text); +} + +void xprint(fmt) + char *fmt; +{ + (void) wprintw(Text, "%s", fmt); +} + +void xprintint(fmt, a) + char *fmt; + int a; +{ + (void) wprintw(Text,fmt, a); +} + +void cleartext() +{ + clearok (Text,TRUE); + (void) wclear (Text); +} + +/* Jump back to the interact function only on an interrupt */ +void jumpback() +{ + (void) waddstr(Text,"\n*** Interrupted ***\n"); + (void) wrefresh(Text); + longjmp(env, TRUE); +} + +/* This is used as a declaration, when no function callback is required */ +void nullfn() +{} + +/* This is used by widgets that just want to kill the current level */ +void quitfn() +{ + (void) wclear(Text); + (void) wrefresh(Text); + killwidgets(activelist.widgets[activelist.count - 1]); +} + +void endwidgets() +{ + move(LINES-1, 0); + refresh(); + endwin(); +} + + + diff --git a/usr/src/contrib/isode/others/quipu/uips/sd/widget.h b/usr/src/contrib/isode/others/quipu/uips/sd/widget.h new file mode 100644 index 0000000000..f25f498f1d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/sd/widget.h @@ -0,0 +1,127 @@ +/* widget.h - definition of the widget structure and assorted constants */ + +/* + * $Header: /f/osi/others/quipu/uips/sd/RCS/widget.h,v 7.2 91/02/22 09:32:32 mrose Interim $ + */ + + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +/*****************************************************************************/ +/*This file has been modified; +/*Modifier: Damanjit Mahl @ Brunel University, Uxbridge +/*****************************************************************************/ + +/*****************************************************************************/ +/* File: widget.h +/* Author: Paul Sharpe @ GEC Research, Hirst Research Centre. +/* Date: August 12, 1988. +/* Function: Definition of the widget structure and assorted constants. +/* +/* DISCLAIMER: +/* This source file is deemed to be public domain: any person may use the +/* code in any way, on two simple provisos - +/* 1 - That this header remains in this file, +/* 2 - It is accepted that neither the author, nor the authors employees +/* accept any responsibility for the use, abuse or misuse of the +/* contained code. +/* No guarantee is made by the author to provide maintainance or up-grading +/* of this source. However, any adaptations made to this file will be viewed +/* at least with interest. +/*****************************************************************************/ + +#ifndef WIDGETDEFS +#define WIDGETDEFS + +#include + +/* These define the type of the widget involved */ +#define FINISH 0 +#define LABEL 1 +#define COMMAND 2 +#define TOGGLE 3 +#define DIALOG 4 +#define SCROLLBAR 5 +#define DUMMY 6 + +/* These define functions that aren't really needed */ +#define NULLFN nullfn +#define TOGGLEFN NULLFN +#define QUITFN quitfn + +/* These define the LABEL wdgt text justification */ +#define CENTER CENTRE +#define CENTRE 1 +#define LEFT 2 +#define RIGHT 4 + +/* Thisdefines an expanded widget box */ +#define EXPAND -1 + +/* This defines a widget position starting on a new line */ +#define CRNL -1 + +/* This is the default shown length of the dialog string */ +#define DIALOGLEN 4 + +/* This defines the maximum number of levels of active widgets */ +#define MAXACTIVE 10 +#ifndef BUFLEN +#define BUFLEN 1024 +#endif + +int lowy; + +/* This is the height of a widget box, in number of lines */ +#define WDGTHGHT 3 + +typedef struct widget { + char type; /* Type of widget: see the above definitions */ + char *label; /* text string label for the widget */ + + /* The former is used by LABEL and COMMAND widgets: the latter by COMMAND */ + char callch; /* Character to activate the COMMAND widget */ + void (*callfn)(); /* Function called by an activated COMMAND */ + + /* ALL widgets need these fields to be set */ + int x,y; /* Position of the top right of the window */ + int wdth, hght; /* width and height of the widget window */ + + /* These are only used by the DIALOG type widgets */ + int dstrlen; /* Maximum length of the DIALOG widget str */ + char *dstr; /* Pointer to the DIALOG string to fill in */ + + /* These are only used by the TOGGLE type widgets */ + char tindx; /* Index into the toggle values */ + char **tvalues; /* NULL-terminated array of TOGGLE strings */ + + WINDOW *wndw; /* The curses-widget window structure */ +} WIDGET; + +WIDGET *currwidgets; +char typetoggled; + +void initwidgets(), textfresh(), makewidgets(), setwdgtwdth(), + killwidgets(), activewidget(), deleteactive(), activeindex(), + redraw(), rfrshwidgets(), boxwdgt(), printwdgt(), printbar(), + printlabel(), printdialog(), printtoggle(), printcommand(), + interact(), docallback(), dialog(), setdialogstr(), + toggle(), settogglstrs(), setlabel(), getlabel(), wprint(), tprint(), + xprint(), xprintint(), cleartext(), jumpback(), nullfn(), quitfn(), + endwidgets(); + +int linec(), gety(), posnwidgets(), getwidgetindex(), getdialogstr(), + settogglindx(), gettogglindx(), gettogglstr(), lowesty(), + findactiveinput(); + +WIDGET *getwidget(); + +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/Makefile b/usr/src/contrib/isode/others/quipu/uips/xd/Makefile new file mode 100644 index 0000000000..7ad528c0de --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/Makefile @@ -0,0 +1,288 @@ +# $Header: /f/osi/others/quipu/uips/xd/RCS/Makefile,v 7.7 91/02/22 09:32:34 mrose Interim $ +# +# $Log: Makefile,v $ +# Revision 7.7 91/02/22 09:32:34 mrose +# Interim 6.8 +# +# Revision 7.6 91/01/24 14:51:57 mrose +# update +# +# Revision 7.5 90/12/23 18:46:49 mrose +# update +# +# Revision 7.4 90/11/20 15:33:55 mrose +# update +# +# Revision 7.3 90/10/17 11:50:11 mrose +# sync +# +# Revision 7.2 90/07/27 08:45:51 mrose +# update +# +# Revision 7.1 90/07/09 14:42:07 mrose +# sync +# +# Revision 7.0 90/06/12 13:10:31 mrose +# *** empty log message *** +# +# Revision 1.6 90/04/26 10:22:28 emsrssn +# Installation fixed +# +# +# Revision 1.5 90/04/26 10:21:41 emsrssn +# *** empty log message *** +# +# Revision 1.4 90/04/25 17:27:56 emsrssn +# Lint tidy up +# +# +# Revision 1.3 90/04/19 13:47:38 emsrssn +# keyboard accelerator now activates button highlight. +# +# search types available is dependent on current position +# to prevent unreasonable searches. +# +# the help popup changes automatically depending on the +# position of the cursor +# +# buttons remain a fixed size when the application is +# resized +# +# command line options are now handled properly +# +# logging added +# +# "reads" are now sorted to show mail address at top etc. +# +# +# Revision 1.2 90/03/09 15:57:21 emsrssn +# First public distribution +# +# +# Revision 1.1 90/03/08 13:18:50 emsrssn +# Initial revision +# +# +# +############################################################## +# +# Xd Makefile - Xd uses the Athena widget set +# +# Stefan Nahajski, Brunel University 28/2/90 +############################################################## + +XLIB = -lX11 +XTLIB = -lXt + +# athena widget library compiled with debugging option +#XAWLIB = /usr/local/lib/libXaw.a +XAWLIB = -lXaw + +XMULIB = -lXmu +XEXTLIB = -lXext + +XLIBDIR = /usr/lib/X11/ + +INCLUDE = -I$(TOPDIR)h + +LIBES = $(TOPDIR)libdsap.a $(TOPDIR)libisode.a +LIBS = $(XAWLIB) $(XMULIB) $(XTLIB) $(XLIB) $(XEXTLIB) + +LLIBES = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode + +############################################################## + +CFILES = filt.c Xd.c sequence.c main.c calls.c symtab.c y.tab.c +OFILES = filt.o Xd.o sequence.o main.o calls.o symtab.o y.tab.o +YFILES = conf_read.y + +############################################################## + +all: xxd +#inst-all: inst-xd config helpfiles app-defaults manuals +inst-all: inst-xd confandhelp app-defaults manuals +install: inst-all clean +lint: l-xd + +############################################################## + +inst-xd: $(BINDIR)xd + -mkdir $(ETCDIR)xd + +$(BINDIR)xd: xxd + -cp $@ zxxd + -rm -f $@ + cp xxd $@ + -@ls -gls $@ + -@echo "" + +################################################################ +# app-defaults files for X +################################################################ + +app-defaults:; -cp Xd.ad $(XLIBDIR)app-defaults/Xd + +################################################################ +# config and help files +################################################################ + +confandhelp:; -mkdir $(ETCDIR)xd/ + cp -R Xd/* $(ETCDIR)xd/. + -@echo "" + +################################################################ +# manual pages +################################################################ + +MANUALS = xd.1c + +# Just in case someone does 'rm x*'.... +xd.1c: Xd.1c + cp Xd.1c xd.1c + chmod 444 xd.1c + +manuals: $(MANUALS) + @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + +################################################################ +# lint +################################################################ + +l-xd:; $(LINT) $(LFLAGS) $(CFILES) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +############################################################# +# clean +############################################################## + +clean:; rm -f y.tab.* *.o a.out _* xx* z* core + +grind:; iprint Makefile + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + + +############################################################## +# xd +############################################################## + +xd: xxd + +xxd: $(OFILES) $(LIBES) + $(CC) $(INCLUDE) -o $@ $(CFLAGS) $(OFILES) $(LIBS) \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) + + +y.tab.c: conf_read.y + yacc -d $(YFILES) + +############################################################## +# RCS +############################################################## + +ci: FRC + vi RCS_message_text + ci -l -f RCS/* : highlight() Call_Change_Help("xdsearch.help") + +Xd*list_but.translations: #override \ + : Call_Change_Help("xdlist.help") highlight() + +Xd*list_area.translations: #override \ + : Call_Change_Help("xdlistsel.help") + +Xd*lookback_but.translations: #override \ + : Call_Change_Help("xdlookback.help") highlight() + +Xd*widen_but.translations: #override \ + : Call_Change_Help("xdwiden.help") highlight() + +Xd*type_but.translations: #override \ + : Call_Change_Help("xdtype.help") highlight() + +Xd*help_but.translations: #override \ + : Call_Change_Help("xd.help") highlight() + diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/Xd.c b/usr/src/contrib/isode/others/quipu/uips/xd/Xd.c new file mode 100644 index 0000000000..957aef89a1 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/Xd.c @@ -0,0 +1,882 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/Xd.c,v 7.2 91/02/22 09:32:39 mrose Interim $ */ +#ifndef lint + static char *rcsid = "$Id: Xd.c,v 7.2 91/02/22 09:32:39 mrose Interim $"; +#endif +/* + $Log: Xd.c,v $ + * Revision 7.2 91/02/22 09:32:39 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:50:17 mrose + * sync + * + * Revision 7.0 90/06/12 13:10:46 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:32 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:02 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:00 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:25 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:43 emsrssn + * Initial revision + * + * +*/ + +#include +#include "quipu/util.h" +#include "sequence.h" +#include "dirtitle.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define ASIZELIMIT 50 /* used for result list size and directory limits */ + +#define MAXLOOKBACKLENGTH 10 +#define MAXLENGTH 255 +#define MAXRESULTLISTLENGTH ASIZELIMIT +#define NOHISTORY "You've not been anywhere yet" + +extern char base_path[]; +extern char friendly_base_path[]; +extern char goto_path[]; +extern char mvalue[]; +extern int filt_num; +extern unsigned int typeindx; +extern char *filtvalue[]; +extern char *filttype[]; +extern char dua_help_dir[]; +extern int *av_typeindx; +extern D_seq showseq, dnseq; +extern int entry_number; + +int element_number = 0; +int asizelimit = ASIZELIMIT; + +void add_to_lookback(), xprint(), CreatePopupHelp(), Change_Help(); + +static void Call_Change_Help(); +static void Quit(), create_genform(), create_inputform(); +static void create_viewlist(), create_commandform(), create_outputform(); +static void PopupList(), PopupTypelist(), Quit_Popup(); +static void PopupHelp(), PopdownHelp(), Change_Type(), Change_Search_Area(); +static void Search(), List(), widen_search(); + +static Boolean lookback_open = False; /* is there a look back popup? */ +static Boolean help_popped_up= False; /* is the help window up? */ + +String result_list[MAXRESULTLISTLENGTH]; +String lookback_list[MAXLOOKBACKLENGTH]; +Widget toplevel; +XtAppContext app_con; + +static XtActionsRec buttonActionsTable[] = { + {"Call_Change_Help", (XtActionProc) Call_Change_Help}, +}; + + + + + +void +init_widgets () +{ + Arg args[1]; + Widget outer; + int count; + + outer = XtCreateManagedWidget("outer", panedWidgetClass, toplevel, + args, 0); + + XtAppAddActions(app_con, buttonActionsTable, XtNumber(buttonActionsTable)); + + create_genform(outer); + create_inputform(outer); + create_outputform(outer); + create_commandform(outer); + create_viewlist(outer); + + for(count=0; count < MAXRESULTLISTLENGTH; count++) { + result_list[count] = XtMalloc(MAXLENGTH); + } + + for(count=0; count < MAXLOOKBACKLENGTH; count++) { + lookback_list[count] = XtMalloc(MAXLENGTH); + } + /* add text to stop widget assuming daft size */ + (void) strcpy(lookback_list[0], NOHISTORY ); + +} + +free_memory() +{ + int count; + + for(count=0; count < MAXRESULTLISTLENGTH; count++) { + XtFree(result_list[count]); + } + + for(count=0; count < MAXLOOKBACKLENGTH; count++) { + XtFree(lookback_list[count]); + } +} + + +void +Loop() +{ + Arg args[5]; + Pixmap title_pix; + String title_name = "outer.genform.title"; + Widget title_widg = XtNameToWidget(toplevel,title_name); + + XtRealizeWidget(toplevel); + XFlush(XtDisplay(toplevel)); /* this ensures that all requests are sent */ + /* without this line, linking with cc means */ + /* that the requests are not all sent */ + + title_pix = XCreateBitmapFromData(XtDisplay(title_widg), + XtWindow(title_widg), stef_bits, stef_width, + stef_height); + XtSetArg(args[0], XtNbitmap, title_pix); + XtSetValues(title_widg, args, 1); + + XtAppMainLoop(app_con); +} + + +/*ARGSUSED*/ +static void +Call_Change_Help(w, event, params, num_params) +Widget w; +XEvent *event; +String *params; +int num_params; +{ + Change_Help(params[0]); +} + + +static void +create_viewlist(parent) +Widget parent; +{ + Widget view_list, list_area; + Arg args[10]; + + view_list = XtCreateManagedWidget("view_list", viewportWidgetClass, parent, + args, 0); + + XtSetArg(args[0], XtNlist, result_list); + XtSetArg(args[1], XtNdefaultColumns, (int) 1); + XtSetArg(args[2], XtNverticalList, True ); + list_area = XtCreateManagedWidget("list_area", listWidgetClass, + view_list, args, 3); + XtAddCallback(list_area, XtNcallback, Change_Search_Area, (XtPointer) 0 ); + +} + + + +static void +create_outputform(parent) +Widget parent; +{ + Arg args[10]; + static XawTextSelectType sarray[] = { + XawselectLine, + XawselectPosition, + XawselectAll, + XawselectNull + }; + + XtSetArg(args[0], XtNselectTypes, sarray); + (void) XtCreateManagedWidget("result_area", asciiTextWidgetClass, + parent, args, 1); + +} + + + +static void +create_commandform(parent) +Widget parent; +{ + Arg args[1]; /* used to pass zero args...to be consistent for lint */ + Widget form, widen_but; + Widget search_but, list_but, lookback_but; + + + form = XtCreateManagedWidget("commandform", formWidgetClass, parent, + args, 0 ); + + search_but = XtCreateManagedWidget("search_but", commandWidgetClass, + form, args, 0 ); + XtAddCallback(search_but, XtNcallback, Search, (XtPointer)0 ); + + + list_but = XtCreateManagedWidget("list_but", commandWidgetClass, + form, args, 0 ); + XtAddCallback(list_but, XtNcallback, List, (XtPointer)0 ); + + + lookback_but = XtCreateManagedWidget("lookback_but", commandWidgetClass, + form, args, 0); + XtAddCallback(lookback_but, XtNcallback, PopupList, (XtPointer)0 ); + + + widen_but = XtCreateManagedWidget("widen_but", commandWidgetClass, form, + args, 0 ); + XtAddCallback(widen_but, XtNcallback, widen_search, (XtPointer)0 ); +} + + + + +void +Searchpress() +{ + XEvent search_event; + Widget search_but = XtNameToWidget(toplevel, "outer.commandform.search_but"); + + search_event.type = ButtonPress; + search_event.xbutton.button = Button1; + search_event.xany.display = XtDisplay(search_but); + search_event.xany.window = XtWindow(search_but); + + XSendEvent(XtDisplay(search_but), XtWindow(search_but), True, + ButtonPressMask | ButtonReleaseMask, &search_event); + + search_event.type = ButtonRelease; + XSendEvent(XtDisplay(search_but), XtWindow(search_but), True, + ButtonPressMask | ButtonReleaseMask, &search_event); +} + + + +static Widget +create_type_menu(parent) +Widget parent; +{ + Arg args[1]; /* used to pass zero args...to be consistent for lint */ + Widget menu, button; + int n; + + menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, + parent, args, 0 ); + + n = 0; + while (av_typeindx[n] != -1) { + button = XtCreateManagedWidget((String) filttype[av_typeindx[n]], + smeBSBObjectClass, + menu, args, 0); + XtAddCallback(button, XtNcallback, Change_Type, (XtPointer) av_typeindx[n]); + n++; + } + return menu; +} + + + +static void +create_inputform(parent) +Widget parent; +{ + Widget form, area_form, for_form, type_form; + Widget type_but; + Widget search_for; + + Arg args[10]; + + + static XtActionsRec actionsTable[] = { + {"Searchpress", (XtActionProc) Searchpress}, + }; + + static char defaultTranslations[] = + "Return: Searchpress() \n\ + CtrlM: Searchpress() \n\ + CtrlO: Searchpress()"; + + XtTranslations trans_table; + + form = XtCreateManagedWidget("inputform", formWidgetClass, parent, + args, 0 ); + + area_form = XtCreateManagedWidget("area_form", formWidgetClass, form, + args, 0 ); + + (void) XtCreateManagedWidget("search_area_label", + labelWidgetClass, area_form, args, 0); + + + XtSetArg(args[0], XtNstring, friendly_base_path); + XtSetArg(args[1], XtNwidth, (Dimension) 300); + (void) XtCreateManagedWidget("search_area", asciiTextWidgetClass, + area_form, args, 2); + + for_form = XtCreateManagedWidget("for_form", formWidgetClass, form, + args, 0); + + (void) XtCreateManagedWidget("search_for_label", labelWidgetClass, + for_form, args, 0); + + search_for = XtCreateManagedWidget("search_for", asciiTextWidgetClass, + for_form, args, 0); + + XtAppAddActions(app_con, actionsTable, XtNumber(actionsTable)); + trans_table = XtParseTranslationTable(defaultTranslations); + XtOverrideTranslations(search_for, trans_table); + + type_form = XtCreateManagedWidget("type_form", formWidgetClass, form, + args, 0 ); + + type_but = XtCreateManagedWidget("type_but", menuButtonWidgetClass, + type_form, args, 0); + + (void) XtCreateManagedWidget("search_type", asciiTextWidgetClass, + type_form, args, 0); + + (void) create_type_menu(type_but); +} + + + + + +static void +create_genform(parent) +Widget parent; +{ + Widget form, quit_but, help_but; + Arg args[10]; + + form = XtCreateManagedWidget("genform", formWidgetClass, parent, + args, 0 ); + + XtSetArg(args[0], XtNheight, stef_height); + XtSetArg(args[1], XtNwidth, stef_width); + (void) XtCreateManagedWidget("title", labelWidgetClass,form, + args, 2); + + quit_but = XtCreateManagedWidget("quit_but", commandWidgetClass, form, + args, 0); + XtAddCallback(quit_but, XtNcallback, Quit, (XtPointer) toplevel); + + + help_but = XtCreateManagedWidget("help_but", commandWidgetClass, form, + args, 0); + CreatePopupHelp(help_but); + XtAddCallback(help_but, XtNcallback, PopupHelp, (XtPointer)0 ); +} + + + +/*ARGSUSED*/ +static void +Quit(widget, closure, callData) +Widget widget; +XtPointer closure, callData; +{ + XtDestroyWidget((Widget) closure); + exit(0); +} + + +void +CreatePopupHelp(button) +Widget button; +{ + Widget popup, form, quit_but; + Arg args[5]; + FILE *file; + char fullname[MAXLENGTH]; + char filename[MAXLENGTH]; + + (void) strcpy(filename, "xd.help"); + + popup = XtCreatePopupShell("popup", transientShellWidgetClass, button, + args, 0); + + form = XtCreateManagedWidget("form", formWidgetClass, popup, + args, 0); + + quit_but = XtCreateManagedWidget("quit_but", commandWidgetClass, form, + args, 0); + XtAddCallback(quit_but, XtNcallback, PopdownHelp, (XtPointer)0 ); + + (void) strcpy(fullname, dua_help_dir); + (void) strcat(fullname, filename); + if (!(file = fopen(fullname, "r"))) { + (void) strcpy(fullname, "./xd/helpdir/"); + (void) strcat(fullname, filename); + if (!(file = fopen(fullname, "r"))) (void) printf("Helpfile not found"); + } + + if(file != NULL) { + (void) fclose(file); + XtSetArg(args[0], XtNstring, fullname ); + } + (void) XtCreateManagedWidget("help_text", asciiTextWidgetClass, form, + args, 1); +} + + +/*ARGSUSED*/ +static void +PopupHelp(button, client_data, call_data) +Widget button; +XtPointer client_data, call_data; +{ + Widget pop_widg = XtNameToWidget(button, "popup"); + Arg args[5]; + Position x, y; + Cardinal n; + + + XtTranslateCoords(button, (Position) 0, (Position) 0, + &x, &y); + + n = 0; + XtSetArg(args[n], XtNx, x); n++; + XtSetArg(args[n], XtNy, y-245); n++; + XtSetValues(pop_widg, args, n); + + help_popped_up = TRUE; + XtPopup(pop_widg, XtGrabNone); + +} + +/*ARGSUSED*/ +static void +PopdownHelp(button, client_data, call_data) +Widget button; +XtPointer client_data, call_data; +{ + Widget pop_widg = XtParent( XtParent(button) ); + + help_popped_up = FALSE; + XtPopdown(pop_widg); +} + +void +Change_Help(filename) +String filename; +{ + Arg args[5]; + FILE *file; + char *fullname; + static char * old_pointer = 0; + + /* this gets around a problem mine or athena widgets ? */ + /* does usestringinplace=false work for type = file */ + /* when using asciitext widgets? */ + + if(help_popped_up){ + fullname = XtMalloc(MAXLENGTH * sizeof(char)); + if(old_pointer != 0) { + XtFree((char *) old_pointer); + old_pointer = fullname; + } + + (void) strcpy(fullname, dua_help_dir); + (void) strcat(fullname, filename); + if (!(file = fopen(fullname, "r"))) { + (void) strcpy(fullname, "./Xd/helpdir/"); + (void) strcat(fullname, filename); + if (!(file = fopen(fullname, "r"))) (void) fprintf(stderr, "Helpfile not found\n"); + } + + if(file != NULL) { + (void) fclose(file); + XtSetArg(args[0], XtNstring, fullname ); + XtSetValues( XtNameToWidget(toplevel, + "outer.genform.help_but.popup.form.help_text"), args, 1); + } + XFlush(XtDisplay(toplevel)); + } +} + + +/*ARGSUSED*/ +static void +PopupList(button, client_data, call_data) +Widget button; +XtPointer client_data, call_data; +{ + Arg args[5]; + Widget popup, form, list_places, quit_but; + Position x, y; + Dimension width, height; + Cardinal n; + String widget_name = "outer.commandform.lookback_but.popup"; + + + if(lookback_open == True) { + XtPopup(XtNameToWidget(toplevel, widget_name), XtGrabNone); + return; + } + + + n = 0; + XtSetArg(args[0], XtNwidth, &width); n++; + XtSetArg(args[1], XtNheight, &height); n++; + XtGetValues(button, args, n); + XtTranslateCoords(button, (Position) (width / 2), (Position) (height / 2), + &x, &y); + + n = 0; + XtSetArg(args[n], XtNx, x); n++; + XtSetArg(args[n], XtNy, y); n++; + + popup = XtCreatePopupShell("popup", transientShellWidgetClass, button, + args, n); + + form = XtCreateManagedWidget("form", formWidgetClass, popup, + args, 0); + + XtSetArg(args[0], XtNlabel, (String) "Quit"); + quit_but = XtCreateManagedWidget("quit_but", commandWidgetClass, form, + args, 1); + XtAddCallback(quit_but, XtNcallback, Quit_Popup, (XtPointer) form); + + XtSetArg(args[0], XtNlist, lookback_list); + XtSetArg(args[1], XtNfromVert, quit_but); + XtSetArg(args[2], XtNverticalList, True ); + XtSetArg(args[3], XtNnumberStrings, MAXLOOKBACKLENGTH ); + list_places = XtCreateManagedWidget("list_places", listWidgetClass, form, + args, 4); + XtAddCallback(list_places, XtNcallback, Change_Search_Area, (XtPointer)0 ); + + lookback_open = True; + + XtPopup(popup, XtGrabNone); +} + + + + +void +Add_To_Results(add_this) +String add_this; +{ + Arg args[10]; + String str; + char new_str[2000]; + Widget result_widg = XtNameToWidget(toplevel, "outer.result_area"); + + XtSetArg(args[0], XtNstring, &str); + XtGetValues(result_widg, args, ONE); + + if(*str == '\0') + (void) strcpy(new_str, add_this); + else + (void) sprintf((char *)new_str,"%s\n%s", str, add_this); + + XtSetArg(args[0], XtNstring, new_str); + XtSetValues(result_widg, args, 1); +} + + + +void Clear_Results() +{ + Arg args[10]; + Widget result_widg = XtNameToWidget(toplevel, "outer.result_area"); + + XtSetArg(args[0], XtNstring, "\0"); + XtSetValues(result_widg, args, 1); +} + + + +Switch_Off_Result_Update() +{ + Widget result_widg = XtNameToWidget(toplevel, "outer.result_area"); + XawTextDisableRedisplay(result_widg); +} + + +Switch_On_Result_Update() +{ + Widget result_widg = XtNameToWidget(toplevel, "outer.result_area"); + XawTextEnableRedisplay(result_widg); +} + + + +/*ARGSUSED*/ +static void +Search(w, client_data, call_data) +Widget w; +XtPointer client_data, call_data; +{ + Arg args[10]; + int n, numb; + String str; + String string; + Widget list_widg = XtNameToWidget(toplevel, "outer.view_list.list_area"); + Widget widg = XtNameToWidget(toplevel, + "outer.inputform.for_form.search_for"); + + Clear_Results(); + XtSetArg(args[0], XtNstring, &str); + XtGetValues(widg, args, ONE); + (void) strcpy(mvalue, str); + srch_start(); + xprint("Search completed"); + showseq = dnseq; + element_number = entry_number; + + numb = element_number; + if(numb >= MAXRESULTLISTLENGTH) + numb = MAXRESULTLISTLENGTH-1; + + for (n = 0; n < numb; n++) { + string = get_from_seq(n+1, showseq); + (void) strcpy(result_list[n], string); + } + + for(; n= MAXRESULTLISTLENGTH) + numb = MAXRESULTLISTLENGTH-1; + + for (n = 0; n < numb; n++) { + string = get_from_seq(n+1, showseq); + (void) strcpy(result_list[n], string); + } + + for(; nstring) != 0) && (strcmp(item->string, NOHISTORY))){ + Set_Search_Area(item->string); + rd_start(); + add_to_lookback(base_path); + } + + XawListUnhighlight(w); +} + + + +Set_Search_Area(string) +String string; +{ + Arg args[10]; + String widget_name = "outer.inputform.area_form.search_area"; + Widget search_w = XtNameToWidget(toplevel, widget_name); + + XtSetArg(args[0], XtNstring, string); + XtSetValues(search_w, args, 1); + + (void) strcpy(base_path, string); + set_default_type(); +} + +/*ARGSUSED*/ +static void +Quit_Popup(widget, client_data, call_data) +Widget widget; +XtPointer client_data, call_data; +{ + Widget popup = XtParent((Widget) client_data); + + if(lookback_open == True) + if(XtNameToWidget(toplevel, + "outer.commandform.lookback_but.popup.form.quit_but") == widget) + lookback_open = False; + + XtDestroyWidget(popup); +} + + +void +xprint(str) +String str; +{ + Add_To_Results(str); +} + +/*ARGSUSED*/ +static void +widen_search() +{ + Arg args[10]; + String widget_name = "outer.inputform.area_form.search_area"; + Widget search_w = XtNameToWidget(toplevel, widget_name); + + widen(); + XtSetArg(args[0], XtNstring, base_path); + XtSetValues(search_w, args, 1); +} + + +void +add_to_lookback(addthis) +String addthis; +{ + int count; + String widget_name = "outer.commandform.lookback_but.popup.form.list_places"; + Widget list_w; + + for(count=0; count +#include "usr.dirent.h" +#include "tailor.h" +#include "sequence.h" +#include "filt.h" +#include "y.tab.h" +#include "symtab.h" + +struct attrcomp * sort_attrs(); +static dn2str (); + +#define RESBUF 10000 + +PS opt; +Attr_Sequence read_types = 0, read_types2; + +table_entry symtab = 0; +int typetoggled = 0; + +int dn_print (), rdn_print(), as_print(); + +char bound = FALSE; /* indication of whether bound */ +char * TidyString(); + +D_seq dnseq = NULLDS, backseq = NULLDS, showseq = NULLDS; +int entry_number, back_buf_num, element_num; + +/* These are common operation variables */ +#define STRINGLEN 1000 +#define SMALLSTRING 255 +#define MAXTYPES 255 + +char goto_path[STRINGLEN]; /* Used by the 'G:goto' command*/ +char base_path[STRINGLEN]; /* Used by all DS operations */ +char friendly_base_path[STRINGLEN]; +char friendly_name[STRINGLEN]; +char namestr[STRINGLEN]; +char cache [STRINGLEN]; +char bindpass [STRINGLEN]; +char srchvalue[STRINGLEN]; /* Used by search */ +char svalue [STRINGLEN]; +char mvalue [STRINGLEN]; + +unsigned int curr_filt = 0; +unsigned int filt_num = 0; +unsigned int typeindx = 0; +filt_struct *filt_arr[MAXTYPES]; +char *filtvalue[MAXTYPES]; +char *filttype[MAXTYPES]; + +int default_num; +int *av_typeindx; +int *available_types[MAXTYPES]; +char *levels[MAXTYPES]; +int defaults[MAXTYPES]; + +extern Filter make_filter(); +extern int Switch_On_Result_Update(); +extern int Switch_Off_Result_Update(); +extern void Clear_Results(); +extern void xprint(); + +extern char *local_dit; + +#ifndef NO_STATS +extern LLog *log_stat; +#endif + + +/* These are used as the data for the binding connection */ +char passwd[STRINGLEN]; +extern char * myname; + +extern int asizelimit; +DN user_name; + +char * addobj = NULLCP; +Filter search_filter; +FILE *file; +char *file_names[MAXTYPES]; +char dua_help_dir[256]; + +char *get_strioid(ptr) +register char *ptr; +{ + register char *end_ptr; + + while(*ptr == '"') ptr++; + while(*ptr != '"') ptr++; + + while(*ptr > '9' || *ptr < '0') ptr++; + + end_ptr = ptr; + while(*end_ptr != '\n') end_ptr++; + + *end_ptr = '\0'; + return ptr; +} + + +user_tailor () +{ + char *part1; + char *part2; + char *getenv (); + char *ptr = "/.quipurc"; + char *config_dir = "/.duaconfig/"; + char *isode_config_dir = "xd/duaconfig/"; + char *type_dir = "filterTypes/"; + char *read_File = "readTypes"; + char *type_defaults = "typeDefaults"; + + char Dish_Home[BUFSIZ]; + char read_Home[BUFSIZ]; + char type_Home[BUFSIZ]; + char type_defaults_Home[BUFSIZ]; + + char stroid_buf[BUFSIZ]; + + DIR *dir; + + struct dirent *dir_ent; + + char Read_in_Stuff[STRINGLEN]; + char *p, + *TidyString(), + *SkipSpace(), + *end; + + int count, n, num; + int tempints[MAXTYPES]; + + (void) strcpy(dua_help_dir, isodefile("xd/helpdir/", 0)); + + + if ((opt = ps_alloc (std_open)) == NULLPS) + fatal (-1,"ps_alloc failed"); + if (std_setup (opt,stdout) == NOTOK) + fatal (-1,"std_setup failed"); + + namestr[0] = '\0'; + *passwd = '\0'; + cache[0] = '\0'; + + (void) strcpy (Dish_Home, getenv ("HOME")); + (void) strcpy(read_Home, Dish_Home); + (void) strcpy(type_Home, Dish_Home); + + (void) strcat(Dish_Home, ptr); + (void) strcat(read_Home, config_dir); + (void) strcat(read_Home, read_File); + (void) strcat(type_Home, config_dir); + (void) strcat(type_Home, type_dir); + + if (!(dir = opendir(type_Home))) { + (void) strcpy(type_Home, isodefile(isode_config_dir,0)); + (void) strcat(type_Home, type_dir); + if(!(dir = opendir(type_Home))) { + (void) strcpy(type_Home, "./"); + (void) strcat(type_Home, isode_config_dir); + (void) strcat(type_Home, type_dir); + if(!(dir = opendir(type_Home))) { + (void) printf("Can't find directory %s!\n", type_dir); + quit(1); + } + } + } + + rewinddir(dir); + filt_num = 0; + while(dir_ent = readdir(dir)) { + if (!(strncmp(dir_ent->d_name, "Type_", 5))) { + file_names[filt_num] = + (char *) malloc((unsigned int) (strlen(dir_ent->d_name) + strlen(type_Home) + 2) ); + (void) strcpy(file_names[filt_num], type_Home); + (void) strcat(file_names[filt_num], dir_ent->d_name); + filt_num++; + } + } + (void) closedir(dir); + + if ((file = fopen (Dish_Home, "r")) == 0); + else { + while (fgets (Read_in_Stuff, STRINGLEN, file) != 0) { + p = SkipSpace (Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; /* ignore comments and blanks */ + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) + continue; /* ignore it */ + + *part2++ = '\0'; + part2 = TidyString(part2); + + if (strcmp (part1, "username") == 0) + (void) strcpy (namestr, part2); + else if (strcmp (part1, "password") == 0) + (void) strcpy (passwd, part2); + else if (lexequ (part1, "dsap") == 0) + (void) tai_string (part2); + else if (lexequ (part1, "isode") == 0) { + char * split; + if ((split = index (part2,' ')) != NULLCP) { + *split++ = 0; + (void) isodesetvar (part2,split,0); + } + } else if (strcmp (part1, "service") == 0) + new_service (part2); + } + isodexport (NULLCP); + (void) fclose(file); + } + + if (!(file = fopen(read_Home, "r"))) { + (void) strcpy(read_Home, isodefile(isode_config_dir,0)); + (void) strcat(read_Home, read_File); + if (!(file = fopen(read_Home, "r"))) { + (void) strcpy(read_Home, "./"); + (void) strcat(read_Home, isode_config_dir); + (void) strcat(read_Home, read_File); + if (!(file = fopen(read_Home, "r"))) { + (void) printf("Can't find read file (%s)!\n", read_Home); + quit(1); + } + } + } + load_oid_table("oidtable"); + + while(fgets(Read_in_Stuff, STRINGLEN, file) != 0) { + (void) strcpy(stroid_buf, get_strioid(Read_in_Stuff)); + if (*stroid_buf) { + if (!read_types) + read_types = as_comp_new(AttrT_new(stroid_buf), NULLAV, NULLACL_INFO); + else { + read_types2 = as_comp_new(AttrT_new(stroid_buf) ,NULLAV, NULLACL_INFO); + read_types = as_merge(read_types, read_types2); + } + } + } + (void) fclose(file); + + for (curr_filt = 0; curr_filt < filt_num; curr_filt++) { + if (!(file = fopen(file_names[curr_filt], "r"))) { + (void) printf("Can't find file %s!\n", (char *) file_names[curr_filt]); + quit(1); + } + filtvalue[curr_filt] = (char *) malloc(STRINGLEN); + *filtvalue[curr_filt] = '\0'; + + yyparse(); + (void) fclose(file); + } + filttype[curr_filt] = NULLCP; + for (count = 0; count < filt_num; count++) + free(file_names[count]); + + if (!(file = fopen(type_defaults_Home, "r"))) { + (void) strcpy(type_defaults_Home, isodefile(isode_config_dir,0)); + (void) strcat(type_defaults_Home, type_defaults); + if (!(file = fopen(type_defaults_Home, "r"))) { + (void) strcpy(type_defaults_Home, "./Xd/duaconfig/"); + (void) strcat(type_defaults_Home, type_defaults); + if (!(file = fopen(type_defaults_Home, "r"))) { + (void) fprintf(stderr, "Can't open typeDefaults file\n"); + quit(1); + } + } + } + + default_num = 0; + while (fgets (Read_in_Stuff, STRINGLEN, file) != 0) { + p = SkipSpace(Read_in_Stuff); + if (( *p == '#') || (*p == '\0')) + continue; + + part1 = p; + if ((part2 = index (p,':')) == NULLCP) + continue; + + end = part2 - 1; + while (isspace(*end)) end--; + *++end = '\0'; + + *part2++ = '\0'; + + while (isspace(*part2)) part2++; + end = part2; + + while (!isspace(*end) && *end != ',' && *end != ':') end++; + + count = 0; + while (*part2 != ':') { + n = 0; + while (n < filt_num && strncmp(filttype[n], part2, + (int) (end - part2))) n++; + + if (n == filt_num) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } else { + tempints[count] = n; + count++; + part2 = end; + while (!isalpha(*part2) && *part2 != ':' && part2 != '\0') part2++; + + if (*part2 == '\0') { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } + + if (*part2 != ':') { + while (!isalpha(*part2)) part2++; + end = part2; + while (!isspace(*end) && *end != ',' && + *end != ':' && *end != '\0') end++; + if (*end == '\0') { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } + } else end = part2; + } + } + + if (*end == ':') { + while(isspace(*++end)); + p = end; + while(!isspace(*++end)); + *end = '\0'; + + n = 0; + while (n < filt_num && strcmp(filttype[n], p)) n++; + + if (n == filt_num) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } else { + num = 0; + while (num < count && n != tempints[num]) num++; + if (num == count) { + (void) fprintf(stderr, "Parsing error in typeDefaults file!"); + quit(1); + } + } + + defaults[default_num] = n; + + levels[default_num] = malloc((unsigned int) (strlen(part1) + 1) ); + (void) strcpy(levels[default_num], part1); + available_types[default_num] = + (int *) malloc((unsigned int) (sizeof(int) * (count+1)) ); + + for (n = 0; n < count; n++) + available_types[default_num][n] = tempints[n]; + + available_types[default_num][n] = -1; + default_num++; + } + } + av_typeindx = available_types[0]; + typeindx = defaults[0]; +} + +cnnct_bind() +{ + struct ds_bind_arg bindarg; + struct ds_bind_arg bindresult; + struct ds_bind_error binderr; + extern char * dsa_address, + * myname; + extern char * tailfile; + FILE * fp; + char buf [BUFSIZ]; + + if (*passwd != 0) + (void) strcpy(bindpass,"******"); + else + bindpass[0] = '\0'; + /* set dsa_address */ + dsa_address = NULLCP; + /* read tailor file to get address */ + if( (fp = fopen(isodefile(tailfile,0), "r")) == (FILE *)NULL) { + (void) printf ("Cannot open tailor file %s\n",isodefile(tailfile,0)); + return; + } + while(fgets(buf, sizeof(buf), fp) != NULLCP) + if ( (*buf != '#') && (*buf != '\n') ) + (void) tai_string (buf); + + (void) fclose(fp); + + if (dsa_address == NULLCP) + dsa_address = myname; + + /* set password */ + if (bindpass[0] != 0) { + if (strcmp (bindpass,"******") != 0) + (void) strcpy (passwd,bindpass); + } else + passwd[0] = 0; + + /* now bind */ + bindarg.dba_version = DBA_VERSION_V1988; + if (passwd[0] == 0) { + bindarg.dba_passwd_len = 0; + bindarg.dba_passwd [0] = '\0'; + } else { + bindarg.dba_passwd_len = strlen (passwd); + (void) strcpy (bindarg.dba_passwd,passwd); + } + + bindarg.dba_dn = (*namestr == 0? NULLDN: str2dn(namestr)); + + if (ds_bind (&bindarg,&binderr,&bindresult) != DS_OK) { + (void) printf (binderr.dbe_type == DBE_TYPE_SECURITY? + "Bind security error - Check name and pasword.\n": + "Bind service error - Can't contact DSA!\n"); + quit(1); + } else { + user_name = bindarg.dba_dn; + (void) strcpy (buf, "TERM"); + if(local_dit && *local_dit) + (void) strcpy(base_path, local_dit); + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("bound ('%s' to '%s')",namestr,dsa_address)); +#endif +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("xd bound to directory")); +#endif + + make_friendly(friendly_base_path, base_path); + set_default_type(); + } + entry_number = 0; + back_buf_num = 0; + backseq = dnseq = NULLDS; +} + +rd_start() +{ + struct ds_read_arg read_arg; + struct ds_read_result result; + struct DSError error; + Entry read_entry; + + if (*friendly_base_path == 'T') { + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + return; + } + + + if (get_default_service (&read_arg.rda_common) != 0) { + xprint ("Default service error -> check your .quipurc\n"); + return ; + } + + read_arg.rda_eis.eis_allattributes = FALSE; + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + read_arg.rda_eis.eis_select = read_types; + + read_arg.rda_common.ca_servicecontrol.svc_options = 1; + read_arg.rda_object = (*friendly_base_path != 'T'? str2dn(base_path): NULLDN); + if ((read_entry = + local_find_entry (read_arg.rda_object, FALSE)) != NULLENTRY) { + read_entry->e_attributes = sort_attrs(read_entry->e_attributes); + read_print (as_print, (caddr_t) read_entry->e_attributes); + return; + } + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("read +%s",base_path)); +#endif + + if (ds_read (&read_arg,&error,&result) != DS_OK) { + /* deal with error */ + Clear_Results(); + xprint("Read error due to:\n"); + quipu_error(&error); + } else { + /* use data */ + if (result.rdr_entry.ent_attr == NULLATTR) { + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint("No attributes found! Sorry."); + return; + } + xprint("Result of look up ...\n"); + + if (result.rdr_common.cr_aliasdereferenced) + xprint("Alias dereferenced)\n"); + + result.rdr_entry.ent_attr = sort_attrs(result.rdr_entry.ent_attr); + cache_entry(&(result.rdr_entry), TRUE, TRUE); + read_print(as_print, (caddr_t) result.rdr_entry.ent_attr); + } +} + +back_start() +{ + if (!back_buf_num) { + xprint("You haven't been anywhere yet!\n"); + return; + } + element_num = back_buf_num; + showseq = backseq; +} + +widen() +{ + register char *str, *sptr; + int count = 0; + + str = get_from_seq(count+1, backseq); + while (count < back_buf_num && strcmp(str, base_path)){ + count++; + str = get_from_seq(count+1, backseq); + } + if (count == back_buf_num) { + add_seq(&backseq, base_path); + back_buf_num++; + } + + str = base_path; + if (*str != 'T') { + + for (sptr = str; *sptr != '\0'; sptr++) + if (*sptr == '@') str = sptr; + + sptr = str; + typetoggled = 0; + + if (str != base_path) { + if (*--sptr == ' ') + str = sptr; + *str = '\0'; + } else + (void) strcpy(base_path, "The World"); + + make_friendly(friendly_base_path, base_path); + rd_start(); + set_default_type(); + } +} + +set_default_type() +{ + int count; + DN base_name; + + if (*base_path != 'T') { + base_name = str2dn(base_path); + while (base_name->dn_parent) base_name = base_name->dn_parent; + for (count = 0; count < default_num && + strcmp(levels[count] ,base_name->dn_rdn->rdn_at-> + oa_ot.ot_stroid); + count++); + + if (count < default_num) { + av_typeindx = available_types[count]; + typeindx = defaults[count]; + } else { + av_typeindx = available_types[0]; + typeindx = defaults[0]; + } + } else { + for(count = 0; count < default_num && strcmp(levels[count], "@"); count++); + if (count < default_num) { + av_typeindx = available_types[count]; + typeindx = defaults[count]; + } else { + av_typeindx = available_types[0]; + typeindx = defaults[0]; + } + } + + make_friendly(friendly_base_path, base_path); + typetoggled = 0; + Set_Search_Type(filttype[typeindx]); /* change string in widget */ +} + +/* These are the functions called by the list level widgets */ + +list_start() +{ + struct ds_search_arg search_arg; + struct ds_search_result result; + struct DSError error; + + xprint("OK, listing."); + xprint("Chugging along....."); + + if (get_default_service (&search_arg.sra_common) != 0) { + xprint ("Default service error -> check your .quipurc\n"); + return ; + } + + search_arg.sra_common.ca_servicecontrol.svc_sizelimit = asizelimit; + search_arg.sra_common.ca_servicecontrol.svc_options = 1; + search_arg.sra_baseobject = (*base_path != 'T'? + str2dn (base_path): + NULLDN); + search_arg.sra_eis.eis_allattributes = FALSE; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + search_arg.sra_eis.eis_select = read_types; + search_arg.sra_subset = SRA_ONELEVEL; + + search_arg.sra_filter = filter_alloc(); + search_arg.sra_filter->flt_type = FILTER_NOT; + search_arg.sra_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_un.flt_un_filter = filter_alloc(); + search_arg.sra_filter->flt_un.flt_un_filter->flt_type = FILTER_ITEM; + search_arg.sra_filter->flt_un.flt_un_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_type + = FILTERITEM_EQUALITY; + + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un. + fi_un_ava.ava_type = AttrT_new("2.5.4.0"); + + search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item.fi_un. + fi_un_ava.ava_value = + str2AttrV("dsa", search_arg.sra_filter->flt_un.flt_un_filter-> + flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax); + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("search +%s,extent %d, val objectClass != dsa",base_path,search_arg.sra_subset)); +#endif + + + if (search_arg.sra_filter->flt_un.flt_un_filter->flt_un.flt_un_item. + fi_un.fi_un_ava.ava_value == NULLAttrV) { + xprint("No can do. Sorry!"); + } else if (ds_search (&search_arg,&error,&result) != DS_OK) { + /* deal with error */ + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint("Search error due to:\n"); + quipu_error(&error); + } else { + correlate_search_results (&result); + if (result.CSR_entries != NULLENTRYINFO) { + register EntryInfo *ptr; + + xprint ("Result of search ...\n"); + if (result.CSR_common.cr_aliasdereferenced) { + xprint ("(Alias dereferenced - object is "); + quipu_print (dn_print, (caddr_t) result.CSR_object); + dn_free (result.CSR_object); + xprint (")\n"); + } + + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + + for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; + ptr = ptr->ent_next) { + entry_number++; + dn2str ((caddr_t)ptr->ent_dn, goto_path); + add_seq (&dnseq, goto_path); + cache_entry (ptr,TRUE,TRUE); + } + + if (entry_number == 1) + get_listed_object(1); + + } else if (result.CSR_limitproblem != LSR_TIMELIMITEXCEEDED) { + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint("Nothing found. Sorry!"); + } + + if(result.CSR_limitproblem != LSR_NOLIMITPROBLEM) { + if(result.CSR_limitproblem == LSR_TIMELIMITEXCEEDED) { + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint("(Time limit exceeded)"); + } else + xprint("(Size limit exceeded)"); + } + entryinfo_free(result.CSR_entries, 0); + } + + filter_free(search_arg.sra_filter); +} + +rdn2str(ptr,cptr) +caddr_t ptr; +char * cptr; +{ + PS ps; + char buffer [RESBUF]; + + if ((ps = ps_alloc(str_open)) == NULLPS) { + return ; + } + if (str_setup(ps, buffer, RESBUF, 1) == NOTOK) { + return ; + } + rdn_print(ps, (RDN) ptr, READOUT); + + ps_free(ps); + *ps->ps_ptr = 0; + + (void) strcpy(cptr, buffer); +} + + +/* search ... */ + +srch_start() +{ + struct ds_search_arg search_arg; + struct ds_search_result result; + struct DSError error; + char *str = base_path; + + if (*mvalue == '\0') { + list_start(); + return; + } + + xprint("OK. Starting search.\n"); + + if (get_default_service (&search_arg.sra_common) != 0) { + xprint ("Default service error -> check your .quipurc\n"); + return ; + } + + search_arg.sra_common.ca_servicecontrol.svc_sizelimit = asizelimit; + search_arg.sra_common.ca_servicecontrol.svc_options = 1; + search_arg.sra_baseobject = (*base_path != 'T'? + str2dn (base_path): + NULLDN); + search_arg.sra_eis.eis_allattributes = FALSE; + search_arg.sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + search_arg.sra_eis.eis_select = read_types; + + while (*str != '\0' && *str != '@') str++; + + search_arg.sra_subset = ((*base_path != 'T' && *str == '@')? + SRA_WHOLESUBTREE: + SRA_ONELEVEL); + search_arg.sra_filter = + make_filter(filt_arr[typeindx]); + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("search +%s, extent %d, val %s",base_path,search_arg.sra_subset,mvalue)); +#endif + + + if(ds_search (&search_arg,&error,&result) != DS_OK) { + /* deal with error */ + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint(" Search error due to:\n "); + quipu_error(&error); + } else { + correlate_search_results (&result); + + if (result.CSR_entries != NULLENTRYINFO) { + register EntryInfo *ptr; + + if (result.CSR_common.cr_aliasdereferenced) { + xprint (" (Alias dereferenced - object is "); + quipu_print (dn_print, (caddr_t) result.CSR_object); + dn_free (result.CSR_object); + xprint (")\n"); + } + + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + for (ptr = result.CSR_entries; + ptr != NULLENTRYINFO; ptr = ptr->ent_next){ + entry_number++; + dn2str ((caddr_t) ptr->ent_dn, goto_path); + add_seq (&dnseq, goto_path); + cache_entry (ptr,TRUE,TRUE); + } + + if (entry_number == 1) + get_listed_object(1); + + } else if(result.CSR_limitproblem != LSR_TIMELIMITEXCEEDED) { + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint("Nothing found using current search parameters. Sorry!\n"); + } + + if(result.CSR_limitproblem != LSR_NOLIMITPROBLEM) + if(result.CSR_limitproblem == LSR_TIMELIMITEXCEEDED) { + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + xprint("(Time limit exceeded)"); + } else + xprint("(Size limit exceeded)"); + + entryinfo_free(result.CSR_entries, 0); + } + filter_free(search_arg.sra_filter); +} + +static dn2str (ptr,cptr) +caddr_t ptr; +char * cptr; +{ + PS ps; + char buffer [RESBUF]; + + if((ps = ps_alloc(str_open)) == NULLPS) return ; + + if(str_setup(ps, buffer, RESBUF, 1) == NOTOK) return ; + + dn_print(ps, (DN) ptr, EDBOUT); + *ps->ps_ptr = 0; + + ps_free (ps); + + (void) strcpy(cptr, buffer); +} + + +read_print(func,ptr) +int (*func) (); +caddr_t ptr; +{ + PS ps; + char buffer [RESBUF]; + char save; + int i, size; + register char *str, *sptr; + + if ((ps = ps_alloc (str_open)) == NULLPS) return ; + + if (str_setup (ps,buffer,RESBUF,1) == NOTOK) return ; + + (*func) (ps, ptr, READOUT); + *ps->ps_ptr = 0; + + ps_free(ps); + str = buffer ; + sptr = str; + size = strlen(buffer); + + free_seq(dnseq); + dnseq = NULLDS; + entry_number = 0; + + Switch_Off_Result_Update(); + + for (i = 0; i <= size; i++, sptr++) + if (*sptr == '\n' || *sptr == '\0') { + entry_number++; + save = *sptr ; + *sptr = '\0'; + xprint(str); + str = sptr+1; + *sptr = save; + } + + Switch_On_Result_Update(); +} + +quipu_print (func,ptr) +int (*func) (); /* assumes func (PS ,dataptr,(int) format); */ +caddr_t ptr; +{ + /* log info to pstream */ + PS ps; + char buffer [RESBUF]; + register char *str, *sptr; + char save; + + if ((ps = ps_alloc (str_open)) == NULLPS) return ; + + if (str_setup (ps,buffer,RESBUF,1) == NOTOK) return ; + + (*func) (ps,ptr,READOUT); + *ps->ps_ptr = 0; + + ps_free (ps); + + /* print in blocks of 100 bytes-larger seems too much for curses*/ + str = buffer; + do { + for (sptr = str; *sptr != '\0'; sptr++); + save = *sptr; + *sptr = 0; + xprint (str); + *sptr = save; + str = sptr; + } while (*sptr != '\0'); +} + +quipu_error (err) +struct DSError * err; +{ + PS ps; + char buffer [RESBUF]; + + if ((ps = ps_alloc(str_open)) == NULLPS) return ; + + if (str_setup (ps, buffer, RESBUF, 1) == NOTOK) return ; + ds_error(ps, err); + + *ps->ps_ptr = 0; + xprint(buffer); +} + +free_all() +{ + int count; + + free_seq(dnseq); + free_seq(backseq); + free_table(symtab); + for (count = 0; count < filt_num; count++) { + free_filt(filt_arr[count]); + free(filtvalue[count]); + free(filttype[count]); + } +} + +get_listed_object(entrynum) +int entrynum; +{ + int count = 0; + char *sptr, *str; + + if (entrynum > element_num) return; + + if (sptr = get_from_seq (entrynum, showseq)) { + + str = get_from_seq(count+1, backseq); + while (count < back_buf_num && strcmp(str, base_path)){ + count++; + str = get_from_seq(count+1, backseq); + } + + if (count == back_buf_num) { + add_seq(&backseq, base_path); + back_buf_num++; + } + + (void) strcpy(base_path, sptr); + make_friendly(friendly_base_path, base_path); + rd_start(); + typetoggled = 0; + set_default_type(); + } + *srchvalue = '\0'; +} + +make_friendly(fstr, str) +char *fstr; +register char *str; +{ + register char *end_ptr; + char save; + + *fstr = '\0'; + if (!strcmp(str, "The World")) { + (void) strcpy(fstr, str); + return; + } + + while (*str != '\0') { + while (*str != '=') str++; + while (*str == ' ') str++; + + end_ptr = ++str; + while (*end_ptr != '@' && *end_ptr != '\0') end_ptr++; + save = *end_ptr; + *end_ptr = '\0'; + if (*fstr == '\0') + (void) strcpy(fstr, str); + else + (void) strcat(fstr, str); + *end_ptr = save; + str = end_ptr; + if (*str != '\0') + (void) strcat(fstr, ", "); + } +} + + + +goto_addr() +{ + set_default_type(); + rd_start(); +} + +struct attrcomp * +sort_attrs(entry_attrs) +struct attrcomp *entry_attrs; +{ + struct attrcomp *last, *next, *curr, *first, *firstn; + + first = curr = entry_attrs; + firstn = last = next = 0; + + while (curr) + if (!strcmp("2.5.4.3", curr->attr_type->oa_ot.ot_stroid) || + !strcmp("2.5.4.4", curr->attr_type->oa_ot.ot_stroid) || + !strcmp("0.9.2342.19200300.100.1.3", + curr->attr_type->oa_ot.ot_stroid) || + !strcmp("0.9.2342.19200300.100.1.2", + curr->attr_type->oa_ot.ot_stroid) || + !strcmp("2.5.4.20", curr->attr_type->oa_ot.ot_stroid)) { + + if (first == curr) first = curr->attr_link; + + if (next) + next->attr_link = curr; + else + firstn = curr; + + next = curr; + + if (last) + last->attr_link = curr->attr_link; + + curr = curr->attr_link; + next->attr_link = 0; + } else { + last = curr; + curr = curr->attr_link; + } + + if (next) { + next->attr_link = first; + return firstn; + } else + return first; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/conf_read.y b/usr/src/contrib/isode/others/quipu/uips/xd/conf_read.y new file mode 100644 index 0000000000..407bc69045 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/conf_read.y @@ -0,0 +1,313 @@ +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/xd/RCS/conf_read.y,v 7.2 91/02/22 09:32:44 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/xd/RCS/conf_read.y,v 7.2 91/02/22 09:32:44 mrose Interim $ + */ + +/* + * $Log: conf_read.y,v $ + * Revision 7.2 91/02/22 09:32:44 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:50:23 mrose + * sync + * + * Revision 7.0 90/06/12 13:12:18 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:36 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:06 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:07 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/16 11:32:01 emsrdsm + * *** empty log message *** + * + * Revision 1.1 90/03/09 16:49:53 emsrdsm + * Initial revision + * + * Revision 1.1 90/03/09 12:14:12 emsrdsm + * Initial revision + * + * Revision 1.1 90/03/09 11:43:15 emsrdsm + * Initial revision + * + */ + +#include +#include +#include "quipu/util.h" +#include "filt.h" +#include "symtab.h" + +extern make_type(); +extern filt_struct *make_item_filter(); +extern filt_struct *link_filters(); +extern filt_struct *make_parent_filter(); +extern put_symbol_value(); + +extern FILE *file; +extern int curr_filt; +extern char **file_names; +extern table_entry symtab; +%} +%start type_spec + +%union { + filt_struct *filt; + char strval[255]; + int symbol; +} + +%token NUMBER NAME DEFAULT STRING OID AND OR NOT APPROX EQUAL ITEM + +%type filter filter_list assertion filter_item +%type filt_type match +%token NOT AND OR APPROX EQUAL SUBSTRING +%token '"' ':' '(' ')' +%token STRING OID +%type name default + +%% + type_spec : name filter {make_type($1, $2);} + ; + + name : NAME ':' STRING {(void) strcpy($$, $3);} + ; + + default : DEFAULT ':' STRING {(void) strcpy($$, $3);} + | {(void) strcpy($$, "\0");} + ; + + assertion : '(' filt_type filter filter filter_list ')' {$$ = make_parent_filter($2, $3, $4, $5);} + | '(' NOT filter ')' {$$ = make_parent_filter($2, $3, (filt_struct *) 0,(filt_struct *) 0);} + | filter_item {$$ = $1;} + ; + + filter_list : filter filter_list {$$ = link_filters($1, $2);} + | filter {$$ = $1;} + | {$$ = (filt_struct *) 0;} + ; + + filter : filter_item {$$ = $1;} + | assertion {$$ = $1;} + ; + + filter_item : '(' OID match STRING ')' {$$ = make_item_filter($2, $3, $4);} + ; + + match : APPROX {$$ = $1;} + | EQUAL {$$ = $1;} + | SUBSTRING {$$ = $1;} + ; + + filt_type : AND {$$ = $1;} + | OR {$$ = $1;} + ; +%% + +yylex() +{ + int c, count = 0; + char lexeme[255]; + + while(iswspace(c = getc(file))) + if (c == EOF) return(0); + + lexeme[count++] = c; + + switch(c) { + case '#': + while (getc(file) != '\n'); + return(yylex()); + + case '"': + count = 0; + while ((c = getc(file)) != '"') + lexeme[count++] = c; + lexeme[count] = '\0'; + (void) strcpy(yylval.strval, lexeme); + return STRING; + + case '$': + while (!iswspace((c = getc(file))) && !issymbol(c)) + lexeme[count++] = c; + lexeme[count] = '\0'; + put_symbol_value(symtab, lexeme+1, (char *) 0); + (void) strcpy(yylval.strval, lexeme); + return STRING; + + case '(': + return (int) c; + case ')': + return (int) c; + case ':': + return (int) c; + case '&': + yylval.symbol = AND; + return AND; + case '|': + yylval.symbol = OR; + return OR; + case '!': + yylval.symbol = NOT; + return NOT; + case '*': + lexeme[count] = '\0'; + (void) strcpy(yylval.strval, lexeme); + return STRING; + case '~': + if((lexeme[count] = getc(file)) == '=') { + yylval.symbol = APPROX; + return APPROX; + } + break; + case '%': + if((lexeme[count] = getc(file)) == '=') { + yylval.symbol = SUBSTRING; + return SUBSTRING; + } + + case '=': + yylval.symbol = EQUAL; + return EQUAL; + } + + while(!iswspace(c = getc(file)) && c != '\0' && !issymbol(c)) + if (c != EOF) + lexeme[count++] = c; + else + return(0); + + (void) fseek(file,(long) -1, 1); + + lexeme[count] = '\0'; + switch(*lexeme) { + case 'd': + case 'D': + if(!strcmp(lexeme, "default") || !strcmp(lexeme, "DEFAULT")) + return DEFAULT; + else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + + case 'n': + case 'N': + if(!strcmp(lexeme, "name") || !strcmp(lexeme, "NAME")) + return NAME; + else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + count = 0; + while (isdigit(lexeme[count]) || lexeme[count] == '.') count++; + if (lexeme[count] == '\0') { + (void) strcpy(yylval.strval, lexeme); + return OID; + } else { + (void) strcpy(yylval.strval, lexeme); + return STRING; + } + + default: + (void) strcpy(yylval.strval, lexeme); + return STRING; + } +} + +yyerror(str) +char *str; +{ + (void) fprintf(stderr, "%s: ", str); + (void) fprintf(stderr, "Parse error in -\n"); +} + +int +issymbol(c) +char c; +{ + switch(c) { + case '#': + return 1; + case '"': + return 1; + case '(': + return 1; + case ')': + return 1; + case ':': + return 1; + case '&': + return 1; + case '|': + return 1; + case '!': + return 1; + case '*': + return 1; + case '~': + return 1; + case '=': + return 1; + case '$': + return 1; + case '%': + return 1; + } + return 0; +} + +int +iswspace(c) +char c; +{ + switch(c) { + case ' ': + return 1; + case '\n': + return 1; + case '\t': + return 1; + } + return 0; +} + + + diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/dirtitle.h b/usr/src/contrib/isode/others/quipu/uips/xd/dirtitle.h new file mode 100644 index 0000000000..b8e62a48b2 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/dirtitle.h @@ -0,0 +1,227 @@ +#define stef_width 350 +#define stef_height 61 +static char stef_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x01, 0xe0, 0x7f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xff, 0x0f, 0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0x1f, 0xfc, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0x1f, 0xff, 0xfd, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0xbf, 0x7f, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x80, + 0xff, 0x3f, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xbe, 0xff, 0x0f, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x3f, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xfc, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x9f, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xfc, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xc3, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, + 0x01, 0x00, 0x3e, 0x00, 0x00, 0xfe, 0x07, 0x00, 0xf8, 0x07, 0x00, 0xfe, + 0x07, 0x00, 0x00, 0x7c, 0xc0, 0x07, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, + 0xef, 0x1f, 0x00, 0x3f, 0x00, 0xe0, 0x7f, 0xfe, 0x01, 0xc0, 0xff, 0x00, + 0x80, 0xff, 0x0f, 0x00, 0xf8, 0x07, 0x00, 0xff, 0x1f, 0x00, 0x80, 0xff, + 0xf9, 0x07, 0xe0, 0x0f, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x0f, 0x80, 0x3f, + 0x00, 0xf8, 0xff, 0xff, 0x01, 0xf8, 0xff, 0x00, 0xe0, 0xff, 0x1f, 0x00, + 0xfe, 0x03, 0xc0, 0xff, 0x7f, 0x00, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0x0f, + 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xdf, 0xff, 0x0f, 0x80, 0x3f, 0x00, 0xfc, 0xff, 0xff, + 0x01, 0xfc, 0xff, 0x00, 0xf0, 0xbf, 0x1f, 0x00, 0xff, 0x03, 0xe0, 0xff, + 0xff, 0x00, 0xf0, 0xff, 0xff, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, + 0xff, 0x07, 0xc0, 0x3f, 0x00, 0xfe, 0xfd, 0xff, 0x01, 0xfe, 0xf7, 0x00, + 0xf8, 0x8f, 0x1f, 0x80, 0xff, 0x01, 0xf0, 0xef, 0xff, 0x01, 0xf8, 0xf7, + 0xff, 0x07, 0xf0, 0x07, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xfc, 0x07, 0xc0, 0x1f, + 0x00, 0x7f, 0xfe, 0xf3, 0x00, 0xfe, 0xf9, 0x00, 0xf8, 0x87, 0x1f, 0x80, + 0xff, 0x01, 0xf0, 0xe7, 0xfb, 0x01, 0xfc, 0xf9, 0xcf, 0x03, 0xf8, 0x07, + 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x03, 0xf8, 0xc3, 0xe7, 0x1f, 0x3e, 0x3f, 0xfe, 0xf0, + 0x7f, 0xfe, 0xf8, 0xe0, 0xfb, 0x03, 0x80, 0x8f, 0xff, 0xe0, 0xfb, 0xe7, + 0xf3, 0xf9, 0xfc, 0xf8, 0xc3, 0xff, 0xf9, 0x03, 0xfe, 0xc3, 0x07, 0x00, + 0x00, 0x7e, 0xc0, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, + 0xfc, 0xe3, 0xe7, 0x0f, 0x3f, 0x1f, 0xff, 0xf0, 0x7f, 0x7e, 0xfe, 0xf0, + 0xfb, 0x01, 0xc0, 0x8f, 0xff, 0xf8, 0xfb, 0xe3, 0xff, 0xff, 0x7c, 0xfc, + 0xc3, 0xff, 0xfd, 0x03, 0xff, 0xe3, 0x07, 0x00, 0x00, 0xfe, 0xe0, 0xff, + 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfe, 0xf1, 0xe7, 0x8f, + 0x3f, 0x0f, 0x7f, 0xf0, 0x7f, 0xfe, 0x7f, 0xf8, 0xfb, 0x01, 0xe0, 0x0f, + 0x7f, 0xfc, 0xfb, 0xc1, 0xff, 0xff, 0x3c, 0xfc, 0xc1, 0xff, 0xfd, 0x81, + 0xff, 0xf1, 0x07, 0x00, 0x00, 0xff, 0xf8, 0xdf, 0x07, 0xff, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0xfe, 0xf1, 0xe3, 0x87, 0x1f, 0x80, 0x7f, 0xc0, + 0x1f, 0xfe, 0x3f, 0xff, 0xf9, 0x01, 0xe0, 0x07, 0x7f, 0xfe, 0xf9, 0xc1, + 0xff, 0x7f, 0x00, 0xfe, 0x01, 0x7f, 0xfc, 0xe1, 0xff, 0xf1, 0x03, 0x00, + 0x00, 0xff, 0xf8, 0xcf, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, + 0xff, 0xfc, 0xe1, 0xe7, 0x0f, 0x80, 0x3f, 0x00, 0x00, 0xfe, 0xdf, 0xff, + 0xf8, 0x03, 0xfc, 0x03, 0x3f, 0x7f, 0xf8, 0x83, 0xff, 0x0f, 0x00, 0xfe, + 0x00, 0x00, 0xfc, 0xf0, 0xff, 0xfe, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc7, + 0xef, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe7, 0xff, 0xff, 0xe0, 0xff, + 0x07, 0xc0, 0x3f, 0x00, 0x00, 0xfe, 0xf3, 0x7f, 0xf8, 0x0f, 0xff, 0x01, + 0xff, 0x3f, 0xf8, 0xef, 0x7f, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfc, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x81, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xff, 0xff, 0x7f, 0xe0, 0xff, 0x03, 0xc0, 0x1f, 0x00, + 0x00, 0xfc, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x00, 0xff, 0x1f, 0xf0, 0xff, + 0x1f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0xfe, 0xff, 0x80, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, + 0xff, 0x3f, 0xe0, 0xff, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xf8, 0xff, 0x03, + 0xf0, 0xff, 0x3f, 0x00, 0xfe, 0x0f, 0xc0, 0xff, 0x07, 0x00, 0x00, 0x7f, + 0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xf9, 0x07, 0xc0, 0x1f, + 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0xc0, 0xff, 0x0f, 0x00, + 0xfc, 0x01, 0x80, 0xff, 0x01, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf0, 0xdf, + 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf9, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/filt.c b/usr/src/contrib/isode/others/quipu/uips/xd/filt.c new file mode 100644 index 0000000000..7334a70d46 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/filt.c @@ -0,0 +1,278 @@ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/xd/RCS/filt.c,v 7.2 91/02/22 09:32:47 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/xd/RCS/filt.c,v 7.2 91/02/22 09:32:47 mrose Interim $ + */ + +/* + * $Log: filt.c,v $ + * Revision 7.2 91/02/22 09:32:47 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/27 08:45:57 mrose + * update + * + * Revision 7.0 90/06/12 13:10:49 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:40 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:10 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:11 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/16 11:29:41 emsrdsm + * *** empty log message *** + * + * Revision 1.1 90/03/09 16:48:58 emsrdsm + * Initial revision + * + * Revision 1.1 90/03/09 12:10:17 emsrdsm + * Initial revision + * + * Revision 1.1 90/03/09 11:36:42 emsrdsm + * Initial revision + * + */ + +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/entry.h" +#include "filt.h" +#include "y.tab.h" +#include "symtab.h" + +extern unsigned int curr_filt; +extern unsigned int filt_num; +extern unsigned int typeindx; +extern filt_struct *filt_arr[]; +extern char *filtvalue[]; +extern char *filttype[]; +extern char *default_arr[]; + +extern char svalue[], mvalue[]; + +make_type(name_val, filt) +char * name_val; +filt_struct * filt; +{ + filttype[curr_filt] = (char *) malloc((unsigned int) (strlen(name_val) + 1)); + (void) strcpy(filttype[curr_filt], name_val); + +/* if (default_val) { + default_arr[curr_filt] = + (char *) malloc((unsigned int) (strlen(default_val)+1)); + (void) strcpy(default_arr[curr_filt], default_val); + } else { + default_arr[curr_filt] = (char *) malloc((unsigned int) 2); + *default_arr[curr_filt] = '\0'; + }*/ + filt_arr[curr_filt] = filt; +} + +filt_struct * +make_item_filter(oid, match, value) +char *oid; +int match; +char *value; +{ + register filt_struct * filt = (filt_struct *) malloc(sizeof(filt_struct)); + + filt->flt_type = ITEM; + filt->next = 0; + + filt->fu_cont.item.fi_type = match; + filt->fu_cont.item.stroid = + (char *) malloc((unsigned int) (strlen(oid) + 1)); + (void) strcpy(filt->fu_cont.item.stroid, oid); + + if (*value == '*') filt->fu_cont.item.name = (char *) 0; + else { + filt->fu_cont.item.name = + (char *) malloc((unsigned int) (strlen(value) + 1)); + (void) strcpy(filt->fu_cont.item.name, value); + } + return filt; +} + +filt_struct * +link_filters(filt1, filt2) +filt_struct *filt1; +filt_struct *filt2; +{ + filt1->next = filt2; + return filt1; +} + +filt_struct * +make_parent_filter(filt_type, filt1, filt2, filt3) +int filt_type; +filt_struct * filt1; +filt_struct * filt2; +filt_struct * filt3; +{ + filt_struct * parent = (filt_struct *) malloc(sizeof(filt_struct)); + + switch (filt_type) { + + case NOT: + parent->flt_type = NOT; + parent->fu_cont.sub_filt = filt1; + parent->next = 0; + break; + + case AND: + parent->flt_type = AND; + parent->fu_cont.sub_filt = filt1; + filt1->next = filt2; + filt2->next = filt3; + parent->next = 0; + break; + + default: + parent->flt_type = OR; + parent->fu_cont.sub_filt = filt1; + filt1->next = filt2; + filt2->next = filt3; + parent->next = 0; + break; + } + + return parent; +} + +free_filt(filt) +filt_struct *filt; +{ + if (filt) { + free_filt(filt->next); + + if (filt->flt_type = ITEM) { + free(filt->fu_cont.item.stroid); + if (filt->fu_cont.item.name) free(filt->fu_cont.item.name); + } else + free_filt(filt->fu_cont.sub_filt); + + free((char *) filt); + } else + return; +} + +Filter +make_filter(filt) +filt_struct *filt; +{ + int type; + Filter rfilt, sfilt = filter_alloc(); + + if (!filt) + return 0; + + switch(filt->flt_type) { + + case ITEM: + sfilt->flt_type = FILTER_ITEM; + sfilt->flt_next = make_filter(filt->next); + + (void) strcpy(svalue, (filt->fu_cont.item.name? + filt->fu_cont.item.name: + mvalue)); + + type = filt->fu_cont.item.fi_type; + + switch(type) { + case APPROX: + case EQUAL: + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type = + AttrT_new(filt->fu_cont.item.stroid); + + if ((sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_value = + str2AttrV(svalue, + sfilt->flt_un.flt_un_item.fi_un.fi_un_ava.ava_type-> + oa_syntax)) == NULL) { + + rfilt = sfilt->flt_next; + sfilt->flt_next = NULLFILTER; + filter_free(sfilt); + return rfilt; + } + + if (type == EQUAL) + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_EQUALITY; + else + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; + + break; + + case SUBSTRING: + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_SUBSTRINGS; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_type = + AttrT_new(filt->fu_cont.item.stroid); + + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_initial = + NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_final = + NULLAV; + sfilt->flt_un.flt_un_item.fi_un.fi_un_substrings.fi_sub_any = + avs_comp_new(str2AttrV(svalue, + sfilt->flt_un.flt_un_item.fi_un. + fi_un_substrings.fi_sub_type-> + oa_syntax)); + break; + + default: + sfilt->flt_un.flt_un_item.fi_type = FILTERITEM_APPROX; + break; + } + return sfilt; + + + case AND: + sfilt->flt_type = FILTER_AND; + sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); + sfilt->flt_next = make_filter(filt->next); + return sfilt; + + + case OR: + sfilt->flt_type = FILTER_OR; + sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); + sfilt->flt_next = make_filter(filt->next); + return sfilt; + + + case NOT: + sfilt->flt_type = FILTER_NOT; + sfilt->flt_next = make_filter(filt->next); + sfilt->flt_un.flt_un_filter = make_filter(filt->fu_cont.sub_filt); + return sfilt; + + + default: + return NULLFILTER; + } +} diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/filt.h b/usr/src/contrib/isode/others/quipu/uips/xd/filt.h new file mode 100644 index 0000000000..09b2267728 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/filt.h @@ -0,0 +1,65 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/filt.h,v 7.1 91/02/22 09:32:48 mrose Interim $ */ +/* + $Log: filt.h,v $ + * Revision 7.1 91/02/22 09:32:48 mrose + * Interim 6.8 + * + * Revision 7.0 90/06/12 13:10:55 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:41 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:11 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:12 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:31 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:46 emsrssn + * Initial revision + * + * +*/ + +#ifndef FILT +#define FILT + +typedef struct stroid_list { + int fi_type; + char *stroid; + char *name; + } filt_item; + +typedef struct filter_struct { + int flt_type; + union ftype { + filt_item item; + struct filter_struct *sub_filt; + } fu_cont; + struct filter_struct *next; + } filt_struct; + +#endif diff --git a/usr/src/contrib/isode/others/rfa/Makefile b/usr/src/contrib/isode/others/rfa/Makefile new file mode 100644 index 0000000000..4a1d98cfa6 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/Makefile @@ -0,0 +1,268 @@ +############################################################################### +# +# RFA - Remote File Access +# +# Access and Management for a partial file system tree that exists +# at two sites either as master files or slave files +# +# Makefile +# +# Contributed by Oliver Wenzel, GMD Berlin, 1990 +# +# +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/rfa/RCS/Makefile,v 7.4 91/02/22 09:27:45 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.4 91/02/22 09:27:45 mrose +# Interim 6.8 +# +# Revision 7.3 91/01/14 13:54:20 mrose +# update +# +# Revision 1.1 91/01/04 16:11:05 ow +# Initial revision +# +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +PEPYPATH= -DPEPYPATH + +.SUFFIXES: .ry .py .c .o + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +LIBES = librfa.a $(LIBDIR)libisode$(LPP).a +LLIBS = $(ISODE)llib-lisode$(LPP) +HFILES = $(HDIR)rosy.h $(HDIR)rosap.h $(HDIR)acsap.h $(HDIR)psap2.h \ + $(HDIR)psap.h $(HDIR)ssap.h $(HDIR)isoaddrs.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h +RFAOBJS = ls.o dirname.o rfainfo.o sync.o rfa2fi.o getfile.o printerr.o\ + error.o tailor.o advise.o filemode.o +RFADOBJS= reqmaster.o filedata.o fileinfo.o dirname.o synctime.o \ + rfa2fi.o rfainfo.o error.o ls.o advise.o tailor.o filemode.o +LLOCKOBJS = rfainfo.o dirname.o tailor.o ls.o advise.o $(LIBES) + +ROS = ros. + +ROSY = $(BINDIR)/rosy +POSY = $(BINDIR)/posy +PEPY = $(BINDIR)/pepy + + +################################################################## +# Here it is... +################################################################## + +all: rfad rfa rfatime llock +inst-all: inst-rfad inst-rfa inst-rfatime inst-llock manuals inst-tailor +install: inst-all clean +lint: l-rfad l-rfa l-rfatime l-llock + +all-lpp:; $(MAKE) LPP=-lpp all +inst-lpp:; $(MAKE) LPP=-lpp ROS=lpp. inst-all +install-lpp:; $(MAKE) LPP=-lpp ROS=lpp. install +lint-lpp:; $(MAKE) LPP=-lpp lint + + +################################################################## +# llock +################################################################## + +inst-llock: $(BINDIR)llock + +$(BINDIR)llock: xllock + -cp $@ zllock + -rm -f $@ + -rm -f $(BINDIR)lunlock + cp xllock $@ + ln $@ $(BINDIR)lunlock + -@ls -gls $@ + -@echo "" + +llock: xllock + +xllock: llock.o $(LLOCKOBJS) + $(LDCC) $(LDFLAGS) -o $@ llock.o $(LLOCKOBJS) + +l-llock:; $(LINT) $(LFLAGS) llock.c \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################## +# rfatime +################################################################## + +inst-rfatime: $(SBINDIR)rfatime + +$(SBINDIR)rfatime: xrfatime + -cp $@ zrfatime + -rm -f $@ + cp xrfatime $@ + chown root $@ + chmod u+s $@ + -@ls -gls $@ + -@echo "" + +rfatime: xrfatime + +xrfatime: rfatime.o + $(LDCC) $(LDFLAGS) -o $@ rfatime.o $(LIBES) + +l-rfatime:; $(LINT) $(LFLAGS) rfatime.c \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################## +# rfad +################################################################## + +inst-rfad: $(SBINDIR)$(ROS)rfa + +$(SBINDIR)$(ROS)rfa: xrfad$(LPP) + -cp $@ z$(ROS)rfa + -rm -f $@ + cp xrfad$(LPP) $@ + chown root $@ + chmod u+s $@ + -@ls -gls $@ + -@echo "" + +rfad: xrfad$(LPP) + +xrfad$(LPP): rfad.o RFA-Rops.o ryresponder.o $(RFADOBJS) $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ rfad.o $(RFADOBJS) RFA-Rops.o \ + ryresponder.o $(LIBES) $(LSOCKET) + +l-rfad: RFA-ops.c RFA-C true + $(LINT) $(LFLAGS) -DPERFORMER rfad.c RFA-ops.c \ + ryresponder.c $(RFA-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +rfad.o: ryresponder.h RFA-ops.h RFA-types.h $(HFILES) $(HDIR)logger.h + +RFA-Rops.o: RFA-ops.c RFA-ops.h $(HFILES) + $(CC) $(CFLAGS) -DPERFORMER -c RFA-ops.c + mv RFA-ops.o $@ + +ryresponder.o: ryresponder.h $(HFILES) $(HDIR)tailor.h + + +################################################################## +# rfa +################################################################## + +inst-rfa: $(BINDIR)rfa$(LPP) + +$(BINDIR)rfa$(LPP): xrfa$(LPP) + -cp $@ zxrfa$(LPP) + -rm -f $@ + cp xrfa$(LPP) $@ + chown root $@ + chmod u+s $@ + -@ls -gls $@ + -@echo "" + +rfa: xrfa$(LPP) + +xrfa$(LPP): rfa.o RFA-Iops.o ryinitiator.o $(RFAOBJS) $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ rfa.o $(RFAOBJS) RFA-Iops.o \ + ryinitiator.o $(LIBES) $(LSOCKET) + +l-rfa: RFA-ops.c RFA-C true + $(LINT) $(LFLAGS) -DINVOKER rfa.c RFA-ops.c \ + ryinitiator.c $(RFA-C) RFA-stubs.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +rfa.o: RFA-ops.h RFA-types.h $(HFILES) + +RFA-Iops.o: RFA-ops.c RFA-ops.h $(HFILES) + $(CC) $(CFLAGS) -DINVOKER -c RFA-ops.c + mv RFA-ops.o $@ + +ryinitiator.o: $(HFILES) + + +################################################################ +# librfa +################################################################ + +librfa.a: RFA-O + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(RFA-O) + -@ls -l $@ + -@echo "RFA library built normally" + +RFA-O = RFA-[0-9]*.o +RFA-C = RFA-[0-9]*.c + +RFA-O: RFA-C + @$(MAKE) `/bin/ls $(RFA-C) | sed 's/\.c$$/.o/'` + -@touch $@ + +RFA-C: RFA-types.py $(PEPY) + -@rm -f $(RFA-C) $(RFA-O) + $(PEPY) -a PY_advise -m -A -b RFA $(PYFLAGS) RFA-types.py + -@touch $@ + +RFA-types.py: RFA-asn.py $(POSY) + $(POSY) -f -h -m -o $@ $(POFLAGS) RFA-asn.py + +RFA-types.h: RFA-types.py + +RFA-asn.py: rfa.ry $(ROSY) + $(ROSY) -m $(RYFLAGS) -o $@ rfa.ry + +RFA-ops.c: rfa.ry +RFA-ops.h: rfa.ry +RFA-stubs.c: rfa.ry + + +################################################################ +# manual pages +################################################################ + +MANUALS = rfad.8c rfa.1c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# tailoring file +################################################################ + +inst-tailor: $(ETCDIR)rfatailor + +$(ETCDIR)rfatailor: rfatailor + -mv $@ $(ETCDIR)rfatailor.old + cp rfatailor $@ + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a RFA* x* z* _* core + +true:; diff --git a/usr/src/contrib/isode/others/rfa/READ-ME b/usr/src/contrib/isode/others/rfa/READ-ME new file mode 100644 index 0000000000..3f772686a2 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/READ-ME @@ -0,0 +1,26 @@ +[ READ-ME - Mon Jan 14 13:52:06 1991 - Remote File Access - /mtr ] + + + RFA - Remote File Access - Contributed by Oliver Wenzel, GMD Berlin 1990 + + Access and Management for a partial file system tree that exists + at two sites, either as master files or slave files. + + See config.h for compile time options + + See file $(ETCDIR)/rfatailor for run-time configuration setup + + See file rfa.tr for a detailed description ([t|n]roff -ms rfa.tr). + See file rfa.ps for a PostScript version of rfa.tr + + + Comments to: + + **************************************************************************** + * Dipl.Inf. ******** Internet: wenzel%fokus.berlin.gmd.dbp.de@relay.cs.net * + *** Oliver Wenzel **** UUCP: wenzel%fokus.berlin.gmd.dbp.de@unido.uucp ** + ****** GMD - FOKUS ********* X.400: wenzel@fokus.berlin.gmd.dbp.de ****** + ********* D-1000 Berlin 12 ******* Phone: +49 03 254-232 **************** + ************ Hardenbergplatz 2 ********* FAX: +49 03 254-202 ************ + **************************************************************************** + diff --git a/usr/src/contrib/isode/others/rfa/advise.c b/usr/src/contrib/isode/others/rfa/advise.c new file mode 100644 index 0000000000..d5193a672e --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/advise.c @@ -0,0 +1,150 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * advise.c - log error messages + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/advise.c,v 7.3 91/02/22 09:27:48 mrose Interim $ + * + * $Log: advise.c,v $ + * Revision 7.3 91/02/22 09:27:48 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:23 mrose + * update + * + * Revision 1.1 91/01/04 16:01:23 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/advise.c,v 7.3 91/02/22 09:27:48 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include "manifest.h" +#include "logger.h" + +static LLog _pgm_log = { + "rfa.log", NULLCP, NULLCP, + LLOG_FATAL | LLOG_EXCEPTIONS, LLOG_FATAL, 100, + LLOGCLS | LLOGCRT | LLOGZER, NOTOK +}; +LLog *pgm_log = &_pgm_log; + + +void initLog(myname) + char *myname; +{ +/* if (isatty (fileno (stderr))) + ll_dbinit (pgm_log, myname); + else */ { + + static char myfile[BUFSIZ]; + + (void) sprintf (myfile, "%s.log", (strncmp (myname, "ros.", 4) + && strncmp (myname, "lpp.", 4)) + || myname[4] == NULL + ? myname : myname + 4); + pgm_log -> ll_file = myfile; + ll_hdinit (pgm_log, myname); + } +} + + +#ifndef lint +void adios (va_alist) +va_dcl +{ + char *what; + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_FATAL, ap); + + va_end (ap); + + cleanup (); + + _exit (1); +} +#else +/* VARARGS2 */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + +#ifndef lint +void advise (va_alist) +va_dcl +{ + int code; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + _ll_log (pgm_log, code, ap); + + va_end (ap); +} + +#else +/* VARARGS */ + +void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif + + + +#ifndef lint +void ryr_advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_NOTICE, ap); + + va_end (ap); +} +#else +/* VARARGS2 */ +void ryr_advise (what, fmt) +char *what, + *fmt; +{ + ryr_advise (what, fmt); +} +#endif + diff --git a/usr/src/contrib/isode/others/rfa/config.h b/usr/src/contrib/isode/others/rfa/config.h new file mode 100644 index 0000000000..29d657cc9c --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/config.h @@ -0,0 +1,72 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * Contributed by Oliver Wenzel 1990 + * + * config.h - installation dependant configuration + * + * $Header: /f/osi/others/rfa/RCS/config.h,v 7.3 91/02/22 09:27:49 mrose Interim $ + * + * $Log: config.h,v $ + * Revision 7.3 91/02/22 09:27:49 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:24 mrose + * update + * +Revision 1.1 91/01/04 16:25:12 ow +Initial revision + + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/*--- default root for RFA tree (can be changed at runtime) ---*/ +#define FS_BASE "/usr/something" + +/*--- dir where isotailor and .rfarc files are expected ---*/ +#define RFA_TAILDIR "/usr/local/isode/etc" + +/*--- number of secs. for sending the time during the timeSync operation ---*/ +#define SENDTIME_DELAY 1 + +/*--- default limit for filesize when compression of file shall occur. + (can be changed at runtime) ---*/ +#define COMPRESSLIMIT 4500 +/*--- Will be calculated as follows: + + C0 : time required to start compress process + U0 : time required to start compress process + C : time required to compress 1K data + U : time required to compress 1K data + T : time required to transfer 1K data + FC : factor by which the data size is reduced by compression + L : Limit when data should be transfered compressed + + FC * (C0 + U0) + L = --------------------------- + (FC - 1) * T - FC * (U + C) + + With: + + C0 = 1s + CU = 1s + C = 1/50s (1/100 on Sparc with load = 1) + U = 1/70s (1/140 on Sparc with load = 1) + T = 8/10 s (X.25) + FC = 2.5 + + then L = 4.48 Kbytes +---*/ diff --git a/usr/src/contrib/isode/others/rfa/dirname.c b/usr/src/contrib/isode/others/rfa/dirname.c new file mode 100644 index 0000000000..67c863336f --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/dirname.c @@ -0,0 +1,232 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * dirname.c : create local filenames + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/dirname.c,v 7.3 91/02/22 09:27:50 mrose Interim $ + * + * $Log: dirname.c,v $ + * Revision 7.3 91/02/22 09:27:50 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:25 mrose + * update + * + * Revision 1.1 91/01/04 16:01:47 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/dirname.c,v 7.3 91/02/22 09:27:50 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include "rfa.h" + +static char p[MAXPATHLEN]; +char *fsBase = FS_BASE; + +extern char *rindex(); +extern int errno; +int commandMode = 0; + +char *basename(fn) + char *fn; +{ + register char *f; + + if (f = rindex(fn,'/')) + return f+1; + else + return fn; +} + + +char *dirname(fn) + char *fn; +{ + static char buf[MAXPATHLEN]; + register char *f; + + strcpy(buf, fn); + if ((f = rindex(buf,'/')) && (f != buf)) { + + *f = '\0'; + return buf; + } else + return "/"; +} + + +char *makeFN(fn) +char *fn; +{ + return makeFN2("", fn); +} + +char *makeFN2(dir ,fn) +char *dir; +char *fn; +{ + register char *s = p; + + strcpy(s,fsBase); + s += strlen(fsBase); + if (*(s-1) != '/') + *(s++) = '/'; + while (*dir == '/') + dir++; + if (*dir != '\0') { + strcpy(s, dir); + s += strlen(dir); + } + if (*(s-1) != '/') + *(s++) = '/'; + + while (*fn == '/') + fn++; + strcpy(s, fn); + + return p; +} + + +char * getRelativeFN(fn) + char *fn; +{ + if (strncmp(fsBase, fn, strlen(fsBase))) + return NULL; + return fn + strlen(fsBase); +} + + +char *expandSymLinks(path) + char *path; +{ + static char exp[MAXPATHLEN]; + char *r; + + /*--- expand symbolic links in fn ---*/ + if (realpath(makeFN(path), exp, sizeof exp) == NULL) { + if (errno != ENOENT) { + sprintf(rfaErrStr,"%s - %s", sys_errname(errno),getRelativeFN(exp)); + return NULL; + } + } + if ((r = getRelativeFN(exp)) == NULL) { + sprintf(rfaErrStr, "%s not within RFA subtree", exp); + return NULL; + } + return r; +} + + +char *realPath3 (dir, path1, path2) + char *dir, *path1, *path2; +{ + register char *s, *s1, *rp; + static char realp[MAXPATHLEN]; + char givenp[MAXPATHLEN]; + + s = givenp; + strcpy(s, dir); + s += strlen(dir); + if (*path1) { + *(s++) = '/'; + strcpy(s, path1); + s += strlen(path1); + } + if (*path2) { + *(s++) = '/'; + strcpy(s, path2); + } + + rp = realp; + *(rp++) = '/'; + + for (s = givenp; *s;) { + while(*s == '/') + s++; + if (*s == '.') { + s1 = s+1; + if (*(s1) == '/') { + s += 2; + continue; + } + if (*s1 == '.' && ((*(s1+1) == '/')||(*(s1-1) == '\0'))) { + if ((rp - 1) != realp) { + for( rp -= 2; *rp != '/'; rp--) + ; + rp++; + } + s += 3; + continue; + } + } + for (; *s && *s != '/'; s++, rp++) + *rp = *s; + *(rp++) = *(s++); + } + *rp = '\0'; + + return realp; +} + + +char *realPath (dir, path) + char *dir, *path; +{ + return realPath3("", dir, path); +} + + +/*--------------------------------------------------------------*/ +/* getRfaContext */ +/*--------------------------------------------------------------*/ +char *getRfaContext(cwd, fn) + char *cwd, *fn; +{ + char *rp; + char buf[MAXPATHLEN]; + + if (*fn == '@') + rp = realPath(fsBase, fn+1); + else + if (*fn == '/') + rp = realPath("/", fn); + else + if(commandMode) { + (void)getwd(buf); + rp = realPath(buf, fn); + } else + rp = realPath3(fsBase, cwd, fn); + + if (strncmp(fsBase, rp, strlen(fsBase))) + return NULL; + + /*--- extract realtive path ---*/ + rp += strlen(fsBase); + + return rp; +} + + diff --git a/usr/src/contrib/isode/others/rfa/error.c b/usr/src/contrib/isode/others/rfa/error.c new file mode 100644 index 0000000000..8c35551dc2 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/error.c @@ -0,0 +1,151 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * error.c : functions for the various error types + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/error.c,v 7.3 91/02/22 09:27:52 mrose Interim $ + * + * $Log: error.c,v $ + * Revision 7.3 91/02/22 09:27:52 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:27 mrose + * update + * + * Revision 1.1 91/01/04 16:02:16 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/error.c,v 7.3 91/02/22 09:27:52 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include "ryresponder.h" /* for generic idempotent responders */ +#include "psap.h" /* for generic idempotent responders */ +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfa.h" + +/*--------------------------------------------------------------*/ +/* aux_error */ +/*--------------------------------------------------------------*/ +int aux_error (sd, err, param, rox, roi) +int sd, + err; +caddr_t param; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + if (RyDsError (sd, rox -> rox_id, err, param, ROS_NOPRIO, roi) == NOTOK) + ros_adios (&roi -> roi_preject, "ERROR"); + return OK; +} + + +/*--------------------------------------------------------------*/ +/* strerror */ +/*--------------------------------------------------------------*/ +int strerror (sd, err, str, rox, roi) +int sd, err; +char *str; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + struct type_RFA_Reason *qb; + int r; + + qb= str2qb(str, strlen(str), 1); + + r = aux_error (sd, err, (caddr_t)qb, rox, roi); + + qb_free(qb); + return r; +} + + +/*--------------------------------------------------------------*/ +/* syserror */ +/*--------------------------------------------------------------*/ +int syserror (sd, err, rox, roi) +int sd, err; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + extern int errno; + return strerror (sd, err, sys_errname (errno), rox, roi); +} + + +/*--------------------------------------------------------------*/ +/* error */ +/*--------------------------------------------------------------*/ +int error(sd, err, type, rox, roi) + int sd, err, type; + struct RoSAPinvoke *rox; + struct RoSAPindication *roi; +{ + if(type == NOTOK) + return strerror(sd, err, rfaErrStr, rox, roi); + else + return syserror(sd, err, rox, roi); +} + + +/*--------------------------------------------------------------*/ +/* errMsg */ +/*--------------------------------------------------------------*/ +char *errMsg(type) + int type; +{ + if(type == NOTOK) + return rfaErrStr; + else + return sys_errname(errno); +} + + + +/*--------------------------------------------------------------*/ +/* statusError */ +/*--------------------------------------------------------------*/ +int statusError (sd, reason, user, since, rox, roi) +int sd; +int reason; +char *user; +long since; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + struct type_RFA_StatusErrorParm se, *sep = & se; + + if((sep->reason = reason) == int_RFA_reason_locked) { + sep->user = str2qb(user, strlen(user), 1); + sep->since = (int)since; + } else { + sep->user = NULL; + sep->since = 0; + } + + return aux_error (sd, error_RFA_statusError, (caddr_t *)sep, rox, roi); +} + diff --git a/usr/src/contrib/isode/others/rfa/filedata.c b/usr/src/contrib/isode/others/rfa/filedata.c new file mode 100644 index 0000000000..285fa73ecb --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/filedata.c @@ -0,0 +1,252 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * filedata.c : operation to transfer the content of a file + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/filedata.c,v 7.1 91/02/22 09:27:56 mrose Interim $ + * + * $Log: filedata.c,v $ + * Revision 7.1 91/02/22 09:27:56 mrose + * Interim 6.8 + * + * Revision 7.0 91/01/14 13:52:45 mrose + * *** empty log message *** + * + * Revision 1.1 91/01/04 16:04:30 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/filedata.c,v 7.1 91/02/22 09:27:56 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include "ryresponder.h" /* for generic idempotent responders */ +#include "psap.h" /* for generic idempotent responders */ +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfainfo.h" +#include "rfa.h" + +/*-------------------------------------------------------------- + * spawn compress + *-------------------------------------------------------------*/ +int getCompressed(fn, qbp) + char *fn; + struct qbuf **qbp; +{ + static int p[2]; + int rc; + + if (pipe(p) == -1) { + advise(LLOG_EXCEPTIONS,NULLCP,"spawnCompress: pipe failed"); + return 0; + } + + switch (fork()) { + case -1: + advise(LLOG_EXCEPTIONS,NULLCP,"spawnCompress: fork failed"); + return 0; + break; + case 0: /* son */ + close(1); + close(p[0]); + if (dup2(p[1], 1) == -1) + exit(1); + execl("/usr/ucb/compress", "/usr/ucb/compress", "-c", fn, NULL); + advise(LLOG_EXCEPTIONS,NULLCP,"spawnCompress: exec failed %s", + sys_errname(errno)); + exit(1); + default: + break; + } + + close (p[1]); + + rc = fd2qb(p[0], qbp); + close (p[0]); + + return rc; +} + + +/*-------------------------------------------------------------- + * fd2qb - read data from fd and create qbuf list + *-------------------------------------------------------------*/ +int fd2qb(fd, qbp) + int fd; + struct qbuf **qbp; +{ + struct qbuf *qb; + int c, tot, head = 1; + char buf[BUFSIZ * 100]; + + tot = 0; + while ( c = read(fd, buf, sizeof(buf))) { + tot += c; + if (head) { + (*qbp) = str2qb(buf, c, 1); + head = 0; + } else { + qb = str2qb(buf, c, 0); + insque(qb, (*qbp)->qb_back); + } + } + return tot; +} + + +/*-------------------------------------------------------------- + * op_getFileData - get mastership of a file + *-------------------------------------------------------------*/ +op_getFileData (sd, ryo, rox, in, roi) +int sd; +struct RyOperation *ryo; +struct RoSAPinvoke *rox; +caddr_t in; +struct RoSAPindication *roi; +{ + struct type_RFA_GetFileDataArg *gfa = (struct type_RFA_GetFileDataArg *)in; + struct type_RFA_GetFileDataRes gfr; + struct RfaInfo *rfa, *rfalist; + char buf[BUFSIZ * 100]; + char *s, *fn; + int bytes = 0, rc, c, fd; + time_t v; + + if (rox -> rox_nolinked == 0) { + advise (LLOG_NOTICE, NULLCP, + "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", + sd, ryo -> ryo_name, rox -> rox_linkid); + return ureject (sd, ROS_IP_LINKED, rox, roi); + } + advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", + sd, ryo -> ryo_name); + + if((s = qb2str(gfa->filename)) == NULL) + return NOTOK_SYS; + + /*--- expand symlinks and get relative path ---*/ + if ((fn = expandSymLinks(s)) == NULL) { + free(s); + advise(LLOG_EXCEPTIONS,NULLCP,"getFileData: %s", rfaErrStr); + return strerror(sd, error_RFA_fileAccessError, rfaErrStr, rox, roi); + } + free(s); + + /*--- get file info (begin of critical region) ---*/ + if ((rc = getLockedRfaInfoList(dirname(fn), &rfalist,basename(fn))) != OK) { + return error(sd, error_RFA_fileAccessError, rc, rox, roi); + } + if ((rfa = findRfaInfo(basename(fn), rfalist)) == NULL) { + releaseRfaInfoList(dirname(fn), rfalist); + return strerror(sd, error_RFA_fileAccessError, "no such file",rox, roi); + } + + /*--- check if regular file ---*/ + if ((rfa->ri_mode & S_IFMT) != S_IFREG) { + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_NOTICE,NULLCP,"getFileData: not regular file %s", fn); + return statusError(sd, int_RFA_reason_notRegularFile, NULL,0L,rox,roi); + } + + /*--- see if we are slave for file ---*/ + if (IS_SLAVE(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_EXCEPTIONS,NULLCP,"getFileData: not master for %s", fn); + return statusError(sd, int_RFA_reason_notMaster, NULL, 0L, rox, roi); + } + + unlock_rfainfo(dirname(fn)); + + advise (LLOG_DEBUG, NULLCP, "getFileData: mv=%ld sv=%d", + rfa->ri_modTime, gfa->slaveVersion); + + /*--- see if proposed version is actual ---*/ + v = gfa->slaveVersion; + if (v > rfa->ri_modTime) { + freeRfaInfoList(rfalist); + advise(LLOG_EXCEPTIONS,NULLCP,"reqMaster: slave newer than master of %s" + , fn); + return statusError(sd, int_RFA_reason_slaveNewer, NULL,0L,rox,roi); + } + if (v == rfa->ri_modTime) { + gfr.mode = int_RFA_mode_actual; + gfr.data = NULL; + } else { + if (rfa->ri_size == 0) { + gfr.mode = int_RFA_mode_zero; + gfr.data = NULL; + } else { + /*--- get file data ---*/ + fd = 0; + if (rfa->ri_size > compLimit) { + /*--- open fd as stdout of background compress ---*/ + advise (LLOG_DEBUG, NULL,"getFileData: size=%d,send compressed", + rfa->ri_size); + gfr.mode = int_RFA_mode_compressed; + if ((bytes = getCompressed(makeFN(fn), &(gfr.data))) == 0) { + advise (LLOG_EXCEPTIONS,NULL,"getFileData: compress fails"); + } + } + if (bytes == 0) { + advise (LLOG_DEBUG, NULLCP, "getFileData: size=%d, send orig", + rfa->ri_size); + if ((fd = open (makeFN(fn), O_RDONLY)) == -1) { + advise(LLOG_EXCEPTIONS,NULLCP,"getFileData: can't open %s", + fn); + freeRfaInfoList(rfalist); + return syserror(sd, error_RFA_miscError, rox, roi); + } + gfr.mode = int_RFA_mode_data; + if ((bytes = fd2qb(fd, &(gfr.data))) == 0) { + advise (LLOG_EXCEPTIONS, NULLCP,"getFileData: read failed"); + freeRfaInfoList(rfalist); + close(fd); + return strerror(sd, error_RFA_miscError, + "can't read file", rox, roi); + } + close(fd); + } + advise (LLOG_DEBUG, NULLCP, "getFileData: send %d bytes", bytes); + } + } + gfr.fileinfo = rfa2fi(dirname(fn), rfa); + + /*--- return result ---*/ + if (RyDsResult (sd, rox->rox_id, (caddr_t)&gfr, ROS_NOPRIO, + roi) == NOTOK) + { + if (gfr.data) + qb_free(gfr.data); + freeRfaInfoList(rfalist); + free_RFA_FileInfo(gfr.fileinfo); + ros_adios (&roi -> roi_preject, "RESULT"); + } + if (gfr.data) + qb_free(gfr.data); + freeRfaInfoList(rfalist); + free_RFA_FileInfo(gfr.fileinfo); + + return OK; +} diff --git a/usr/src/contrib/isode/others/rfa/fileinfo.c b/usr/src/contrib/isode/others/rfa/fileinfo.c new file mode 100644 index 0000000000..88e0c20442 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/fileinfo.c @@ -0,0 +1,103 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * fileinfo.c : responder part of GetFileInfo operation + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/fileinfo.c,v 7.3 91/02/22 09:27:59 mrose Interim $ + * + * $Log: fileinfo.c,v $ + * Revision 7.3 91/02/22 09:27:59 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:31 mrose + * update + * + * Revision 1.1 91/01/04 16:04:56 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/fileinfo.c,v 7.3 91/02/22 09:27:59 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ryresponder.h" +#include "psap.h" +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfa.h" +#include "rfainfo.h" + +/*-------------------------------------------------------------- + * op_listDir - get list of fileinfos for directory + *-------------------------------------------------------------*/ +int op_listDir (sd, ryo, rox, in, roi) + int sd; + struct RyOperation *ryo; + struct RoSAPinvoke *rox; + caddr_t in; + struct RoSAPindication *roi; +{ + register struct type_RFA_FileName *arg = (struct type_RFA_FileName *) in; + struct type_RFA_FileInfoList *fi; + char *dir, *s; + struct RfaInfo *rfalist; + int rc; + + if (rox -> rox_nolinked == 0) { + advise (LLOG_NOTICE, NULLCP, + "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", + sd, ryo -> ryo_name, rox -> rox_linkid); + return ureject (sd, ROS_IP_LINKED, rox, roi); + } + advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", + sd, ryo -> ryo_name); + + s = qb2str(arg); + + /*--- expand symlinks and get relative path ---*/ + if ((dir = expandSymLinks(s)) == NULL) { + free(s); + advise(LLOG_EXCEPTIONS,NULLCP,"getFileInfo: %s", rfaErrStr); + return strerror(sd, error_RFA_fileAccessError, rfaErrStr, rox, roi); + } + free(s); + + if ((rc = getRfaInfoList(dir, &rfalist, NULL)) != OK) + return error(sd, error_RFA_fileAccessError, rc, rox, roi); + + /*--- convert to FileInfoList ---*/ + if ((fi = rfa2fil(dir, rfalist)) == NULL) + return syserror(sd, error_RFA_miscError, rox, roi); + + /*--- return result ----*/ + if (RyDsResult (sd, rox->rox_id, (caddr_t) fi, ROS_NOPRIO, roi) == NOTOK) + ros_adios (&roi -> roi_preject, "RESULT"); + free_RFA_FileInfoList(fi); + + return OK; +} + diff --git a/usr/src/contrib/isode/others/rfa/filemode.c b/usr/src/contrib/isode/others/rfa/filemode.c new file mode 100644 index 0000000000..524e8551dd --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/filemode.c @@ -0,0 +1,231 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * filemode.c : manipulate file owner, groups and access mode + * + * contributed by: Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/filemode.c,v 7.1 91/02/22 09:28:00 mrose Interim $ + * + * $Log: filemode.c,v $ + * Revision 7.1 91/02/22 09:28:00 mrose + * Interim 6.8 + * + * Revision 7.0 91/01/14 13:52:47 mrose + * *** empty log message *** + * + * Revision 1.1 91/01/04 16:05:06 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/filemode.c,v 7.1 91/02/22 09:28:00 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rfa.h" +#include "rfainfo.h" + + +static int runAsRoot = 0; /* we started with effective uid of root */ + +/*--------------------------------------------------------------*/ +/* initUserId */ +/* called when rfa or rfad is started. Even if */ +/* they are started with effective uid of root */ +/* they are running with eff. uid of user until */ +/* the eff. uid of root is REALLY needed (see */ +/* below) */ +/*--------------------------------------------------------------*/ +int initUserId(uid, gid, user) + int uid, gid; + char *user; +{ + if (geteuid() == 0) { + runAsRoot++; + if (setregid (gid, gid) < 0) { + sprintf (rfaErrStr, "Can't set group-id %d for %s", gid, user); + return NOTOK; + } + if(setreuid (-1, uid) < 0) { + sprintf (rfaErrStr, "Can't set user-id %d for %s", uid, user); + return NOTOK; + } + } + return OK; +} + + +/*--------------------------------------------------------------*/ +/* changeFileOwner */ +/*--------------------------------------------------------------*/ +int changeFileOwner(fn, rfa) + char *fn; + struct RfaInfo *rfa; +{ + struct group *gr; + struct passwd *pw; + int changedUID = 0; + int rc = OK; + + if ((doChgrp || doChown) && runAsRoot) + if (setreuid(-1, 0) == -1) + sprintf(rfaErrStr, "can't change owner/group of %s\n", fn); + else + changedUID++; + + if (doChgrp) + if ((gr = getgrnam(rfa->ri_group)) == NULL) { + sprintf(rfaErrStr, "can't change group to %s (invalid group)", + rfa->ri_group); + rc = NOTOK; + } else + if (chown(makeFN(fn), -1, gr->gr_gid) == -1) { + sprintf(rfaErrStr, "can't change group to %s (%s)", + rfa->ri_group, sys_errname(errno)); + rc = NOTOK; + } + if (doChown && runAsRoot) + if ((pw = getpwnam(rfa->ri_owner)) == NULL) { + sprintf(rfaErrStr, "can't change owner to %s (invalid user-name)", + rfa->ri_owner); + rc = NOTOK; + } else + if (chown(makeFN(fn), pw->pw_uid, -1) == -1) { + sprintf(rfaErrStr, "can't change owner to %s (%s)", + rfa->ri_owner, sys_errname(errno)); + rc = NOTOK; + } + + if (changedUID) + setreuid(-1, getuid()); + + return rc; +} + +/*--------------------------------------------------------------*/ +/* changeFileMode */ +/*--------------------------------------------------------------*/ +int changeFileMode(fn, mode, errmsg) + char *fn; + int mode; + char *errmsg; +{ + int changedUID = 0; + int rc = OK; + + if (runAsRoot) + if (setreuid(-1, 0) == -1) { + sprintf(rfaErrStr, "can't %s of file %s", errmsg, fn); + } else + changedUID++; + + /*-- clear set uid on execution bit --*/ + if (doClearSUID) + mode &= ~S_ISUID; + + if (chmod(makeFN(fn), mode & 07777) == -1) { + sprintf(rfaErrStr, "can't %s of file %s", errmsg, fn); + rc = NOTOK; + } + + if (changedUID) + setreuid(-1, getuid()); + return rc; +} + + +/*--------------------------------------------------------------*/ +/* makeFileReadOnly */ +/*--------------------------------------------------------------*/ +int makeFileReadOnly(fn, rfa) + struct RfaInfo *rfa; + char *fn; +{ + if (doChmod && (rfa->ri_mode & 0222)) { + rfa->ri_mode &= ~0222; + return changeFileMode(fn, rfa->ri_mode, "clear write permission"); + } + return OK; +} + +/*--------------------------------------------------------------*/ +/* makeFileReadWrite */ +/*--------------------------------------------------------------*/ +int makeFileReadWrite(fn, rfa) + struct RfaInfo *rfa; + char *fn; +{ + if (doChmod) { + rfa->ri_mode |= 0220; + return changeFileMode(fn, rfa->ri_mode, "set write permission"); + } + return OK; +} + +/*--------------------------------------------------------------*/ +/* changeTime - change local time if eff. uid is root */ +/*--------------------------------------------------------------*/ +int changeTime (dt) + time_t dt; +{ + struct timeval tv; + int rc = OK; + int changedUID = 0; + + if (runAsRoot) + if (setreuid(-1, 0) == -1) { + sprintf(rfaErrStr, "can't switch to user ID of ROOT"); + } else + changedUID++; + else { + sprintf (rfaErrStr, "can't set time myself, using 'rfatime'"); + return NOTOK; + } + + if (dt > 0) { + /*--- clock "jumps" forwards ---*/ + gettimeofday(&tv, NULL); + tv.tv_sec += dt; + if (settimeofday(&tv, NULL) == -1) { + sprintf(rfaErrStr, "can't set time : %s ", sys_errname(errno)); + rc = NOTOK; + } + } else { + tv.tv_sec = dt; + tv.tv_usec = 0L; + if (adjtime(&tv, NULL) == -1) { + sprintf(rfaErrStr, "can't set time : %s", sys_errname(errno)); + rc = NOTOK; + } + } + + if (changedUID) + setreuid(-1, getuid()); + + return rc; +} + diff --git a/usr/src/contrib/isode/others/rfa/getfile.c b/usr/src/contrib/isode/others/rfa/getfile.c new file mode 100644 index 0000000000..a361c85d09 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/getfile.c @@ -0,0 +1,246 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * getfile.c - get file content from remote + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/getfile.c,v 7.3 91/02/22 09:28:02 mrose Interim $ + * + * $Log: getfile.c,v $ + * Revision 7.3 91/02/22 09:28:02 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:34 mrose + * update + * + * Revision 1.1 91/01/04 16:06:19 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/getfile.c,v 7.3 91/02/22 09:28:02 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "logger.h" +#include "RFA-ops.h" +#include "RFA-types.h" +#include "rfa.h" +#include "rfainfo.h" +#include "tailor.h" + +extern FILE *out, *err; + +/*--------------------------------------------------------------*/ +/* getfile_aux */ +/*--------------------------------------------------------------*/ +int getfile_aux(fn, rfa, rmode) +char *fn; +struct RfaInfo *rfa; +int *rmode; +{ + struct type_RFA_GetFileDataRes *gfr; + struct type_RFA_GetFileDataArg *gfa; + int num, res, rc; + time_t ts, te; + + if (getConnection() != OK) + return NOTOK_REMOTE_ERROR; + + if ((gfa = (struct type_RFA_GetFileDataArg *) + malloc(sizeof(struct type_RFA_GetFileDataArg))) == NULL) + { + fprintf(err,"*** local error : no memory ***\n"); + return NOTOK_LOCAL_ERROR; + } + gfa->filename = str2qb(fn, strlen(fn), 1); + gfa->slaveVersion = rfa->ri_modTime; + + fprintf(err,"requesting from master..."); + fflush(err); + time(&ts); + if (invoke(operation_RFA_getFileData, (caddr_t) gfa, &gfr, &res) ==NOTOK) { + fprintf(err, "\n\t*** remote operation invocation failed ***\n"); + free_RFA_GetFileDataArg(gfa); + return NOTOK_REMOTE_ERROR; + } + free_RFA_GetFileDataArg(gfa); + if (res != RY_RESULT) { + fprintf(err, "failed\n"); + printError(res, gfr, &rc); + return rc; + } + + + /*-- set file characteristics in rfa --*/ + rfa->ri_mode = gfr->fileinfo->mode; + rfa->ri_modTime = gfr->fileinfo->modTime; + rfa->ri_size = gfr->fileinfo->size; + rfa->ri_owner = qb2str(gfr->fileinfo->user); + rfa->ri_group = qb2str(gfr->fileinfo->group); + if (IS_MASTER(gfr->fileinfo->status)) { + SET_STATUS(rfa->ri_status, RI_SLAVE); + SET_TRANSFER(rfa->ri_status, RI_TRANSFER(gfr->fileinfo->status)); + rfa->ri_mode &= ~0222; + } else { + SET_STATUS(rfa->ri_status, RI_UNREGISTERED); + SET_TRANSFER(rfa->ri_status, default_transfer); + } + + /*-- create the file --*/ + if ((rc = instfile(fn, gfr, rfa, &num)) != OK) { + free_RFA_GetFileDataRes(gfr); + return rc; + } + + time(&te); + te = (te - ts) ? te - ts : 1L; + switch (gfr->mode) { + case int_RFA_mode_compressed: + fprintf(err, "transfered compressed\n\t(%2.1f Kbytes in %d sec, ", + (float)(gfr->fileinfo->size) / 1024, te); + fprintf(err, "%2.1f Kbytes/s, %2.1f%% compression)\n", + (float)(gfr->fileinfo->size) / (float)te / 1024, + (float)((gfr->fileinfo->size - num) * 100) / + (float)(gfr->fileinfo->size + 1)); + break; + case int_RFA_mode_actual: + fprintf(err, "local file up-to-date\n"); + break; + case int_RFA_mode_zero: + fprintf(err, "file is empty\n"); + break; + default: + fprintf(err,"transfered\n\t(%2.1f Kbytes in %d sec, %2.1f Kbytes/s)\n", + (float)(gfr->fileinfo->size) / 1024, te, + (float)(gfr->fileinfo->size) / (float)te / 1024 ); + } + + /*--- set file access mode bits ---*/ + if (changeFileMode(fn, rfa->ri_mode, "set permissions") != OK) + fprintf(err, "\t*** %s ***\n", rfaErrStr); + if (changeFileOwner(fn, rfa) != OK) + fprintf(err, "\t*** %s ***\n", rfaErrStr); + + *rmode = gfr->fileinfo->mode; + free_RFA_GetFileDataRes(gfr); + return OK; +} + + +/*--------------------------------------------------------------* + * instfile - install file + *--------------------------------------------------------------*/ +int instfile(fn, gfr, rfa, nump) + char *fn; + struct type_RFA_GetFileDataRes *gfr; + struct RfaInfo *rfa; + int *nump; +{ + time_t tt[2]; + char fnbak[512]; + char fnz[512]; + char buf[BUFSIZ]; + struct qbuf *qp; + FILE *f; + struct stat st; + + if (gfr->mode == int_RFA_mode_actual) + return OK; + + /*--- save old file ---*/ + sprintf(fnbak, "%s.bak", makeFN(fn)); + rename(makeFN(fn), fnbak); + + /*--- open new file ---*/ + if ((f = fopen(makeFN(fn), "w")) == NULL) { + fprintf(err, "failed\n\t*** local error : open of %s failed ***\n", fn); + unlink (makeFN(fn)); + rename(fnbak, makeFN(fn)); + return NOTOK_LOCAL_ERROR; + } + + /*--- write new file with data in result ---*/ + if (gfr->mode != int_RFA_mode_zero) { + *nump = 0; + for (qp = gfr->data->qb_forw; qp != gfr->data; qp = qp->qb_forw) { + *nump += qp->qb_len; + if (fwrite(qp->qb_data, 1, qp->qb_len, f) != qp->qb_len) { + fprintf(err, "failed\n\t*** local error : write of %s failed ***\n", + fn); + fclose(f); + unlink (makeFN(fn)); + rename(fnbak, makeFN(fn)); + return NOTOK_LOCAL_ERROR; + } + } + } + fclose(f); + + /*--- see if new file is compressed ---*/ + if (gfr->mode == int_RFA_mode_compressed) { + sprintf(fnz, "%s.Z", makeFN(fn)); + rename (makeFN(fn), fnz); + sprintf(buf, "exec uncompress %s", fnz); + if (system(buf) != 0) { + fprintf(err, "failed\n\t*** local error : can't uncompress %s ***\n" , fn); + unlink (fnz); + rename(fnbak, makeFN(fn)); + return NOTOK_LOCAL_ERROR; + } + } + + /*--- check size of transfered file ---*/ + if (stat(makeFN(fn),&st) == -1) { + fprintf(err, + "failed\n\t*** local error : can't stat transfered file ***\n"); + unlink (makeFN(fn)); + rename(fnbak, makeFN(fn)); + return NOTOK_LOCAL_ERROR; + } + if (st.st_size != gfr->fileinfo->size) { + fprintf(err, "failed\n\t*** wrong size after transfer ***\n"); + unlink (makeFN(fn)); + rename(fnbak, makeFN(fn)); + return NOTOK_LOCAL_ERROR; + } + + /*--- set time of file ---*/ + tt[0] = gfr->fileinfo->modTime; + tt[1] = gfr->fileinfo->modTime; + if (utime(makeFN(fn), tt) == -1) { + fprintf(err, "failed\n\t*** local error : can't set time of %s ***\n", + fn); + unlink (makeFN(fn)); + rename(fnbak, makeFN(fn)); + return NOTOK_LOCAL_ERROR; + } + + /*--- remove old file ---*/ + if(!backup) + unlink(fnbak); + + return OK; +} + diff --git a/usr/src/contrib/isode/others/rfa/llock.c b/usr/src/contrib/isode/others/rfa/llock.c new file mode 100644 index 0000000000..97bfcc7b1f --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/llock.c @@ -0,0 +1,271 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * llock.c : do a local lock if possible + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/llock.c,v 7.3 91/02/22 09:28:04 mrose Interim $ + * + * $Log: llock.c,v $ + * Revision 7.3 91/02/22 09:28:04 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:36 mrose + * update + * + * Revision 1.1 91/01/04 16:06:33 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/llock.c,v 7.3 91/02/22 09:28:04 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "logger.h" +#include "rfa.h" +#include "rfainfo.h" + +extern char *fsBase; +extern char *strtok(); +extern char *getRfaContext(); +extern char *isodetcpath; +extern int commandMode; +extern char *sys_errname(); +extern char *strdup(); + +char *myname; +int connected = 0; +FILE *err, *out; +char cwd_remote[512]; +int interactive = 1; +int retcode; + + +cleanup() {} + +/*--------------------------------------------------------------*/ +/* errMsg */ +/*--------------------------------------------------------------*/ +char *errMsg(type) + int type; +{ + if(type == NOTOK) + return rfaErrStr; + else + return sys_errname(errno); +} + +/*--------------------------------------------------------------*/ +/* getLocalFileRfaInfo */ +/*--------------------------------------------------------------*/ +int getLocalRfaInfo(fn, rfap, rfalp, reg) + char **fn; + struct RfaInfo **rfap, **rfalp; + int reg; +{ + int rc; + + + /*--- expand symbolic links in fn ---*/ + if((*fn = getRfaContext(cwd_remote, *fn)) == NULL) { + fprintf(err, + "*** local file access error : not within RFA subtree %s ***\n" + , fsBase); + return(NOTOK_OUTOFSUBTREE); + } + if ((*fn = expandSymLinks(*fn)) == NULL) { + fprintf(err, "*** local file access error : %s ***\n", rfaErrStr); + return(NOTOK_OUTOFSUBTREE); + } + + /*--- get file Info ---*/ + if ((rc = getLockedRfaInfoList(dirname(*fn), rfalp, basename(*fn))) != OK) { + fprintf(err, + "*** local file access error : can't read %s/.rfainfo (%s) ***\n", + dirname(*fn), errMsg(rc)); + return(NOTOK_FILEACCESS); + } + + if ((*rfap = findRfaInfo(basename(*fn), *rfalp)) == NULL) { + releaseRfaInfoList(*fn,*rfalp); + *rfalp = NULL; + fprintf(err,"*** local file access error : %s does not exist ***\n", + *fn); + return(NOTOK_FILEACCESS); + } + + /*--- check if regular file ---*/ + if (reg) + if (((*rfap)->ri_mode & S_IFMT) != S_IFREG) { + releaseRfaInfoList(*fn,*rfalp); + fprintf(err," *** status error : not a regular file ***\n"); + *rfalp = NULL; + return NOTOK_NOTREGULAR; + } + + return OK; +} + + +/*--------------------------------------------------------------*/ +/* unlockFile */ +/*--------------------------------------------------------------*/ +do_lunlock(fn) + char *fn; +{ + int rc; + struct RfaInfo *rfalist, *rfa; + + /*--- get file Info ---*/ + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 1)) != OK) + return rc; + + /*--- check if we are master ---*/ + if (IS_SLAVE(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** local file %s is slave version ***\n", fn); + return NOTOK_IS_SLAVE; + } + if (!IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** local file %s not locked ***\n", fn); + return NOTOK_NOTLOCKED; + } + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + rfa->ri_lcksince = NULL; + free(rfa->ri_lckname); + rfa->ri_lckname = "NONE"; + + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, "*** local file access error : %s ***\n", errMsg(rc)); + return NOTOK_FILEACCESS; + } + releaseRfaInfoList(dirname(fn), rfalist); + return OK; +} + + +/*--------------------------------------------------------------*/ +/* lockFile */ +/*--------------------------------------------------------------*/ +do_llock(fn) + char *fn; +{ + int res, rc; + struct RfaInfo *rfalist, *rfa; + + /*--- get file Info ---*/ + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 1)) != OK) + return rc; + + /*--- check if we are master ---*/ + if (IS_MASTER(rfa->ri_status) || IS_UNREGISTERED(rfa->ri_status)) { + if (IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file already locked by %s since %s ***\n", + rfa->ri_lckname, shortTime(&(rfa->ri_lcksince))); + return NOTOK_LOCKED; + } + SET_LOCKINFO(rfa->ri_status, RI_LOCKED); + rfa->ri_lckname = strdup(getenv("USER")); + (void)time(&(rfa->ri_lcksince)); + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + return NOTOK_FILEACCESS; + } + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "locked file %s\n",fn); + return OK; + } + + /*-- here we will need help from Big-Brother "rfa" --*/ + return NOTOK_LOCAL_LOCK; +} + + +main (ac, av) +int ac; +char **av; +{ + char c, *cwd, buf[BUFSIZ]; + char *cmd=NULL; + int rc; + + myname = av[0]; + + out = stdout; + err = stderr; + + initLog(myname); + + if (ac < 2) { + fprintf(stderr, "USAGE: %s filename [-q]\n", basename(myname)); + exit (1); + } + if (ac > 2 && strcmp(av[2], "-q") == 0) + interactive = 0; + + /*--- rfa tailoring ---*/ + sprintf(buf, "%s/rfatailor", isodetcpath); + if (tailor(buf) != OK) { + fprintf(stderr, "*** tailoring %s - %s ***\n", buf, rfaErrStr); + exit(1); + } + sprintf(buf, "%s/rfatailor", RFA_TAILDIR); + if (tailor(buf) != OK) { + fprintf(stderr, "*** tailoring %s - %s ***\n", buf, rfaErrStr); + exit(1); + } + sprintf(buf,"%s/.rfarc", getenv("HOME")); + if (tailor(buf) != OK) { + fprintf(stderr, "*** tailoring %s - %s ***\n", buf, rfaErrStr); + exit(1); + } + + /*--- init cwd ---*/ + (void)getwd(buf); + if (strncmp(buf, fsBase, strlen(fsBase)) == 0) + strcpy(cwd_remote, buf + strlen(fsBase)); + + interactive = 0; + commandMode = 1; + if (strcmp(basename(myname), "llock") == 0) + rc = do_llock(av[1]); + else + rc = do_lunlock(av[1]); + + if (interactive && (rc == 2)) + fprintf(stderr,"*** can't LOCK locally, must use RFA command ***\n"); + + exit (rc); +} + + + diff --git a/usr/src/contrib/isode/others/rfa/ls.c b/usr/src/contrib/isode/others/rfa/ls.c new file mode 100644 index 0000000000..6e2d17e037 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/ls.c @@ -0,0 +1,144 @@ +/* + * RFA - Remote File Access + /* + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * ls.c : prepare file info in a "ls" style + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/ls.c,v 7.3 91/02/22 09:28:06 mrose Interim $ + * + * $Log: ls.c,v $ + * Revision 7.3 91/02/22 09:28:06 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:37 mrose + * update + * + * Revision 1.1 91/01/04 16:06:44 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/ls.c,v 7.3 91/02/22 09:28:06 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include "RFA-types.h" +#include "rfa.h" +#include "rfainfo.h" + +struct pair { + u_short val; + char *s; +}; + +static struct pair ftype[] = { {S_IFIFO, "?"}, { S_IFCHR, "c" }, {S_IFDIR, "d"}, + {S_IFBLK, "b"}, { S_IFREG, "-" }, {S_IFLNK, "l"}, + {S_IFSOCK, "s"}, { 0, NULL }}; + +static struct pair facc[] = { { 01, "--x" }, { 02, "-w-" }, { 03, "-wx" }, + { 04, "r--" }, { 05, "r-x" }, { 06, "rw-" }, + { 07, "rwx" }, { 00, "---" } }; + +static void mode2str(m, mstr) + u_short m; + char *mstr; +{ + u_short v; + struct pair *pp; + + v = m & S_IFMT; + for (pp = ftype; pp->s; pp++) + if (v == pp->val) { + strcat(mstr, pp->s); + break; + } + v = (m & 0700) >> 6; + for (pp = facc; pp->s; pp++) + if (v == pp->val) { + strcat(mstr, pp->s); + break; + } + if (m & S_ISUID) + *(mstr + strlen(mstr) - 1) = 's'; + v = (m & 070) >> 3; + for (pp = facc; pp->s; pp++) + if (v == pp->val) { + strcat(mstr, pp->s); + break; + } + if (m & S_ISGID) + *(mstr + strlen(mstr) - 1) = 's'; + v = m & 07; + for (pp = facc; pp->s; pp++) + if (v == pp->val) { + strcat(mstr, pp->s); + break; + } +} + +char *shortTime(t) + long *t; +{ + char *s; + + s = ctime(t); + + *(rindex(s, ':')) = '\0'; + + s+=4; + return s; +} + + +char *rfa2ls(rfa) + struct RfaInfo *rfa; +{ + static char buf[512], *bp; + long t; + + *buf = '\0'; + bp = buf; + + mode2str(rfa->ri_mode, bp); + bp += strlen(bp); + + sprintf(bp, " %3.3s", status2str(rfa->ri_status)); + bp += strlen(bp); + + if(IS_LOCKED(rfa->ri_status)) { + sprintf(bp, " lockby %-10s %8d", rfa->ri_lckname, rfa->ri_size); + } else + sprintf(bp, " %-8s %-8s %8d", rfa->ri_owner, rfa->ri_group, + rfa->ri_size); + bp += strlen(bp); + + sprintf(bp, " %12s", shortTime(&(rfa->ri_modTime))); + bp += strlen(bp); + sprintf(bp, " %s", rfa->ri_filename); + if ((rfa->ri_mode & S_IFMT) == S_IFLNK) { + bp += strlen(bp); + sprintf(bp, " -> %s", rfa->ri_lnkName); + } + + return buf; +} + diff --git a/usr/src/contrib/isode/others/rfa/make b/usr/src/contrib/isode/others/rfa/make new file mode 100644 index 0000000000..1ec8feb7ed --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M ARCH=`arch` TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/rfa/printerr.c b/usr/src/contrib/isode/others/rfa/printerr.c new file mode 100644 index 0000000000..09dd552246 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/printerr.c @@ -0,0 +1,113 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * printerr.c - print error message for protocol defined errors + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/printerr.c,v 7.3 91/02/22 09:28:09 mrose Interim $ + * + * $Log: printerr.c,v $ + * Revision 7.3 91/02/22 09:28:09 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:40 mrose + * update + * + * Revision 1.1 91/01/04 16:06:52 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/printerr.c,v 7.3 91/02/22 09:28:09 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfa.h" + +extern FILE *err; +extern char *shortTime(); + + +/*--------------------------------------------------------------*/ +/* Print Error */ +/*--------------------------------------------------------------*/ +printError(error, param, rc) + int error; + caddr_t *param; + int *rc; +{ + struct RyError *rye; + time_t t; + struct type_RFA_StatusErrorParm *se = + (struct type_RFA_StatusErrorParm *)param; + + switch(error) { + case error_RFA_miscError: + printf("*** remote error : %s ***\n", qb2str(param)); + *rc = 3; + break; + case error_RFA_fileAccessError: + printf("*** remote file access error : %s ***\n", qb2str(param)); + *rc = 4; + break; + case error_RFA_statusError: + switch (se->reason) { + case int_RFA_reason_notMaster: + fprintf(err,"*** status error : remote site is not master ***\n"); + *rc = 10; + break; + case int_RFA_reason_locked: + t = se->since; + fprintf(err,"*** status error : locked at remote site by %s since %s ***\n", qb2str(se->user), shortTime(&t)); + *rc = 11; + break; + case int_RFA_reason_notRegistered: + fprintf(err, "*** status error : file not registered at remote site ***\n"); + *rc = 12; + break; + case int_RFA_reason_notWritable: + fprintf(err,"*** status error : file not writable at remote site ***\n"); + *rc = 13; + break; + case int_RFA_reason_wrongVersion: + fprintf(err, "*** status error : wrong version ***\n"); + *rc = 14; + break; + case int_RFA_reason_notRegularFile: + fprintf(err,"*** status error : not a regular file ***\n"); + *rc = 16; + break; + case int_RFA_reason_slaveNewer: + fprintf(err,"*** status error : local slave version is newer than remote master ***\n"); + *rc = 17; + break; + default: + fprintf(err,"*** status error : unknown error (%d) ***\n", + se->reason); + *rc = 19; + } + break; + default: + fprintf(err, "*** unknown error (%d) ***\n", error); + *rc = 2; + } +} + diff --git a/usr/src/contrib/isode/others/rfa/reqmaster.c b/usr/src/contrib/isode/others/rfa/reqmaster.c new file mode 100644 index 0000000000..975eefbf87 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/reqmaster.c @@ -0,0 +1,196 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * reqmaster.c : responder operation to transfer mastership for file + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/reqmaster.c,v 7.3 91/02/22 09:28:10 mrose Interim $ + * + * $Log: reqmaster.c,v $ + * Revision 7.3 91/02/22 09:28:10 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:41 mrose + * update + * + * Revision 1.1 91/01/04 16:07:02 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/reqmaster.c,v 7.3 91/02/22 09:28:10 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ryresponder.h" /* for generic idempotent responders */ +#include "psap.h" /* for generic idempotent responders */ +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfa.h" +#include "rfainfo.h" + +/*-------------------------------------------------------------- + * op_reqMaster - get mastership of a file + *-------------------------------------------------------------*/ +op_requestMaster (sd, ryo, rox, in, roi) +int sd; +struct RyOperation *ryo; +struct RoSAPinvoke *rox; +caddr_t in; +struct RoSAPindication *roi; +{ + register struct type_RFA_RequestMasterArg *rma = + (struct type_RFA_RequestMasterArg *) in; + struct type_RFA_RequestMasterRes rmr; + struct RfaInfo *rfalist, *rfa; + char *s; + time_t t; + char buf[BUFSIZ]; + char *fn; + int rc; + + if (rox -> rox_nolinked == 0) { + advise (LLOG_NOTICE, NULLCP, + "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", + sd, ryo -> ryo_name, rox -> rox_linkid); + return ureject (sd, ROS_IP_LINKED, rox, roi); + } + advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", + sd, ryo -> ryo_name); + + if((s = qb2str(rma->filename)) == NULL) + return NOTOK_SYS; + + /*--- expand symlinks and get relative path ---*/ + if ((fn = expandSymLinks(s)) == NULL) { + free(s); + advise(LLOG_EXCEPTIONS,NULLCP,"reqMaster: %s", rfaErrStr); + return strerror(sd, error_RFA_fileAccessError, rfaErrStr, rox, roi); + } + free(s); + + /*--- get rfainfo list for directory (begin of critical section) ---*/ + if ((rc = getLockedRfaInfoList(dirname(fn), &rfalist, basename(fn))) + != OK) + { + return rc; + } + + /*--- check if file exists and user is allowed to write it ---*/ + if ((rfa = findRfaInfo(basename(fn), rfalist)) == NULL) { + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_NOTICE,NULLCP,"reqMaster: %s not .rfainfo", + fn); + return statusError(sd, int_RFA_reason_notRegistered, NULL, 0L,rox,roi); + } + + if (access(makeFN(fn), W_OK) == -1) { + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_NOTICE,NULLCP,"reqMaster: %s not writable", + fn); + return statusError(sd, int_RFA_reason_notWritable, NULL, 0L,rox,roi); + } + + /*--- check if we are master of the file ---*/ + switch(RI_STATUS(rfa->ri_status)) { + case RI_MASTER: + if (IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + return statusError(sd, int_RFA_reason_locked, + rfa->ri_lckname, rfa->ri_lcksince, rox, roi); + } + break; + case RI_SLAVE: + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_NOTICE,NULLCP,"reqMaster: not master for %s", + fn); + return statusError(sd, int_RFA_reason_notMaster, NULL, + 0L, rox, roi); + break; + case RI_UNREGISTERED: + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_NOTICE,NULLCP,"reqMaster: %s not registered", + fn); + return statusError(sd, int_RFA_reason_notRegistered, NULL, + 0L, rox, roi); + break; + default: + releaseRfaInfoList(dirname(fn), rfalist); + sprintf(buf, "unknown file status %d for %s",rfa->ri_status,fn); + return strerror(sd, error_RFA_miscError, buf, rox, roi); + break; + } + + advise(LLOG_DEBUG,NULLCP,"reqMaster: allowing lock mv=%ld sv=%d", + rfa->ri_modTime, rma->slaveVersion); + + /*--- so we are master of the file, check the modify times ---*/ + if (rfa->ri_mode & S_IFMT & S_IFREG) { + t = rma->slaveVersion; + if (rfa->ri_modTime != t) { + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_NOTICE,NULLCP,"reqMaster: lock %s: wrong version %s", + fn, ctime(&t)); + return statusError(sd, int_RFA_reason_wrongVersion, NULL, + 0L, rox, roi); + } + } + + /*--- grant mastership, update rfalist ---*/ + SET_STATUS(rfa->ri_status, RI_SLAVE); + time(&(rfa->ri_lastChange)); + rfa->ri_lcksince = NULL; + if (rfa->ri_lckname) + free(rfa->ri_lckname); + rfa->ri_lckname = NULL; + if (putRfaInfoList(dirname(fn), rfalist) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + advise(LLOG_EXCEPTIONS,NULLCP,"reqMaster: could not write %s/.rfainfo", + dirname(fn)); + return syserror(sd, error_RFA_miscError, rox, roi); + } + advise(LLOG_NOTICE,NULLCP,"reqMaster: sending result"); + + /*--- return result ----*/ + rmr.parm = rfa->ri_modTime; + if (RyDsResult(sd, rox->rox_id, (caddr_t) &rmr, ROS_NOPRIO, roi) != OK) { + + /*--- result failed, so assume that peer has not become master ---*/ + advise(LLOG_NOTICE,NULLCP,"reqMaster: sending result failed"); + SET_STATUS(rfa->ri_status, RI_MASTER); + if (putRfaInfoList(dirname(fn), rfalist) != OK) + advise(LLOG_EXCEPTIONS,NULLCP,"reqMaster: couldn't reset MASTER for %s" + , fn); + releaseRfaInfoList(dirname(fn), rfalist); + ros_adios (&roi -> roi_preject, "RESULT"); + } + + + if (rfa->ri_mode & S_IFMT & S_IFREG) + if(makeFileReadOnly(fn, rfa) != OK) + advise(LLOG_EXCEPTIONS,NULLCP,"reqMaster: %s",rfaErrStr); + + releaseRfaInfoList(dirname(fn), rfalist); + return OK; +} diff --git a/usr/src/contrib/isode/others/rfa/rfa.1c b/usr/src/contrib/isode/others/rfa/rfa.1c new file mode 100644 index 0000000000..df9b102cc7 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfa.1c @@ -0,0 +1,96 @@ +.TH RFA 1C "31 Oct 1990" +.\" $Header: /f/osi/others/rfa/RCS/rfa.1c,v 7.2 91/02/22 09:28:11 mrose Interim $ +.\" +.\" +.\" $Log: rfa.1c,v $ +.\" Revision 7.2 91/02/22 09:28:11 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 91/01/14 13:54:43 mrose +.\" update +.\" +Revision 1.1 91/01/04 16:27:11 ow +Initial revision + +.\" +.SH NAME +rfa \- remote file access and management \-\- initiator +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B rfa +\%[\0-u\0username\0 -p\0password\0] +\%[\0-h\0hostname\0] +\%[\0-c\0command\0] +\%[\0-q\0] +.in -.5i +.SH DESCRIPTION +The RFA client (\fBrfa\fP) provides an interactive mode and a command mode. +.LP +The name of the host (as defined in the +\fBisoentities\fP database) where the +remote site is located can be specified using the +\fB-h\fP option. Because the RFA client +binds to the remote RFA server with a username that must be valid at the +remote site, the \fB-u\fP and +\fB-p\fP options can be used to specify the +username and the password for the remote site. The +\fB-q\fP option directs +\fBrfa\fP to run in quit-mode, where only +severe errors are reported and no user interaction is performed. Using +the \fB-c\fP option, a command can be +passed to rfa in command mode. This can be any command described +below. +.LP +If the rfa is called without the +\fB-c\fP option, is runs in interactive +mode. The \fBrfa\fP provides the following +commands. A command can be abbreviated with its unambiguous +prefix. +.sp +If the \fIchown\fR, \fIchgrp\fR and \fIchmod\fR options in the rfatailor +file are set to \fIon\fR, rfa should run under the effective uid of +root, otherwise it will not be able to change permissions of files. +.SH FILES + +.sp +.in +.5i +.nf +.ta \w'\fIunregister\fR 'u +\fIoperation\fR \fIdescription\fR +\fBget\fR update a local SLAVE file according to the remote MASTER +\fBlock\fR request lock for a local file +\fBunlock\fR release lock for a local file +\fBrlist\fR list files in the remote directory +\fBlist\fR list files in a local directory +\fBpwd\fR print the current directory path +\fBcd\fR change the current directory path +\fBmaster\fR make a local file a MASTER version +\fBslave\fR make a local file a SLAVE version +\fBunregister\fR unregister a previously MASTER or SLAVE file +\fBsetreq\fR set file transfer mode to 'request' +\fBsetauto\fR set file transfer mode to 'automatic' +\fBsyncdir\fR synchronize files in a directory with the remote site +\fBrsyncdir\fR recursively synchronize files in a directory with the + remote site +\fBtimesync\fR syncronize local time with masters clock +\fBquit,exit\fR terminate RFA session +.re +.fi +.in -.5i +.sp + +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(ED~/.rfarc user rcfile for RFA +\*(EDrfatailor common tailoring for RFA +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Oliver Wenzel, GMD FOKUS, Berlin diff --git a/usr/src/contrib/isode/others/rfa/rfa.c b/usr/src/contrib/isode/others/rfa/rfa.c new file mode 100644 index 0000000000..05b7eb5bb2 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfa.c @@ -0,0 +1,1206 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfa.c : initiator for RFA commands + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfa.c,v 7.3 91/02/22 09:28:12 mrose Interim $ + * + * $Log: rfa.c,v $ + * Revision 7.3 91/02/22 09:28:12 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:44 mrose + * update + * + * Revision 1.1 91/01/04 16:07:16 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/rfa.c,v 7.3 91/02/22 09:28:12 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "logger.h" +#include "RFA-ops.h" +#include "RFA-types.h" +#include "rfa.h" +#include "rfainfo.h" + +#define START retcode=OK +#define RETURN return retcode +#define CONT(r) {retcode=(r); continue;} + +extern char *fsBase; +extern char *isodesbinpath; +extern char *isodetcpath; +extern char *strtok(); +extern char *getRfaContext(); + +char *myname; +int connected = 0; +FILE *err, *out; +char cwd_remote[512]; +int interactive = 1; +extern int commandMode; +int retcode; + + +/*--------------------------------------------------------------*/ +/* getLocalFileRfaInfo */ +/*--------------------------------------------------------------*/ +int getLocalRfaInfo(fn, rfap, rfalp, reg) + char **fn; + struct RfaInfo **rfap, **rfalp; + int reg; +{ + int rc; + + + /*--- expand symbolic links in fn ---*/ + if((*fn = getRfaContext(cwd_remote, *fn)) == NULL) { + fprintf(err, + "*** local file access error : not within RFA subtree %s ***\n" + , fsBase); + return NOTOK_OUTOFSUBTREE; + } + if ((*fn = expandSymLinks(*fn)) == NULL) { + fprintf(err, "*** local file access error : %s ***\n", rfaErrStr); + return NOTOK_OUTOFSUBTREE; + } + + /*--- get file Info ---*/ + if ((rc = getLockedRfaInfoList(dirname(*fn), rfalp, basename(*fn))) != OK) { + fprintf(err, + "*** local file access error : can't read %s/.rfainfo (%s) ***\n", + dirname(*fn), errMsg(rc)); + return NOTOK_FILEACCESS; + } + + if ((*rfap = findRfaInfo(basename(*fn), *rfalp)) == NULL) { + releaseRfaInfoList(*fn,*rfalp); + *rfalp = NULL; + fprintf(err,"*** local file access error : %s does not exist ***\n", + *fn); + return NOTOK_FILEACCESS; + } + + /*--- check if regular file ---*/ + if (reg) + if (((*rfap)->ri_mode & S_IFMT) != S_IFREG) { + releaseRfaInfoList(*fn,*rfalp); + fprintf(err," *** status error : not a regular file ***\n"); + *rfalp = NULL; + return NOTOK_NOTREGULAR; + } + + return OK; +} + + +/*--------------------------------------------------------------*/ +/* Local List Dir */ +/*--------------------------------------------------------------*/ +do_localListDir(av) + char **av; +{ + struct RfaInfo *rfa, *rfalist; + char *fn; + int rc; + + if (*av == NULL) { + *av = ""; + *(av+1) = NULL; + } + + START; + for(; *av; av++) { + if((fn = getRfaContext(cwd_remote, *av)) == NULL) { + fprintf(err,"*** can't LLIST dir : not within RFA subtree %s ***\n" + , fsBase); + CONT(NOTOK_OUTOFSUBTREE); + } + + if ((rc = getRfaInfoList(fn, &rfalist, NULL)) != OK) { + fprintf(err, "*** local file access error : %s ***\n", errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + sortRfaInfoList(&rfalist); + for (rfa = rfalist; rfa; rfa = rfa->ri_next) + fprintf(out, "%s\n", rfa2ls(rfa)); + freeRfaInfoList(rfalist); + } + RETURN; +} + +/*--------------------------------------------------------------*/ +/* List Dir */ +/*--------------------------------------------------------------*/ +do_listDir(av) + char **av; +{ + struct RfaInfo *rfa, *rfalist; + int rc; + char *fn; + + if (*av == NULL) { + *av = ""; + *(av+1) = NULL; + } + + START; + for(; *av; av++) { + if((fn = getRfaContext(cwd_remote, *av)) == NULL) { + fprintf(err,"*** can't LIST dir : not within RFA subtree %s ***\n" + , fsBase); + CONT(NOTOK_OUTOFSUBTREE); + } + + if ((rc= getRemoteRfaInfoList(fn, &rfalist)) != OK) + CONT(rc); + + sortRfaInfoList(&rfalist); + for (rfa = rfalist; rfa; rfa = rfa->ri_next) + fprintf(out, "%s\n", rfa2ls(rfa)); + freeRfaInfoList(rfa); + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* getRemoteRfaInfoList +/*--------------------------------------------------------------*/ +getRemoteRfaInfoList(fn, rfap) + char *fn; + struct RfaInfo **rfap; +{ + struct type_RFA_FileName *arg; + struct type_RFA_FileInfoList *fil; + int res, rc; + + + if (getConnection() != OK) + return NOTOK_REMOTE_ERROR; + + arg = str2qb(fn, strlen(fn), 1); + if (invoke(operation_RFA_listDir, (caddr_t)arg, &fil, &res) == NOTOK) { + fprintf(err, "*** remote operation invocation failed ***\n"); + qb_free(arg); + return NOTOK_REMOTE_ERROR; + } + qb_free(arg); + + if (res != RY_RESULT) { + printError(res, (caddr_t)fil, &rc); + return rc; + } + if ((*rfap = fi2rfa(fil)) == NULL) { + fprintf(err,"*** local error : no memory ***\n"); + return NOTOK_LOCAL_ERROR; + } + return OK; +} + + +/*--------------------------------------------------------------*/ +/* Get File */ +/*--------------------------------------------------------------*/ +do_getFile(av) + char **av; +{ + int rc, new = 0; + struct RfaInfo *rfalist, *rfa; + char *fn, buf[512]; + int rmode = 0; + + START; + for(; *av; av++) { + + if((fn = getRfaContext(cwd_remote, *av)) == NULL) { + fprintf(err,"*** can't GET file : not within RFA subtree %s ***\n" + , fsBase); + CONT(NOTOK_OUTOFSUBTREE); + } + /*--- expand symbolic links in fn ---*/ + if ((fn = expandSymLinks(fn)) == NULL) { + fprintf(err, "*** local file access error : %s ***", rfaErrStr); + CONT(NOTOK_OUTOFSUBTREE); + } + + /*--- get file Info ---*/ + if ((rc=getLockedRfaInfoList(dirname(fn),&rfalist,basename(fn))) != OK) + { + fprintf(err, + "*** local file access error : can't read rfainfo (%s) ***\n", + errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + + if ((rfa = findRfaInfo(basename(fn), rfalist)) == NULL) { + + /*--- file does locally not exist, get it from master ---*/ + if ((rfa = mallocRfaInfo(strdup(basename(fn)))) == NULL) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, "*** local error : %s ***\n", rfaErrStr); + CONT(NOTOK_LOCAL_ERROR); + } + SET_STATUS(rfa->ri_status, RI_SLAVE); + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + SET_TRANSFER(rfa->ri_status, default_transfer); + time(&(rfa->ri_lastChange)); + rfa->ri_modTime = 0L; + rfa->ri_next = rfalist; + rfalist = rfa; + new++; + } + + /*--- check if file is master ---*/ + if (IS_MASTER(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** local file %s is master version ***\n", fn ); + CONT(NOTOK_GETMASTER); + } + + /*--- check if file is unregistered ---*/ + if (IS_UNREGISTERED(rfa->ri_status)) { + if(interactive) { + fprintf(err, + "unregistered local version of %s exists, overwrite ? (y/n) : ", + fn); + gets(buf); + if ((*buf != 'y') && (*buf != 'Y')) { + releaseRfaInfoList(dirname(fn), rfalist); + CONT(NOTOK_UNREG_LOCAL_FILE); + } else { + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + + /*--- will be set in getfile_aux acc. to remote state ---*/ + SET_STATUS(rfa->ri_status, RI_SLAVE); + SET_TRANSFER(rfa->ri_status, default_transfer); + + time(&(rfa->ri_lastChange)); + rfa->ri_modTime = 0L; + new++; + } + } else { + fprintf(err, + "*** error : unregistered local version of %s exists ***\n", + fn); + releaseRfaInfoList(dirname(fn), rfalist); + CONT(NOTOK_UNREG_LOCAL_FILE); + } + } + + /*--- otherwise we are slave or unregistered file, get from master ---*/ + if ((rc = getfile_aux(fn, rfa, &rmode)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + CONT(rc); + } + + if(new) + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + releaseRfaInfoList(dirname(fn), rfalist); + CONT(NOTOK_FILEACCESS); + } + + releaseRfaInfoList(dirname(fn), rfalist); + + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* unlockFile */ +/*--------------------------------------------------------------*/ +do_unlockFile(av) + char **av; +{ + int rc; + struct RfaInfo *rfalist, *rfa; + char *fn; + + START; + for(; *av; av++) { + + /*--- get file Info ---*/ + fn = *av; + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 0)) != OK) + CONT(rc); + + /*--- check if we are master ---*/ + if (IS_SLAVE(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** local file %s is slave version ***\n", fn); + CONT(NOTOK_IS_SLAVE); + } + if (!IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** local file %s not locked ***\n", fn); + CONT(NOTOK_NOTLOCKED); + } + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + rfa->ri_lcksince = NULL; + free(rfa->ri_lckname); + rfa->ri_lckname = "NONE"; + + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, "*** local file access error : %s ***\n", errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + releaseRfaInfoList(dirname(fn), rfalist); + if (interactive) + fprintf(out,"unlocked file %s\n", fn); + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* lockFile */ +/*--------------------------------------------------------------*/ +do_lockFile(av) + char **av; +{ + struct type_RFA_RequestMasterRes *rmr; + struct type_RFA_RequestMasterArg *rma; + int res, rc; + struct RfaInfo *rfalist, *rfa; + char *fn, *shortTime(); + int rmode = 0; + + START; + for(; *av; av++) { + + /*--- get file Info ---*/ + fn = *av; + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 0)) != OK) + CONT(rc); + + /*--- check if we are master ---*/ + if (IS_MASTER(rfa->ri_status) || IS_UNREGISTERED(rfa->ri_status)) { + if (IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file already locked by %s since %s ***\n", + rfa->ri_lckname, shortTime(&(rfa->ri_lcksince))); + CONT(NOTOK_LOCKED); + } + SET_LOCKINFO(rfa->ri_status, RI_LOCKED); + rfa->ri_lckname = strdup(getenv("USER")); + (void)time(&(rfa->ri_lcksince)); + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "locked file %s\n",fn); + continue; + } + + /*--- otherwise we are slave, get from master ---*/ + if (getConnection() != OK) + CONT(NOTOK_REMOTE_ERROR); + + if (rfa->ri_mode & S_IFMT & S_IFREG) + if ((rc = getfile_aux(fn, rfa, &rmode)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + CONT(NOTOK_REMOTE_ERROR); + } + + if ((rma = (struct type_RFA_RequestMasterArg *) + malloc(sizeof(struct type_RFA_RequestMasterArg))) == NULL) + { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err,"*** local error : no memory ***\n"); + CONT(NOTOK_LOCAL_ERROR); + } + + rma->filename = str2qb(fn, strlen(fn), 1); + rma->slaveVersion = rfa->ri_modTime; + + if (invoke(operation_RFA_requestMaster, (caddr_t) rma, &rmr, &res) + == NOTOK) + { + releaseRfaInfoList(dirname(fn), rfalist); + free_RFA_RequestMasterArg(rma); + fprintf(err, "*** remote operation invocation failed ***\n"); + CONT(NOTOK_REMOTE_ERROR); + } + if (res != RY_RESULT) { + releaseRfaInfoList(dirname(fn), rfalist); + free_RFA_RequestMasterArg(rma); + printError(res, (caddr_t)rmr, &rc); + CONT(rc); + } + + free_RFA_RequestMasterRes(rmr); + free_RFA_RequestMasterArg(rma); + SET_LOCKINFO(rfa->ri_status, RI_LOCKED); + SET_STATUS(rfa->ri_status, RI_MASTER); + (void)time(&(rfa->ri_lastChange)); + rfa->ri_lckname = strdup(getenv("USER")); + (void)time(&(rfa->ri_lcksince)); + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err,"*** PANIC : can't set local Master status of %s ***\n", + fn); + CONT(NOTOK_FILEACCESS); + } + + /*--- set owner and group mode to writable ---*/ + if (rmode && (rfa->ri_mode & S_IFMT & S_IFREG)) + if (changeFileMode(fn, rmode, "set write permissions") != OK) + fprintf(err, "*** %s ***\n", rfaErrStr); + + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "locked file %s\n",fn); + } + RETURN; +} + +/*--------------------------------------------------------------*/ +/* master */ +/*--------------------------------------------------------------*/ +do_master(av) + char **av; +{ + int rc, res; + struct RfaInfo *rfalist, *rfa, *remoteRfaList, *rrfa; + char *fn, *shortTime(); + char buf[512]; + struct type_RFA_RequestMasterRes *rmr; + struct type_RFA_RequestMasterArg *rma; + int rmode = 0; + + START; + for(; *av; av++) { + + /*--- get file Info ---*/ + fn = *av; + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 0)) != OK) + CONT(rc); + + /*--- check if not a .rfaexec file ---*/ + if (strcmp(rfa->ri_filename, ".rfaexec") == 0) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** not allowed on file '%s' ***\n",rfa->ri_filename); + CONT(NOTOK_NOT_ALLOWED); + } + + /*--- check if unregistered ---*/ + if (IS_MASTER(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file %s is already master version ***\n", fn); + CONT(NOTOK_ALREADY_MASTER); + } + + /*--- check if remote is already master ---*/ + if ((rc = getRemoteRfaInfoList(dirname(fn), &remoteRfaList)) != OK) { + if (interactive) { + fprintf(err, "can't determine remote status, become master"); + fprintf(err, " anyway ? (y/n): "); + gets(buf); + if ((*buf != 'y') && (*buf != 'Y')) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err,"...aborted\n"); + CONT(NOTOK_REMOTE_ERROR); + } + } else { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err,"*** can't determine remote status of %s ***\n",fn); + CONT(NOTOK_REMOTE_ERROR); + } + } else { + + /*--- consistency checks ---*/ + if (rrfa = findRfaInfo(basename(fn), remoteRfaList)) { + if (IS_MASTER(rrfa->ri_status)) { + + /*--- try to become master ---*/ + if (rfa->ri_mode & S_IFMT & S_IFREG) + if ((rc = getfile_aux(fn, rfa, &rmode)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + CONT(NOTOK_REMOTE_ERROR); + } + + if ((rma = (struct type_RFA_RequestMasterArg *) + malloc(sizeof(struct type_RFA_RequestMasterArg))) == NULL) + { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + fprintf(err,"*** local error : no memory ***\n"); + CONT(NOTOK_LOCAL_ERROR); + } + + rma->filename = str2qb(fn, strlen(fn), 1); + rma->slaveVersion = rfa->ri_modTime; + + if (invoke(operation_RFA_requestMaster, (caddr_t) rma, + &rmr, &res) ==NOTOK) + { + releaseRfaInfoList(dirname(fn), rfalist); + free_RFA_RequestMasterArg(rma); + freeRfaInfoList(remoteRfaList); + fprintf(err, + "*** remote operation invocation failed ***\n"); + CONT(NOTOK_REMOTE_ERROR); + } + if (res != RY_RESULT) { + releaseRfaInfoList(dirname(fn), rfalist); + free_RFA_RequestMasterArg(rma); + printError(res, (caddr_t)rmr, &rc); + CONT(rc); + } + free_RFA_RequestMasterArg(rma); + free_RFA_RequestMasterRes(rmr); + } + if (IS_SLAVE(rrfa->ri_status)) { + if (interactive) { + fprintf(err, "remote version is already slave, become"); + fprintf(err, " master anyway ? (y/n): "); + gets(buf); + if ((*buf != 'y') && (*buf != 'Y')) { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + fprintf(err,"...aborted\n"); + CONT(NOTOK_REMOTE_ERROR); + } + } else { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + fprintf(err, + "*** remote version of %s is already slave ***\n",fn); + CONT(NOTOK_REMOTE_ERROR); + } + } + } + freeRfaInfoList(remoteRfaList); + } + + if (IS_UNREGISTERED(rfa->ri_status)) + SET_TRANSFER(rfa->ri_status, default_transfer); + SET_STATUS(rfa->ri_status, RI_MASTER); + time(&(rfa->ri_lastChange)); + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + + /*--- set owner and group mode to writable ---*/ + if (rmode && (rrfa->ri_mode & S_IFMT & S_IFREG)) + if (changeFileMode(fn, rmode, "set write permissions") != OK) + fprintf(err, "*** %s ***\n", rfaErrStr); + + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "changed local version of %s to MASTER\n",fn); + } + RETURN; +} + +/*--------------------------------------------------------------*/ +/* slave */ +/*--------------------------------------------------------------*/ +do_slave(av) + char **av; +{ + int rc; + struct RfaInfo *rfalist, *rfa, *remoteRfaList, *rrfa; + char *fn, *shortTime(); + char buf[512]; + + START; + for(; *av; av++) { + + /*--- get file Info ---*/ + fn = *av; + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 0)) != OK) + CONT(rc); + + /*--- check if not a .rfaexec file ---*/ + if (strcmp(rfa->ri_filename, ".rfaexec") == 0) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** not allowed on file '%s' ***\n",rfa->ri_filename); + CONT(NOTOK_NOT_ALLOWED); + } + + /*--- check if unregistered ---*/ + if (IS_SLAVE(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file %s already is slave version ***\n", fn); + CONT(NOTOK_ALREADY_SLAVE); + } + + /*--- check if unregistered ---*/ + if (IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file %s is currently locked ***\n", fn); + CONT(NOTOK_LOCKED); + } + + /*--- check if remote is already master ---*/ + if ((rc = getRemoteRfaInfoList(dirname(fn), &remoteRfaList)) != OK) { + if (interactive) { + fprintf(err, "can't determine remote status, become slave"); + fprintf(err, " anyway ? (y/n): "); + gets(buf); + if ((*buf != 'y') && (*buf != 'Y')) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err,"...aborted\n"); + CONT(NOTOK_REMOTE_ERROR); + } + } else { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err,"*** can't determine remote status of %s ***\n",fn); + CONT(NOTOK_REMOTE_ERROR); + } + } else { + + /*--- consistency checks ---*/ + if (rrfa = findRfaInfo(basename(fn), remoteRfaList)) { + if (!IS_MASTER(rrfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + fprintf(err, + "*** remote site is not master for file %s ***\n", fn); + CONT(NOTOK_REMOTE_NOT_MASTER); + } + if (((rfa->ri_mode & S_IFMT & S_IFDIR) == 0) + && (rrfa->ri_modTime < rfa->ri_modTime)) { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + fprintf(err,"*** remote master version of %s would be", fn); + fprintf(err, " older than local slave version ***\n"); + CONT(NOTOK_REMOTE_MASTER_OLDER); + } + } else { + releaseRfaInfoList(dirname(fn), rfalist); + freeRfaInfoList(remoteRfaList); + fprintf(err, + "*** remote site is not master for file %s ***\n", fn); + CONT(NOTOK_REMOTE_NOT_MASTER); + } + freeRfaInfoList(remoteRfaList); + } + + if ((rfa->ri_mode & S_IFMT & S_IFDIR) == 0) + if (makeFileReadOnly(fn, rfa) != OK) + fprintf(err, "*** %s ***\n", rfaErrStr); + + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + if (IS_UNREGISTERED(rfa->ri_status)) + SET_TRANSFER(rfa->ri_status, default_transfer); + SET_STATUS(rfa->ri_status, RI_SLAVE); + (void)time(&(rfa->ri_lastChange)); + + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "changed local version of %s to SLAVE\n",fn); + } + RETURN; +} + +/*--------------------------------------------------------------*/ +/* unregister */ +/*--------------------------------------------------------------*/ +do_unregister(av) + char **av; +{ + int rc; + struct RfaInfo *rfalist, *rfa; + char *fn; + char buf[512]; + + START; + for(; *av; av++) { + + /*--- get file Info ---*/ + fn = *av; + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 0)) != OK) + CONT(rc); + + /*--- check if unregistered ---*/ + if (IS_UNREGISTERED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file %s already is unregistered ***\n", fn); + CONT(NOTOK_ALREADY_UNREG); + } + + /*--- check if locked ---*/ + if (IS_LOCKED(rfa->ri_status)) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err," *** file %s is currently locked ***\n", fn); + CONT(NOTOK_LOCKED); + } + + if ((rfa->ri_mode & S_IFMT & S_IFDIR) == 0) + if (makeFileReadWrite(fn, rfa) != OK) + fprintf(err, "*** %s ***\n", rfaErrStr); + + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + SET_TRANSFER(rfa->ri_status, RI_TR_REQ); + SET_STATUS(rfa->ri_status, RI_UNREGISTERED); + (void)time(&(rfa->ri_lastChange)); + + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "changed local version of %s to UNREGISTERED\n",fn); + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* rsyncdir */ +/*--------------------------------------------------------------*/ +do_rsyncdir(av) + char **av; +{ + char *fn; + int rc; + + if (*av == NULL) { + *av = ""; + *(av+1) = NULL; + } + START; + for(; *av; av++) { + if((fn = getRfaContext(cwd_remote, *av)) == NULL) { + fprintf(err,"*** can't RSYNC dir : not within RFA subtree %s ***\n", + fsBase); + CONT(NOTOK_OUTOFSUBTREE); + } + if ((fn = expandSymLinks(fn)) == NULL) { + fprintf(err, "*** local file access error : %s ***\n", rfaErrStr); + CONT(NOTOK_OUTOFSUBTREE); + } + if((rc = syncDir(fn, 1)) != OK) + CONT(rc); + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* syncdir */ +/*--------------------------------------------------------------*/ +do_syncdir(av) + char **av; +{ + int rc; + char *fn; + + if (*av == NULL) { + *av = ""; + *(av+1) = NULL; + } + + START; + for(; *av; av++) { + if((fn = getRfaContext(cwd_remote, *av)) == NULL) { + fprintf(err,"*** can't SYNC dir : not within RFA subtree %s ***\n", + fsBase); + CONT(NOTOK_OUTOFSUBTREE); + } + if ((fn = expandSymLinks(fn)) == NULL) { + fprintf(err, "*** local file access error : %s ***\n", rfaErrStr); + CONT(NOTOK_OUTOFSUBTREE); + } + + if((rc = syncDir(fn, 0)) != OK) + CONT(rc); + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* settransfer */ +/*--------------------------------------------------------------*/ +do_setreq(av) + char **av; +{ do_settransfer(av, RI_TR_REQ); } + +do_setauto(av) + char **av; +{ do_settransfer(av, RI_TR_AUTO); } + +do_settransfer(av, mode) + char **av; + int mode; +{ + int rc; + struct RfaInfo *rfalist, *rfa; + char *fn, *shortTime(); + + START; + for(; *av; av++) { + + /*--- get file Info ---*/ + fn = *av; + if ((rc = getLocalRfaInfo(&fn, &rfa, &rfalist, 0)) != OK) + CONT(rc); + + SET_TRANSFER(rfa->ri_status, mode); + + if ((rc = putRfaInfoList(dirname(fn), rfalist)) != OK) { + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(err, + "*** local file access error : can't write rfainfo (%s) ***\n", + errMsg(rc)); + CONT(NOTOK_FILEACCESS); + } + releaseRfaInfoList(dirname(fn), rfalist); + fprintf(out, "set transfer mode to %s for file %s\n", + mode == RI_TR_AUTO ? "AUTOMATIC" : "REQUEST", fn); + } + RETURN; +} + + +/*--------------------------------------------------------------*/ +/* Print WD */ +/*--------------------------------------------------------------*/ +do_pwd(av) + char **av; +{ + fprintf(out,"working directory: %s\n",*cwd_remote? cwd_remote : "/"); +} + +/*--------------------------------------------------------------*/ +/* Change Dir */ +/*--------------------------------------------------------------*/ +do_changeDir(av) + char **av; +{ + register char *s, *r, *fn = *av; + char buf[512]; + + if (fn == NULL) { + *cwd_remote = '\0'; + return OK; + } + if (*fn == '@') { + *cwd_remote = '\0'; + fn++; + } + + for (s = strtok(fn, "/"); s; s = strtok(NULL, "/")) { + if (strcmp(s, ".") == 0) + continue; + if (strcmp(s, "..") == 0) { + if (*cwd_remote) + if ( r = rindex(cwd_remote, '/')) + *r = '\0'; + else + *cwd_remote = '\0'; + continue; + } + strcat(cwd_remote, "/"); + strcat(cwd_remote, s); + } + return OK; +} + +/*--------------------------------------------------------------*/ +/* timesync */ +/*--------------------------------------------------------------*/ +int do_timesync(av) + char **av; +{ + struct type_RFA_SyncTimeArg sta; + struct type_RFA_SyncTimeRes *str; + int res, rc; + time_t rt, lt, dt; + char buf[BUFSIZ]; + + if (getConnection() != OK) { + return NOTOK_REMOTE_ERROR; + } + + if (timeSlave) { + sta.role = int_RFA_role_slave; + sta.time = 0; + } else { + sta.role = int_RFA_role_master; + (void)time(&(sta.time)); + sta.time += SENDTIME_DELAY; + } + if (invoke(operation_RFA_syncTime, (caddr_t)&sta, &str, &res) + ==NOTOK) + { + fprintf(err, "*** remote operation invocation failed ***\n"); + return (NOTOK_REMOTE_ERROR); + } + (void)time(<); + + if (res != RY_RESULT) { + printError(res, (caddr_t)str, &rc); + return rc; + } + rt = str->parm; + free_RFA_SyncTimeRes(str); + if (timeSlave) { + if (dt = rt - lt) { + if (changeTime(dt) != OK) { + fprintf(err, "*** %s ***\n", rfaErrStr); + sprintf(buf, "%s/rfatime %ld", isodesbinpath, dt); + if (system(buf) != OK) { + fprintf(err, "*** %s ***\n", rfaErrStr); + return NOTOK_LOCAL_ERROR; + } + } + if(dt > 0) + fprintf(out, "advanced local time by %ld sec\n", dt); + else + fprintf(out, "retarding local time by %ld sec\n", dt); + } + } else { + if(rt > 0) + fprintf(out, "remote site advanced local time by %ld sec\n", rt); + else + if (rt < 0) + fprintf(out,"remote site is retarding local time by %ld sec\n",rt); + } + return OK; +} + + +/*--------------------------------------------------------------*/ +/* Execute Command */ +/*--------------------------------------------------------------*/ +executeCommand(cmd) + char *cmd; +{ + char **ap, *aps[BUFSIZ]; + static struct cmd { + char *n; + int (*f)(); + char *h; + } cmds[] = { + { "get", do_getFile, + "update a local SLAVE file according to the remote MASTER"}, + { "lock", do_lockFile, + "request lock for a local file"}, + { "unlock", do_unlockFile, + "release lock for a local file"}, + { "rlist", do_listDir, + "list files in the remote directory"}, + { "list", do_localListDir, + "list files in a local directory"}, + { "pwd", do_pwd, + "print the current directory path"}, + { "cd", do_changeDir, + "change the current directory path"}, + { "master", do_master, + "make a local file a MASTER version"}, + { "slave", do_slave, + "make a local file a SLAVE version"}, + { "unregister", do_unregister, + "unregister a previously MASTER or SLAVE file"}, + { "setreq", do_setreq, + "set file transfer mode to 'request'"}, + { "setauto", do_setauto, + "set file transfer mode to 'automatic'"}, + { "syncdir", do_syncdir, + "synchronize files in a directory with the remote site"}, + { "rsyncdir", do_rsyncdir, + "recursively synchronize files in a directory with the remote site"}, + { "timesync", do_timesync, + "syncronize local time with masters clock"}, + { "quit", NULL, + "terminate RFA session"}, + { "exit", NULL, + "terminate RFA session"}, + { NULL, NULL, NULL } + }, *cmdp, *fc; + + + aps[0] = strtok (cmd, " "); + for (ap = aps+1; *ap = strtok(NULL," "); ap++) + ; + + if (aps[0]) { + if ((strncmp(*aps, "h", 1) == 0) || (strncmp(*aps, "?", 1) == 0)) { + for (cmdp = cmds; cmdp->n; cmdp++) + fprintf(out,"%8.8s - %s\n", cmdp->n, cmdp->h); + return OK; + } + + fc = NULL; + for (cmdp = cmds; cmdp->n; cmdp++) + if (strncmp(cmdp->n, *aps, strlen(*aps)) == 0) { + if (fc) { + fprintf(stderr,"command '%s' ambiguous, use one of\n",*aps); + for (cmdp = cmds; cmdp->n; cmdp++) + if (strncmp(cmdp->n, *aps, strlen(*aps)) == 0) + fprintf(out," %8.8s - %s\n", cmdp->n, cmdp->h); + return OK; + } + fc = cmdp; + } + if (fc == NULL) { + fprintf(err, "unknown command: %s\n",*aps); + return OK; + } + + if (fc->f) + (*(fc->f))(aps+1); + else + return NOTOK; + + } + return OK; +} + +cleanup() +{ +} + + +int getConnection() +{ + if (connected) + return OK; + if (makeconn(host, passwd, user) == NOTOK) { + fprintf(err,"*** provider error: can't establish connection to %s ***\n" + , host); + return NOTOK; + } + connected = 1; + return OK; +} + + +main (ac, av) +int ac; +char **av; +{ + char c, *cwd, buf[BUFSIZ]; + extern char *optarg; + extern int optind; + char *cmd=NULL; + int rc; + char *homesave; + + host = "localhost"; + myname = av[0]; + + out = stdout; + err = stderr; + + isodetailor (myname, 1); + + /*-- create log file --*/ + initLog(myname); + + /*--- rfa tailoring ---*/ + sprintf(buf, "%s/rfatailor", isodetcpath); + if (tailor(buf) != OK) { + fprintf(stderr,"*** tailoring of file '%s' failed:%s\n",buf, rfaErrStr); + exit(NOTOK_LOCAL_ERROR); + } + sprintf(buf,"%s/.rfarc", getenv("HOME")); + if (tailor(buf) != OK) { + fprintf(stderr,"*** tailoring of file '%s' failed:%s\n",buf, rfaErrStr); + exit(NOTOK_LOCAL_ERROR); + } + + while ((c = getopt(ac, av, "qu:p:c:h:")) != -1) + switch (c) { + case 'u': + user = optarg; + break; + case 'p': + passwd = optarg; + break; + case 'c': + cmd = optarg; + break; + case 'h': + host = optarg; + break; + case 'q': + out = fopen("/dev/null", "w"); + interactive = 0; + break; + case '?': + fprintf(stderr, "USAGE: %s [-h hostname] [-u user] [-p password] [-c command] [ -q ]\n", basename(myname)); + exit(NOTOK_LOCAL_ERROR); + } + + /*-- set uid, gid --*/ + if (initUserId(getuid(), getgid(), "") != OK) + fprintf(err, "*** %s ***\n", rfaErrStr); + + /*--- init cwd ---*/ + (void)getwd(buf); + if (strncmp(buf, fsBase, strlen(fsBase)) == 0) + strcpy(cwd_remote, buf + strlen(fsBase)); + + if (cmd) { + commandMode = 1; + rc = executeCommand(cmd); + if (connected) + closeconn(); + exit(rc); + } + + printf("rfa-%s@%s> ", user, host); + gets(buf); + while (executeCommand(buf) == OK) { + printf("rfa-%s@%s> ", user, host); + gets(buf); + } + if (connected) + closeconn(); + exit (0); +} + + + diff --git a/usr/src/contrib/isode/others/rfa/rfa.h b/usr/src/contrib/isode/others/rfa/rfa.h new file mode 100644 index 0000000000..21d746f77c --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfa.h @@ -0,0 +1,86 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfa.h : common definitions for RFA + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfa.h,v 7.3 91/02/22 09:28:15 mrose Interim $ + * + * $Log: rfa.h,v $ + * Revision 7.3 91/02/22 09:28:15 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:50 mrose + * update + * + * Revision 1.1 91/01/04 16:09:45 ow + * Initial revision + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "config.h" + +#ifndef OK +#define OK 0 +#define NOTOK 1 +#endif +#define NOTOK_LOCAL_LOCK 2 +#define NOTOK_LOCAL_ERROR 3 +#define NOTOK_REMOTE_ERROR 4 +#define NOTOK_LOCKED 5 +#define NOTOK_FILEACCESS 6 +#define NOTOK_NOTREGULAR 7 +#define NOTOK_GETMASTER 8 +#define NOTOK_OUTOFSUBTREE 9 +#define NOTOK_NOTLOCKED 10 +#define NOTOK_ALREADY_SLAVE 11 +#define NOTOK_ALREADY_MASTER 12 +#define NOTOK_ALREADY_UNREG 13 +#define NOTOK_REMOTE_NOT_MASTER 14 +#define NOTOK_REMOTE_MASTER_OLDER 15 +#define NOTOK_UNREG_LOCAL_FILE 16 +#define NOTOK_IS_SLAVE 17 +#define NOTOK_SYS 18 +#define NOTOK_INCONSISTENCY 19 +#define NOTOK_NOT_ALLOWED 20 + + +extern char *makeFN2(); +extern char *makeFN(); +extern char *basename(); +extern char *dirname(); +extern char *expandSymLinks(); +extern char *realPath(), *realPath3(); + +extern char rfaErrStr[]; +extern char *errMsg(); + +/*--- tailor variables ---*/ +extern int default_transfer; +extern int doChown; +extern int doChgrp; +extern int doChmod; +extern int doClearSUID; +extern int doRmWidows; +extern int doRfaExec; +extern int timeSlave; +extern int compLimit; +extern char *passwd; +extern char *user; +extern char *host; +extern int backup; diff --git a/usr/src/contrib/isode/others/rfa/rfa.ry b/usr/src/contrib/isode/others/rfa/rfa.ry new file mode 100644 index 0000000000..650350dcc2 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfa.ry @@ -0,0 +1,168 @@ +-- +-- RFA - Remote File Access +-- +-- Access and Management for a partial file system tree that exists +-- at two side either as master files or slave files +-- +-- rfa.ry : Definition of Remote Operations that are used by RFA +-- +-- +-- Contributed by Oliver Wenzel, GMD Berlin, 1990 +-- +-- $Header: /f/osi/others/rfa/RCS/rfa.ry,v 7.3 91/02/22 09:28:16 mrose Interim $ +-- +-- $Log: rfa.ry,v $ +-- Revision 7.3 91/02/22 09:28:16 mrose +-- Interim 6.8 +-- +-- Revision 7.2 91/01/14 13:54:51 mrose +-- update +-- +-- Revision 1.1 91/01/04 16:10:29 ow +-- Initial revision +-- +-- +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- + + +RFA DEFINITIONS ::= + +BEGIN + +-- operations + + +getFileData OPERATION + ARGUMENT GetFileDataArg + RESULT GetFileDataRes + ERRORS { miscError, fileAccessError } + ::= 1 + +GetFileDataArg ::= SEQUENCE { + filename FileName, + slaveVersion INTEGER +} + +GetFileDataRes ::= SEQUENCE { + mode INTEGER { + actual(0), -- local version is still valid + data(1), + zero(2), + compressed(3) }, + fileinfo FileInfo, + data OCTETSTRING OPTIONAL +} + + +requestMaster OPERATION + ARGUMENT RequestMasterArg + RESULT RequestMasterRes + ERRORS { miscError, statusError, fileAccessError } + ::= 2 + +RequestMasterArg ::= SEQUENCE { + filename FileName, + slaveVersion INTEGER +} + +RequestMasterRes ::= INTEGER -- modification time + + + +listDir OPERATION + ARGUMENT FileName + RESULT FileInfoList + ERRORS { miscError, fileAccessError } + ::= 3 + +FileName ::= IA5String + +FileInfo ::= SEQUENCE { + name IA5String, + mode INTEGER, + user IA5String, + group IA5String, + size INTEGER, + accTime INTEGER, + modTime INTEGER, + lnkName [0] IA5String OPTIONAL, + status INTEGER { + unregistered(0), + master(1), + masterLocked(2), + slave(3) }, + lockedBy [1] IA5String OPTIONAL, + lockedSince INTEGER +} + +FileInfoList ::= SEQUENCE OF FileInfo + + + +syncTime OPERATION + ARGUMENT SyncTimeArg + RESULT SyncTimeRes + ERRORS { miscError } + ::= 4 + +SyncTimeArg ::= SEQUENCE { + role INTEGER { + master(0), + slave(1) + }, + time INTEGER -- only used when role = master +} + +SyncTimeRes ::= SEQUENCE { + time INTEGER -- contains clock of master if role was slave + -- otherwise the time diff at slave +} + + +-- errors + +miscError ERROR + PARAMETER Reason + ::= 0 + +fileAccessError ERROR + PARAMETER Reason + ::= 1 + +Reason ::= SEQUENCE { + reason IA5String +} + +statusError ERROR + PARAMETER StatusErrorParm + ::= 2 + +StatusErrorParm ::= SEQUENCE { + reason INTEGER { + notMaster (0), + locked (1), + notRegistered(2), + notWritable(3), + wrongVersion(4), + notRegularFile(5), + slaveNewer(6)}, + user [0] IA5String OPTIONAL, + since [1] INTEGER +} + +-- types + + +Initiate ::= SEQUENCE { + user IA5String, + password IA5String +} + +END diff --git a/usr/src/contrib/isode/others/rfa/rfa.tr b/usr/src/contrib/isode/others/rfa/rfa.tr new file mode 100644 index 0000000000..d8f3b35b99 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfa.tr @@ -0,0 +1,862 @@ +.\" +.\" RFA - Remote File Access +.\" +.\" rfa.tr : RFA User Manual (run through "roff -ms") +.\" +.\" Contributed by Oliver Wenzel, GMD Berlin, 1990 +.\" +.\" +.\" $Header: /f/osi/others/rfa/RCS/rfa.tr,v 7.3 91/02/22 09:28:17 mrose Interim $ +.\" +.\" $Log: rfa.tr,v $ +.\" Revision 7.3 91/02/22 09:28:17 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.2 91/01/14 13:54:52 mrose +.\" update +.\" +Revision 1.1 91/01/04 16:25:50 ow +Initial revision + +.\" +.AM +.nr LL 7i +.pl 11i +.nr li 1 1 +.nr PD 50 +.TL +RFA - Remote File Access + +.br +A tool for managing access to files that are distributed at multiple sites +.AU +Oliver Wenzel +GMD - Fokus +Berlin - Germany + +.br +Version 1.0 + +.sp 4 +.NH +Introduction +.XS +Introduction +.XE +.LP +This software tool called \fIRemote File +Access\fP (RFA) has been designed to allow access to a set +of files in a UNIX(TM) filesystem that are shared between multiple +sites. It has been created within the VERDI 3 project as a result of our +own requirements for a distributed document and file management system. +Basis for this requirements is the VERDI 3 project which members are +located at two different sites. Both sites of the project share a common +set of documents and files which need to be accessed and modified during +the everyday-project-work. For some time we used the FTAM software to +exchange files between the two sites, but after the number of shared +files and transfer operations grew, very often questions like +.ds is \(bu +.RS +.IP \*(is 3 +at which site the up-to-date (master) version of the file is +located ? +.IP \*(is 3 +is the local version up-to-date ? +.IP \*(is 3 +is anyone already editing this file ? +.IP \*(is 3 +are there any newly created files ? +.RE +.LP +appeared. Using a distributed filesystem like NFS was discussed as +an alternative solution, but this did not seemed to be practicable +because of the very slow communication links between the sites +(9600Bps). Therefore, we tried to build a simple tool to handle theses +questions. So the RFA tool was born and because the project is working +with ISO protocols, we built the tool on top of the ISODE software +package using the remote operation compiler +\fBrosy(1)\fP. Currently the tools only +supports to share files between two sites (because this was our primary +goal), but it should be possible to extend it to support multiple +sites. +.NH +The Model +.XS +The Model +.XE + +.NH 2 +The Data Model +.XS +The Data Model +.XE +.LP +The Data Model is based on the hierarchical structure of the +UNIX(TM) filesystem. The RFA tools allows to share a subtree of the +hierarchical filesystem structure between (currently) two sites. The +structure of the shared subtree must be identical at both sites. The +local root of the shared subtree may be different at both sites. Subject +of the operation of the RFA tool are the files and directories within +the shared subtree. +.NH 3 +File Version-Time +.XS +File Version-Time +.XE +.LP +A file within a shared subtree exists at the different sites as +different (local) versions of the file. The version-time (state of +modification) of a file version at a site is determined by the +\fBmodification time\fP provided by the +UNIX(TM) system call \fBstat(2)\fP. To +determine which version of file is up-to-date, the youngest version-time +is chosen. This requires that the sites participating in the file +sharing use synchronized clocks. This is necessary because the +modification time is set automatically by the UNIX system using the +local operating system clock. The RFA tool provides an operation to +synchronize the clocks where one of the sites is declared to be the +\fBtime-master\fP which provides the time +to the \fBtime-slave\fP. +.NH 3 +RFA File Status +.XS +RFA File Status +.XE +.LP +Each local version of a file that exists within the shared subtree +at a site has a RFA-specific status which is one of: +.IP "MASTER" 15 +the file is the up-to-date version of the file and +modifications to the local version of the file are allowed. +.IP "SLAVE" 15 +the file is the read-only version of the file and may be +up-to-date but it need not. For each local file with SLAVE status there +must be a MASTER version at the remote site. File version with SLAVE +status will have file write permissions cleared. +.IP "UNREGISTERED" 15 +the file not shared and has only local significance. It may +be modified locally. +.LP +.LP +This file status allows to determine which site has the up-to-date +version of a file and is allowed to do modifications to the file. The +site holding a SLAVE version of the file has to request the mastership +before it is allowed to do any modifications. Further, it has to be +assured that the local version of the file at the new MASTER site is +up-to-date. Otherwise the file has to be transferred first. A local +version of a file may change its status during its lifetime (e.g. from +UNREGISTERED to MASTER) as a result of several RFA operations described +later. +.NH 3 +File Locking +.XS +File Locking +.XE +.LP +To avoid that a file is modified by multiple users at the MASTER +site or that the mastership is transferred to the remote site while the +local version is under modify-access by a local user, a local version of +a file can be (soft)-locked. Locking of files is only applicable to file +versions with status MASTER or UNREGISTERED. +.LP +Setting the lock flag of a directory has the effect, that the +\fB.rfaexec\fP file is not executed during +a RFA \fBsync\fP or +\fBrsync\fP command. This can be used to +enable the execution of the \fB.rfaexec\fP +file for a period of time (e.g. while doing incomplete modifications to +the source-code when \fB.rfaexec\fP +contains commands for re-compilation). +.NH 3 +Transferlevel +.XS +Transferlevel +.XE +.LP +One mode of operation of the RFA tool is to synchronize sets of +local version of files with the remote site. To determine if a file that +is mastered remote should be transferred during this synchronization, a +transferlevel can be associated with each file: +.IP "REQUEST" 15 +The file is not transferred automatically during +synchronization. If a new MASTER file is detected at the remote site, +only a local dummy (empty file) is created to indicate the existence of +the file. +.IP "AUTOMATIC" 15 +The file is transferred automatically during synchronization +if the local version is not up-to-date. If a new MASTER file is detected +at the remote site, it is transferred. +.NH 2 +The Functional Model +.XS +The Functional Model +.XE +.LP +The RFA tools is built using the +\fBClient-Server\fP model of the ISODE +remote operations environment. There is a RFA server (called +\fBros.rfa)\fP at each site which is +started dynamically by the ISODE +\fBtsapd\fP. Most of the RFA commands are +interpreted by the RFA client (called +\fBrfa\fP) which issues a remote operation +to the remote RFA server. The RFA client does not perform a 1-to-1 +mapping of its commands onto the remote operations. It uses none, one or +more remote operations to execute a RFA command. The association +establishment is done when the first remote operation is invoked. The +RFA client can operate in an interactive mode or a command mode. +.LP +One of the basic principles of RFA is that modifications to any +files are only performed locally by the RFA client. The remote RFA +server never modifies any file, so no remote file modifications are +possible. The ensure a certain autonomy of the two sites concerning +modifications of their local files. +.NH +The RFA Client +.XS +The RFA Client +.XE +.LP +The RFA client (\fBrfa\fP) provides an +interactive mode and a command mode. The rfa command has the following +syntax: + +.DS I 3 +rfa [ -u username -p password ] [ -h hostname] [ -q ] + [ -c rfa-command ] +.DE +.LP +The name of the host (as defined in the +\fBisoentities\fP database) where the +remote site is located can be specified using the +\fB-h\fP option. Because the RFA client +binds to the remote RFA server with a username that must be valid at the +remote site, the \fB-u\fP and +\fB-p\fP options can be used to specify the +username and the password for the remote site. The +\fB-q\fP option directs +\fBrfa\fP to run in quit-mode, where only +severe errors are reported and no user interaction is performed. Using +the \fB-c\fP option, a command can be +passed to rfa in command mode. This can be any command described +below. +.LP +If the rfa is called without the +\fB-c\fP option, is runs in interactive +mode. The \fBrfa\fP provides the following +commands. A command can be abbreviated with its unambiguous +prefix. +.NH 2 +pwd +.XS +pwd +.XE +.LP +During interactive mode, \fBrfa\fP has +a current directory. This directory is relative to the root of the +shared subtree. The \fBpwd\fP command shows +the name of the current working directory relative to the root of the +shared subtree. Initially this is the current working directory of the +UNIX \fBsh(1)\fP where +\fBrfa\fP has been called if it is within +the shared subtree. +.NH 2 +cd +.XS +cd +.XE +.LP +The \fBcd\fP command changes the +current directory of \fBrfa\fP in +interactive mode to the directory given as the first argument. No check +is made if this directory exists. It is not possible to change the +working directory above the root of the shared subtree. +.NH 2 +list +.XS +list +.XE +.LP +The \fBlist\fP command provides a +listing of the files within the directories given as the command +arguments. If no argument is given, the current working directory is +listed. The output of the \fBlist\fP +command is similar to the output of the UNIX \fBls +-lg\fP command, e.g. + +.DS I 3 +-rw-rw-r-- M-A ow verdi 754 Jul 12 13:59 .sunview +drwxr-xr-x --- ow verdi 512 Jul 12 14:01 bin +.DE +.LP +The three character field after the file permissions is used to +indicated the different rfa-specific states of the file. The first +character indicates the status of the file, with M +for master version, S for slave Version and +- for unregistered version. The second character is +the lock indicator with an L indicating that the +file is currently locked and an - for unlocked. The +third character indicates the transfer mode of the files with +A for automatic transfer and - +for transfer on request. +.NH 2 +rlist +.XS +rlist +.XE +.LP +The \fBrlist\fP command is similar to +the \fBlist\fP command with the difference +that the files in the directory at the remote site are listed. +.NH 2 +lock +.XS +lock +.XE +.LP +The \fBlock\fP command is used to get +a locked local version of the file(s) that are provided as argument(s) +to the command. Only regular files within the shared subtree are valid. +It is not possible to lock directories, links, etc. . If the name of the +file to be locked is a symbolic link, the file referenced by the link is +locked if it is located within the shared subtree. +.LP +The \fBlock\fP command should be used +whenever a file within the shared subtree is modified to ensure that the +local version of the file is a) the master version and b) not currently +under modify-access by another local user. +.LP +If the local version of the files has a SLAVE status, the lock +command will try to get the mastership for the file. Therefore, it first +verifies that the local version is up-to-date, otherwise it transfers +the up-to-date version from the current master, similar to the +\fBgetfile\fP command. After an up-to-date +local version of the requested file exists, a +\fBRequestMaster\fP operation is issued to +the remote site to transfer the mastership. If the file is not locked at +the remote site, the mastership is granted to the local site which then +is the new master. The local lock is set the by setting the +L (ocked) flag in the local files state. +.LP +If the local version of the requested file already is the MASTER +version or is an UNREGISTERED file, it is checked if the file is already +locked by another local user, where the requested lock is rejected. +Otherwise the local lock is set the by setting the +L (ocked) flag in the local files state. +.LP +Because the lock command will be applied in the most cases to a +local version of the file that is already master, it is not necessary to +execute the whole \fBrfa\fP program to do +the local lock. Because the \fBrfa\fP +program includes the whole code needed for the execution of the remote +operations (ISODE stack, etc.), there may be a significant time delay +while loading this huge program. To optimize this, a stand-alone program +called \fBllock\fP is provided which is +able to perform the locking if the local version is the master version. +If \fBllock\fP could perform the local +lock, it exits with exit-code 0. If the file is already locked +locally or an error condition occurred it exits with exit-code 1. If the +local version of the file is not MASTER, it returns 2 which indicates +that the \fBrfa\fP command is needed to +perform the locking. +.NH 2 +unlock +.XS +unlock +.XE +.LP +The \fBunlock\fP command is used to +release a lock for a local MASTER version of the file(s) provided as +command argument(s). If the name of the file to be unlocked is a +symbolic link, the file referenced by the link is unlocked if it is +located within the shared subtree. There is are no checks made if the +file has been locked by the user that performs the unlock operation. +.LP +Similar to the \fBllock\fP command +there exists an \fBlunlock\fP command which +is capable to perform the release of the (always) local locks to avoid +the expensive use of the \fBrfa\fP +command. +.NH 2 +master +.XS +master +.XE +.LP +The \fBmaster\fP command can be used +to request that the local version of the file(s) provided as argument(s) +will become the MASTER version. If the name of the file is a symbolic +link, the file referenced by the link is target of the operation if it +is located within the shared subtree. +.LP +If the local version of the file is in UNREGISTERED status, its +status is set to MASTER if there is no version of the file with MASTER +status at the remote site. This is the way how locally created files +will be introduced into the set of shared files where the creating site +becomes the initial master. +.LP +If the local version of the file is in SLAVE status, then the +mastership for the file is requested from the remote site similar to the +\fBlock\fP command. The write access +permissions of the new local MASTER version are set. +.NH 2 +slave +.XS +slave +.XE +.LP +The \fBslave\fP command can be used to +request that the local version of the file(s) provided as argument(s) +will become a SLAVE version. If the name of the file is a symbolic link, +the file referenced by the link is target of the operation if it is +located within the shared subtree. +.LP +If the local version of the file is in UNREGISTERED or MASTER +status, its status is set to SLAVE if there is version of the file with +MASTER status at the remote site. The write access permissions of the +new local SLAVE version are cleared. +.NH 2 +unregister +.XS +unregister +.XE +.LP +The \fBunregister\fP command can be +used to request that the local version of the file(s) provided as +argument(s) will become an UNREGISTERED version. If the local version of +the file is locked, this results in an error. If the name of the file is +a symbolic link, the file referenced by the link is target of the +operation if it is located within the shared subtree. +.NH 2 +setrequest +.XS +setrequest +.XE +.LP +The \fBsetrequest\fP command is used +to set the transfer mode of the local version of the file(s) provided as +argument(s) to REQUEST mode. If the name of the file is a symbolic link, +the file referenced by the link is target of the operation if it is +located within the shared subtree. +.NH 2 +setauto +.XS +setauto +.XE +.LP +The \fBsetauto\fP command is used to +set the transfer mode of the local version of the file(s) provided as +argument(s) to AUTOMATIC mode. If the name of the file is a symbolic +link, the file referenced by the link is target of the operation if it +is located within the shared subtree. +.NH 2 +getfile +.XS +getfile +.XE +.LP +The \fBgetfile\fP command is used to +request the transfer of the shared file(s) provided as argument(s). If +the name of the file is a symbolic link, the file referenced by the link +is target of the operation if it is located within the shared +subtree. +.LP +If the remote version of the file is in MASTER status, a local +SLAVE version is created if the file does locally not exist. If a local +SLAVE version already exists, it is updated from the remote MASTER +version. +.LP +If the remote version of the file is in UNREGISTERED status, a +local version of the file with status UNREGISTERED is created if the +file does locally not exist. If a local version already exists, it is +updated from the remote version. +.LP +The transfer of the file is performed according the version-time +(time of last modification) of the local and remote files. If both the +version-times of both files are equal, no transfer has to be performed +because the SLAVE version is already up-to-date. If the version-time of +the remote MASTER is older that the version-time of the local SLAVE (or +UNREGISTERED) version, an inconsistency has been detected and an error +is reported. Otherwise, the content of the file has to be transmitted to +update the local SLAVE (or UNREGISTERED) version of the file. +.LP +The content of the file can be transferred either in uncompressed +or in compressed mode, depending on the size of the file. The size limit +when compression shall occur can be configured as described in +chapter 5. The compression and decompression is done using +the UNIX(TM) \fBcompress(1)\fP and +\fBuncompress(1)\fP commands. +.LP +Optionally, the old version of the local file will be saved in as a +file with the suffix \fB.bak\fP if the +local file is updated. This option can be configured as described in +chapter 5. +.NH 2 +syncdir +.XS +syncdir +.XE +.LP +The \fBsyncdir\fP command is used to +synchronize the files within the directory/ies provided as argument(s) +with their counterparts at the remote site. Here the basic principle is, +that the site executing the \fBsyncdir\fP +command is only synchronizing the local site by applying the following +actions to the list of files that exists at the +\fIremote\fP site within the given +directory: +.ds is \(bu +.RS +.IP \*(is 3 +Create a local SLAVE file versions for newly found remote MASTER +version file. This is done according to the transfer mode of the file. +If the transfer mode is set to REQUEST, only a dummy SLAVE version of +file is created which indicates the existence of the file, but does not +have its actual content. Otherwise, the content of the file is +transferred as described with the +\fBgetfile\fP command. +.IP \*(is 3 +Update local SLAVE file version with a remote MASTER version if +the transfer mode of the file is AUTOMATIC +.IP \*(is 3 +Create local SLAVE sub-directory if a new MASTER sub-directory has +been found at the remote site. By this, the shared subtree will grow in +size. Directories found at the remote site that are in status +UNREGISTERED are \fINOT\fP created +locally. +.IP \*(is 3 +Create a local symbolic link if a symbolic link has been found at +the remote site. This is only done if the file referenced by the link is +located within the shared subtree. +.IP \*(is 3 +Perform various checks to insure consistency between local and +remote sites views of the files within the directory. +.IP \*(is 3 +Removes local SLAVE files if there is no corresponding MASTER file +at the remote site. If there is a UNREGISTERED file at remote, the local +file state is set to UNREGISTERED. +.IP \*(is 3 +Execute a existing \fB.rfaexec\fP +file if any file within the directory has been updated and the directory +itself in not LOCKED. +.RE +.LP +To achieve a fully synchronized directory, both sites need to +perform a \fBsyncdir\fP operation for that +directory at periodic times. This will be typically done by creating an +entry into the systems \fBcrontab\fP. +.NH 2 +rsyncdir +.XS +rsyncdir +.XE +.LP +The \fBrsyncdir\fP command is very +similar to the \fBsyncdir\fP command, but +performs a recursive synchronization of the whole subtree starting at +the directory/ies provided as argument(s). The same actions are +performed as within the \fBsyncdir\fP +command with an additional actions: +.LP + +.ds is \(bu +.RS +.IP \*(is 3 +If a MASTER directory is detected at the remote site and the +transfer mode of this directory is set to AUTOMATIC, the directory is +synchronized recursively. +.IP \*(is 3 +It does not follow symbolic links pointing to directories +.RE +.LP +Directories found at the remote site that are in status +UNREGISTERED or don't have transfer mode AUTOMATIC are +\fINOT\fP synchronized recursively. They have +to be updated individually by applying the +\fBsyncdir\fP command. +.LP +Using the \fBrsyncdir\fP command it is +possible to synchronize the whole shared subtree. The configuration +which parts of a subtree at a site belongs to that shared subtree is +done by setting the MASTER status and the transfer level of the files +and directories appropriately. +.NH 2 +timesync +.XS +timesync +.XE +.LP +To synchronize the local clocks of the participating sites, the +\fBtimesync\fP command can be used. This +command synchronizes the local clock of the site acting as the +\fBtime slave\fP with the clock of the +\fBtime master\fP site. The command can be +called at both sites to initiate the synchronization. The configuration +of a site to be \fBtime slave\fP or +\fBtime master\fP is described in chapter +5 +.NH 2 +help +.XS +help +.XE +.LP +The \fBhelp\fP command shows the list +of available command and gives a one-line description of each +command. +.NH 2 +quit +.XS +quit +.XE +.LP +Obviously, the \fBquit\fP commands +terminates the \fBrfa\fP session. +.NH +The RFA-EXEC facility +.XS +The RFA-EXEC facility +.XE +.LP +When a directory within the shared subtree is synchronized using +the RFA \fBsync\fP or +\fBrsync\fP commands, in most cases there +are further actions required if any files have been updated, e.g. +issuing a \fBmake\fP command to re-build +the updated software. This can be achieved by RFA's facility to create a +file called \fB.rfaexec\fP in each +directory. This file is executed by +\fBsh(1)\fP every time the directory is +synchronized and minimally one file within the directory has been +updated. The file \fB.rfaexec\fP can be +have executable format (sh, csh, binary) and should have the executed +permission set. When RFA executed this file, it passes the names of the +files that have been updated as arguments to it. +.LP +This facility can be disabled by setting the +\fBrfaexec\fP tailoring option to +\fBoff\fP. Further, it can be disabled for +a single directory by setting the LOCKED status of the directory. This +is useful to prevent re-compilations of software during an unfinished +development cycle. +.LP +For security reasons, the +\fB.rfaexec\fP file can +\fINOT\fP be registered as MASTER or SLAVE +file. An automatic transfer of this file may cause a user to execute +something during the \fBsync\fP command +which has been "imported" from the remote site. Therefore, +the \fB.rfaexec\fP file is always a local +unregistered file. +.NH +RFA Configuration +.XS +RFA Configuration +.XE +.LP +The configuration of the RFA client +(\fBrfa\fP) and the RFA server +(\fBros.rfa)\fP server can be tailored at +start time by a configuration file. This file is called +\fBrfatailor\fP and can exist either in the +ISODE's $(ETCDIR) or the RFA specific tailoring directory which is +defined in the \fBconfig.h\fP file of RFA +as \fBRFA_TAILDIR\fP. This file is read by +both the RFA client and server. The file consists of a number of +tailoring statements with the syntax +tailoringOption = tailoringValue +.LP +Lines with comments start with a "#". +.LP +The options that are valid for both the RFA client and server +are: +.IP "root" 15 +the pathname of the root of the shared subtree at the local +site +.IP "time" 15 +the role that the local site plays for time synchronization. +Possible values are \fBmaster\fP or +\fBslave\fP. +.LP +The following options are only recognized by the RFA server: +.IP "compress" 15 +The limit for the filesize in bytes when compression during +the transfer operation shall occur. +.IP "chmod" 15 +determines if the write permissions of local SLAVE files +shall be removed and write permissions to local MASTER and UNREGISTERED +versions shall be set. This requires that user executing the +\fBrfa\fP command is the owner of the file +or the \fBrfa\fP program runs under the +effective user id of root. Possible values are +\fBon\fP and +\fBoff\fP. +.IP "debuglog" 15 +enables more detailed logging information to be written to +the RFA logfile \fBrfa.log\fP in the ISODE +logdir. Possible values are \fBon\fP and +\fBoff\fP. +.LP +The following options are only recognized by the RFA client. They +may additionally be defined on a per-user basis in a file called +\fB.rfarc\fP in the users home +directory. +.IP "host" 15 +the name of the remote host. This name must be defined in +the ISODE's \fBisoentities\fP +database. +.IP "user" 15 +the username that shall be used to authenticate with the +remote RFA server. This must be a UNIX(TM) login name that is valid +on the remote site. +.IP "password" 15 +The password corresponding to the user name. This password +must be the password for the given login name at the remote +site. +.IP "backup" 15 +determines if a backup file with suffix +\fB.bak\fP shall be created when a local +file is updated. Possible values are +\fBon\fP and +\fBoff\fP. +.IP "chgrp" 15 +determines if the group-id of local SLAVE files shall be set +according to the group-id of the remote MASTER file. This requires that +user executing the \fBrfa\fP command is +member of all groups that may appear or the +\fBrfa\fP program runs under the effective +user id of root. Possible values are +\fBon\fP and +\fBoff\fP. +.IP "chown" 15 +determines if the user-id of local SLAVE files shall be set +according to the user-id of the remote MASTER file. This requires that +user executing the \fBrfa\fP command is the +owner of the file or the \fBrfa\fP program +runs under the effective user id of root. Possible values are +\fBon\fP and +\fBoff\fP. +.IP "transfer" 15 +the default transfer mode that is set when a file is +registered the first time. Possible values are +\fBauto\fP and +\fBrequest\fP +.IP "clearsuid" 15 +determines if the set-uid-on-execution bit of files is +cleared if they are transferred to the remote site. Possible values are +\fBon\fP and +\fBoff\fP. If RFA runs with effective +user-id of root and \fBchown\fP options is +enabled, \fBclearsuid\fP should be enabled +to avoid that privileged users from one sites are able to gain illegal +privileges at the other site. +.IP "rmslaves" 15 +determines if slave files with no remote master file are +deleted during the \fBsync\fP and +\fBrsync\fP command. Possible values are +\fBon\fP and +\fBoff\fP. If a there is a remote +UNREGISTERED file, the status of the local SLAVE file is only changed to +UNREGISTERED. +.IP "rfaexec" 15 +determines if the +\fB.rfaexec\fP files are executed during a +\fBsync\fP or +\fBrsync\fP command. Possible values are +\fBon\fP and +\fBoff\fP. +.NH +Some Words on User-IDs and Permissions +.XS +Some Words on User-IDs and Permissions +.XE +.LP +In principle, the RFA client runs with the user-id of the user that +invokes the client. The RFA server either runs with the user-id of the +user who owns the server program (as performed by +\fBtsapd(8)\fP), or it runs with the +user-id the invoker has supplied with the bind arguments (a username and +password valid at the remote server host). In the later case +\fBtsapd\fP needs to run with user-id of +root and ros.rfa needs to be owned by root. +.LP +Under certain circumstances, RFA client and server need to do +modification to files which are not owned by the user-id that RFA is +running with, such as +.ds is \(bu +.RS +.IP \*(is 3 +changing a files access right (e.g. if it becomes a slave +version) +.IP \*(is 3 +changing a files owner of group (e.g. if a local slave is updates +according to a remote master and the +\fBchown\fP and +\fBchmod\fP options are enabled +.RE +.LP +One way to deal with these problems is to disable these facilities +of RFA by setting the \fBchown\fP, +\fBchgrp\fP and +\fBchmod\fP options to +\fBoff\fP. This will be suitable in an +environment where all files within the shared subtree belong to a single +user and only this user runs RFA client and server processes. +.LP +Otherwise, if different users access the files, minimally the +\fBchmod\fP option should be enabled to +avoid modifications to slave files (remember that locking in rfa is +advisory) by making slave files read-only. Further, the +\fBchown\fP and +\fBchgrp\fP options should be enabled if +the users and groups are the same at both sites to maintain the +ownership (and originatorship of modification) across the two sites. +.LP +This can be achieved by running the RFA client and server with the +effective user-id of root (by setting the set-uid-on-execution flag). +The RFA client will set his effective user-id during start-up to his +real user-id and switches back to the effective user-id of root only for +these sections of code where the root permissions are really required to +change the access mode, owner or group of files. Otherwise, the RFA +client run with the effective user-id equal to his real user-id. +.LP +The RFA server changes his effective user-id during start-up to the +user-id provided by the calling client. Like the RFA client, it switches +back to the effective user-id of root only for these sections of code +where the root permissions are really required to change the access mode +of a file. +.LP +If the RFA client and server do not run with effective user-id of +root, the time synchronization command of RFA can only be used, if the +external program \fBrfatime\fP of the RFA +package is installed to run with set-uid root +.NH +What is still missing ... +.XS +What is still missing ... +.XE +.LP +The current version of RFA is a first shot which needs some +completion and extensions. +.ds is \(bu +.RS +.IP \*(is 3 +A command like "remote-diff" could be helpful for +resolving inconsistencies. +.IP \*(is 3 +The time synchronization only works if the local time of a +\fBtime-slave\fP site can be modified, +which may not hold true in each environment. +.IP \*(is 3 +There is a problem with the +\fBchown\fP, +\fBchgrp\fP and +\fBchmod\fP facilities of RFA because the +enabling of them may cause "permission denied" errors if the +RFA does not run with the effective used id of root. +.IP \*(is 3 +RFA is only capable to support distribution over two sites, which +should be extended to allow a multiple site configuration. This may +require the redesign of the RFA model and will introduce a new level of +complexity. +.RE diff --git a/usr/src/contrib/isode/others/rfa/rfa2fi.c b/usr/src/contrib/isode/others/rfa/rfa2fi.c new file mode 100644 index 0000000000..7e79dfd6cf --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfa2fi.c @@ -0,0 +1,165 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfa2fi.c : convert between RfaInfo and type_RFA_FileInfoList and vice versa + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfa2fi.c,v 7.3 91/02/22 09:28:20 mrose Interim $ + * + * $Log: rfa2fi.c,v $ + * Revision 7.3 91/02/22 09:28:20 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:54:56 mrose + * update + * + * Revision 1.1 91/01/04 16:07:24 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/rfa2fi.c,v 7.3 91/02/22 09:28:20 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "rfa.h" +#include "RFA-types.h" +#include "rfainfo.h" + +extern char *getRelativeFN(); +extern char *fsBase; + +/*-------------------------------------------------------------------- + * rfa2fi - RfaInfo to type_RFA_FileInfo + *--------------------------------------------------------------------*/ +struct type_RFA_FileInfo *rfa2fi(dir, rfa) + char *dir; + struct RfaInfo *rfa; +{ + struct type_RFA_FileInfo *fi; + char *l; + + if ((fi = (struct type_RFA_FileInfo *) + malloc(sizeof(struct type_RFA_FileInfo))) == NULL) + { + sprintf(rfaErrStr, "out of memory"); + return NULL; + } + fi->name = str2qb(rfa->ri_filename, strlen(rfa->ri_filename), 1); + fi->mode = rfa->ri_mode; + fi->user = str2qb(rfa->ri_owner, strlen(rfa->ri_owner), 1); + fi->group = str2qb(rfa->ri_group, strlen(rfa->ri_group), 1); + fi->size = rfa->ri_size; + fi->accTime = rfa->ri_accTime; + fi->modTime = rfa->ri_modTime; + if (l = rfa->ri_lnkName) { + if (*l != '/') { + if (getRelativeFN(realPath3(fsBase, dir, l)) == NULL) + l = "(link outside RFA context)"; + } else + if ((l = getRelativeFN(rfa->ri_lnkName)) == NULL) + l = "(link outside RFA context)"; + fi->lnkName = str2qb(l, strlen(l), 1); + } else + fi->lnkName = NULL; + fi->status = rfa->ri_status; + if (IS_LOCKED(rfa->ri_status)) { + fi->lockedBy = str2qb(rfa->ri_lckname, strlen(rfa->ri_lckname), 1); + fi->lockedSince = rfa->ri_lcksince; + } else { + fi->lockedBy = NULL; + fi->lockedSince = NULL; + } + return fi; +} + +/*-------------------------------------------------------------------- + * rfa2fil - RfaInfo to type_RFA_FileInfoList + *--------------------------------------------------------------------*/ +struct type_RFA_FileInfoList *rfa2fil(dir, rfa) + char *dir; + struct RfaInfo *rfa; +{ + struct type_RFA_FileInfoList *fil, **filp; + + filp = &fil; + for (; rfa; rfa = rfa->ri_next) { + if (((*filp) = (struct type_RFA_FileInfoList *) + malloc(sizeof(struct type_RFA_FileInfoList))) == NULL) + { + free_RFA_FileInfoList(fil); + sprintf(rfaErrStr, "out of memory"); + return NULL; + } + (*filp)->next = NULL; + if (((*filp)->FileInfo = rfa2fi(dir, rfa)) == NULL) { + free_RFA_FileInfoList(fil); + return NULL; + } + filp = &((*filp)->next); + } + return fil; +} + +/*-------------------------------------------------------------------- + * fi2rfa - type_RFA_FileInfoList to RfaInfo + *--------------------------------------------------------------------*/ +struct RfaInfo *fi2rfa(fil) + struct type_RFA_FileInfoList *fil; +{ + struct type_RFA_FileInfo *fi; + struct RfaInfo *rfa, *rfaNew; + char *l; + + rfa = NULL; + for (; fil; fil = fil->next) { + fi = fil->FileInfo; + if ((rfaNew = mallocRfaInfo(qb2str(fi->name))) == NULL) { + freeRfaInfoList(rfa); + return NULL; + } + rfaNew->ri_next = rfa; + rfa = rfaNew; + + rfa->ri_mode = fi->mode; + rfa->ri_owner = qb2str(fi->user); + rfa->ri_group = qb2str(fi->group); + rfa->ri_size = fi->size; + rfa->ri_accTime = fi->accTime; + rfa->ri_modTime = fi->modTime; + if (fi->lnkName) { + l = qb2str(fi->lnkName); + if (*l == '/') + l = makeFN(l); + rfa->ri_lnkName = strdup(l); + } else + rfa->ri_lnkName = NULL; + rfa->ri_status = fi->status; + if (IS_LOCKED(rfa->ri_status)) { + rfa->ri_lckname = qb2str(fi->lockedBy); + rfa->ri_lcksince = fi->lockedSince; + } else { + rfa->ri_lckname = NULL; + rfa->ri_lcksince = NULL; + } + } + return rfa; +} + + diff --git a/usr/src/contrib/isode/others/rfa/rfad.8c b/usr/src/contrib/isode/others/rfa/rfad.8c new file mode 100644 index 0000000000..f4364b24c3 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfad.8c @@ -0,0 +1,50 @@ +.TH RFAD 8C "9 Nov 1990" +.\" $Header: /f/osi/others/rfa/RCS/rfad.8c,v 7.2 91/02/22 09:28:21 mrose Interim $ +.\" +.\" +.\" $Log: rfad.8c,v $ +.\" Revision 7.2 91/02/22 09:28:21 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 91/01/14 13:54:58 mrose +.\" update +.\" +Revision 1.1 91/01/04 16:27:23 ow +Initial revision + +.\" +.SH NAME +rfad \- remote file access service \-\- responder +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDros.rfa +\fImagic\0arguments\fR +.in -.5i +(under \fI\*(SDtsapd\fR\0) +.SH DESCRIPTION +The \fIrfad\fR server implements the remote file access service +using remote operations services. +.sp +Formally, +it is known as the \*(lqrfa\*(rq, +responding with the \*(lqrfa\*(rq application context +utilizing the \*(lqrfa pci\*(rq presentation context. +.sp +If the \fIchown\fR, \fIchgrp\fR and \fIchmod\fR options in the rfatailor +file are set to \fIon\fR, ros.rfa should run under the effective uid of +root, otherwise it will not be able to change permissions of files. +.SH FILES +.nf +.ta \w'\*(LDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +\*(LDrfatailor rfa tailoring file +\*(LDrfa.log rfa logging file +.re +.fi +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Oliver Wenzel, GMD Berlin, Germany diff --git a/usr/src/contrib/isode/others/rfa/rfad.c b/usr/src/contrib/isode/others/rfa/rfad.c new file mode 100644 index 0000000000..b6125c85e6 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfad.c @@ -0,0 +1,220 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfad.c : responder for RFA commands + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfad.c,v 7.4 91/02/22 09:28:22 mrose Interim $ + * + * $Log: rfad.c,v $ + * Revision 7.4 91/02/22 09:28:22 mrose + * Interim 6.8 + * + * Revision 7.3 91/01/14 13:54:59 mrose + * update + * + * Revision 1.1 91/01/04 16:07:38 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/rfad.c,v 7.4 91/02/22 09:28:22 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include "ryresponder.h" +#include "tsap.h" +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfa.h" + + +static char *myservice = "rfa"; + +extern int error (), strerror (), syserror (), ureject (); +extern struct type_RFA_QueryResult *query (); +extern struct type_RFA_FileList *do_listcdir (); +extern int op_init (); +extern int ros_init (), ros_work (), ros_indication (), ros_lose (); +extern IFP startfnx, stopfnx; +extern char *isodetcpath; + + +extern int op_getFileData(), op_requestMaster(), op_listDir(), op_syncTime(); +static struct dispatch dispatches[] = { + "getFileData", operation_RFA_getFileData, op_getFileData, + "requestMaster", operation_RFA_requestMaster, op_requestMaster, + "listDir", operation_RFA_listDir, op_listDir, + "syncTime", operation_RFA_syncTime, op_syncTime, + NULL +}; + +char target[BUFSIZ]; +char *host; +int groupid, userid; +char homedir[BUFSIZ]; + +/* MAIN */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + static int initiate (); + char buf[BUFSIZ]; + register struct dispatch *ds; + AEI aei; + struct TSAPdisconnect tds; + struct TSAPdisconnect *td = &tds; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + char *myname; + + host = getlocalhost (); + myname = argv[0]; + if (myname = rindex (argv[0], '/')) + myname++; + + /*--- isode initialization and tailoring ---*/ + sprintf(buf,"HOME=%s", RFA_TAILDIR); + putenv(buf); + isodetailor (myname, 1); + initLog(myname); + + /*--- rfa tailoring ---*/ + sprintf(buf, "%s/rfatailor", isodetcpath); + if (tailor(buf) != OK) + advise (LLOG_EXCEPTIONS, NULLCP, rfaErrStr); + sprintf(buf, "%s/rfatailor", RFA_TAILDIR); + if (tailor(buf) != OK) + advise (LLOG_EXCEPTIONS, NULLCP, rfaErrStr); + + /*--- get application entity identifier for rfa service ---*/ + if ((aei = str2aei (host, myservice)) == NULLAEI) + adios (NULLCP, "%s-%s: unknown application-entity", + host, myservice); + + /*--- register operation to serve ---*/ + for (ds = dispatches; ds -> ds_name; ds++) + if (RyDispatch (NOTOK, table_RFA_Operations, ds -> ds_operation, + ds -> ds_vector, roi) == NOTOK) + ros_adios (rop, ds -> ds_name); + + startfnx = initiate; + stopfnx = NULLIFP; + + advise (LLOG_NOTICE, NULLCP, "starting"); + if (isodeserver (argc, argv, aei, ros_init, ros_work, ros_lose, td) + == NOTOK) { + if (td -> td_cc > 0) + adios (NULLCP, "isodeserver [%s] %*.*s", + TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data); + else + adios (NULLCP, "isodeserver: [%s]", + TErrString (td -> td_reason)); + } + + exit(0); +} + + +cleanup() +{ +} + + +/* ARGSUSED */ +initiate (sd, acs, pe) +int sd; +struct AcSAPstart *acs; +PE *pe; +{ + struct type_RFA_Initiate *initial; + char *cp; + struct passwd *pw; + + *pe = NULLPE; + if ( acs -> acs_ninfo != 1) + return init_lose (ACS_PERMANENT, pe, "No Bind data"); + + if (decode_RFA_Initiate (acs -> acs_info[0], 1, NULLIP, NULLVP, + &initial) == NOTOK) + return init_lose (ACS_PERMANENT, pe, "Can't parse Bind data"); + + user = qb2str (initial -> user); + + advise (LLOG_NOTICE, NULLCP, "Bind of user %s", user); + + if (baduser (NULLCP, user)) { + advise (LLOG_EXCEPTIONS, NULLCP, "Bad listed user '%s'", user); + return init_lose (ACS_PERMANENT, pe, "Bad user/password"); + } + + if ((pw = getpwnam (user)) == NULL) { + advise (LLOG_EXCEPTIONS, NULLCP, "Unknown user '%s'", user); + return init_lose (ACS_PERMANENT, pe, "Bad user/password"); + + } + + userid = pw -> pw_uid; + groupid = pw -> pw_gid; + (void) strcpy (homedir, pw -> pw_dir); + + cp = qb2str (initial -> password); + + if (pw -> pw_passwd == NULL + || !chkpassword (user, pw -> pw_passwd, cp)) { + advise (LLOG_NOTICE, NULLCP, "Password mismatch for %s", user); + return init_lose (ACS_PERMANENT, pe, "Bad user/password"); + + } + bzero (cp, strlen(cp)); /* in case of cores */ + free (cp); + + free_RFA_Initiate (initial); + + if (chdir (homedir) == -1) { + advise (LLOG_NOTICE, NULLCP, "Can't set home directory to '%s'", + homedir); + return init_lose (ACS_PERMANENT, pe, "No home directory"); + } + + if (initUserId(userid, groupid, user) != OK) { + advise (LLOG_NOTICE, NULLCP, "%s\n", rfaErrStr); + return init_lose (ACS_PERMANENT, pe, rfaErrStr); + } + return ACS_ACCEPT; +} + +init_lose (type, pe, str) +int type; +PE *pe; +char *str; +{ + *pe = ia5s2prim (str, strlen(str)); + (*pe) -> pe_context = 3; /* magic!! - don't ask me why */ + return type; +} diff --git a/usr/src/contrib/isode/others/rfa/rfainfo.c b/usr/src/contrib/isode/others/rfa/rfainfo.c new file mode 100644 index 0000000000..230f7a1f43 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfainfo.c @@ -0,0 +1,604 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfainfo.c : functions to manipulate fileinfo structure and files + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfainfo.c,v 7.3 91/02/22 09:28:23 mrose Interim $ + * + * $Log: rfainfo.c,v $ + * Revision 7.3 91/02/22 09:28:23 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:00 mrose + * update + * + * Revision 1.1 91/01/04 16:07:48 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/rfainfo.c,v 7.3 91/02/22 09:28:23 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "psap.h" +#include "logger.h" +#include "rfainfo.h" +#include "rfa.h" + +#define MAXSTAT 4 +static char *statusTable[] = { "UNREGISTERED", "MASTER","MASTER_LOCKED", NULL}; +static char *statusTableShort[] = { "NON", "MST","LCK", "SLV", NULL }; +char rfaErrStr[512]; + +extern char *sys_errname(); + +/*------------------------------------------------------ + * str2status - convert status string to integer code + *------------------------------------------------------*/ +int str2status (stat) + char *stat; +{ + char **sp; + int i = 0; + + switch(*(stat++)) { + case '-': + SET_STATUS(i, RI_UNREGISTERED); + break; + case 'M': + case 'm': + SET_STATUS(i, RI_MASTER); + break; + case 'S': + case 's': + SET_STATUS(i, RI_SLAVE); + break; + default: + return NOTOK; + } + switch(*(stat++)) { + case '-': + SET_LOCKINFO(i, RI_UNLOCKED); + break; + case 'L': + case 'l': + SET_LOCKINFO(i, RI_LOCKED); + break; + default: + return NOTOK; + } + switch(*(stat++)) { + case '-': + SET_TRANSFER(i, RI_TR_REQ); + break; + case 'A': + case 'a': + SET_TRANSFER(i, RI_TR_AUTO); + break; + default: + return NOTOK; + } + return i; +} + +/*------------------------------------------------------ + * status2str - convert status to string + *------------------------------------------------------*/ +char *status2str(stat) + int stat; +{ + static char sbuf[5]; + register char *s = sbuf; + + switch(RI_STATUS(stat)) { + case RI_UNREGISTERED: + *s = '-'; + break; + case RI_MASTER: + *s = 'M'; + break; + case RI_SLAVE: + *s = 'S'; + break; + default: + sbuf[0] = '?'; + } + s++; + switch(RI_LOCKINFO(stat)) { + case RI_LOCKED: + *s = 'L'; + break; + case RI_UNLOCKED: + *s = '-'; + break; + default: + *s = '?'; + } + s++; + switch(RI_TRANSFER(stat)) { + case RI_TR_AUTO: + *s = 'A'; + break; + case RI_TR_REQ: + *s = '-'; + break; + default: + *s = '?'; + } + *(++s) = '\0'; + return sbuf; +} + +/*------------------------------------------------------ + * mallocRfaInfo - malloc list elements + *------------------------------------------------------*/ +struct RfaInfo *mallocRfaInfo (fn) + char *fn; +{ + register struct RfaInfo *rfa; + + if ((rfa = (struct RfaInfo *) malloc(sizeof(struct RfaInfo))) == NULL) { + sprintf(rfaErrStr, "out of memory"); + advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr); + return NULL; + } + bzero(rfa, sizeof(struct RfaInfo)); + rfa->ri_filename = fn; + return rfa; +} + + +/*------------------------------------------------------ + * freeRfaInfoList - free list elements + *------------------------------------------------------*/ +void freeRfaInfoList (rfa) + struct RfaInfo *rfa; +{ + struct RfaInfo *r; + + for (; rfa; rfa = r) { + if (rfa->ri_filename) + free(rfa->ri_filename); + if (rfa->ri_lckname) + free(rfa->ri_lckname); + if (rfa->ri_owner) + free(rfa->ri_owner); + if (rfa->ri_group) + free(rfa->ri_group); + r = rfa->ri_next; + free((char *)rfa); + } +} + + +/*------------------------------------------------------ + * lock_rfainfo - semaphore P operation + *------------------------------------------------------*/ +void lock_rfainfo(fn) + char *fn; +{ + int fd; + + if ((fd =open(makeFN2(fn, ".rfainfo"), O_RDWR)) == -1) { + advise (LLOG_EXCEPTIONS, NULLCP, "lock: can't open '%s':%s", fn, + sys_errname(errno)); + return; + } + if (flock(fd, LOCK_EX) == -1) + advise (LLOG_EXCEPTIONS, NULLCP, "lock: can't lock '%s':%s", fn, + sys_errname(errno)); + close(fd); +} + +/*------------------------------------------------------ + * unlock_rfainfo - semaphore V operation + *------------------------------------------------------*/ +void unlock_rfainfo(fn) + char *fn; +{ + int fd; + + if ((fd = open(makeFN2(fn, ".rfainfo"), O_RDWR)) == -1) { + advise (LLOG_EXCEPTIONS, NULLCP, "unlock: can't open '%s':%s", fn, + sys_errname(errno)); + return; + } + if (flock(fd, LOCK_UN) == -1) + advise (LLOG_EXCEPTIONS, NULLCP, "unlock: can't lock '%s':%s", fn, + sys_errname(errno)); + close(fd); +} + +/*------------------------------------------------------ + * releaseRfaInfoList - unlock list and free it + *------------------------------------------------------*/ +void releaseRfaInfoList(fn, rfa) + char *fn; + struct RfaInfo *rfa; +{ + unlock_rfainfo(fn); + freeRfaInfoList(rfa); +} + +/*------------------------------------------------------ + * statFile - return RfaInfo with results of stat(2) for "fn" + *------------------------------------------------------*/ +int statFile(fn, rfa) + char *fn; + struct RfaInfo *rfa; +{ + struct stat st; + struct group *gr, *getgrgid(); + struct passwd *pw, *getpwuid(); + char lnkbuf[BUFSIZ]; + char *f, buf[100]; + int rc; + static char lastuname[100], lastgname[100]; + static int lastuid = -1, lastgid = -1; + + /*advise (LLOG_DEBUG, NULLCP, "statFile: '%s'", fn);*/ + + if (lstat(fn,&st) == -1) { + advise (LLOG_EXCEPTIONS, NULLCP, "cant stat '%s':%s", fn, + sys_errname(errno)); + sprintf(rfaErrStr, "%s - %s", fn, sys_errname(errno)); + return NOTOK; + } + rfa->ri_size = st.st_size; + rfa->ri_accTime = st.st_atime; + rfa->ri_modTime = st.st_mtime; + rfa->ri_mode = st.st_mode; + + /*--- get user and group of owner ---*/ + if(st.st_uid == lastuid) + rfa->ri_owner = strdup(lastuname); + else + if ((pw = getpwuid (lastuid = st.st_uid)) == NULL) { + advise (LLOG_EXCEPTIONS, NULLCP, "Unknown user-id '%d'", lastuid); + sprintf(lastuname, "user-id %d", lastuid); + rfa->ri_owner = strdup(lastuname); + } else { + rfa->ri_owner = strdup(pw->pw_name); + strcpy(lastuname, pw->pw_name); + } + if(st.st_gid == lastgid) + rfa->ri_group = strdup(lastgname); + else + if ((gr = getgrgid (lastgid = st.st_gid)) == NULL) { + advise (LLOG_EXCEPTIONS, NULLCP, "Unknown group-id '%d'", lastgid); + sprintf(buf, "group-id %d", st.st_gid); + rfa->ri_group = strdup(buf); + } else { + rfa->ri_group = strdup(gr->gr_name); + strcpy(lastgname, gr->gr_name); + } + + /*--- read symbolic links ---*/ + if ((rfa->ri_mode & S_IFMT) == S_IFLNK) { + if ((rc = readlink(fn, lnkbuf, sizeof lnkbuf)) == -1) + sprintf(lnkbuf, "(error reading link)"); + else + lnkbuf[rc] = '\0'; + rfa->ri_lnkName = strdup(lnkbuf); + } + + return OK; +} + + +/*------------------------------------------------------ + * getFileLockInfo - read RFA file info from ".rfainfo" + *------------------------------------------------------*/ +int getFileLockInfo(dirname, rfap) + char *dirname; + struct RfaInfo **rfap; +{ + FILE *f; + + register char *s, *d; + char buf[BUFSIZ]; + char line[BUFSIZ]; + time_t version, lcksince; + int rc = 1; + struct RfaInfo *rfa; + + advise(LLOG_DEBUG,NULLCP,"getFileLockInfo: %s",dirname); + + if ((f = fopen(makeFN2(dirname, ".rfainfo"), "r")) == NULL) { + if (errno != ENOENT) { + return NOTOK_SYS; + } + else + return OK; + } + + while (fgets(line, sizeof(line), f)) { + s = line; + + while (isspace(*s)) + s++; + for(d = buf; ! isspace(*s); s++, d++) + *d = *s; + *d = '\0'; + if ((rfa = findRfaInfo(buf, *rfap)) == NULL) + continue; + + while (isspace(*s)) + s++; + for(d = buf; ! isspace(*s); s++, d++) + *d = *s; + *d = '\0'; + if ((rc = str2status(buf)) == NOTOK) { + sprintf(rfaErrStr, "invalid status in rfainfo '%s'", + makeFN2(dirname, ".rfainfo")); + advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr); + continue; + } + rfa->ri_status = rc; + + while (isspace(*s)) + s++; + for(d = buf; ! isspace(*s); s++, d++) + *d = *s; + *d = '\0'; + rfa->ri_lastChange = atol(buf); + + while (isspace(*s)) + s++; + for(d = buf; ! isspace(*s); s++, d++) + *d = *s; + *d = '\0'; + if (strcmp(buf, "NONE")) + rfa->ri_lckname = strdup(buf); + else + rfa->ri_lckname = NULL; + + + while (isspace(*s)) + s++; + for(d = buf; ! isspace(*s); s++, d++) + *d = *s; + *d = '\0'; + rfa->ri_lcksince = atol(buf); + + } /*-- while fgets --*/ + fclose(f); + return OK; +} + +/*------------------------------------------------------ + * getlockedRfaInfoList - get file info list for "dir" an lock it + *------------------------------------------------------*/ +int getLockedRfaInfoList(dir, rfaHeadp, target) + char *dir; + struct RfaInfo **rfaHeadp; + char *target; +{ + int rc; + + lock_rfainfo(dir); + if ((rc = getRfaInfoList(dir, rfaHeadp, target)) != OK) { + unlock_rfainfo(dir); + return rc; + } + return OK; +} + + +/*------------------------------------------------------ + * getRfaInfoList - get file info list for "dir" + *------------------------------------------------------*/ +int getRfaInfoList(dir, rfaHeadp, target) + char *dir; + struct RfaInfo **rfaHeadp; + char *target; +{ + struct RfaInfo *rfalist = NULL, **rfap = & rfalist; + DIR *dirp; + struct dirent *dp; + struct stat st; + int rc; + + advise (LLOG_DEBUG, NULLCP, "getRfaInfoList: '%s', target '%s'", dir, target); + /*--- find out if directory --*/ + if (stat(makeFN(dir),&st) == -1) { + advise (LLOG_EXCEPTIONS, NULLCP, "cant stat '%s':%s", dir, + sys_errname(errno)); + sprintf(rfaErrStr, "%s - %s", dir, sys_errname(errno)); + return NOTOK; + } + if (st.st_mode & S_IFDIR) { + + /*--- dir is a directory name, so open dir ---*/ + if ((dirp = opendir(makeFN(dir))) == NULL) { + sprintf(rfaErrStr, "%s - %s", dir, sys_errname(errno)); + return NOTOK; + } + + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + if (((*rfap) = mallocRfaInfo(strdup(dp->d_name))) == NULL) { + freeRfaInfoList(rfalist); + sprintf(rfaErrStr, "out of memory"); + return NOTOK; + } + SET_STATUS((*rfap)->ri_status, RI_UNREGISTERED); + SET_LOCKINFO((*rfap)->ri_status, RI_UNLOCKED); + SET_TRANSFER((*rfap)->ri_status, RI_TR_REQ); + + if ((target == NULL ) || (strcmp(target, dp->d_name) == 0)) { + if ((rc = statFile(makeFN2(dir, dp->d_name), *rfap)) != OK) { + freeRfaInfoList(rfalist); + return rc; + } + } + rfap = &((*rfap)->ri_next); + } + closedir(dirp); + if ((rc = getFileLockInfo(dir, &rfalist)) != OK) { + freeRfaInfoList(rfalist); + return rc; + } + } else { + /*--- dir is a single file ---*/ + + if (((*rfap) = mallocRfaInfo(strdup(basename(dir)))) == NULL) { + freeRfaInfoList(rfalist); + return NOTOK; + } + SET_STATUS((*rfap)->ri_status, RI_UNREGISTERED); + SET_LOCKINFO((*rfap)->ri_status, RI_UNLOCKED); + SET_TRANSFER((*rfap)->ri_status, RI_TR_REQ); + + if ((rc = statFile(makeFN(dir), *rfap)) != OK) { + freeRfaInfoList(rfalist); + return rc; + } + + /*--- get locking info ---*/ + if ((rc = getFileLockInfo(dirname(dir), &rfalist)) != OK) { + freeRfaInfoList(rfalist); + return rc; + } + } + *rfaHeadp = rfalist; + + return OK; +} + +/*------------------------------------------------------ + * putRfaInfoList - write RFA file info list to ".rfainfo" + *------------------------------------------------------*/ +int putRfaInfoList(dirname, rfa) + char *dirname; + struct RfaInfo *rfa; +{ + FILE *f; + char buf[BUFSIZ]; + + advise(LLOG_DEBUG,NULLCP,"putRfaInfo %s", makeFN(dirname)); + strcpy(buf, makeFN2(dirname,".rfainfo")); + rename (buf, makeFN2(dirname,".rfainfo.bak")); + if ((f = fopen(makeFN2(dirname, ".rfainfo"), "w")) == NULL) { + sprintf(rfaErrStr, "can't write %s/.rfainfo (%s)", dirname, + sys_errname(errno)); + return NOTOK; + } + for (; rfa; rfa = rfa->ri_next) { + if (rfa->ri_mode && (rfa->ri_mode & S_IFMT & (S_IFREG | S_IFDIR)) == 0) + continue; + + if (fprintf(f, "%s %s %ld %s %ld\n", rfa->ri_filename, + status2str(rfa->ri_status), rfa->ri_lastChange, + rfa->ri_lckname ? rfa->ri_lckname : "NONE", + rfa->ri_lcksince) == EOF) + { + sprintf(rfaErrStr, "can't write %s/.rfainfo (%s)", dirname, + sys_errname(errno)); + advise(LLOG_EXCEPTIONS,NULLCP,rfaErrStr); + fclose(f); + unlink(makeFN2(dirname, ".rfainfo")); + strcpy(buf, makeFN2(dirname,".rfainfo.bak")); + rename (buf, makeFN2(dirname,".rfainfo")); + return NOTOK; + } + } + fclose(f); + return OK; +} + + +/*------------------------------------------------------ + * extractRfaInfo - extract RFA file info by filename + *------------------------------------------------------*/ +struct RfaInfo *extractRfaInfo(fn, rfap) + char *fn; + struct RfaInfo **rfap; +{ + struct RfaInfo *h; + + for (; *rfap; rfap = &((*rfap)->ri_next)) + if (strcmp(fn, (*rfap)->ri_filename) == 0) { + h = *rfap; + *rfap = h->ri_next; + h->ri_next = NULL; + return h; + } + return NULL; +} + +/*------------------------------------------------------ + * remRfaInfo - remove RFA file info from list + *------------------------------------------------------*/ +void remRfaInfo (fn, rfap) + char *fn; + struct RfaInfo **rfap; +{ + struct RfaInfo *h; + + if ((h = extractRfaInfo(fn, rfap))) { + h->ri_next = NULL; + freeRfaInfoList(h); + } +} + +/*------------------------------------------------------ + * findRfaInfo - find RFA file info by filename + *------------------------------------------------------*/ +struct RfaInfo *findRfaInfo(fn, rfa) + char *fn; + register struct RfaInfo *rfa; +{ + for (; rfa; rfa = rfa->ri_next) + if (strcmp(fn, rfa->ri_filename) == 0) + return rfa; + return NULL; +} + +/*------------------------------------------------------ + * sortRfaInfoList - sort RFA list + *------------------------------------------------------*/ +void sortRfaInfoList(rfap) + struct RfaInfo **rfap; +{ + struct RfaInfo *tnext, *tosort, *sorted, **spp; + + sorted = NULL; + for (tosort = *rfap; tosort; tosort = tnext) { + tnext = tosort->ri_next; + for (spp = &sorted; *spp ; spp = &((*spp)->ri_next)) + if (strcmp((*spp)->ri_filename, tosort->ri_filename) > 0) + break; + tosort->ri_next = *spp; + *spp = tosort; + } + *rfap = sorted; +} + + + diff --git a/usr/src/contrib/isode/others/rfa/rfainfo.h b/usr/src/contrib/isode/others/rfa/rfainfo.h new file mode 100644 index 0000000000..c3c0801f5a --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfainfo.h @@ -0,0 +1,90 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfainfo.h : data structures to represent content of ".rfainfo" files + * and stat info of files + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfainfo.h,v 7.3 91/02/22 09:28:25 mrose Interim $ + * + * $Log: rfainfo.h,v $ + * Revision 7.3 91/02/22 09:28:25 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:02 mrose + * update + * + * Revision 1.1 91/01/04 16:09:53 ow + * Initial revision + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include + +struct RfaInfo { + char *ri_filename; + int ri_status; + time_t ri_lastChange; /* time when status change was done */ + char *ri_lckname; /* name of user that locked file */ + time_t ri_lcksince; /* time when file has been locked */ + + char *ri_owner; /* file info as per stat(2) */ + char *ri_group; + int ri_mode; + int ri_size; + time_t ri_modTime; + time_t ri_accTime; + char *ri_lnkName; + + struct RfaInfo *ri_next; +}; + +#define RI_STATUS(s) ((s) & 07) +#define SET_STATUS(v, s) (v)=(((v) & ~07) | (s)) +#define RI_UNREGISTERED 0 +#define IS_UNREGISTERED(s) (RI_STATUS(s) == RI_UNREGISTERED) +#define RI_MASTER 1 +#define IS_MASTER(s) (RI_STATUS(s) == RI_MASTER) +#define RI_SLAVE 2 +#define IS_SLAVE(s) (RI_STATUS(s) == RI_SLAVE) + +#define RI_LOCKINFO(s) ((s) & 070) +#define SET_LOCKINFO(v, s) (v)=(((v) & ~070) | (s)) +#define RI_LOCKED 010 +#define IS_LOCKED(s) (RI_LOCKINFO(s) == RI_LOCKED) +#define RI_UNLOCKED 020 +#define IS_UNLOCKED(s) (RI_LOCKINFO(s) == RI_UNLOCKED) + +#define RI_TRANSFER(s) ((s) & 0700) +#define SET_TRANSFER(v, s) (v)=(((v) & ~0700) | (s)) +#define RI_TR_AUTO 0100 +#define IS_TR_AUTO(s) (RI_TRANSFER(s) == RI_TR_AUTO) +#define RI_TR_REQ 0200 +#define IS_TR_REQ(s) (RI_TRANSFER(s) == RI_TR_REQ) + +extern int getLockedRfaInfoList(), getRfaInfoList(), putRfaInfoList(); +extern void remRfaInfo(); +extern struct RfaInfo *mallocRfaInfo(), *findRfaInfo(), *extractRfaInfo(); +extern int str2status(); +extern char *status2str(), *status2sstr(); + +extern struct RfaInfo *fi2rfa(); +extern struct type_RFA_FileInfoList *rfa2fil(); +extern struct type_RFA_FileInfo *rfa2fi(); + + diff --git a/usr/src/contrib/isode/others/rfa/rfatailor b/usr/src/contrib/isode/others/rfa/rfatailor new file mode 100644 index 0000000000..b633d44458 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfatailor @@ -0,0 +1,48 @@ +########################################################################## +# +# run-time Tailoring file for RFA +# +########################################################################## + +# default host to connect to +host = hostname + +# default user name used to log in at remote host +user = rfauser + +# password for default login name +password = secret + +# local root of shared subtree +root = /usr/shared + +# role of local site for time synchronization procedure +time = slave + +# default transfer mode for shared files +transfer = auto + +# back-up old version if it is replaced by newer version +backup = off + +# change owner of local file according to remote owner during syncronization +chown = off + +# change group of local file according to remote owner during syncronization +chgrp = on + +# change rights of local file according to remote owner during syncronization +chmod = on + +# clear set-uid-on-exec flag of files is transfered +clearsuid = on + +# automatically remove slave versions with no master version at remote site +rmslaves = on + +# debug logging +debuglog = on + +# execution of .rfaexec scripts during synchronization +rfaexec = on + diff --git a/usr/src/contrib/isode/others/rfa/rfatime.c b/usr/src/contrib/isode/others/rfa/rfatime.c new file mode 100644 index 0000000000..bbdbe57e42 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/rfatime.c @@ -0,0 +1,86 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * rfatime.c : external program to set time of local site + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/rfatime.c,v 7.3 91/02/22 09:28:27 mrose Interim $ + * + * $Log: rfatime.c,v $ + * Revision 7.3 91/02/22 09:28:27 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:05 mrose + * update + * + * Revision 1.1 91/01/04 16:07:59 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/rfatime.c,v 7.3 91/02/22 09:28:27 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include + +extern int errno; + +main(ac, av) + int ac; + char **av; +{ + + struct timeval tv; + time_t dt; + int err; + + + if (ac < 2) { + fprintf(stderr, + "*** can't set time : options for rfatime missing ***\n"); + exit(-1); + } + if ((dt = atol(av[1])) == 0L) { + fprintf(stderr,"*** can't set time : invalid time delta %s ***\n", + av[1]); + exit(-2); + } + if (dt > 0) { + /*--- clock "jumps" forwards ---*/ + gettimeofday(&tv, NULL); + tv.tv_sec += dt; + if (settimeofday(&tv, NULL) == -1) { + err = errno; + fprintf(stderr,"*** can't set time : %s ***\n", sys_errname(errno)); + exit(err); + } + } else { + tv.tv_sec = dt; + tv.tv_usec = 0L; + if (adjtime(&tv, NULL) == -1) { + err = errno; + fprintf(stderr,"*** can't set time : %s ***\n", sys_errname(errno)); + exit(err); + } + } + exit(0); +} + diff --git a/usr/src/contrib/isode/others/rfa/ryinitiator.c b/usr/src/contrib/isode/others/rfa/ryinitiator.c new file mode 100644 index 0000000000..143b2a6d7b --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/ryinitiator.c @@ -0,0 +1,377 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * ryinitiator.c : initators interface to the ISODE Ry-Library + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/ryinitiator.c,v 7.3 91/02/22 09:28:28 mrose Interim $ + * + * $Log: ryinitiator.c,v $ + * Revision 7.3 91/02/22 09:28:28 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:06 mrose + * update + * + * Revision 1.1 91/01/04 16:08:08 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/ryinitiator.c,v 7.3 91/02/22 09:28:28 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include "RFA-ops.h" +#include "RFA-types.h" + + +void errexit (), errmsg (), ros_adios (), ros_errmsg (), + acs_errmsg (), acs_errexit (); + + +static char *myservice = "rfa"; + +static char *mycontext = "rfa"; +static char *mypci = "rfa pci"; + + +extern char *isodeversion; +extern char *myname; + +static int ryconnect (); + + +makeconn (thehost, password, user) +char *thehost; +char *password, *user; +{ + int result; + PE data; + struct type_RFA_Initiate *initial; + + if ((initial = (struct type_RFA_Initiate *)malloc(sizeof *initial)) == NULL) + errexit ("memory", "out of"); + + initial -> user = str2qb (user, strlen (user), 1); + initial -> password = str2qb (password, strlen(password), 1); + + if (encode_RFA_Initiate (&data, 1, 0, NULLCP, initial) == NOTOK) { + errmsg (NULLCP, "Error encoding data"); + return 0; + } + data -> pe_context = 3; /* hack */ + + result = ryconnect (thehost, data, myservice, mycontext, mypci); + + free_RFA_Initiate (initial); + + return result; +} + + +static int ry_sd = NOTOK; + +static int ryconnect (thehost, data, theservice, thecontext, thepci) +char *thehost, + *theservice, + *thecontext, + *thepci; +PE data; +{ + struct SSAPref sfs; + register struct SSAPref *sf; + register struct PSAPaddr *pa; + struct AcSAPconnect accs; + register struct AcSAPconnect *acc = &accs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + AEI aei; + OID ctx, + pci; + struct PSAPctxlist pcs; + register struct PSAPctxlist *pc = &pcs; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + if ((aei = str2aei (thehost, theservice)) == NULLAEI) + errexit (NULLCP, "%s-%s: unknown application-entity",thehost, theservice); + if ((pa = aei2addr (aei)) == NULLPA) + errexit (NULLCP, "address translation failed"); + + if ((ctx = ode2oid (thecontext)) == NULLOID) + errexit (NULLCP, "%s: unknown object descriptor", thecontext); + if ((ctx = oid_cpy (ctx)) == NULLOID) + errexit (NULLCP, "out of memory"); + if ((pci = ode2oid (thepci)) == NULLOID) + errexit (NULLCP, "%s: unknown object descriptor", thepci); + if ((pci = oid_cpy (pci)) == NULLOID) + errexit (NULLCP, "out of memory"); + pc -> pc_nctx = 1; + pc -> pc_ctx[0].pc_id = 1; + pc -> pc_ctx[0].pc_asn = pci; + pc -> pc_ctx[0].pc_atn = NULLOID; + + if ((sf = addr2ref (PLocalHostName ())) == NULL) { + sf = &sfs; + (void) bzero ((char *) sf, sizeof *sf); + } + + if (AcAssocRequest (ctx, NULLAEI, aei, NULLPA, pa, pc, NULLOID, + 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, &data, 1, NULLQOS, + acc, aci) + == NOTOK) + acs_errexit (aca, "A-ASSOCIATE.REQUEST"); + + if (acc -> acc_result != ACS_ACCEPT) { + int slen; + char *str; + + if (acc -> acc_ninfo > 0 && (str = prim2str(acc->acc_info[0], &slen))) + errexit (NULLCP, "association rejected: [%s] %*.*s", + AcErrString (acc -> acc_result), slen, slen, str); + else + errexit (NULLCP, "association rejected: [%s]", + AcErrString (acc -> acc_result)); + } + + ry_sd = acc -> acc_sd; + ACCFREE (acc); + + if (RoSetService (ry_sd, RoPService, roi) == NOTOK) + ros_adios (rop, "set RO/PS fails"); + return OK; +} + +closeconn () +{ + struct AcSAPrelease acrs; + register struct AcSAPrelease *acr = &acrs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + + if (ry_sd == NOTOK) + return; + + if (AcRelRequest (ry_sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci) == NOTOK) + acs_errexit (aca, "A-RELEASE.REQUEST"); + + if (!acr -> acr_affirmative) { + (void) AcUAbortRequest (ry_sd, NULLPEP, 0, aci); + errexit (NULLCP, "release rejected by peer: %d", acr -> acr_reason); + } + + ACRFREE (acr); +} + + + +invoke (op, arg, res, err) +int op; +caddr_t arg, *res; +int *err; +{ + int result; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + switch (result = RyOperation (ry_sd, table_RFA_Operations, op, + arg, res, err, roi)) { + case NOTOK: /* failure */ + if (ROS_FATAL (rop -> rop_reason)) + ros_adios (rop, "STUB"); + ros_errmsg (rop, "STUB"); + break; + + case OK: /* got a result/error response */ + if (*err == RY_REJECT) { + errmsg (NULLCP, "REJECTED"); + return NOTOK; + } + break; + + case DONE: /* got RO-END? */ + errexit (NULLCP, "got RO-END.INDICATION"); + /* NOTREACHED */ + + default: + errexit (NULLCP, "unknown return from RyStub=%d", result); + /* NOTREACHED */ + } + + return result; +} + + +void ros_adios (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + ros_errmsg (rop, event); + + cleanup (); + + _exit (1); +} + + +void ros_errmsg (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + char buffer[BUFSIZ]; + + if (rop -> rop_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data); + else + (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason)); + + errmsg (NULLCP, "%s: %s", event, buffer); +} + + +void acs_errexit (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + acs_errmsg (aca, event); + + cleanup (); + _exit (1); +} + + +void acs_errmsg (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + char buffer[BUFSIZ]; + + if (aca -> aca_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + AcErrString (aca -> aca_reason), + aca -> aca_cc, aca -> aca_cc, aca -> aca_data); + else + (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason)); + + errmsg (NULLCP, "%s: %s (source %d)", event, buffer, + aca -> aca_source); +} + + +#ifndef lint +void _errmsg (); + + +void errexit (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _errmsg (ap); + + cleanup (); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +void errexit (what, fmt) +char *what, + *fmt; +{ + errexit (what, fmt); +} +#endif + + +#ifndef lint +void errmsg (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _errmsg (ap); + + va_end (ap); +} + + +static void _errmsg (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +void errmsg (what, fmt) +char *what, + *fmt; +{ + errmsg (what, fmt); +} +#endif + + +#ifndef lint +void ryr_errmsg (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _errmsg (ap); + + va_end (ap); +} +#else +/* VARARGS */ + +void ryr_errmsg (what, fmt) +char *what, + *fmt; +{ + ryr_errmsg (what, fmt); +} +#endif + diff --git a/usr/src/contrib/isode/others/rfa/ryresponder.c b/usr/src/contrib/isode/others/rfa/ryresponder.c new file mode 100644 index 0000000000..52189723e1 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/ryresponder.c @@ -0,0 +1,298 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * ryresponder.c : responders interface to the ISODE Ry-Library + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/ryresponder.c,v 7.3 91/02/22 09:28:30 mrose Interim $ + * + * $Log: ryresponder.c,v $ + * Revision 7.3 91/02/22 09:28:30 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:07 mrose + * update + * + * Revision 1.1 91/01/04 16:08:19 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/ryresponder.c,v 7.3 91/02/22 09:28:30 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include "ryresponder.h" +#include "tsap.h" /* for listening */ +#include "RFA-ops.h" +#include "rfa.h" + + +int debug = 0; +IFP startfnx; +IFP stopfnx; + +static jmp_buf toplevel; + +extern int errno; + + +int ros_init (vecp, vec) +int vecp; +char **vec; +{ + int reply, + result, + sd; + struct AcSAPstart acss; + register struct AcSAPstart *acs = &acss; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + register struct PSAPstart *ps = &acs -> acs_start; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + PE pe[1]; + + if (AcInit (vecp, vec, acs, aci) == NOTOK) { + acs_advise (aca, "initialization fails"); + return NOTOK; + } + advise (LLOG_NOTICE, NULLCP, + "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>", + acs -> acs_sd, oid2ode (acs -> acs_context), + sprintaei (&acs -> acs_callingtitle), + sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo); + + sd = acs -> acs_sd; + + for (vec++; *vec; vec++) + advise (LLOG_EXCEPTIONS, NULLCP, "unknown argument \"%s\"", *vec); + + reply = startfnx ? (*startfnx) (sd, acs, &pe[0]) : ACS_ACCEPT; + + result = AcAssocResponse (sd, reply, + reply != ACS_ACCEPT ? ACS_USER_NOREASON : ACS_USER_NULL, + NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult, + ps -> ps_prequirements, ps -> ps_srequirements, SERIAL_NONE, + ps -> ps_settings, &ps -> ps_connect, pe, + reply != ACS_ACCEPT ? 1 : 0, aci); + + ACSFREE (acs); + + if (result == NOTOK) { + acs_advise (aca, "A-ASSOCIATE.RESPONSE"); + return NOTOK; + } + if (reply != ACS_ACCEPT) + return NOTOK; + + if (RoSetService (sd, RoPService, roi) == NOTOK) + ros_adios (rop, "set RO/PS fails"); + + return sd; +} + + +int ros_work (fd) +int fd; +{ + int result; + caddr_t out; + struct AcSAPindication acis; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + switch (setjmp (toplevel)) { + case OK: + break; + + default: + if (stopfnx) + (*stopfnx) (fd, (struct AcSAPfinish *) 0); + case DONE: + (void) AcUAbortRequest (fd, NULLPEP, 0, &acis); + (void) RyLose (fd, roi); + return NOTOK; + } + + switch (result = RyWait (fd, NULLIP, &out, OK, roi)) { + case NOTOK: + if (rop -> rop_reason == ROS_TIMER) + break; + case OK: + case DONE: + ros_indication (fd, roi); + break; + + default: + adios (NULLCP, "unknown return from RoWaitRequest=%d", result); + } + + return OK; +} + + +int ros_indication (sd, roi) +int sd; +register struct RoSAPindication *roi; +{ + int reply, + result; + + switch (roi -> roi_type) { + case ROI_INVOKE: + case ROI_RESULT: + case ROI_ERROR: + adios (NULLCP, "unexpected indication type=%d", roi -> roi_type); + break; + + case ROI_UREJECT: + { + register struct RoSAPureject *rou = &roi -> roi_ureject; + + if (rou -> rou_noid) + advise (LLOG_EXCEPTIONS, NULLCP, "RO-REJECT-U.INDICATION/%d: %s", + sd, RoErrString (rou -> rou_reason)); + else + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-REJECT-U.INDICATION/%d: %s (id=%d)", + sd, RoErrString (rou -> rou_reason), + rou -> rou_id); + } + break; + + case ROI_PREJECT: + { + register struct RoSAPpreject *rop = &roi -> roi_preject; + + if (ROS_FATAL (rop -> rop_reason)) + ros_adios (rop, "RO-REJECT-P.INDICATION"); + ros_advise (rop, "RO-REJECT-P.INDICATION"); + } + break; + + case ROI_FINISH: + { + register struct AcSAPfinish *acf = &roi -> roi_finish; + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION/%d: %d", + sd, acf -> acf_reason); + + reply = stopfnx ? (*stopfnx) (sd, acf) : ACS_ACCEPT; + + result = AcRelResponse (sd, reply, ACR_NORMAL, NULLPEP, 0, + &acis); + + ACFFREE (acf); + + if (result == NOTOK) + acs_advise (aca, "A-RELEASE.RESPONSE"); + else + if (reply != ACS_ACCEPT) + break; + longjmp (toplevel, DONE); + } + /* NOTREACHED */ + + default: + adios (NULLCP, "unknown indication type=%d", roi -> roi_type); + } +} + + +int ros_lose (td) +struct TSAPdisconnect *td; +{ + if (td -> td_cc > 0) + adios (NULLCP, "TNetAccept: [%s] %*.*s", + TErrString (td -> td_reason), td -> td_cc, td -> td_cc, + td -> td_data); + else + adios (NULLCP, "TNetAccept: [%s]", TErrString (td -> td_reason)); +} + + +void ros_adios (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + ros_advise (rop, event); + + cleanup (); + + longjmp (toplevel, NOTOK); +} + + +void ros_advise (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + char buffer[BUFSIZ]; + + if (rop -> rop_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data); + else + (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason)); + + advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s", event, buffer); +} + + +void acs_advise (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + char buffer[BUFSIZ]; + + if (aca -> aca_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + AcErrString (aca -> aca_reason), + aca -> aca_cc, aca -> aca_cc, aca -> aca_data); + else + (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason)); + + advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s (source %d)", event, buffer, + aca -> aca_source); +} + + + +/*--------------------------------------------------------------*/ +/* ureject */ +/*--------------------------------------------------------------*/ +int ureject (sd, reason, rox, roi) +int sd, + reason; +struct RoSAPinvoke *rox; +struct RoSAPindication *roi; +{ + if (RyDsUReject (sd, rox -> rox_id, reason, ROS_NOPRIO, roi) == NOTOK) + ros_adios (&roi -> roi_preject, "U-REJECT"); + + return OK; +} + diff --git a/usr/src/contrib/isode/others/rfa/ryresponder.h b/usr/src/contrib/isode/others/rfa/ryresponder.h new file mode 100644 index 0000000000..c43ff6436f --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/ryresponder.h @@ -0,0 +1,47 @@ +/* ryresponder.h - include file for the generic idempotent responder + * + * $Header: /f/osi/others/rfa/RCS/ryresponder.h,v 7.2 91/02/22 09:28:33 mrose Interim $ + * + * $Log: ryresponder.h,v $ + * Revision 7.2 91/02/22 09:28:33 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/14 13:55:08 mrose + * update + * + * Revision 1.1 91/01/04 16:10:08 ow + * Initial revision + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "rosy.h" +#include "logger.h" + + +static struct dispatch { + char *ds_name; + int ds_operation; + + IFP ds_vector; +}; + + +void adios (), advise (); +void acs_advise (); +void ros_adios (), ros_advise (); +void ryr_advise (); + +int ryresponder (); + + +extern int debug; diff --git a/usr/src/contrib/isode/others/rfa/sync.c b/usr/src/contrib/isode/others/rfa/sync.c new file mode 100644 index 0000000000..143d027cfc --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/sync.c @@ -0,0 +1,660 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * sync.c synchronize local dir with remote site + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/sync.c,v 7.3 91/02/22 09:28:34 mrose Interim $ + * + * $Log: sync.c,v $ + * Revision 7.3 91/02/22 09:28:34 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:09 mrose + * update + * + * Revision 1.1 91/01/04 16:08:27 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/sync.c,v 7.3 91/02/22 09:28:34 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "RFA-ops.h" +#include "RFA-types.h" +#include "rfa.h" +#include "rfainfo.h" + +extern FILE *err, *out; +extern int interactive; + +char *incstr = "\t*** INCONSISTENCY : "; + +/*--------------------------------------------------------------*/ +/* createEmptyFile */ +/*--------------------------------------------------------------*/ +int createEmptyFile(dir, rfa) + char *dir; + struct RfaInfo *rfa; +{ + int tt[2], fd; + char buf[BUFSIZ]; + char fn[BUFSIZ]; + + sprintf(fn, "%s%s%s", dir, *(dir+strlen(dir)-1) == '/' ? "" : "/", + rfa->ri_filename); + /*-- create empty file for now --*/ + if ((fd = open(makeFN(fn), O_WRONLY | O_CREAT, rfa->ri_mode & 07555)) == -1) + { + fprintf(err,"\t*** can't create local SLAVE for %s (%s) ***\n" + , fn, sys_errname(errno)); + return NOTOK; + } + strcpy(buf,"This file has been created by RFA as a dummy."); + strcat(buf," Use RFA commands 'get' and 'setauto'\nto retrieve"); + strcat(buf," the actual content of this file\n"); + + if (write(fd, buf, strlen(buf)) == 0) { + fprintf(err,"\t*** can't write local SLAVE for %s (%s) ***\n" + , fn, sys_errname(errno)); + unlink(makeFN(fn)); + close(fd); + return NOTOK; + } + close(fd); + tt[0] = rfa->ri_modTime - 60; + tt[1] = rfa->ri_modTime - 60; + if (utime(makeFN(fn), tt) == -1) { + fprintf(err,"\t*** can't create local SLAVE for %s (%s) ***\n" + , fn, sys_errname(errno)); + unlink(makeFN(fn)); + return NOTOK; + } + changeFileOwner(fn, rfa); + return OK; +} + +/*--------------------------------------------------------------*/ +/* removeDir - check if dir is empty and remove it */ +/*--------------------------------------------------------------*/ +int removeDir(dir) + char *dir; +{ + struct dirent *dp; + DIR *dirp; + + + /*--- dir is a directory name, so open dir ---*/ + if ((dirp = opendir(makeFN(dir))) == NULL) { + fprintf(err, "*** can't open %s - %s ***", dir, sys_errname(errno)); + return NOTOK; + } + + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + if (strncmp(dp->d_name, "..", 2) && strncmp(dp->d_name, ".", 1) + && strncmp(dp->d_name, ".rfainfo", 8)) + { + closedir(dirp); + fprintf(err, "%scan't remove %s - not empty ***\n", incstr, dir); + return NOTOK; + } + } + closedir(dirp); + fprintf(err,"\tremoved local SLAVE directory '%s'\n", dir); + return OK; +} + +/*--------------------------------------------------------------*/ +/* checkState - check state of files and perform actions to */ +/* resolve inconsistencies if possible */ +/*--------------------------------------------------------------*/ +int checkState(rfa, rrfa, dir, wrp) + struct RfaInfo *rfa, *rrfa; + char *dir; + int *wrp; +{ + char fn[BUFSIZ]; + + if ((rfa == NULL) && (rrfa == NULL)) + return OK; + + sprintf(fn, "%s%s%s", dir, *(dir+strlen(dir)-1) == '/' ? "" : "/", + rfa ? rfa->ri_filename : rrfa->ri_filename); + /*-- checks if file exists only local --*/ + if (rrfa == NULL) + switch (RI_STATUS(rfa->ri_status)) { + case RI_MASTER: + case RI_UNREGISTERED: + return OK; + case RI_SLAVE: + fprintf(err, "%sno remote MASTER for local SLAVE '%s' ***\n" + , incstr, rfa->ri_filename); + if (doRmWidows) { + if (rfa->ri_mode & S_IFDIR) + removeDir(fn); + else { + unlink(makeFN(fn)); + fprintf(err,"\tremoved local SLAVE file '%s'\n", + rfa->ri_filename); + } + return OK; + } else + return NOTOK; + + default: + fprintf(err, "%sinvalid state for local '%s' ***\n", + incstr, rfa->ri_filename); + return NOTOK; + } + + /*-- checks if file exists only remote --*/ + if (rfa == NULL) + switch (RI_STATUS(rrfa->ri_status)) { + case RI_MASTER: + case RI_UNREGISTERED: + return OK; + case RI_SLAVE: + fprintf(err, "%sno local MASTER for remote SLAVE '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + default: + fprintf(err, "%sinvalid state for remote '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + } + + + /*-- checks if file exists at both sides --*/ + switch (RI_STATUS(rfa->ri_status)) { + case RI_UNREGISTERED: + switch (RI_STATUS(rrfa->ri_status)) { + case RI_UNREGISTERED: + return OK; + case RI_SLAVE: + fprintf(err, "%sUNREG/SLAVE state for '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + case RI_MASTER: + fprintf(err, "%sUNREG/MASTER state for '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + default: + fprintf(err, "%sinvalid state for remote '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + } + /* NOTREACHED */ + case RI_MASTER: + switch (RI_STATUS(rrfa->ri_status)) { + case RI_UNREGISTERED: + fprintf(err, "%sMASTER/UNREG state for '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + case RI_SLAVE: + return OK; + case RI_MASTER: + fprintf(err, "%sMASTER/MASTER state for '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + default: + fprintf(err, "%sinvalid state for remote '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + } + /* NOTREACHED */ + case RI_SLAVE: + switch (RI_STATUS(rrfa->ri_status)) { + case RI_UNREGISTERED: + fprintf(err, "%sSLAVE/UNREG state for '%s' ***\n", + incstr, rrfa->ri_filename); + if (doRmWidows) { + SET_STATUS(rfa->ri_status, RI_UNREGISTERED); + SET_TRANSFER(rfa->ri_status, RI_TR_REQ); + fprintf(err,"\tchanged status of '%s' to UNREGISTERED\n" + , rfa->ri_filename); + *wrp = 1; + } + return NOTOK; + + case RI_SLAVE: + fprintf(err, "%sSLAVE/SLAVE state for '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + case RI_MASTER: + return OK; + default: + fprintf(err, "%sinvalid state for remote '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + } + + /* NOTREACHED */ + default: + fprintf(err, "%sinvalid state for local '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK; + } + /* NOTREACHED */ +} + +/*--------------------------------------------------------------*/ +/* checkMasterSlave - do a consistency check on master and */ +/* slave file infos */ +/*--------------------------------------------------------------*/ +int checkMasterSlave(m, s, ms, ss) + struct RfaInfo *m, *s; + char *ms, *ss; +{ + if (m->ri_modTime < s->ri_modTime) { + fprintf(err,"%s %s SLAVE version of '%s' is newer than %s MASTER ***\n" + , incstr, ss, m->ri_filename, ms); + return NOTOK; + } + if ((m->ri_modTime == s->ri_modTime) && (m->ri_size != s->ri_size)) { + fprintf(err,"%s %s MASTER of '%s'", incstr, ms, m->ri_filename); + fprintf(err," has different size than %s SLAVE ***\n", ss); + return NOTOK; + } + return OK; +} + +/*--------------------------------------------------------------*/ +/* handleDir */ +/*--------------------------------------------------------------*/ +int handleDir(dir, localRfaListPtr, rrfa, rec, wrp) + char *dir; + struct RfaInfo **localRfaListPtr; + struct RfaInfo *rrfa; + int rec; + int *wrp; +{ + struct RfaInfo *rfa; + char fn[BUFSIZ]; + int rc; + + if (!strcmp(rrfa->ri_filename, ".") || !strcmp(rrfa->ri_filename, "..")) + return OK; + + sprintf(fn, "%s/%s", strcmp(dir,"/") ? dir : "", rrfa->ri_filename); + rfa = findRfaInfo(rrfa->ri_filename, *localRfaListPtr); + + switch (RI_STATUS(rrfa->ri_status)) { + case RI_UNREGISTERED: + if (rfa) + checkState(rfa, rrfa, dir, wrp); + return OK; + + case RI_SLAVE: + if (rfa == NULL) { + fprintf(err,"%sno local MASTER for remote SLAVE dir '%s' ***\n", + incstr, rrfa->ri_filename); + return NOTOK_INCONSISTENCY; + } + if ((rfa->ri_mode & S_IFDIR & S_IFMT) == 0) { + fprintf(err, + "%slocal file '%s' conflicts with remote directory ***\n", + incstr, rrfa->ri_filename); + return NOTOK_INCONSISTENCY; + } + if (checkState(rfa, rrfa, dir, wrp) == NOTOK) + return NOTOK_INCONSISTENCY; + break; + + case RI_MASTER: + if (rfa == NULL) { + fprintf(err, "found new MASTER sub-directory '%s' at remote\n", + rrfa->ri_filename); + if ((rfa = mallocRfaInfo(strdup(rrfa->ri_filename))) == NULL) { + fprintf(err,"%scant't create local SLAVE for %s ***\n", + incstr, rrfa->ri_filename); + return NOTOK_LOCAL_ERROR; + } + if (mkdir(makeFN(fn), rrfa->ri_mode & 07777) == -1) { + fprintf(err,"*** can't create subdir %s ***\n", + rrfa->ri_filename); + return NOTOK_FILEACCESS; + } + SET_STATUS(rfa->ri_status, RI_SLAVE); + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + SET_TRANSFER(rfa->ri_status, RI_TRANSFER(rrfa->ri_status)); + time(&(rfa->ri_lastChange)); + rfa->ri_modTime = 0L; + rfa->ri_mode = rrfa->ri_mode; + rfa->ri_next = *localRfaListPtr; + *localRfaListPtr = rfa; + changeFileOwner(fn, rrfa); + if (putRfaInfoList(dir, *localRfaListPtr) != OK) { + fprintf(err,"%scan't set SLAVE status of %s ***\n", incstr, + rrfa->ri_filename); + return NOTOK_FILEACCESS; + } + } else { /*--- local rfa found ---*/ + if((rfa->ri_mode & S_IFDIR & S_IFMT) == 0) { + fprintf(err,"%slocal file '%s' conflicts with",incstr, + rrfa->ri_filename); + fprintf(err," remote directory ***\n"); + return NOTOK_INCONSISTENCY; + } + if (checkState(rfa, rrfa, dir, wrp) == NOTOK) + return NOTOK_INCONSISTENCY; + + } /* if local rfa exists */ + } /* switch rrfa->ri_status */ + + /*--- now we have a local version of the dir ---*/ + if(rec && IS_TR_AUTO(rfa->ri_status)) + if ((rc = syncDir(fn, rec)) != OK) { + fprintf(err,"\t*** syncdir for %s failed ***\n", rrfa->ri_filename); + return rc; + } + + return OK; +} + + +/*--------------------------------------------------------------*/ +/* syncDir */ +/*--------------------------------------------------------------*/ +int syncDir (dir, rec) +char *dir; + int rec; +{ + struct RfaInfo *rfa, *localRfaList, *rrfa, *remoteRfaList; + char buf[BUFSIZ]; + int writeList, rc; + char *l, *lp; + struct stat st; + int rmode; + char fn[BUFSIZ]; + char syncfiles[BUFSIZ*10]; + + + /*--- get file Info ---*/ + if ((rc = getLockedRfaInfoList(dir, &localRfaList, NULL)) != OK) { + fprintf(err,"\t*** can't get rfainfo : %s ***\n", errMsg(rc)); + return(rc); + } + + /*--- get remote rfa list ---*/ + if ((rc = getRemoteRfaInfoList(dir, &remoteRfaList)) != OK) { + releaseRfaInfoList(dir, localRfaList); + return rc; + } + fprintf(err, "syncing directory %s\n", dir); + *syncfiles = '\0'; + + /*-- check remote list agaist local one --*/ + for(rrfa = remoteRfaList; rrfa; rrfa = rrfa->ri_next) { + writeList = 0; + switch(rrfa->ri_mode & S_IFMT) { + case S_IFIFO: + case S_IFCHR: + case S_IFBLK: + case S_IFSOCK: + continue; + + case S_IFLNK: + if (rrfa->ri_lnkName == NULL) + continue; + + strcpy(buf, makeFN2(dir, rrfa->ri_filename)); + if (*(rrfa->ri_lnkName) == '/') + lp = l = makeFN(rrfa->ri_lnkName); + else { + l = rrfa->ri_lnkName; + lp = makeFN2(dir, rrfa->ri_lnkName); + } + + if (stat(lp, &st) == -1) + continue; + + if ((rfa = findRfaInfo(rrfa->ri_filename,localRfaList)) == NULL) + { + fprintf(err, "\tcreating link %s to %s\n", + rrfa->ri_filename, l); + if(symlink(l, buf) == -1) { + fprintf(err,"\t*** can't create link %s ***\n",buf); + continue; + } + continue; + } + if ((rfa->ri_mode & S_IFMT) == S_IFLNK) { + if(strcmp(rfa->ri_lnkName, l) == 0) + continue; + unlink(makeFN2(dir, rfa->ri_filename)); + fprintf(err, "\tcreating link %s to %s\n", + rrfa->ri_filename, l); + if(symlink(l, buf) == -1) { + fprintf(err,"\t*** can't create link %s ***\n",buf); + continue; + } + continue; + } + fprintf(err,"%slocal file %s conflicts with remote link ***\n", + incstr, buf); + continue; + break; + + + case S_IFDIR: + if (handleDir(dir, &localRfaList, rrfa,rec,&writeList) != OK) { + continue; + } + continue; + + case S_IFREG: + break; + + default: + continue; + } + + /*--- rrfa->ri_filename is regular file ---*/ + + rfa = findRfaInfo(rrfa->ri_filename, localRfaList); + + switch (RI_STATUS(rrfa->ri_status)) { + case RI_UNREGISTERED: + checkState(rfa, rrfa, dir, &writeList); + break; + case RI_SLAVE: + if (checkState(rfa, rrfa, dir, &writeList) == NOTOK) + continue; + checkMasterSlave(rfa, rrfa, "local", "remote"); + break; + + case RI_MASTER: + if (rfa == NULL) { + + /*--- check if not a .rfaexec file ---*/ + if (strcmp(rrfa->ri_filename, ".rfaexec") == 0) { + fprintf(err, + "%sremote file '%s' is MASTER, not transfered ***\n" + ,rfa->ri_filename); + continue; + } + + fprintf(err, "\tfound new MASTER file '%s' at remote\n", + rrfa->ri_filename); + if ((rfa=mallocRfaInfo(strdup(rrfa->ri_filename)))==NULL) { + fprintf(err,"%scant't create local SLAVE for %s ***\n", + incstr, rrfa->ri_filename); + continue; + } + SET_STATUS(rfa->ri_status, RI_SLAVE); + SET_LOCKINFO(rfa->ri_status, RI_UNLOCKED); + SET_TRANSFER(rfa->ri_status, RI_TRANSFER(rrfa->ri_status)); + time(&(rfa->ri_lastChange)); + rfa->ri_modTime = 0L; + rfa->ri_mode = rrfa->ri_mode; + rfa->ri_next = localRfaList; + localRfaList = rfa; + writeList++; + } else { + if (checkState(rfa, rrfa, dir, &writeList) == NOTOK) + break;; + checkMasterSlave(rrfa, rfa, "remote", "local"); + } /* if local rfa exists */ + + /*--- now we are ready to get the remote file ---*/ + if (writeList && IS_TR_REQ(rfa->ri_status)) { + if (createEmptyFile(dir, rrfa) == NOTOK) + continue; + } else + if( IS_TR_AUTO(rfa->ri_status) && + (rfa->ri_modTime < rrfa->ri_modTime)) + { + sprintf(fn, "%s%s%s", dir, + *(dir+strlen(dir)-1) == '/' ? "" : "/", + rfa->ri_filename); + fprintf(err, "\t%s - ", rrfa->ri_filename); + if ((rc = getfile_aux(fn, rfa, &rmode)) != OK) + continue; + strcat(syncfiles, rfa->ri_filename); + strcat(syncfiles, " "); + } + break; + + default: + fprintf(err, "%sinvalid state for remote '%s' ***\n", + incstr, rrfa->ri_filename); + continue; + } /* switch rrfa->ri_status */ + + /*--- now we have a local slave version of the file ---*/ + if (writeList) + if ((rc = putRfaInfoList(dir, localRfaList)) != OK) { + fprintf(err,"%scan't set SLAVE status of %s ***\n", incstr, + rfa->ri_filename); + continue; + } + + } /* for rrfa */ + + + /*-- now check local list against remote list --*/ + for(rfa = localRfaList; rfa; rfa = rfa->ri_next) + if (findRfaInfo(rfa->ri_filename, remoteRfaList) == NULL) { + checkState(rfa, NULL, dir, &writeList); + } + if (writeList) + if ((rc = putRfaInfoList(dir, localRfaList)) != OK) { + fprintf(err,"%scan't set SLAVE status of %s ***\n", incstr, + rfa->ri_filename); + } + + releaseRfaInfoList(dir, localRfaList); + freeRfaInfoList(remoteRfaList); + + /*-- look for .rfaexec script --*/ + return rfaMake(dir, syncfiles); +} + +/*--------------------------------------------------------------*/ +/* rfaMake */ +/*--------------------------------------------------------------*/ +int rfaMake(dir, fns) + char *dir, *fns; +{ + struct RfaInfo *rfa, *rrfa, *localRfaList, *remoteRfaList; + char parentDir[BUFSIZ]; + char execfn[BUFSIZ]; + char buf[BUFSIZ]; + struct stat st; + int rc; + + /*-- check if files sync'ed --*/ + if (*fns == '\0' || doRfaExec == 0) + return OK; + + /*-- check if .rfaexec exists --*/ + sprintf(execfn, "%s/.rfaexec", dir); + if (lstat(makeFN(execfn),&st) == -1) { + if (errno == ENOENT) + return OK; + fprintf(err, "\t*** can't stat %s - %s", execfn,sys_errname(errno)); + return NOTOK_LOCAL_ERROR; + } + if (access(makeFN(execfn), X_OK) == -1) { + fprintf(err,"\t*** can't exec '%s' (%s) ***\n", execfn, + sys_errname(errno)); + return NOTOK_LOCAL_ERROR; + } + + /*-- check if dir is locked --*/ + if ((rc = getRfaInfoList(dirname(dir), &localRfaList)) != OK) { + return rc; + } + if (rfa = findRfaInfo(basename(dir),localRfaList)) { + if (IS_MASTER(rfa->ri_status) && IS_LOCKED(rfa->ri_status)) { + freeRfaInfoList(localRfaList); + return OK; + } + } + if ((rfa == NULL) || (rfa && !IS_MASTER(rfa->ri_status))) { + freeRfaInfoList(localRfaList); + + /*--- get remote rfa list ---*/ + if ((rc = getRemoteRfaInfoList(dirname(dir), &remoteRfaList)) != OK) { + return rc; + } + if ((rrfa = findRfaInfo(basename(dir),remoteRfaList)) == NULL) { + fprintf(err,"\t*** can't determine status of '%s' ***\n", dir); + freeRfaInfoList(remoteRfaList); + return NOTOK_REMOTE_ERROR; + } + if (!IS_MASTER(rrfa->ri_status)) { + fprintf(err,"\t*** can't find MASTER version of '%s' ***\n", dir); + freeRfaInfoList(remoteRfaList); + return NOTOK_REMOTE_ERROR; + } + if (IS_LOCKED(rrfa->ri_status)) { + freeRfaInfoList(remoteRfaList); + return OK; + } + freeRfaInfoList(remoteRfaList); + } + + /*-- change cwd to sync'ed dir --*/ + if (chdir(makeFN(dir)) == -1) { + fprintf(err,"\t*** can't change dir to '%s' (%s) ***\n", dir, + sys_errname(errno)); + return NOTOK_LOCAL_ERROR; + } + + /*-- so we are able to exec .rfaexec --*/ + fprintf(err,"\texecuting '%s'...\n", execfn); + sprintf(buf, "%s %s", makeFN(execfn), fns); + if (system(buf) == -1) + return NOTOK_LOCAL_ERROR; + + return OK; +} + diff --git a/usr/src/contrib/isode/others/rfa/synctime.c b/usr/src/contrib/isode/others/rfa/synctime.c new file mode 100644 index 0000000000..db04d6915e --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/synctime.c @@ -0,0 +1,192 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * synctime.c : SyncTime operation + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/synctime.c,v 7.3 91/02/22 09:28:36 mrose Interim $ + * + * $Log: synctime.c,v $ + * Revision 7.3 91/02/22 09:28:36 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:12 mrose + * update + * + * Revision 1.1 91/01/04 16:08:36 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/synctime.c,v 7.3 91/02/22 09:28:36 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ryresponder.h" +#include "psap.h" +#include "RFA-ops.h" /* operation definitions */ +#include "RFA-types.h" /* type definitions */ +#include "rfa.h" +#include "rfainfo.h" + +extern char *isodesbinpath; + +/*-------------------------------------------------------------- + * changeTimeWithRfatime - change time by executing external + * rfatime command as root + *-------------------------------------------------------------*/ +int changeTimeWithRfatime (dt) + long dt; +{ + char buf[BUFSIZ]; + char dtbuf[BUFSIZ]; + int pid, rc; + union wait st; + int p[2]; + + + if (pipe(p) == -1) { + sprintf(rfaErrStr, "can't set remote time (%s)",sys_errname(errno)); + return NOTOK; + } + + switch (pid = fork()) { + case NOTOK: + sprintf(rfaErrStr, "can't set remote time (%s)",sys_errname(errno)); + return NOTOK; + + case 0: /* child */ + close(2); + dup2(p[1], 2); + sprintf(buf, "%s/rfatime", isodesbinpath, dt); + sprintf(dtbuf,"%ld", dt); + advise (LLOG_NOTICE, NULLCP, "syncTime: start %s", buf); + + execl(buf, buf, dtbuf, NULL); + + fprintf(stderr, "can't set remote time (%s)",sys_errname(errno)); + advise (LLOG_NOTICE, NULLCP, "syncTime: exec failed: %s", buf); + exit(-2); + + default: + break; + } + + /*-------- does not work, wait always returns error "no children" + st.w_status =0; + if ((rc = wait(&st)) == -1) { + sprintf(rfaErrStr, "can't set remote time (%s)",sys_errname(errno)); + advise (LLOG_NOTICE, NULLCP, "syncTime: wait failed %s" sys_errname(errno)); + return NOTOK; + } + rc = st.w_status >>= 8; + if (rc > 0) + sprintf(buf, "can't set time (%s)", sys_errname(rc)); + else + sprintf(buf, "can't set remote time"); + advise (LLOG_NOTICE, NULLCP, "syncTime: start failed %x", rc); + -------------------*/ + + close(p[1]); + if (read(p[0], buf, sizeof buf)) { + *(buf+strlen(buf)-1) = '\0'; + advise (LLOG_EXCEPTIONS, NULLCP, "syncTime: rfatime failed - %s", buf); + close(p[0]); + strcpy(rfaErrStr, buf); + return NOTOK; + } + close(p[0]); + return OK; + +} + + +/*-------------------------------------------------------------- + * op_syncTime - synchronize time with peer + *-------------------------------------------------------------*/ +int op_syncTime (sd, ryo, rox, in, roi) + int sd; + struct RyOperation *ryo; + struct RoSAPinvoke *rox; + caddr_t in; + struct RoSAPindication *roi; +{ + register struct type_RFA_SyncTimeArg *sta = + (struct type_RFA_SyncTimeArg *) in; + struct type_RFA_SyncTimeRes str; + int rc; + time_t lt, dt; + char buf[BUFSIZ]; + + (void)time(<); + + if (rox -> rox_nolinked == 0) { + advise (LLOG_NOTICE, NULLCP, + "RO-INVOKE.INDICATION/%d: %s, unknown linkage %d", + sd, ryo -> ryo_name, rox -> rox_linkid); + return ureject (sd, ROS_IP_LINKED, rox, roi); + } + advise (LLOG_DEBUG, NULLCP, "RO-INVOKE.INDICATION/%d: %s", + sd, ryo -> ryo_name); + + if (sta->role == int_RFA_role_slave) { + if (timeSlave) { + return strerror(sd, error_RFA_miscError,"remote is not TIME master", + rox, roi); + } + (void)time(&(str.parm)); + str.parm += SENDTIME_DELAY; + } else { + if (!timeSlave) { + return strerror(sd, error_RFA_miscError,"remote is not TIME master", + rox, roi); + } + str.parm = dt = sta->time - lt; + + if (changeTime(dt) != OK) + if (changeTimeWithRfatime(dt) != OK) + return strerror(sd, error_RFA_miscError, rfaErrStr, rox, roi); + + if (dt > 0) + advise (LLOG_NOTICE, NULLCP, "syncTime: advanced time %ld sec", dt); + else + advise (LLOG_NOTICE, NULLCP, "syncTime: delayed time %ld sec", dt); + } + + /*--- return result ---*/ + if (RyDsResult (sd, rox->rox_id, (caddr_t)&str, ROS_NOPRIO,roi) == NOTOK) { + ros_adios (&roi -> roi_preject, "RESULT"); + } + + return OK; +} + + + + + + + diff --git a/usr/src/contrib/isode/others/rfa/tailor.c b/usr/src/contrib/isode/others/rfa/tailor.c new file mode 100644 index 0000000000..e8e57b34a3 --- /dev/null +++ b/usr/src/contrib/isode/others/rfa/tailor.c @@ -0,0 +1,280 @@ +/* + * RFA - Remote File Access + * + * Access and Management for a partial file system tree that exists + * at two sites either as master files or slave files + * + * tailor.c - read rfatailor and .rfarc file + * + * Contributed by Oliver Wenzel, GMD Berlin, 1990 + * + * $Header: /f/osi/others/rfa/RCS/tailor.c,v 7.3 91/02/22 09:28:37 mrose Interim $ + * + * $Log: tailor.c,v $ + * Revision 7.3 91/02/22 09:28:37 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/14 13:55:13 mrose + * update + * + * Revision 1.1 91/01/04 16:08:47 ow + * Initial revision + * + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rfa/RCS/tailor.c,v 7.3 91/02/22 09:28:37 mrose Interim $"; +#endif + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "logger.h" +#include "rfa.h" +#include "rfainfo.h" + +extern char *fsBase; +extern char *user, *host, *passwd, *strdup(); +extern LLog *pgm_log; + +int default_transfer = RI_TR_REQ; +int doChown = 0; +int doChgrp = 1; +int doChmod = 1; +int doClearSUID = 1; +int doRmWidows = 0; +int doRfaExec = 1; +int timeSlave = 0; +int compLimit = COMPRESSLIMIT; +char *passwd = "rfa"; +char *user = "rfa"; +char *host = "localhost"; +int backup = 0; + +#define VERROR(v) { sprintf(errp,"\n\tinvalid tailor value '%s'",(v));\ + errp += strlen(errp); \ + err++; } + +char *cut(s) + char *s; +{ + register char *s1; + + for (; *s && isspace(*s); s++) + ; + for (; *s && (*s == '"'); s++) + ; + for (s1 = s + strlen(s) - 1; (s1 != s) && isspace(*s1); s1--) + ; + for (; *s1 && (*s1 == '"'); s1--) + ; + if (*s1) + *(s1+1) = '\0'; + return s; +} + + + +int tailor(fn) + char *fn; +{ + FILE *f; + char buf[BUFSIZ]; + char *errp, *v, *o, *index(); + int err = 0; + + if ((f = fopen(fn, "r")) == NULL) + return OK; + + errp = rfaErrStr; + while (fgets(buf, BUFSIZ, f)) { + for (v = buf; isspace(*v); v++) + ; + if (*v == '\0') + continue; + if (*buf == '#') + continue; + if ((v = index(buf,'=')) == NULL) { + sprintf(rfaErrStr, "\n\tinvalid tailor string '%s'", cut(buf)); + fclose(f); + return NOTOK_LOCAL_ERROR; + } + *v = '\0'; + v = cut(v+1); + o = cut(buf); + + /*--- USER ---*/ + if (!strcasecmp(o, "user")) { + user = strdup(v); + } else + + /*--- PASSWORD ---*/ + if (!strcasecmp(o, "password")) { + passwd = strdup(v); + } else + + /*--- HOST ---*/ + if (!strcasecmp(o, "host")) { + host = strdup(v); + } else + + /*--- ROOT ---*/ + if (!strcasecmp(o, "root")) { + char buf[BUFSIZ]; + + if (realpath(v, buf, sizeof buf) == NULL) { + sprintf(errp,"\n\tinvalid local root '%s'", cut(v)); + errp += strlen(errp); + err++; + } + fsBase = strdup(buf); + } else + + /*--- COMPRESS ---*/ + if (!strcasecmp(o, "compress")) { + if((compLimit = atoi(v)) == 0) + VERROR(v); + } else + + /*--- BACKUP ---*/ + if (!strcasecmp(o, "backup")) { + + if (!strcasecmp(v, "on")) + backup = 1; + else + if (!strcasecmp(v, "off")) + backup = 0; + else + VERROR(v); + } else + + /*--- CHGRP ---*/ + if (!strcasecmp(o, "chgrp")) { + + if (!strcasecmp(v, "on")) + doChgrp = 1; + else + if (!strcasecmp(v, "off")) + doChgrp = 0; + else + VERROR(v); + } else + + /*--- TIME ---*/ + if (!strcasecmp(o, "time")) { + + if (!strcasecmp(v, "slave")) + timeSlave = 1; + else + if (!strcasecmp(v, "master")) + timeSlave = 0; + else + VERROR(v); + } else + + /*--- CHOWN ---*/ + if (!strcasecmp(o, "chown")) { + if (!strcasecmp(v, "on")) { + if (geteuid() != 0) { + sprintf(errp, + "\n\tWARNING: must run as root for option"); + errp += strlen(errp); + doChown = 0; + } else + doChown = 1; + } else + if (!strcasecmp(v, "off")) + doChown = 0; + else + VERROR(v); + } else + + /*--- CHMOD ---*/ + if (!strcasecmp(o, "chmod")) { + if (!strcasecmp(v, "on")) + doChmod = 1; + else + if (!strcasecmp(v, "off")) + doChmod = 0; + else + VERROR(v); + } else + + /*--- STRIP SUID ---*/ + if (!strcasecmp(o, "clearsuid")) { + if (!strcasecmp(v, "on")) + doClearSUID = 1; + else + if (!strcasecmp(v, "off")) + doClearSUID = 0; + else + VERROR(v); + } else + + /*--- REMOVE SLAVES ---*/ + if (!strcasecmp(o, "rmslaves")) { + if (!strcasecmp(v, "on")) + doRmWidows = 1; + else + if (!strcasecmp(v, "off")) + doRmWidows = 0; + else + VERROR(v); + } else + + /*--- LOGDEBUG ---*/ + if (!strcasecmp(o, "debuglog")) { + if (!strcasecmp(v, "on")) + pgm_log->ll_events |= LLOG_DEBUG | LLOG_TRACE | LLOG_NOTICE; + else + if (!strcasecmp(v, "off")) + pgm_log->ll_events = LLOG_EXCEPTIONS | LLOG_FATAL; + else + VERROR(v); + + } else + + /*--- RFA EXEC ---*/ + if (!strcasecmp(o, "rfaexec")) { + if (!strcasecmp(v, "on")) + doRfaExec = 1; + else + if (!strcasecmp(v, "off")) + doRfaExec = 0; + else + VERROR(v); + } else + + /*--- TRANSFER ---*/ + if (!strcasecmp(o, "transfer")) { + if (!strcasecmp(v, "request")) + default_transfer = RI_TR_REQ; + else + if (!strcasecmp(v, "auto")) + default_transfer = RI_TR_AUTO; + else + VERROR(v); + + } else { + sprintf(errp, "\n\tinvalid tailor option '%s'",o); + errp += strlen(errp); + err++; + } + } + fclose(f); + if (err) + return NOTOK; + return OK; +} + -- 2.20.1