`eW~ FREEWARE.SAVVQ FREEWARE.SAV.BACKUP/LOG/INTER FREE:[*...] FREEWARE.SAV/SAVE LANE ,+ V6.2 _DUHEP3::  _DUHEP3$DKA200: V6.2 ~ B*[CRINOID0051]000_README.TXT;1+,Q.c/ 4Wc^ <-Ke0123KPWOd56n/ 7s\ 89GHJzAThis is the distribution of CRINOID --- a multi-threaded Perl CGIServer for the OSU HTTPd.TABLE OF CONTENTS: 1. What you'll need first 2. The CRINOID processes 3. DOING THE INSTALLATION 4. EDITING CRINOID.CONFIG 5. STARTING IT UP! 6. RUNNING MULTIPLE CRINOIDs 7. Changing Configurations 8. A Typical Configuration 9. Setting up CGI scripts 10. Licensing 11. Acknowledgements 12. Change History 13. Needs Doing1. What you'll need first:==========================C0. A VMS system, preferably an Alpha...the code *should* compile onF VAXen, but it's mostly untested. VMS >= 6.2 is preferred. Again,A it's untested on earlier VMS versions, and anything <6.0 will; likely have problems with missing features (such as the# READERCHECK flag on MBX reads).E You'll need the DEC C compiler. I'm pretty sure VAXC won't do the< trick, and I've never gotten GNUC to work for me on VMS.E Patches to extend workability to earlier VMS versions, VAXen, and other compilers are welcome!O1. The OSU HTTP server: http://kcgl1.eng.ohio-state.edu/www/doc/serverinfo.htmlE While nearly all versions of the OSU HTTP server should work fineB with CRINOID, if you're going to do "tricky" HTTP requests viaD CGI...such as implementing Netscape Roaming, a patch to the fileB [.base_code]script_cgiexecute.c may be needed. Patch included= with this distribution (SCRIPT_CGIEXECUTE-19990611.PATCH)= The patch is for OSU HTTP server version 3.3b, but almostB certainly applies to previous 3.x releases...and perhaps laterC releases as well. You'll mostly need it if you're doing trickyF stuff with methods other than the "standard" ones (GET,HEAD,POST).K2. Perl, preferably a recent version: http://www.cpan.org/src/stable.tar.gzF CRINOID requires Perl 5.003 or newer, because of the use of Embed.B It's known to work with Perl 5.6.0, and intermediate versions.@ A patch to Opcode.xs used by Safe:: is required for CRINOID.D This patch does two things: it makes scripts running in a Safe::C partition think that they are in "main::" (important for moduleB use in scripts) and fixes a problem with _ use in scripts. IfG you have already patched Opcode.xs with an older patch that doesn'tH take care of the _ problem, don't worry...you'd likely only run into1 it while trying to upload files using CGI.pm.J The CONFIGURE procedure will try and figure out the patchlevel of yourJ Opcode.xs and tell you if you need a patch. If you've already patchedK and need the _ fix, apply the new patch to a virgin (unpatched) versionI of Opcode.xs. And if you've "installed" your Perl so that you don'tL have a copy of Opcode.xs sitting around, grab a copy from CPAN and patch it.M Just make sure that after patching you do the whole "build/install" thingG to get OPCODE.EXE into the right place in PERL_ROOT:[LIB...]. It'sH good to do a directory before and after to make sure that you've got( a new OPCODE.EXE in the right place.G If you're building a fresh copy of Perl, apply the patch before the main Perl build.6 Opcode.xs patches provided with this distribution:F OPCODE_500557_*.PATCH patch for Perl v 5.005.57 and earlierD OPCODE_500559_*.PATCH patch for Perl v 5.005.59 and later. (one of these *should* work for 5.005.58!)C To get the maximum benefit from Perl CGIs, you'll probably want. some or all of the following Perl modules: CGI.PM MIME::Base64 Digest::MD5 libwww GD PGPLOT?Please check the CRINOID web page (http://www.crinoid.com/) for?module compatibility status, pointers to useful utilities, etc.2. The CRINOID processes:========================J CRINOID ---> persistent DECnet server, multithreaded, that processesC requests from the OSU server, divvies up the workE among a number of TENTACLES and manages the various6 processes that actually do the work.A TENTACLE ---> a process running in a 'user' account with PerlH (plus modules) pre-loaded. Gets the request data fromF CRINOID, passes it into Perl and manages the various> +-- startup/shutdown and i/o needed for the CGI. |C +-> the Perl code in TENTACLE is 'OYSTER'; it sets upF Safe:: partitions for the CGI scripts, locates them,= sets up their $ENV, preloaded modules, etc.> Acts as a hard-shelled "wrapper" for a Perl.Helper programs:G STUB ---> temp program used to start a TENTACLE in user context( as a detached process.F LOGGER ---> records logging information from CRINOID and TENTACLE,J started automatically by CRINOID if not already present.FThere's probably a workaround for STUB, but the difficulty is that youEwant user 'A' to start a detached process for user 'B', where the newFprocess does NOT have any extra privs. The CREPRC system service callHlets you start processes with a different UIC, but not username; settingIthe username is typically a CMKRNL call, and if you don't have privs it'sno-go.?The way around this is for CRINOID to start STUB; a very simpleDdetached process that has enough privs that it can "IMPERSONATE" theEtarget user and start a detached (and unpriv'ed) TENTACLE process forFthat user. You don't want to IMPERSONATE from CRINOID, since *all* ofJthe threads get the same impersonation (n.b.: perhaps changed in VMS 7.2).CYou also don't want TENTACLE to have the privs to IMPERSONATE, ergoEthe STUB workaround. A kernel-mode workaround for pre-6.2 systems isLincluded, the configuration script will check if your system can IMPERSONATEor not.DLOGGER was created as a separate process so that we can keep logging$even if TENTACLE or CRINOID crashes.DTENTACLE's that are started for a user will execute their LOGIN.COM,Iso any special setup (stuff like PGPLOT setup, etc) should be done there;Dit'll be a 'network' login so should be absolutely minimal for speed@and robustness. You can also do any "all-TENTACLE" setup in the"TENTACLE.COM file in CRINOID_HOME.EA user with CGI's should also consider having an "OYSTER.CONFIG" fileDin their home directory. The OYSTER.CONFIG can set the logging fileCfor script STDERR output, logging level, preload Perl modules, and5tell Oyster what logicals to import into script %ENV.FAn example OYSTER.CONFIG is provided in the [.MISC] directory. HavingEyour script send stuff to STDERR, which then gets logged in a file isFcurrently one of the better ways of debugging CGIs...at least until weget TkPerl working on VMS.3. DOING THE INSTALLATION=========================!The following steps are required:G @configure & answer the questions (creates WWWPERL.COMG and CONFIGURE.MMS, tests C-compiler and4 system capabilities)E @build to build CRINOID,TENTACLE,STUB and LOGGER+ executables? @install to move files to CRINOID directory,M WWWPERL.COM to WWW_ROOT:[000000] (optionally) You can then3 @build tidy (or 'clean' or 'realclean')to clean up the build area.FNote that @configure and @build only create files in the CRINOID buildGdirectory (where CRINOID was unpacked), and @install only creates filesBin the CRINOID install directory selected during @configure, plus2optionally adding WWWPERL.COM to WWW_ROOT:[000000]After installation:< 1. Move WWWPERL.COM to the HTTP server `home' directory< (WWW_ROOT:[000000]) if not already done by @INSTALL.G 2. Add one or more `EXEC' rules to the HTTP server config files toH direct appropriate URLs to CRINOID. This is usually to be found> in WWW_ROOT:[SYSTEM]HTTP_SCRIPTS.CONF, something like:4.NEXT exec /cgi/* 0::"0=WWWPERL"nl:A if you're using the "metaconfig" stuff...otherwise just a(exec /cgi/* 0::"0=WWWPERL"nl:F You need an `EXEC' entry for each set of URLs that you want to) have CRINOID handle, for example:/ exec /cgi/* 0::"0=WWWPERL"nl:/ exec /~joe/cgi/* 0::"0=WWWPERL"nl:D 3. Edit CRINOID.CONFIG in the CRINOID_HOME directory to set theG mapping between URLs handled by CRINOID and the location of theE Perl scripts, and how many processes owned by whom, etc. willL be running the scripts. See below (and the supplied CRINOID.CONFIG) for more information.L 4. Add calls to @CRINOID_HOME:STARTUP RUN to your code for starting theF HTTP server on system startup, and @CRINOID_HOME:SHUTDOWN FULL* when the HTTP server is shut down.G 5. Do a @STARTUP of the CRINOID server...this will define logicalsRC and install the CRINOID processes with the privs they need.A? 6. Restart the OSU HTTP server to reload the config files.IIThe CRINOID processes will be started when an HTTP request for one of the"CGI's that it handles is received.Uninstallation:D---------------i A clean uninstall is quite easy:F 1. remove "exec" lines in OSU HTTP config that reference WWWPERL,$ and restart OSU HTTP server.1 2. remove WWWPERL.COM from WWW_ROOT:[000000]n? 3. do a @CRINOID_HOME:SHUTDOWN FULL if CRINOID is runninga% 4. delete files in CRINOID_HOME:oA note about privileges needed:s --------------------------------BA serious attempt has been made to minimize the priv's required toDrun CRINOID, and to leave those privs OFF unless needed for specificEoperations. This, of course, means that changes to VMS may result inrEneeding more (or different) privs than what I anticipated. NOTE thatGHI assume that all processes also have the usual NETMBX and TMPMBX privs.MCRINOID: SYSNAM DECNET ACPCONTROL, commands to LOGGERe2 LOG_IO,PHY_IO DECNET I/O> DETACH starting LOGGER, STUBsH WORLD querying/shutting down TENTACLESB SYSLCK for locks used with LOGGERFLOGGER: SYSNAM MBX name, etc. in system table? SYSLCK coordinate with CRINOID1@STUB: SYSPRV "username" impersonation! + IMPERSONATE [v7.2]eH + CMKRNL [pre v6.2] if sys$impersonate not availableC DETACH starting detached TENTACLES CSome of these (The *_IO privs) were found by trial and error, sinceiIthe VMS documentation was a bit vague. They didn't need to be explicitly0.*set*, just available as an "authorized" priv.?It is strongly suggested that you run CRINOID from an unpriv'ed Caccount (and your HTTP server too) with just NETMBX and TMPMBX, andsBhave the images installed with the minimal set of privs needed for operation.>The one case where you can not operate like this is if you are@doing program debugging, since images that are linked /TRACEBACKAcan't be installed with privs. See the files in [.debug_support]a)of the distribution for more information.'4. EDITING CRINOID.CONFIGt=========================eDCRINOID.CONFIG is located in the CRINOID installation directory. ItBtells CRINOID information about which accounts to use for startingCTENTACLE processes, and to direct URLs to the processes will handle Mrequests (NOTE: reinstallation will NOT overwrite an existing CRINOID.CONFIG)a A simple example, one would likeK http://example.com/cgi/~joe/script1.pl to run in JOE's accountandtK http://example.com/cgi/~fred/script2.pl to run in FRED's account BA set of TENTACLE processes running under a single account, with a>common set of privs and quotas, I call a "process group". TheC"process groups" are set up in CRINOID.CONFIG, and their mapping to URLs is also defined.eFWhen a CGI request comes in, CRINOID determines the process group fromEthe URL, then tries to find an idle process in that group, starting a5Dnew TENTACLE process if necessary. The request is handed off to theFidle TENTACLE, which calls its embedded Perl interpreter to invoke the)OYSTER script that actually runs the CGI.eFYou can set parameters for the process groups to determine the max/minDnumber of processes in that group; how many of them (max/min) can be idle, etc.AThis allows one to tune resource use for particular CGIs: a "hightDavailability" CGI might have min_idle = 2 so that there are always a?couple of idle processes ready to process requests. A typical=A"user" CGI process group (used infrequently, longer response timeh:acceptable) would have max_idle = 0 and max_processes = 1BIn addition to specifically designated process groups one can also<have a "user" process group, where the username is filled inBdynamically from the URL...the CGI equivalent of /~user/stuff.htmlEprocessing. Note that the individual processes that handle these CGIaDrequests are kept strictly separate (JOE's processes handle requestsCto ~joe, FRED's to ~fred, etc.) but they are handled with a commonn>set of configuration parameters. This is implemented with the=USERGROUP statement in the CRINOID.CONFIG file; you use it to Cdesignate a subdirectory name to look for the CGI scripts, and then Cuse a ".SCRIPT" command to designate the URLs that are to be run in the USERGROUP.DFor more details, look at the CRINOID.CONFIG with this distribution.5. STARTING IT UPo==================BAfter installing CRINOID, doing the necessary configuration of theFOSU_HTTP server, CRINOID, etc. ...then do @STARTUP in the CRINOID_HOME>directory. This will just define logicals and install images.@You can also do a @STARTUP RUN which will generate a faked HTTPrequest to get CRINOID running.aDDo an HTTP request for a simple CGI with a browser...something like:TEST.PL: #! perls) print "Content-type: text/plain\n\n";s print "I am.\n";6If you do a $SHOW SYSTEM you should see the following: CRINOIDi LOGGER* user/CGI01 -> this is a tentacle If you see:O STUBxxxxxxJor no ".../CGI.." processes, then there's some problem starting TENTACLEs.2Take a look at the README.TXT in [.DEBUG_SUPPORT].DAs CGI requests are made, the number of TENTACLE processes will varyDaccording to the load. CRINOID will automatically shut down TENTACLEDprocesses if they are no longer needed, or if they are consuming toomuch pagefile quota.6. RUNNING MULTIPLE CRINOIDs:n=============================rAI've only used this for debugging purposes (so one CRINOID can be Emessed with without causing problems for normal CGI requests), but itamay be more generally useful.pGHere's how to do it: @CONFIGURE, @BUILD, and @INSTALL CRINOID as normaleEin the "primary" directory. Then do another @CONFIGURE, specifying a Cdifferent ("secondary") directory. Also select a different CRINOIDlFserver process name ("CRINOID2") and Decnet service name ("WWWPERL2").BInstead of WWWPERL.COM being created in by CONFIGURE, WWWPERL2.COMwill be created./@BUILD and @INSTALL to the secondary directory.CECopy the WWWPERL2.COM that is generated in the "secondary" @CONFIGUREgDto your OSU HTTP sys$login directory. Then add "exec" rules in your1OSU HTTP script configuration to invoke WWWPERL2.sExample:F exec /cgi/* 0::"0=WWWPERL"nl: ( primary CRINOID)H exec /alt-cgi/* 0::"0=WWWPERL2"nl: ( secondary CRINOID)CMake sure that the CRINOID.CONFIG for the secondary server does noteGhave any "SERVICE ..." lines. The Decnet service name will be set from='a logical name defined in WWWPERL2.COM.eEYou will need to adjust urls, etc. (to handle /alt-cgi/* rather thanP*/cgi, for example) in CRINOID.CONFIG also.%Then @STARTUP the new CRINOID server. >NOTE: the first CRINOID server to start (in response to a HTTP:request) will start its own LOGGER. All of the subsequentACRINOID servers will use the same LOGGER process, so you may want >to edit the LOGGER.COM procedures in all of the CRINOID serverFdirectories to point them to a common log file. (See the definition ofCRINOIDLOG_FILE in LOGGER.COM).eAThe @SHUTDOWN procedure will only stop the associated CRINOID ButiC@SHUTDOWN FULL will also stop LOGGER, even if other CRINOID serverseBare still running. As of V0.5-2, one of those other CRINOIDs willDthen start a new LOGGER process. So a complete system-wide shutdown should doP [CRINOID_1]@SHUTDOWN] [CRINOID_2]@SHUTDOWN ...W [CRINOID_N]@SHUTDOWNe [CRINOID_1]@SHUTDOWN LOGGER@If you need to use different OYSTER.CONFIG's for the two serversE(probably a good idea), simply edit the OYSTER. script in the CRINOIDtJhome directory and change the line (near the beginning) to something like:# $ConfigFile = 'Oyster2.config';i7. Changing Configurations:/===========================:CWhile scripts and OYSTER.CONFIG files are automatically reloaded ifAthey are changed, this is NOT the case for changes to system-wide !programs and configuration files.hCIf OYSTER. or SCRIPT.PM are changed all TENTACLES should be killed, Ebut it does not require a restart of CRINOID. See KILL_TENTACLES.COM"Ain the [.misc] subdirectory of the distribution for a handy-dandyiTENTACLE killer.BIf CRINOID.CONFIG or the executables are changed, then the CRINOID<server should be shut down (@SHUTDOWN, use @SHUTDOWN FULL ifEexecutables or logging options were changed). If the executables arep=changed, you need to do a @STARTUP to get the new executables #installed in place of the old ones.N8. A Typical Configuration==========================&In WWW_ROOT:[SYSTEM]HTTP_SCRIPTS.CONF: ... , exec /cgi/* 0::"0=WWWPERL"nl: ...T"WWW_ROOT:[SYSTEM]START_SERVER.COM:8 $ here = f$parse("Z.Z;",f$env("procedure")) - "Z.Z;" $ x = f$setprv("all")A $ set def 'here' $ set def [-]o $ base = f$env("default")h $ set def 'here' $!7 $ F = F$SEARCH("DISK$SYSTEM3:[CRINOID]STARTUP.COM") ! $ IF F .NES. "" THEN @'F RUNiV $ @'here'HTTP_Startup HTTP 'base'http_server.log/9 'here'HTTP_MAIN.CONF "80" "443" $! $ x = f$setprv(x)c $ exitCRINOID.CONFIG:  #P@ # very simple, only user-scripts like /cgi/~fred/tryit.cgiH # mapping to disk:[fred.www-cgi]tryit.cgi #e LOGLEVEL 4 USERGROUP /www-cgi .SCRIPT /cgi/~*- .processes 0 3  .PAD 0 1r9. Setting up CGI scripts:==========================CYou can use "standard" (if there is such a thing!) CGI scripts withaCRINOID...two examples:r #! perl() print "Content-type: text/plain\n\n";. print "hello, world!\n"; #! perlo use CGI; $q = new CGI; & print $q->start_html('hey there');( print $q->h1('This is a big title'); print $q->end_html;OScript reusability------------------ATo improve the performance of your scripts, you should write themOBso that they are "reusable"...typically that is when you don't useDvariables before they are initialized, since the value might be leftIover from a previous run. (And don't count on them being there, either... Dtwo sucessive requests might go to two different TENTACLE processes)FYou should be able to run your script interactively with the "-w" flagset: $ perl -w myscript.cgi$and not have any warnings generated.HWhen your script is well behaved, then put in a line near the beginning: $CRINOID::Reuse = 1;KThis will tell the server that the script can be reused, at a great savingsa+in memory use and with much faster startup.iDIf your script is edited, the server will detect the fact and reloadthe newest version. File extensionsr---------------aCYou can specify which file-extensions to use for CGI scripts in theiOYSTER.CONFIG file:tH Suffixes .pl .cgi . # only allow NAME.pl NAME.cgi NAME. scriptsEThe URL still has to have the appropriate extension, but requests fori4files without an acceptable suffix will be rejected. /cgi/mystuff/testit.cgi9 /cgi/mystuff/testit2 -> for "testit2.".Directories and PATH_INFO=-------------------------RFIf you have subdirectories of your "cgi directory" you can put CGIs inCthose subdirectories, and the URLs will need the subdirectory name:EJ /cgi/mystuff/testit.cgi -maps to-> disk:[user.cgis]testit.cgiN /cgi/mystuff/test/test2.cgi -maps to-> disk:[user.cgis.test]test2.cgiJThe server normally searches for CGI scripts "depth first", so if you have!URL: /cgi/mystuff/test/xyz/test1p? [user.cgis.test.xyz]test1. <-- this one gets run: [user.cgis.test]xyz. this isn't run0 [user.cgis]test. "MYou can alter this behavior by setting the "NoDescend" flag in OYSTER.CONFIG;pIif "NoDescend" is set, subdirectories will *not* be searched for scripts.tIWhen a script is found, all of the URL to the right of the script name isnavailable as $ENV{'PATH_INFO'}:T4URL: /cgi/mystuff/test/xyz/something_else/herescript: [user.cgis.test]xyz.ipath_info: something_else/here Script %ENVR -----------aCThe CGI scripts normally don't have access to the "real, true" %ENVpC(i.e., logicals). Instead, they get an %ENV that is populated withnBthe standard CGI variables. This means that there's no "255-byte"Alimitations on CGI variables, but sometimes it's desirable to leta0scripts see or change a limited set of logicals.FThere's several commands you can put in OYSTER.CONFIG to control this:EStatic_ENV, Volatile_ENV, Persistant_ENV, each of which is follwed by #a whitespace list of logical names.= Static_ENV XYZIImports the value of logical XYZ to $ENV{'XYZ'} at each script execution.rCScripts can change $ENV{'XYZ'}, but it does not affect the logical.C Volatile_ENV XYZIImports the value of logical XYZ to $ENV{'XYZ'} at each script execution.sJScripts can change $ENV{'XYZ'}, and the logical XYZ is changed also. WhenGthe script finishes, the logical XYZ is restored to its original value.e Persistant_ENV XYZIImports the value of logical XYZ to $ENV{'XYZ'} at each script execution.IIScripts can change $ENV{'XYZ'}, and the logical XYZ is changed also. ThecHlogical XYZ is NOT reset at script termination and will keep the changesmade by the script.RCOne default setting: if the logical TZ is not defined, Oyster willbIdefine it by copying UCX$TZ (if present). TZ is set as a "Volatile_ENV". *This can be overridden with OYSTER.CONFIG.Modules and @INC----------------IModules that are frequently used, especially if used by multiple scripts,aJcan be pre-loaded to reduce script startup time. Some script pre-loadingKis done in OYSTER, but the scripts preloaded in OYSTER are really a minimallFset that (because of the way Perl loads them) *must* be preloaded if aKscript is going to use them. An example is modules that are linked to PerlS+statically, or that OYSTER uses internally. FIn OYSTER.CONFIG you can add "Preload" lines that will preload modulesfor your scripts:x Preload Digest::MD5s Preload PGPLOT ...aKNote that there are some modules (such as CGI) that you should NOT preload.rLThe CGI module has such tricky symbol export logic (and tends to keep memoryHof what it was doing) that preloading just won't work properly. ModulesHthat are preloaded are shared among ALL the scripts being run in a givenITENTACLE process, so modules that remember stuff from one run to the nexts!should be preloaded with caution.oLIf you preload a module you should also "use" it in your script...it doesn'tGhurt in terms of memory or startup time, and it may help initialize theGHmodule properly....as well as making the script so that it can be testedinteractively.IWhen you try to "use" modules, sometimes it will be necessary to set @INC 5appropriately. The directories on the @INC list are:d CRINOID_ROOT:[LIB]0 ..the usual Perl directories for @INC...* the 'home' directory for the CGI'sA directories specified by OYSTER.CONFIG "AddINC" commandsLD directories specified by #! perl -I ... line in the scriptDThe script "home" directory is either the base directory for the CGID(i.e., something like disk:[user.cgis] ) or the directory specified*in the "HomeDir" command in OYSTER.CONFIG.DIf you need to add directories to @INC for multiple scripts, use theDAddINC command. If it is just one or two scripts, then on the first.line of the script you can put something like:# #! perl -Idisk:[myincdir.stuff]  ...rest of script...HJust like you would do from a command line (except you don't need doublequotes around it).Debugging, Errors, etc.F------------------------CSeveral OYSTER.CONFIG commands are useful for debugging and keepingitabs on your scripts:eF Errlog oyster.log # log file (in sys$login dir, by default)? LogLevel 3 # log level, 1=critical...5=babbleOW MaxLogfileSize 50000 # create new logfile if old one is too big (size in bytes)o? MaxLogfileVersions 5 # purge logfile versions /keep=...D MaxRunTime 100 # max time a script can run, in secondsD Debug m # Perl debug flags (e.g., $Perl -Dm )MUse the "debug" command cautiously, some debug options are extremely verbose.nMIn addition you can specify the "-w" option on the #! line to turn on warning_Imessages. This isn't terribly useful for _running_ CGIs, but is good forDtesting.HThe script STDERR output will be sent to the Errlog file that you set inIOYSTER.CONFIG. If you don't set an Errlog file, the STDERR output windsi=up in CRINOID.LOG where it's much more difficult to decipher.gCSometimes there'll be a nasty, BUG in your CGI. When that happens,.FCRINOID will send back an error message...which may or may not display?properly depending on what stuff has been sent back previously.c)For example, having a text error message:y Error in ... at line ...6doesn't do much good when the script first writes out: Content-type: image/gifu<At that point it's best to look in CRINOID.LOG for guidance.BIf you want to customize the pages generated for errors, there's a&OYSTER.CONFIG command that might help:RErrorHTML disk:[dir]errorpage.html # use this for error messages from OYSTER.GIf an error occurs, OYSTER will grab the file specified and substitute:I-# -> text of error message &# -> name of script0before sending it out as a "text/html" document.GET, POST, PUT--------------FWhen you use a CGI to handle an HTTP request, you really have a lot ofEcontrol over what happens. For example, it's easy to implement your.Cown authentication system....just check $ENV{'HTTP_AUTHORIZATION'}, Fmaybe redirect to a "https:" protocol, check cookies, etc. ...and send1a "401" if you need the user to enter a password. EYou can also implement (using $ENV{'REQUEST_METHOD'}) the POST or PUT.Dmethods...POST gives you form data that you can read from STDIN, PUT!does the same for file uploading."BThere's some "nonstandard" methods that Netscape uses to implementCroaming access: MOVE (renames a file) and DELETE. I've managed tocEdo roaming access with a CRINOID CGI...it works fine (even moderatelytEfast) but your Netscape config will be messed up good if your network9connection goes down in the middle of an up- or download!FIf you're interested in applications like this, please let me know and I'll send you some example code.10. Licensing:===============s@This program is Open Source, under the general terms of the PerlCArtistic License (http://language.perl.com/misc/Artistic.html) with!Done exception: Part #5: "You may charge a reasonable copying fee..."Dfirst two sentences replaced with "You may sell this program as long=as you make available full source code and properly attributee authorship."=Needless to say, this program is provided "AS-IS" and with nosEwarrantee of fitness, usefulness, being non-destructive, etc. Use at your own risk.?Please inform me of any fixes or modifications you make; and ifu?you want to be alerted to upgrades or bugfixes let me know thatgyou're using CRINOID.A11. Acknowledgements====================CThis program owes a tremendous amount to Dave Jones and his work ontMthe OSU web server (http://kcgl1.eng.ohio-state.edu/www/doc/serverinfo.html). ?Astute readers of the code will notice a number of places where;-"Dave's code" was the obvious starting point.a;Larry Wall's Perl, of course, is a simple necessity of lifea3(http://www.perl.org), as well of CGI applications.r?Charles Bailey (bailey@newman.upenn.edu) provided a much-needednDkickstart to the development of this program, with his hints on what5would work best for good Perl CGI performance on VMS.fFThe bugs of course, are mine, all mine. But you're welcome to as manyas you want to take away!p12. Change History:q===================h7 0.1 early 1998? initial version (named `SQUID')g; 0.2 fall 1998 major rewrite of thread/piping code 9 0.25 spring 1999 logging removed from main program-: many thread/network timing changes4 config file capability added1 OYSTER config files added , 0.3 9 Dec 2000 first public releaseD 0.3-1 10 Dec 2000 from Emanuele Ruffaldi = need _PTHREAD_USE_D4 flag for VMS 7.2rI destroy_STRING needs to return a value, all casessG 16 Dec 2000 Fix to STUB.C so that it can compile on AXP fortC VMS 7.2 (extra unused params in IMPERSONATE E system service call). STARTUP.COM modified tohH check for and set IMPERSONATE priv if available.O 0.3-2 13 Jan 2000 from Dr. Martin P.J. Zinser u? VMS::Filespec needed preload, in OYSTER J also copy TZ logical into OYSTER Safe:: partitions@ SHUTDOWN.COM get the single quotes right< INSTALL.COM location of WWWPERL.COMF ~ FREEWARE.SAVQKe[CRINOID0051]000_README.TXT;1Wc*B>CONFIGURE.COM ask about 'installlib' directoryO 0.3-3 20 Jan 2000 from Dr. Martin P.J. Zinser 8 SQUID, ERRLOG, LOGGER found someI picky, picky DECC warnings, all about my abuse off1 signed vs. unsigned ints.iK 0.4 4 Feb 2000 rename to CRINOID; $SQUID::Reuse still works, addeda- $CRINOID::Reuse also.fC EXC_HANDLING.H/DECC bug check functionalityXI during config; Various config and com file fixes}A Define licensing to be applied to CRINOIDo= 8 Feb 2000 Mods to OYSTER: oyster.config can setuD "suffixes" to allow only some file suffixes,F set HomeDir directory to chdir to when runningN scripts, set NoDescend to NOT search in subdirectories7 for a script URL with PATH_INFO$; Generate fake PID in $$ for scriptsaE 0.4-1 10 Feb 2000 CRINOID.COM, SHUTDOWN.COM modified to make itb7 easier to run multiple servers. F Added KILL_TENTACLES.COM to shut down TENTACLE) processes easily.bA SCRIPT.PM improved script error-handling,-D implement -I -D and -w flags on CGI scipt's* leading `#!' line? (options not fully parsed, needs work).e> Extensive change in script compilationF compilation (eliminated the 'do $file' stuff),= and module sharing. It's faster now.SC Script timeout capabilities added in OYSTERcB and SCRIPT.PM, controlled by MaxRunTime in% OYSTER.CONFIGlF mod to CRINOID.C to remove trailing slash fromF CRINOID.CONFIG bindir's. It was making probems; for scripts, giving double slashes.hG Added OYSTER script-lookup caching, so we don'taH have to walk the CGI directory tree for a script) we already found.nF 0.4-2 14 Feb 2000 Modifications to CRINOID.C, SCRIPT.C, SCRIPT.HC and CRINOID_TYPES.H to support multihoming. F After a ".SCRIPT" directive in CRINOID.CONFIG,H one can add a "..LOCALHOST hostname" to restrictG the script URLs to only those from a particularpG localhost name (as specified in the SERVER_NAMEOF parameter generated by the OSU server). SinceG the search for a matching URL in CRINOID.CONFIGOE proceeds from the "top down", one should have.3 "more specific" URLs first. K If no ..LOCALHOST directive is given, any localhost]( name will match.J Added ErrorHTML parameter to OYSTER.CONFIG so thatF one can use a user-generated "CGI error" page;H substitutes on the fly for the error message andF script name. See [.MISC]OYSTER.CONFIG-EXAMPLEF Various OYSTER script/path/cache lookup fixes.K 0.4-3 15 Feb 2000 mods to CONFIGURE.COM, INSTALL.COM, and STARTUP.COMRL to make multi-server operation easier. In CRINOID.CC get DECNET_SERVICE_NAME from logical if notaE defined in CRINOID.CONFIG. The "WWWPERL.COM"5 (or whatever, name defined byd> DECNET_SERVICE_NAME) sets the logical.D Added ..BINDIR command for CRINOID.CONFIG asB an option for the .SCRIPT command, so thatC script URLs in the same process group don'ts/ have to share a bindir.E Note that the "USERGROUP" *does* have to havenC a common BINDIR, in the sense that the samesD subdirectory of a user's SYS$LOGIN is commonE for all. Can add process groups for specific ; users before the USERGROUP command.mK Mods to CRINOID to separate out the part of the URLCC that doesn't map to directory structure andhD make it available to OYSTER (SCRIPT_PREFIX).E Mods to OYSTER to strip the prefix when doing1 tree-search for a script.dE 0.4-4 16 Feb 2000 fixed an annoying bug with bindir finding fortC usergroups in CRINOID.C. And another smallnD (non-harmful) bug in OYSTER's url parsing is fixed.G First attempt at "non-PERSONA" capabilities forSD STUB. Checks for PERSONA system services inH CONFIGURE.COM. If there's no PERSONA, we have toE change the USERNAME in the PCB and JIB systemcE data structures with a little CMKRNL routine.dF We get some MACRO->C definitions converted forF $JIBDEF and $PCBDEF and set the "username" andE uic for the detached process started by STUB.pG Modified STARTUP to look for CMKRNL priv neededn- for non-Persona STUB.nJ Tried the non-Persona version of STUB and it seems% to work okay.s) 17 Feb 2000 Minor doc changeseG 15 May 2000 Martin Zinzer fixedV+ typo in STARTUP.COMtC 0.4-5 6 Jul 2000 move creation of WWWPERL.COM to build phaselK change to SCRIPT.PM to fix package/sub name findingnQ problem reported by Mike Marmor pL Prompted by Mike Marmor's suggestions, OYSTER.CONFIGJ can now have "addinc DIR1 [DIR2 [DIR3...]]" lines,M that will append to the @INC used to look up modules.rF 0.4-6 20 Jul 2000 Added AddENV and ExportENV to OYSTER.CONFIG toF import and export from logicals to script %ENVI This can also be used to export TZ to the processe' logicals table.rG Change to CONFIGURE.COM to look for .h files ineL Perl_root:[000000...], and to print more informativeL message when PERL_SETUP.COM is not found. Change toG INSTALL.COM to set up Perl before installation.nL Note: should use CGI.PM v2.68+, fixes some CGI::CarpN and file uploading problems, but CGI::Carp still callsG exit, resulting in an error. Submitted a minoreI patch to CGI.PM 2.68 to fix file upload: it seemsrD that file tests on _ don't work right in CGI& environment...J Added support for __DATA__ and __END__ in scripts;I note that this is NOT parsed internal to Perl, soPL you have to treat it gently: put __DATA__ on a line; by itself if you want it picked up.hN (E.g. /^\s*__DATA__\s*$/) Which is good style anyway.M The "read position" in the file is maintained between M script invocations (if you're using reusable scripts) L so you can read the data the first time and cache it3 in a persistant variable...eF Added MaxLogfileSize and MaxLogfileVersions toG OYSTER.CONFIG to control OYSTER log generation. H Added dump of module namespace to logfile to aid- in preload debugging. G Minor change to OYSTER and SCRIPT.PM to prevent J variables persisting when a script is modified and! reloaded.TH Tracked down at least one timing-related ACCVIO:G process idling, disconnecting, then DELPROC was H triggering it. A trivial fix, but hard to find!K Added an overload to "exit" for scripts and cleanedSG up messages. Note that to make CGI::Carp worktJ properly an overload to CGI::Carp::exit was added,J and a tricky "init_stash()" call so that the stashE for (root)::CGI:: and (root)::CGI::Carp:: are < initialized into the Safe partition.I Don't try to preload CGI (or any CGI::* modules), G there's too much stuff that shouldn't be sharede2 between different scripts.3 0.5 25 Jul 2000 update docs, bump version # A Fixed use of filetests on _ in scripts... F change in Opcode.xs was needed, so will update patches.@ Check Perl_root:[lib...] permissions andC check for Opcode.xs patch during CONFIGURE.oB Generated new Opcode patches based on Perl$ version #'s.E created [.debug_support]test_global.pl to getG a list of global symbols, added save/restore in D SCRIPT.PM, also sets $^T and $0 for scripts.; 0.5-1 28 Jul 2000 minor changes for VAX compatibility G 0.5-2 10 Aug 2000 changes to localization in OYSTER and SCRIPT.PM * (particularly $^O)J 0.5-3 14 Sep 2000 Add 'Exporter' to list of always-preloaded modules9 (needed for module symbol import) 4 Suppress "exit(0)" messages.H $In_CRINOID = 1 added in script symbol table, soF scripts can tell they're being run by CRINOID.D Thomas Pfau (pfau@maherterminals.com) caughtC misordered parameters in call to $CREMBX intG LOGGER.C. Fixed, and buffer quota defaulted toO- ~ 10 logger messages.c> Added exit_handler in LOGGER to deleteD logicals; was causing CRINOID restart to not@ start logger when needed. Also modifiedD SHUTDOWN.COM to shut down logger gently, and= deassign leftover logicals as needed.g6 Mods to DESCRIP.MMS to installD [.debug_support] stuff when building a debug* version of CRINOIDC Generate nfbdef.h dynamically during build.IE Handling of tentacle idling changed to removeIF deadlock when too many concurrent idle/connect5 requests are being processed. E Thomas Pfau (pfau@maherterminals.com) patched F CRINOID.COM to send info in /subject and avoidH use of tempfile...also patched LOGGER.C to allow5 viewing log while still open. K Added TieENV module so that scripts can selectively F (controlled by oyster.config) the "true" $ENV.J See [.misc]oyster.config-example for keyword info.E 0.51 19 Sep 2000 rewritten ERRLOG_CLIENT to avoid use of MbxQ,OJ hold/restart logging if LOGGER goes away and comes# back later. F added "max active connections" so we don't runE out of BYTCNT quota. Mailbox quotas defined. H Proc_mgr process startup "throttled" so we don'tF start N proc's all at once. Tentacle startupI reordered to flag readiness when closer to ready. K connection requests go directly from AST to thread, < bypassing main event loop in CRINOIDG CRINOID.COM dies if duplicate process, avoidingS: startup overhead from dying later.F 0.51-1 20 Sep 2000 added memory-leak diagnostics, fixed two smallI leaks. To turn on diagnostics, edit CONFIGURE.MMSnI and uncomment the XCD= ... line before compiling.dI Setting the log level to L_MEM+L_INFO gives a logvH entry for each malloc/free/realloc. Routines inE ERRLOG_CLIENT.C excluded from diagnostics for ( obvious reasons.K [.debug_support]mem.pl added to process CRINOID.LOGc> for matching malloc's with free's etc. 0.51-2 21 Sep 2000 > got STARTUP executable working, so nowE @STARTUP RUN will cause the CRINOID server to. start.F revision of LOGGER for speed: reads MBX's withC ASTs, queuing the messages for main programi: loop. Flushing reduced, and added9 "write-behind" with multibuffers.nH now using locks to coordinate LOGGER startup; ifK logger exits, CRINOID will restart. LOGGER will try E and take over MBX's left over from a previous F logger to prevent hanging tentacles. Only oneG LOGGER can run, and (if multiple CRINOIDs) only 9 one CRINOID will attempt restart.uH Revised .com files to deal with rooted logicals,C was causing problems with installed images.mC 0.51-3 22 Sep 2000 Tom Pfau provided F changes to error-handling, including a messageB definition file and new macros VMS_SIGNAL,H RMS_SIGNAL and revised VMS_ABORT and UNIX_ABORT.F Changes to DESCRIP.MMS, MANIFEST, [.misc]*.com3 to improve error reporting.eH 0.51-4 26 Sep 2000 thanks to Tom Pfau forF changes to open of OYSTER.LOG so that multipleH processes can share the logfile; changed open ofI OYSTER.CONFIG and of script files to allow sharedrF read access. Change in SCRIPT.PM for __DATA__E handling: closes file on eof or if script not ! reusable. D Minor bugfix in locking for multiple-CRINOID' logger startup.E0 0.51-5 27 Sep 2000 Added [.EXAMPLE_SCRIPTS]13. Needs Doing:================ Bug Fixes:2 o Lynx request sometimes causes CRINOID crash?3 o status code after crash messed up by pthreadsa Upgrades: o Documentation!. o A better syntax for CRINOID.CONFIG? -or-4 a Perl script to help generate CRINOID.CONFIG?: o get TKperl working, so can use for debugging scripts9 o an intelligent model of #procs/#idle vs. hit rates? ; o Add process quotas etc, that haven't been implementedD o MAJOR PROJECT: implement CRINOID as MST extension to OSU HTTPd1 o Taint check CGI scripts with -T on #! line?pA o IMPERSONATE per-thread and eliminate STUB for VMS 7.1? 7.2?e,--Chuck Lane lane@duphy4.physics.drexel.edu patch to CGI.PM 2.68 to fix file upload: it seemsrD that file tests on _ don't work right in CGI& environment...J Added support for __DATA__ and __END*[CRINOID0051]BUILD.COM;1+,W. / 4R  <-Ke0123KPWO 56nST7[(89GHJ$!5$! do the build..should already have been configured$!4$! p1 = target ... default is to build the s/w$!$ on error then goto cleanup $ on control_y then goto cleanup$ wo := write sys$output$!2$ wo "---------------CRINOID Build---------------"$ wo "...reading configuration")$ open/read/err=noconfig fd CONFIGURE.MMS$ loop:$ read/end=eloop fd lineR$ if f$extract(0,10,line) .eqs. "MAKE_UTIL=" then make_util = f$elem(1,"=",line)R$ if f$extract(0,10,line) .eqs. "PERLSETUP=" then perlsetup = f$elem(1,"=",line) $ goto loop$ eloop: $ close fd$!$ wo "...setting up Perl"$ @'perlsetup'$ name = "s/w build"$ if p1 .nes. "" then name = p1$ wo "...doing ''name'"&$ make_util/macro=(configure.mms) 'p1'$ wo "..''name' complete"$ if p1 .EQS. "" then wo ""7$ if p1 .EQS. "" then wo "The next step is to @INSTALL"$ goto cleanup $ noconfig:?$ write sys$output "You must @CONFIGURE before @BUILD is run" $ cleanup:,$ if f$trnlnm("FD") .nes. "" then close fd$ exit*[CRINOID0051]CONFIGURE.COM;1+,W.-/ 4h-+j<-Ke0123KPWO.56A X7k(89GHJ2$!$!0$! set configurations for CRINOID build/install$!$ wo := write sys$output$ on error then goto cleanup $ on control_y then goto cleanup$!$!/$ wo " CRINOID build/install configuration"-$ wo " ---------------------------------"$ wo ""C$ wo "After configuration, you can do a @BUILD to compile and link"G$ wo "CRINOID, TENTACLE and the ancillary programs STUB and CRINOIDLOG"?$ wo "After a successful build, @INSTALL will copy files to the $ wo "installation directories."$ wo ""C$ wo "------------------------------------------------------------"$!)$ wo "Checking MANIFEST for your kit ..." $ missing = 04$ open/read/err=nokit FD$CRINOID_CONFIGURE manifest.$ mloop:-$ read/end=emloop FD$CRINOID_CONFIGURE line$ line = f$edit(line,"trim")$ f = f$search(line,22)$ if f .eqs. ""$ then$ missing = 1;$ wo "File ''line' seems to be missing from your kit" $ endif $ goto mloop$ nokit:C$ wo "Your manifest. file seems to be missing! Configure aborted"$ exit $ emloop:$ close FD$CRINOID_CONFIGURE $ if missing$ then $ wo ""N$ wo " There seems to be files missing from your kit... configure aborted" $ wo "" $ exit$ endif"$ wo " OK!"$ wo ""$!$ arch = "VAX"8$ if f$getsyi("ARCH_NAME") .nes. "VAX" then arch = "AXP"*$ wo "Building ''arch' version of CRINOID"$ wo ""$!$!$ installdir = "SYS$DISK:[]"$ perl_loc = "".$ perl_setup = "PERL_ROOT:[VMS]PERL_SETUP.COM"$ make_name = ""$ vms_debug = 0$ verbose = 0$ showwhat = "" $ pdebug = 0$ process_name = "CRINOID"$ service_name = "WWWPERL"$ crinoidusr = "HTTP"$!$ x = f$search("configure.mms")$ if x .eqs. ""$ then $ redux = 0G$ wo "No previous configuration file found...using standard defaults"$ else $ redux = 11$ wo "Loading defaults from configuration file"0$ open/read FD$CRINOID_CONFIGURE configure.mms $ rcloop:2$ read/end=ercloop FD$CRINOID_CONFIGURE line$ x = f$elem(0,"=",line)2$ y = f$extract(f$len(x)+1,f$len(line),line)3$ if x .eqs. "INSTALLDIR" then installdir = y1$ if x .eqs. "PERLDIR" then perl_loc = y3$ if x .eqs. "PERLSETUP" then perl_setup = y2$ if x .eqs. "MAKE_NAME" then make_name = y2$ if x .eqs. "DEBUG" then vms_debug = 10$ if x .eqs. "VERBOSE" then verbose = 11$ if x .eqs. "SHOW" then showwhat = y/$ if x .eqs. "PERLDEBUG" then pdebug = 16$ if x .eqs. "CRINOID_MGR" then crinoidmgr = y6$ if x .eqs. "CRINOID_USR" then crinoidusr = y;$ if x .eqs. "EXC_WORKAROUND" then exc_workaround = y7$ if x .eqs. "PROCESS_NAME" then process_name = y7$ if x .eqs. "SERVICE_NAME" then service_name = y4$ if x .eqs. "NO_PERSONA" then no_persona = y$ goto rcloop $ ercloop:$ close FD$CRINOID_CONFIGURE$ endif $ showmode = (showwhat .nes. "")$ wo ""$!$! cc options/modes$!$$ if f$type(exc_workaround) .eqs. ""$ thenP$ wo "Some DECC compiler/library versions have a bug compiling EXC_HANDLING.H"B$ wo "when in /DEBUG mode...Now testing for presense of the bug"C$ wo "If the bug is present, you may see a stack trace, ACCVIO or$ wo "'out of memory' error"9$ wo "You can ignore error messages between the lines:"F$ wo "-------------------------------------------------------------"$!.$ open/write FD$CRINOID_CONFIGURE test_exc.c+$ write FD$CRINOID_CONFIGURE "/* test */":$ write FD$CRINOID_CONFIGURE "#include "*$ write FD$CRINOID_CONFIGURE "main() {}"$ close FD$CRINOID_CONFIGURE $ set noon$ cc/debug/noopt test_exc#$ ok = f$integer($STATUS) .and. 1F$ wo "-------------------------------------------------------------"$ on error then goto cleanup"$ on control_y then goto cleanup$ if (.not. ok)$ thenD$ wo "EXC_HANDLING.H/DEBUG problem detected, using workaround"$ exc_workaround = 1$ elseE$ wo "Your compiler and library are okay..no workaround needed"$ exc_workaround = 0 $ endif$ endif$!0$! check for presense of PERSONA system service$! $ if f$type(NO_PERSONA) .eqs. ""$ then $ wo ""B$ wo "Checking for the presense of the PERSONA system services."!$ tempfile = "test_persona.lis"E$ lib/list='tempfile'/only=secureshr/names sys$library:imagelib.olb$ has_persona = 0&$ open/read/error=done fd 'tempfile' $ loop:$ read/end=eloop fd lineM$ if f$locate("SYS$PERSONA_CREATE",line) .lt. f$len(line) then goto gotit $ goto loop $ gotit:3$ wo "This system has PERSONA system services."$ has_persona = 1 $ eloop: $ close fd $ done:.$ if f$trnlnm("FD") .nes. "" then close fd=$ if f$search(tempfile) .nes. "" then delete 'tempfile';*"$ no_persona = .not. has_personah$ if no_persona then wo "This system does NOT have PERSONA system services, using workaround for STUB"$ endif$ wo ""$!$!$! generate extra bits needed$!$!3$ wo "You need a 'make utility' to do the build..."$ if make_name .eqs. ""$ then$ if f$type(mmk) .nes. ""$ then$ make_name = "MMK"$ else$ make_name = "MMS" $ endif$ endif?$ call query QQQ "Select make utility" "''make_name'" "MMK|MMS"$ make_name = QQQ$ make_util = "MMS"/$ if make_name .eqs. "MMK" then make_util = mmk$!@$! where's Perl? Where's its setup file? Where's the .h files?$!$ if perl_loc .eqs. ""$ then%$ if f$trnlnm("PERL_ROOT") .nes. ""$ then-$ call unconceal Perl_Root:[000000] QQQ$ perl_loc = QQQ $ endif$ endifB$ call query QQQ "Location of Perl to use with CRINOID" 'perl_loc'$ perl_loc = QQQ $ call unconceal 'perl_loc' QQQ$ perl_loc = QQQ$!$ x = perl_loc - "]" + ".VMS]"#$ y = f$search(x+"perl_setup.com;")=$ if y .eqs. "" then y = f$search(perl_loc+"Perl_setup.com;")8$ if y .eqs. "" then y = f$search(perl_loc+"setup.com;")$ if y .eqs. ""$ thenH$ wo "Unable to find a 'perl_setup.com' file in PERL_ROOT:[000000]..."K$ wo "this is needed to set up Perl logicals for the TENTACLE processes."K$ wo "If you did an 'install' of Perl away from its build directory, you"J$ wo "may want to copy Perl_Setup.com to the Perl install directory and"I$ wo "re-run this procedure (control-Y out now). Otherwise, enter the"2$ wo "name of a .com file that will set up Perl";$ call query QQQ "COM file to setup the Perl selected" "" $ y = QQQ+$ if (y .eqs. "" .or. f$find(y) .eqs. "")$ thenE$ wo "unable to find the Perl setup file entered! Aborting..."$ goto cleanup $ endif$ endif)$ perl_setup = y - f$parse(y,,,"version")($ wo "Executing Perl setup procedure..."$ @'perl_setup'$ wo ""$!$! check perl permissions$!$ call check_perl_permission$!*$! check if Opcode patch has been applied$!$ call check_opcode0$ if f$integer($STATUS) .eq. 9 then goto cleanup$!$! get perl shareable images$!#$ x = f$extract(1,f$len(perl),perl)$ y = f$parse(x,".EXE",,"type")0$ ps = f$search("perl_root:[000000]perlshr''y'")3$ dps= f$search("perl_root:[000000]dbgperlshr''y'")#$ if ps .nes. "" .and. dps .nes. ""$ then $ def = "N"$ if pdebug then def = "Y"7$ call query QQQ "Build with DBGPERLSHR?" 'def' "Y|N"$ pdebug = (QQQ .eqs. "Y") $ wo ""$ else$ pdebug = (dps .nes. "")$ endif$!/$ x = f$search("Perl_root:[000000...]extern.h")$ if (x .eqs. "")$ thenN$ write sys$output "---ERROR: unable to locate EXTERN.h in PERL_ROOT:[*...]":$ write sys$output "is your Perl installation complete?"$ goto cleanup$ endif'$ perl_inc = f$parse("Z.Z;",x) - "Z.Z;"$!$!$!$ wo ""J$ wo "It is recommended that you build CRINOID in a 'work' directory that"4$ wo "is separate from its installation directory. "G$ wo "Files will not be moved to the installation directory until the "I$ wo "@INSTALL procedure is run, but the directories will be created (if"$ wo "necessary) now.$ wo ""$!$ uic = f$getjpi("","UIC")"$ if f$trnlnm("WWW_ROOT") .nes. ""$ then*$ f = f$search("WWW_ROOT:[000000]*.log")=$ if f .eqs. "" then f = f$search("WWW_ROOT:[000000]*.dir"),$ if f .nes. "" then uic = f$file(f,"UIC")$ endif$!6$ call query QQQ "CRINOID directories owner UIC" 'uic'$ ownqual = "".$ if uic .nes. "" then ownqual = "/own=''uic'"=$ call query QQQ "CRINOID installation location" 'installdir'$ call unconceal 'QQQ' QQQ$ installdir = QQQ)$ installlib = installdir - "]" + ".lib]"($ if f$parse(installdir+"Z.Z;") .eqs. ""$ then $ wo ""7$ wo "Hmmm....looks like ''installdir' doesn't exist"4$ call query QQQ "Create ''installdir'?" "Y" "Y|N"$ if QQQ .eqs. "Y"$ then,$ create/dir/log'ownqual' 'installdir' $ endif$ endif($ if f$parse(installlib+"Z.Z;") .eqs. ""$ then $ wo ""7$ wo "Hmmm....looks like ''installlib' doesn't exist"4$ call query QQQ "Create ''installlib'?" "Y" "Y|N"$ if QQQ .eqs. "Y"$ then,$ create/dir/log'ownqual' 'installlib' $ endifo$ endifo$!$ wo ""DM$ wo "You can build VMS-DEBUG versions of the CRINOID programs; while useful"nM$ wo "for debugging, they can't be installed with the privs they need to run"a6$ wo "so they must be run from a priviledged account."$ wo "" $ def = "N"o$ if vms_debug then def = "Y"D7$ call query QQQ "Build VMS-DEBUG version?" 'def' "Y|N"n$ vms_debug = (QQQ .eqs. "Y")I$ skip1:$!$ wo ""uH$ wo "A 'verbose' build includes compiler listing and linker map files."G$ wo "Most of the time these aren't needed, but can help to track down"-$$ wo "compilation or link problems."$ wo "" $ def = "N"$ if verbose then def = "Y"/-$ call query QQQ "Build VERBOSE?" 'def' "Y|N"o$ verbose = (QQQ .eqs. "Y")I$ skip2:$!$$ if .not. verbose then showmode = 0"$ if .not. verbose then goto skip3$ wo """B$ wo "When building with VERBOSE, you can set the level of detail"A$ wo "in the compiler listings with the /SHOW=() qualifier. See" A$ wo "the HELP for the CC command for allowed values for /SHOW. "8$ wo "Two useful cases are to omit the /SHOW qualifier ",$ wo "and /SHOW=(ALL) for maximum verbosity"$ wo "" ;$ call query QQQ "Build /SHOW=(...) options?" 'showwhat' ""o$ showwhat = QQQ $ showmode = (showwhat .nes. "")$ skip3:$!$ wo ""!F$ wo "If the CRINOID server crashes, it can optionally send a VMSmail"H$ wo "notification. Subsequent connections should restart CRINOID, but"G$ wo "the notification can be useful to track down problems. The user"RJ$ wo "to notify is put in the CRINOID_MGR logical; if blank or undefined,"*$ wo "no crash notification will be sent."E$ call query QQQ "User to notify if CRINOID crashes?" 'CRINOIDmgr' "" $ CRINOIDmgr = QQQ$!$wo ""H$wo "What USERNAME will the CRINOID server be running under? This will"E$wo "only be used in starting up the server without needing to use a"o$wo "browser."$wo ""?$ call query QQQ "Username for CRINOID server?" 'crinoidusr' ""s($ crinoidusr = f$edit(QQQ,"trim,upcase")$ wo ""_K$ wo "The following two options are generally only useful if you are going")L$ wo "to run multiple CRINOID servers. About the only reason to do so is to"K$ wo "do server debugging and testing separate from a 'production' server."UN$ wo "If you will only be running a single CRINOID server, take the defaults."P$ wo "For multiple CRINOID servers, each separate server should get a different"\$ wo "process name, and a different DECNET service name. (e.g., 'CRINOID2' and 'WWWPERL2')"M$ wo "Please keep in mind that there are length restrictions imposed by VMS."y$ wo "" E$ call query QQQ "Process name for CRINOID server?" 'process_name' ""_*$ process_name = f$edit(QQQ,"trim,upcase")$!L$ call query QQQ "DECNET service name for CRINOID server?" 'service_name' "".$ service_name = f$edit(QQQ,"collapse,upcase")$!$ wo ""t&$ wo "Writing Configuration file ... "/$ open/write FD$CRINOID_CONFIGURE CONFIGURE.MMSi,$ write FD$CRINOID_CONFIGURE "__''ARCH'__=1"8$ if vms_debug then write FD$CRINOID_CONFIGURE "DEBUG=1":$ if verbose then write FD$CRINOID_CONFIGURE "VERBOSE=1"A$ if showmode then write FD$CRINOID_CONFIGURE "SHOW=''showwhat'"d<$ if pdebug then write FD$CRINOID_CONFIGURE "PERLDEBUG=1"7$ write FD$CRINOID_CONFIGURE "INSTALLDIR=''installdir'""7$ write FD$CRINOID_CONFIGURE "INSTALLLIB=''installlib'"a2$ write FD$CRINOID_CONFIGURE "PERLDIR=''perl_loc'"2$ write FD$CRINOID_CONFIGURE "PERLINC=''perl_inc'"6$ write FD$CRINOID_CONFIGURE "PERLSETUP=''perl_setup'"5$ write FD$CRINOID_CONFIGURE "MAKE_NAME=''make_n!0~ FREEWARE.SAVWKe[CRINOID0051]CONFIGURE.COM;1h-$ame'"D5$ write FD$CRINOID_CONFIGURE "MAKE_UTIL=''make_util'"I8$ write FD$CRINOID_CONFIGURE "CRINOID_MGR=''crinoidmgr'"8$ write FD$CRINOID_CONFIGURE "CRINOID_USR=''crinoidusr'"?$ write FD$CRINOID_CONFIGURE "EXC_WORKAROUND=''exc_workaround'"-;$ write FD$CRINOID_CONFIGURE "PROCESS_NAME=''process_name'"p;$ write FD$CRINOID_CONFIGURE "SERVICE_NAME=''service_name'" 1$ write FD$CRINOID_CONFIGURE "!XCD=,DEBUG_MEMORY"c>$ if no_persona then write FD$CRINOID_CONFIGURE "NO_PERSONA=1"$ close FD$CRINOID_CONFIGURE($ wo "----Configuration file written---"$!$!$ wo ""uF$ wo "---------------------------------------------------------------"*$ wo "Configuration sucessfully completed" $ if (redux)$ thenV$ wo "If you have changed DEBUG or PERL options, you may want to @BUILD CLEAN first"$ endifo)$ wo "@BUILD to build the CRINOID files."r$! $ cleanup:9$ if f$type(QQQ) .nes. "" then delete/symbol/global QQQrP$ if f$trnlnm("FD$CRINOID_CONFIGURE") .nes. "" then close FD$CRINOID_CONFIGURE>$ if f$search("test_exc.c") .nes. "" then delete test_exc.c;B$ if f$search("test_exc.obj") .nes. "" then delete test_exc.obj;$ exit$!$!$ query: subroutine$ on error then exit 20 $ on control_y then exit 44"$ symbol = p1l$ if symbol .eqs. ""$ then8$ write sys$output "ERROR: symbol needed to query"$ exit 20 $ endifs$ prompt = p2 $ default= p3a$ allowed= p4 $ edit = p5o2$ if edit .eqs. "" then edit = "collapse,upcase" $ qagain: C$ read/end=qeof/prompt="''prompt' [''default']: " sys$command ans.0$ if edit .nes. "" then ans = f$edit(ans,edit)&$ if ans .eqs. "" then ans = default%$ if allowed .eqs. "" then goto qoke $ j = 0S $ qtest:%$ aa = f$element(j,"|",allowed)m&$ if aa .eqs. "|" then goto qbad%$ if aa .eqs. ans then goto qok.$ if aa .eqs. f$extract(0,f$len(aa),ans) $ then$ ans = aa$ goto qok $ endif$ j = j + 1e$ goto qtest $ qbad:n<$ write sys$output "Please select one of (''allowed')"$ goto qagain$ qok:$ 'symbol' == ansn $ exit 1 $ qeof:q $ exit 44a$ endsubroutines$!%$! call unconceal file symbol-to-setQ$!$ unconceal: subroutine :$ p = f$parse(p1,,,"directory","no_conceal,syntax_only")$!!$ d1 = f$element(1,"[",p) - "]" R$ if f$extract(f$len(d1)-1,1,d1) .eqs. "." then d1 = f$extract(0,f$len(d1)-1,d1)$ l1:c($ if f$extract(0,7,d1) .eqs. "000000."$ then($ d1 = f$extract(7,f$len(d1)-7,d1)$ goto l1: $ endif"%$ if d1 .eqs. "000000" then d1 = "" $!!$ d2 = f$element(2,"[",p) - "]" $ if d2 .eqs. "[" then d2 = ""$ l2:y($ if f$extract(0,7,d2) .eqs. "000000."$ then($ d2 = f$extract(7,f$len(d2)-7,d2)$ goto l2 $ endifn%$ if d2 .eqs. "000000" then d2 = ""t$!$ if d1 .eqs. ""$ then$ if d2 .eqs. "" $ then$ p = "[000000]" $ else$ p = "[''d2']" $ endif($ else$ if d2 .eqs. "" $ then$ p = "[''d1']"t $ else$ p = "[''d1'.''d2']" $ endifp $ endif9$ dev = f$parse(p1,,,"device","no_conceal,syntax_only")o/$ dev2 = f$parse(p1,,,"device","syntax_only")t?$ dev3 = f$parse(dev2,,,"directory","no_conceal,syntax_only")p=$ if (f$locate("][",dev3) .ge. f$len(dev3)) then dev = dev2$ 'p2' == dev + pd$ exit 1$ endsubroutine $!6$! check that PERL_ROOT:[LIB...] has W:RE permissions$!#$ check_perl_permission: subroutineN$ wo "Checking permissions in PERL_ROOT:[LIB...], this may take a few minutes"$ loop:p*$ f = f$search("Perl_Root:[LIB...]*.*;")!$ if f .eqs. "" then goto eloope$ p = f$file(f,"PRO") &$ x = f$element(4,"=",p) - "W" - "D"$ if x .nes. "RE" $ thenV$ wo "-------------------------------------------------------------------------"W$ wo "WARNING: some files in PERL_ROOT:[LIB...] do not have World:Read+Execute !"s3$ wo "this could cause user-scripts to fail."e $ wo ""RR$ wo "You should do a $SET FILE PERL_ROOT:[LIB...]*.*;/PROT=(W:RE) before "'$ wo "proceeding with the @BUILD"=V$ wo "-------------------------------------------------------------------------" $ exit $ endifr $ goto loop$ eloop:$ wo "..permission check OK"$ wo "".$ exit$ endsubroutineb$!$! check_opcode patchinesst$!$ check_opcode: subroutine#$ wo "Checking for Opcode patch..."s0$ open/write FD$CRINOID_CONFIGURE test_opcode.pl#$ wf = "write FD$CRINOID_CONFIGURE")$ wf "#! perl "W$ wf "use Safe;"$ wf "use Opcode;"$ wf "$s = new Safe FOO;"l$ wf "$s->permit(':all');"'$ wf "if (-d '/sys$scratch' && -w _) {""$ wf " $tstdir = '/sys$scratch';$ wf "} else {"$ wf " opendir(D,'/sys$login');"+$ wf " while (defined($_ = readdir(D))) { "$ wf " last if -d $_ && -w _; $ wf " }$ wf " closedir(D); $ wf " $tstdir = $_;$ wf "}"$ wf "$script = <<'THEEND';Q$ wf " blem();$ wf " sub blem {"$ wf " my @s = caller;"f$ wf " $BAR = $s[0];"s!$ wf " print $s[0],qq(\n);"m $ wf " }"i $ wf "THEEND"'$ wf "if ($tstdir) {"a@$ wf " $script .= 'if (-d q('.$tstdir.') && -w _) {'.qq(\n);"4$ wf " $script .= ' print qq(_OK\n);'.qq(\n);"($ wf " $script .= '} else {'.qq(\n);"8$ wf " $script .= ' print qq(_FAILED\n);'.qq(\n);"!$ wf " $script .= '}'.qq(\n);"n$ wf "} else {"a4$ wf " $script .= 'print qq(_NOTEST\n);'.qq(\n);"$ wf "}"$!$ wf "print $],qq(\n);"e%$ wf "print $Opcode::VERSION,qq(\n);"i$ wf "$s->reval($script);"$ close FD$CRINOID_CONFIGURE&$ perl test_opcode.pl >test_opcode.out$ delete test_opcode.pl;$!0$ open/read FD$CRINOID_CONFIGURE test_opcode.out($ read FD$CRINOID_CONFIGURE perl_version*$ read FD$CRINOID_CONFIGURE opcode_version%$ read FD$CRINOID_CONFIGURE main_testa)$ read FD$CRINOID_CONFIGURE underbar_testf$ close FD$CRINOID_CONFIGURE$!=$ if (main_test .eqs. "main" .and. underbar_test .eqs. "_OK")s$ then$ delete test_opcode.out;s$ wo "Opcode patch test: OK" $ exit 1$ else$ if (main_test .eqs. "FOO")$ then$ delete test_opcode.out;K$ wo "Opcode patch has not been applied to this Perl. Please read the" T$ wo "file 000_README.TXT and apply a patch to the file [.ext.Opcode]opcode.xs"L$ wo "in your Perl distribution, or CRINOID will not operate properly." $ wo ""M$ wo "If you have an 'installed' Perl (i.e., with no source code), then")M$ wo "get a copy of Opcode from CPAN, patch it, build it and install it"HQ$ wo "in your Perl (installation = copy OPCODE.EXE to where previous versionA/$ wo "is in your PERL_ROOT:[LIB...] tree)"y $ wo ""U$ wo "You will need to use the correct patch for your version of Perl. If you "Y$ wo "get a copy of Opcode from CPAN, it will probably be for the most recent Perl."i0$ wo "See 000_README.TXT for more details." $ wo ""L$ wo "It is a good idea to do that NOW, before building CRINOID, since"F$ wo "a Perl rebuild might be triggered by the change to Opcode."9$ call query QQQ "Terminate CONFIGURE.COM" "Y" "Y|N" $ if QQQ then exit 9i$$ else if (main_test .eqs. "main")$ then)$ if (underbar_test .eqs. "_FAILED")E $ thenN#$ delete test_opcode.out;lR$ wo "You seem to have a patched Opcode.xs, but not the latest version "R$ wo "patch...you should apply the most recent patch to a 'virgin' copy"?$ wo "of Opcode.xs. See 000_README.TXT for details."w>$ call query QQQ "Terminate CONFIGURE.COM" "Y" "Y|N"$ if QQQ then exit 9.$ else if (underbar_test .eqs. "_NOTEST") $ thene#$ delete test_opcode.out;pT$ wo "Opcode.xs has been patched, but CONFIGURE was not able to determine"V$ wo "if the patch is an up-to-date one. If you have applied an up-to-date"6$ wo "patch, then continue with CONFIGURE. ">$ call query QQQ "Terminate CONFIGURE.COM" "Y" "Y|N"$ if QQQ then exit 9 $ elsei$ goto weird $ endif $ endif$ else$ goto weirdp $ endif'$ endifr$ exit 1$ weird:O$ wo "Hmmm...there seems to be something funny with how Safe:: is working""H$ wo "Please send the following to lane@duphy4.physics.drexel.edu:"F$ wo "----------------------------------------------------------"$ wo "test_opcode output:" $ type test_opcode.outH$ delete test_opcode.out;F$ wo "----------------------------------------------------------"!$ wo "...aborting configure" $ exit 9C$ endsubroutine"*[CRINOID0051]CREATE_OPT.COM;1+,+X. / 4N <-Ke0123KPWO 56R7~(89GHJ$$! p1 = options file to create,$! p2... = keywords for shareables to use$!$!=$! :vector=(proc=procedure) -> SYMBOL_VECTOR or UNIVERSAL $! :threads $! :perl $! :dbgperl&$! :linkopt (options file comment)1$! :jibpcbdef (generate .h file of jib/pcb defs)-$! :nfbdef (generate .h file of nfb defs)!$! :comment rest is a comment$!D$ if f$edit(p2,"upcase") .eqs. ":JIBPCBDEF" then goto gen_jibpcbdefA$ if f$edit(p2,"upcase") .eqs. ":NFBDEF" then goto gen_nfbdef$!----------CONFIG FILE FIRST$ OPEN/READ fd configure.mms$ cloop:$ read/end=ecloop fd line$ x = f$elem(0,"=",line).$ y = f$extract(f$len(x)+1,f$len(line),line),$ if x .eqs. "PERLDIR" then perl_loc = y.$ if x .eqs. "PERLSETUP" then perl_setup = y $ goto cloop $ ecloop: $ close fd$!$ p1 = f$edit(p1,"upcase")$ oopt = "/WRITE"-$ if f$locate("/APPEND",p1) .lt. f$length(p1)$ then$ oopt = "/APPEND"/$ p1 = f$extract(0,f$locate("/APPEND",p1),p1)$ endif$ open'oopt' fd 'p1'$ j = 1$ loop1: $ j = j + 1 $ if j .gt. 8 then goto eloop1 $ x = p'j'!$ if x .eqs. "" then goto loop11$ if f$extract(0,1,x) .eqs. ":" then goto loop1$ write fd x $ p'j' = "" $ goto loop1 $ eloop1:$ j = 1$ loop2: $ j = j + 1 $ if j .gt. 8 then goto eloop2 $ x = p'j'!$ if x .eqs. "" then goto loop2#$ x = f$edit(x,"collapse,upcase")$!.$ if f$locate(":THREADS",x) .lt. f$length(x)$ then-$ write fd "sys$share:cma$open_rtl/share"$ goto loop2 $ endif$!+$ if f$locate(":PERL",x) .lt. f$length(x)$ then'$ write fd "! PERL_LOC=''perl_loc'"+$ write fd "! PERL_SETUP=''perl_setup'"$ write fd "perlshr/share"$ goto loop2 $ endif$!.$ if f$locate(":DBGPERL",x) .lt. f$length(x)$ then'$ write fd "! PERL_LOC=''perl_loc'"+$ write fd "! PERL_SETUP=''perl_setup'"!$ write fd "dbgperlshr/share"$ goto loop2 $ endif$!.$ if f$locate(":LINKOPT",x) .lt. f$length(x)$ then/$ write fd "! ",f$extract(1,f$len(x)-1,x)$ goto loop2 $ endif$!-$ if f$locate(":VECTOR",x) .lt. f$length(x)$ then$ j = f$locate("=",x)($ y = f$extract(j,f$length(x)-j,x),$ if f$getsyi("ARCH_NAME") .nes. "VAX" $ then($ write fd "SYMBOL_VECTOR''y'" $ else"$ y = f$element(1,"(",y)"$ y = f$element(0,"=",y)%$ write fd "UNIVERSAL=''y'" $ endif$ goto loop2 $ endif.$ if f$locate(":COMMENT",x) .lt. f$length(x)$ then$ y = f$element(1,"=",x)$ write fd "! ''y'" $ endif$! $ goto loop2 $ eloop2: $ close fd$ exit$!$!$ gen_pcbjibdef:,$ call generate_hfile 'p1' "$PCBDEF,$JIBDEF"$ exit$! $ gen_nfbdef:$$ call generate_hfile 'p1' "$NFBDEF"$ exit$!$!$ generate_hfile: subroutine$!,$! make an .h file from lib.mlb macro files$!$ filename = p1$ modules = p2$ symbol = f$parse(p1,,,"name")0$ symbol = "_" + f$edit(symbol,"upcase") + "_H"@$ lib/extract=('modules')/out=temp.mar/macro sys$library:lib.mlb$ open/read fd temp.mar$ open/write fd2 'filename'$ write fd2 "#ifndef ''symbol'"$ write fd2 "#define ''symbol'"$ loop:$ read/end=eloop fd line6$ if f$extract(0,4,line) .nes. "$EQU" then goto loop,$ if f$locate("<^X",line) .lt. f$len(line)$ then $ j = f$locate("<^X",line)$ k = f$locate(">",line)N$ line = "#define "+f$extract(4,j-4,line)+"0x"+f$extract(j+3,k-j-3,line)$ else7$ line = "#define "+f$extract(4,f$len(line),line) $ endif$ write fd2 line $ goto loop$ eloop:$ write fd2 "#endif" $ close fd $ close fd2$ delete temp.mar;$ exit$ endsubroutine*[CRINOID0051]CRINOID.C;1+,X./ 4<-Ke0123KPWO56'S 7ES 89GHJF/* test process spawning code*/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "version.h"#include "msg.h"#include "errlog_client.h"#include "util.h"#include "proc_mgr.h"#include "pipe2.h"#include "mbxq.h"#include "script.h"#include "CRINOID.h"#include "parser.h"pthread_key_t TCBkey;1static RQE GotMsgQueueHead = {0, 0};*#define GotMsgQ (&GotMsgQueueHead)static pMBX NetMBX;static pMbxQ NetQ;static pMbxQ TermQ;%static pNDB NDB_Head = 0;,static int Threads_initted = 0;"pthread_mutex_t NDB_mutex;"pthread_cond_t Main_cond;#pthread_mutex_t Main_mutex;*static int Main_Shutdown = 0;-static pGroup LocalScriptGroup = 0; #ifdef ALLOWED_DEFAULT_USERGROUP2#define DEFAULT_USER_CGI_DIRECTORY "/www-cgi"9static char *user_cgi_dir = DEFAULT_USER_CGI_DIRECTORY;#endif/#define STDERRLOG "CRINOIDLOG_STDERR_MBX"&#define DEFAULT_SERVICE_NAME "WWWPERL"#define NET_TIMEOUT 300static pSTRING Decnet_Service_Name = 0;.static int Loglevel = L_CRITICAL;'static int Allowed_Active;(static RQE MsgToThreadQueueHead = {0,0};+#define ThreadMsgQ (&MsgToThreadQueueHead)#define DEFAULT_MAX_THREADS 5-static int MAX_THREADS = DEFAULT_MAX_THREADS;pthread_t *Thread;pthread_cond_t ThreadMsgReady;pthread_mutex_t ThreadMutex;static int Threads_Ready = 0;int'main(int argc, char** argv, char** env){ ROUTINE_NAME("main");7 int iss, shutdown, type, command, done_with_packet; pProc p; pGroup g; pMM m; pMBX net; pMbxE e; pPrivs priv; struct NETDCL { byte type; longword value; } nfb = {NFB$C_DECLNAME, 0}; pSTRING Nfb; IOSB iosb; int logical_Loglevel = -1;* decc$set_reentrancy (C$C_MULTITHREAD);/* error logger startup */ StartLogger(); {: pSTRING p = translate_logical("CRINOID_LOGLEVEL"); if (p) {6 logical_Loglevel = atoi(asciz_pSTRING(p)); destroy_STRING(p); } }e errlog(L_CRITICAL,"This is CRINOID V!AZ, built on !AZ at !AZ",CRINOID_VERSION,__DATE__,__TIME__);E errlog_level(logical_Loglevel > 0 ? logical_Loglevel : Loglevel);F/* i/o initial setup; have to wait until read configfile to finish */; Decnet_Service_Name = new_STRING(DEFAULT_SERVICE_NAME); {@ pSTRING p = translate_logical("CRINOID_DECNET_SERVICE"); if (p) {0 destroy_STRING(Decnet_Service_Name);$ Decnet_Service_Name = p; } }: NetMBX = new_MBX_setquota(0, MAX_MSG, (MAX_MSG+8)*30);/* thread initialization */D iss = pthread_mutex_init(&Main_mutex,pthread_mutexattr_default);8 if (UNIX_ERR(iss)) UNIX_ABORT("main(), mutex_init");A iss = pthread_cond_init(&Main_cond,pthread_condattr_default);7 if (UNIX_ERR(iss)) UNIX_ABORT("main(), cond_init");C iss = pthread_mutex_init(&NDB_mutex,pthread_mutexattr_default);< if (UNIX_ERR(iss)) UNIX_ABORT("main(), ndb mutex_init");5 iss = pthread_keycreate(&TCBkey, &destroy_TCB2);7 if (UNIX_ERR(iss)) UNIX_ABORT("main(), keycreate"); Threads_initted = 1;?/* get program names, device names used for process startup */6 TermQ = MbxQ_new(0 , MBXQ$_READ, &messageAST); {6 pSTRING p = translate_logical("CRINOID_HOME"); char program[500];, tu_strcpy(program,asciz_pSTRING(p));* tu_strcat(program,"tentacle.com");/ init_Group(program,"",NetMBX->name,"");- tu_strcpy(program, asciz_pSTRING(p));' tu_strcat(program, "stub.com");' init_Proc(TermQ->mbx, program); destroy_STRING(p); }%/* configure groups, scripts, etc */* LocalScriptGroup = new_Group("LOCAL");2 ReadMainConfig("CRINOID_HOME:CRINOID.CONFIG");6/* loglevel logical overrides config file, so reset */: if (logical_Loglevel > 0) Loglevel = logical_Loglevel;/* start DECNET task stuff */* net = assign_new_MBX("_NET:", NetMBX);# Nfb = new_STRING2(sizeof(nfb));' asciz_pSTRING(Nfb) = (char *) &nfb; priv = new_Privs(); priv->prv$v_sysnam = 1; iss = Set_Privs(priv);4 if (VMS_ERR(iss)) VMS_ABORT(iss,"main, setprv");a iss = sys$qiow(0,net->chan,IO$_ACPCONTROL, &iosb, 0,0, Nfb, Decnet_Service_Name, 0, 0, 0, 0);' if ((iss&0xFFFF) == SS$_BADPARAM) {> printf("Another CRINOID already running, aborting\n");E VMS_ABORT(SS$_ABORT,"main, another CRINOID already running"); }8 if (VMS_ERR(iss)) VMS_ABORT(iss,"main, acpcontrol");M if (VMS_ERR(iosb.status)) VMS_ABORT(iosb.status,"main, acpcontrol iosb"); iss = Reset_Privs(priv);? if (VMS_ERR(iss)) VMS_ABORT(iss,"setprv, resetting privs");6 NetQ = MbxQ_new(NetMBX, MBXQ$_READ, &messageAST);@ init_manage_Proc(); /* process manager thread */E init_threads(); /* connection handling threads */E init_ATE_Proc(); /* abort timer entry processor */&/* atexit(&Exit_handler); */@/* estimate Allowed_Active from current quota, default sizes */ {! longword pid = get_pid(); int per_connection;B per_connection = 2*DEFAULT_MAILBOX_QUOTA; /* 2 mbx's */K per_connection += 256 + 640; /* + NET: + ? extra */8 Allowed_Active = get_bytcnt(pid)/per_connection;1 Allowed_Active -= 2; /* safety margin */a errlog(L_CRITICAL,"BYTLM quota allows !SL simultaneous active Tentacles",Allowed_Active);! if (Allowed_Active < 1) { Allowed_Active = 1;h errlog(L_CRITICAL,"--> adjusted to 1 active Tentacle, but may have BYTCNT quota problems!"); } }!/* main message-handling loop */ while (!Main_Shutdown) {. iss = pthread_mutex_lock(&Main_mutex);: if (UNIX_ERR(iss)) UNIX_ABORT("main, mutex_lock");& iss = lib$remqhi(GotMsgQ, &e);' while (iss == LIB$_QUEWASEMP) {= iss = pthread_cond_wait(&Main_cond, &Main_mutex);= if (UNIX_ERR(iss)) UNIX_ABORT("main, cond_wait");* iss = lib$remqhi(GotMsgQ, &e); }F if (VMS_ERR(iss)) VMS_ABORT(iss,"main, dequeuing msg packet");0 iss = pthread_mutex_unlock(&Main_mutex);< if (UNIX_ERR(iss)) UNIX_ABORT("main, mutex_unlock"); m = (pMM) e->buf; command = m->code;_ errlog(L_MAIN|L_BABBLE,"got NETMSG packet, code:!UW (!AZ)",command, msg_text(command)); done_with_packet = 1; switch (command) { case MSG$_DEVONLIN: do_online(e); break; case MSG$_IDLE: do_idle(e); break; case MSG$_NETSHUT:" Main_Shutdown = 1;G errlog(L_CRITICAL,"got NETSHUT packet, shutting down"); break; case MSG$_CONNECT:! thread_handle(e);% done_with_packet = 0; break; case MSG$_ABORT: case MSG$_EXIT: case MSG$_PATHLOST: case MSG$_PROTOCOL:! case MSG$_THIRDPARTY: case MSG$_TIMEOUT: break; case MSG$_PENDABORT: do_pendabort(e); break; case MSG$_DISCON:! do_disconnect(e); break; case MSG$_DELPROC:8 do_offline(e); /* process exited */ break; case MSG$_HEARTBEAT: do_heartbeat(e); break; case MSG$_STUBREADY: do_stubstart(e); break; case MSG$_STARTPID: do_startpid(e); break; case MSG$_LOGQLOCK:) StartLogger_queue_lock(); break; case MSG$_LOGSTART:" StartLoggerProc(); break; default: break; } if (done_with_packet) { MbxQ_dispose(e); } } stop_manage_Proc(); kill_all_Procs(); stop_threads(); stop_ATE_Proc(); return(SS$_NORMAL);}voidmessageAST(pMbxE e){ int process = 0; int iss = e->iosb.status; word size = e->iosb.count; word code; pMM m = (pMM) e->buf; if (VMS_ERR(iss)) {@ errlog(L_MAIN|L_ERROR,"messageAST iosb err 0x!XL ",iss); } else if (size < 4) {f errlog(L_MAIN|L_ERROR,"messageAST runt message, !UW bytes from PID !XL",size,e->iosb.dvispec);B logdump(L_ERROR,"messageAST runt message:", e->buf, size); } else {( int max = size > 64 ? 64 : size; errlog(L_MAIN|L_BABBLE,"messageAST message, code: !UW (!AZ), size !UW from PID !XL", m->code, msg_text(m->code),size,e->iosb.dvispec);$ if (m->code > MSG$_MAXMSG) {= errlog(L_ERROR,"Error text?: '!AF'",size,e->buf); } else {G logdump(L_MAIN|L_DEBUG,"messageAST message:", e->buf, max); process = 1; }h }c$ if (process && !Main_Shutdown) {7 if (m->code == MSG$_CONNECT && Threads_Ready) { D errlog(L_MAIN|L_BABBLE,"messageAST, do_connect queued");, iss = lib$insqti(e, ThreadMsgQ);M if (VMS_ERR(iss)) VMS_ABORT(iss,"messageAST, insert ThreadMsgQ"); > iss = pthread_cond_signal_int_np(&ThreadMsgReady);O if (UNIX_ERR(iss)) UNIX_ABORT("messageAST, cond_signal ThreadMsg");e } else {) iss = lib$insqti(e, GotMsgQ);wB if (VMS_ERR(iss)) VMS_ABORT(iss,"messageAST, insqti");9 iss = pthread_cond_signal_int_np(&Main_cond); E if (UNIX_ERR(iss)) UNIX_ABORT("messageAST, cond_signal"); }d } else { MbxQ_dispose(e); }}fint_do_online(pMbxE e){ ROUTINE_NAME("do_online"); int iss, len;  longword pid;  char outbuf[256];  pMM m = (pMM) e->buf;; pSTRING errlogmbx; pProc p; pGroup g;R pMBX cmbx; pid = e->iosb.dvispec;6 errlog(L_MAIN|L_TRACE,"do_online (pid=!XL) ",pid); p = get_Proc(pid);> errlog(L_MAIN|L_BABBLE,"do_online, lookup found p=!XL",p); if (!p) return 0; lock_Proc(p);d p->maintain_lock = 1;_ g = p->group;0 sprintf(outbuf,"_MBA%d:",(longword)m->unit);$ cmbx = assign_new_MBX(outbuf,0);> p->commandQ = MbxQ_new(cmbx, MBXQ$_WRITE|MBXQ$M_RETRY, 0); setidle_Proc(p); p->maintain_lock = 0;  unlock_Proc(p);t return 1; } int ;send_message(pMbxQ q, word code, word unit, void *s, int n)N{,! ROUTINE_NAME("send_message");s int length, iss; MbxE e; pMM m = (pMM) &e.buf; s errlog(L_MAIN|L_TRACE,"send_message(queue=!XL,code=!UW(!AZ),unit=!UW,bytes=!SL)",q,code,msg_text(code),unit,n);(? logdump(L_MAIN|L_DEBUG,"send_message data:",s,(n>64?64:0));v m->code = code;( m->unit = unit;t/ length = sizeof(m->code) + sizeof(m->unit);C if (s && n > 0) {D\ if (n+length > sizeof(e.buf)) VMS_ABORT(SS$_INSFMEM,"send_message, buffer too big"); memcpy(m->info, s, n); length += n; } ' iss = MbxQ_write(q, e.buf, length);o return iss; }nvoiddo_offline(pMbxE e)U{S ROUTINE_NAME("do_offline");S pMM m = (pMM) e->buf;( pProc p; pNDB ndb;  longword pid;  int iss, len;I struct accdef accmsg;  pid = e->iosb.dvispec;E errlog(L_MAIN|L_INFO,"do_offline: got DELPROC msg, pid=!XL",pid);X6 memcpy((char *)&accmsg, (char *)m, ACC$K_TERMLEN);O errlog(L_MAIN|L_INFO,"do_offline: final status !XL",accmsg.acc$l_finalsts);)R errlog(L_MAIN|L_BABBLE,"do_offline: CPU time !UL * 10ms",accmsg.acc$l_cputim);P errlog(L_MAIN|L_BABBLE,"do_offline: pagefaults: !UL",accmsg.acc$l_pageflts);X errlog(L_MAIN|L_BABBLE,"do_offline: peak pagefile usage !UL",accmsg.acc$l_pgflpeak);Z errlog(L_MAIN|L_BABBLE,"do_offline: working set peak usage: !UL",accmsg.acc$l_wspeak);[ errlog(L_MAIN|L_BABBLE,"do_offline: buffered i/o operations: !UL",accmsg.acc$l_biocnt); Y errlog(L_MAIN|L_BABBLE,"do_offline: direct i/o operations: !UL",accmsg.acc$l_diocnt);, p = get_Proc(pid);J errlog(L_MAIN|L_INFO,"do_offline: pid !XL ndb !XL",pid, (p?p->ndb:0)); if (!p) return;) iss = pthread_mutex_lock(&NDB_mutex);? if (UNIX_ERR(iss)) UNIX_ABORT("do_offline, NDBmutex_lock");o lock_Proc(p);" p->maintain_lock = 1;r if (p->commandQ) {# pMBX mc = p->commandQ->mbx;c0 p->commandQ = MbxQ_destroy(p->commandQ); destroy_MBX(mc); }  if (ndb = p->ndb) { O errlog(L_MAIN|L_TRACE,"tentacle offline, connection #!SL",ndb->connum);g. iss = pthread_mutex_lock(&ndb->mutex);@ if (UNIX_ERR(iss)) UNIX_ABORT("do_offline, mutex_lock"); ndb->pending_idle = 1; ndb->process = 0;s& if (ndb->pending_disconnect) {. dequeue_ATE(ndb->unit, ATE_ABORT); destroy_NDB(ndb);= } else {X errlog(L_MAIN|L_BABBLE,"do_offline, waiting for disconnect to destroy NDB");1 queue_ATE(ndb->unit, ATE_DISCON, 10);4 iss = pthread_mutex_unlock(&ndb->mutex);F if (UNIX_ERR(iss)) UNIX_ABORT("do_offline, mutex_unlock"); }  }  destroy_Proc(p);+ iss = pthread_mutex_unlock(&NDB_mutex);MA if (UNIX_ERR(iss)) UNIX_ABORT("do_offline, NDBmutex_unlock");} voidinit_threads(){s! ROUTINE_NAME("init_threads");_ int iss, j; int *id;C Thread = (pthread_t *) malloc(MAX_THREADS * sizeof(pthread_t)); 4 id = (int *) malloc(MAX_THREADS * sizeof(int));. errlog(L_MAIN|L_BABBLE, "init_threads()");F iss = pthread_cond_init(&ThreadMsgReady,pthread_condattr_default);= if (UNIX_ERR(iss)) UNIX_ABORT("init_threads, cond_init");aE iss = pthread_mutex_init(&ThreadMutex,pthread_mutexattr_default);e> if (UNIX_ERR(iss)) UNIX_ABORT("init_threads, mutex_init");# for (j=0; j if (UNIX_ERR(iss)) UNIX_ABORT("thread_code, setspecific");D errlog(L_MAIN|L_BABBLE,"thread_code(!SL) tc at 0x!XL",ThNum,tc); while (1) { / iss = pthread_mutex_lock(&ThreadMutex);tA if (UNIX_ERR(iss)) UNIX_ABORT("thread_code, mutex_lock"); K iss = Allowed_Active ? lib$remqhi(ThreadMsgQ, &e) : LIB$_QUEWASEMP; ' while (iss == LIB$_QUEWASEMP) { B iss = pthread_cond_wait(&ThreadMsgReady,&ThreadMutex);D if (UNIX_ERR(iss)) UNIX_ABORT("thread_code, cond_wait");O iss = Allowed_Active ? lib$remqhi(ThreadMsgQ, &e) : LIB$_QUEWASEMP; }_G if (VMS_ERR(iss)) VMS_ABORT(iss,"thread_code, get msg from q"); Allowed_Active--;(K errlog(L_INFO,"do_connect: Allowed_Active now !SL",Allowed_Active);o1 iss = pthread_mutex_unlock(&ThreadMutex);MC if (UNIX_ERR(iss)) UNIX_ABORT("thread_code, mutex_unlock");lR errlog(L_MAIN|L_BABBLE,"thread_code(thread=!SL) got Msg @ 0x!XL",ThNum,e); do_connect(tc, e); MbxQ_dispose(e); }  destroy_TCB(tc); return 0; } voidthread_handle(pMbxE e){G" ROUTINE_NAME("thread_handle"); int iss;$ iss = lib$insqti(e, ThreadMsgQ);J if (VMS_ERR(iss)) VMS_ABORT(iss,"thread_handle, insert thread msg q");+ iss = pthread_mutex_lock(&ThreadMutex);a? if (UNIX_ERR(iss)) UNIX_ABORT("thread_handle, mutex_lock"); / iss = pthread_cond_signal(&ThreadMsgReady); @ if (UNIX_ERR(iss)) UNIX_ABORT("thread_handle, cond_signal");- iss = pthread_mutex_unlock(&ThreadMutex); A if (UNIX_ERR(iss)) UNIX_ABORT("thread_handle, mutex_unlock");M}_voiddo_connect(pTCB tc, pMbxE e){; ROUTINE_NAME("do_connect"); int iss; pProc p = 0; pGroup g;s pNDB ndb; A errlog(L_MAIN|L_TRACE,"do_connect(tc=0x!XL, e=0x!XL)",tc, e);s&/* assume we start with a clean tc */ ndb = net_connect(e); if (!ndb) return;g tc->ndb = ndb;  ndb->tc = tc;= errlog(L_MAIN|L_TRACE,"new connection #!SL",#t#~ FREEWARE.SAVXKe[CRINOID0051]CRINOID.C;1|$ndb->connum);PS errlog(L_MAIN|L_BABBLE,"do_connect, got new ndb !XL, hooked to tc !XL",ndb,tc); + if (ndb->pending_disconnect) goto done;  net_readENV();+ if (ndb->pending_disconnect) goto done; netwrite("");A/* start talking to the process that is handling this request */+ if (ndb->pending_disconnect) goto done;  g = net_select_group(); if (!g) {/ if (ndb->pending_disconnect) goto done; 1 netwrite("Content-type: text/plain\n\n");? netwrite("unable to find appropriate process group\n");; netwrite("");  goto done; }m if (g == LocalScriptGroup) {/ if (ndb->pending_disconnect) goto done;d local_script();u goto done; };+ if (ndb->pending_disconnect) goto done;  p = getidle_Proc(g);+ if (ndb->pending_disconnect) goto done;U) iss = pthread_mutex_lock(&NDB_mutex);s? if (UNIX_ERR(iss)) UNIX_ABORT("do_connect, NDBmutex_lock");$ ndb->process = p;r p->ndb = ndb;:r errlog(L_MAIN|L_BABBLE,"do_connect: connecting ndb !XL chan !UW to proc !XL PID !XL",ndb, ndb->unit,p,p->pid);+ iss = pthread_mutex_unlock(&NDB_mutex);A if (UNIX_ERR(iss)) UNIX_ABORT("do_connect, NDBmutex_unlock");O#/* set up i/o mailboxes to Perl */ 6 add_ENV("CRINOID:>PERL",ndb->Q2perl->mbx->name,1);7 add_ENV("CRINOID:Pout->in_mbx->name,1);  {_1 pSTRING s = translate_logical(STDERRLOG);s if (s) {9 add_ENV("CRINOID:2pending_disconnect) goto done;  p->state = PS_BUSY;e net_sendENV(p); E/* connect i/o pipe from process to network, from content to proc */s+ if (ndb->pending_disconnect) goto done;  if (tc->content) {A MbxQ_write(ndb->Q2perl, tc->content, tc->content_length);e free(tc->content); tc->content = 0; tc->content_length = 0;N }"C MbxQ_write(ndb->Q2perl, 0, -1); /* EOF at end of content */[$/* tell proc to start the script */M errlog(L_MAIN|L_BABBLE,"do_connect: triggering tentacle pid=!XL",p->pid);i+ if (ndb->pending_disconnect) goto done;_ net_runscript(p);;done: " if (ndb->pending_disconnect) {> if (p) send_message(p->commandQ, MSG$_ABORT, 0, 0, 0);Q errlog(L_CRITICAL,"do_connect: pending_disconnect detected, abort sent");  }(, iss = pthread_mutex_unlock(&ndb->mutex);A if (UNIX_ERR(iss)) UNIX_ABORT("do_connect, ndb->mutex lock");$ clean_TCB(tc);};voiddo_idle(pMbxE e){- ROUTINE_NAME("do_idle"); int iss; longword pid; pProc p; pNDB ndb; pid = e->iosb.dvispec; p = get_Proc(pid);F errlog(L_MAIN|L_TRACE,"do_idle pid=!XL ndb=!XL",pid,(p?p->ndb:0)); if (!p) return;) iss = pthread_mutex_lock(&NDB_mutex);=< if (UNIX_ERR(iss)) UNIX_ABORT("do_idle, NDBmutex_lock");6 errlog(L_MAIN|L_BABBLE,"do_idle: ndb !XL",p->ndb); if (ndb = p->ndb) {-E errlog(L_MAIN|L_BABBLE,"idling connection #!SL",ndb->connum);s. iss = pthread_mutex_lock(&ndb->mutex);= if (UNIX_ERR(iss)) UNIX_ABORT("do_idle, mutex_lock");g ndb->pending_idle = 1;' if (!ndb->pending_disconnect) {$ /* ndb->process = 0; */1 queue_ATE(ndb->unit, ATE_DISCON, 10);f4 iss = pthread_mutex_unlock(&ndb->mutex);C if (UNIX_ERR(iss)) UNIX_ABORT("do_idle, mutex_unlock");p3 iss = pthread_mutex_unlock(&NDB_mutex);F if (UNIX_ERR(iss)) UNIX_ABORT("do_idle, NDBmutex_unlock"); setidle_Proc(p); return;& } else {. dequeue_ATE(ndb->unit, ATE_ABORT); }a destroy_NDB(ndb);f }) p->ndb = 0;M+ iss = pthread_mutex_unlock(&NDB_mutex);a> if (UNIX_ERR(iss)) UNIX_ABORT("do_idle, NDBmutex_unlock"); setidle_Proc(p);}_voidnet_sendENV(pProc p){E ROUTINE_NAME("net_sendENV"); int n, l, remain, jbuf=0; ( char *b, *q, *bend, buffer[MAX_NCB]; pENV e = *get_ENVBase();7 errlog(L_MAIN|L_BABBLE,"net_sendENV(p = 0x!XL)",p);u b = buffer;i# bend = buffer + sizeof(buffer);  while (e) {A q = e->name; remain = tu_strlen(q)+1; while (remain > 0) {2 l = b+remain > bend ? bend-b : remain; if (l == 0) {:N send_message(p->commandQ,MSG$_ENVDATA,jbuf++,buffer,b-buffer); b = buffer;d6 l = b+remain > bend ? bend-b : remain; }k memcpy(b,q,l); b += l;  q += l;  remain -= l; }o q = e->value;o remain = tu_strlen(q)+1; while (remain > 0) {2 l = b+remain > bend ? bend-b : remain; if (l == 0) { N send_message(p->commandQ,MSG$_ENVDATA,jbuf++,buffer,b-buffer); b = buffer; 6 l = b+remain > bend ? bend-b : remain; }n memcpy(b,q,l); b += l;u q += l;  remain -= l; }  e = e->next; }I if (b-buffer)iD send_message(p->commandQ,MSG$_ENVDATA,jbuf,buffer,b-buffer);}upNDBnet_connect(pMbxE e){ ROUTINE_NAME("net_connect"); pMM m = (pMM) e->buf;X pMBX mbx, mbx2;( char *p; int iss, length; pNDB ndb;  $DESCRIPTOR(d_ncb,""); IOSB iosb;" static int connect_number = 0;#ifdef PRINT_QUOTA int quota; longword pid;#endif7 errlog(L_MAIN|L_BABBLE,"net_connect(e = 0x!XL)",e);)#ifdef PRINT_QUOTA pid = get_pid(); quota = get_bytcnt(pid);: errlog(L_INFO,"quota @ net_connect: !SL bytes",quota);#endif p = m->info; p = p + *p + 1;| length = *p++; d_ncb.dsc$a_pointer = p;! d_ncb.dsc$w_length = length;d9 logdump(L_MAIN|L_DEBUG,"net_connect, ncb ",p,length);e ndb = malloc(sizeof(NDB));? if (!ndb) VMS_ABORT(SS$_INSFMEM,"net_connect, malloc NDB");( ndb->tc = 0;( ndb->process = 0;i ndb->pending_disconnect = 0; ndb->pending_idle = 0;) mbx = assign_new_MBX("_NET:",NetMBX);tF iss = sys$qiow(0,mbx->chan,IO$_ACCESS,&iosb,0,0,0,&d_ncb,0,0,0,0);? if (VMS_ERR(iss)) VMS_ABORT(iss,"net_connect, io$_access");  iss = iosb.status; if (VMS_ERR(iss)) {_" pSTRING s = errormsg(iss);G errlog(L_ERROR,"net_connect: io$access err 0x!XL (!AS)",iss,s);  destroy_STRING(s); destroy_MBX(mbx);r free(ndb); return 0;I }( ndb->unit = mbx->unit;+ ndb->Qin = MbxQ_new(mbx,MBXQ$_READ,0);NI ndb->Q2perl = MbxQ_new(0, MBXQ$_WRITE|MBXQ$M_RETRY|MBXQ$M_SEGMENT,0); 5/* ndb->Merr = assign_new_MBX(STDERRLOG,0); */;! ndb->Pout = Pipe_new(0, mbx); - ndb->Pout->outQ->option |= MBXQ$M_NETMBX;u* MbxQ_setname(ndb->Pout->inQ,"pipeIN");, MbxQ_setname(ndb->Pout->outQ,"pipeOUT");o errlog(L_MAIN|L_BABBLE,"net_connect connected NDB @ 0x!XL on chan !UW, unit:!UW",ndb,mbx->chan, mbx->unit);,D iss = pthread_mutex_init(&ndb->mutex,pthread_mutexattr_default);= if (UNIX_ERR(iss)) UNIX_ABORT("net_connect, mutex_init");oA iss = pthread_cond_init(&ndb->cond,pthread_condattr_default); < if (UNIX_ERR(iss)) UNIX_ABORT("net_connect, cond_init");* iss = pthread_mutex_lock(&ndb->mutex);B if (UNIX_ERR(iss)) UNIX_ABORT("net_connect, ndb->mutex lock");) iss = pthread_mutex_lock(&NDB_mutex);oA if (UNIX_ERR(iss)) UNIX_ABORT("net_connect, NDB_mutex lock");  ndb->next = NDB_Head;s NDB_Head = ndb;r# ndb->connum = connect_number++; + iss = pthread_mutex_unlock(&NDB_mutex);_? if (UNIX_ERR(iss)) UNIX_ABORT("net_connect, mutex_unlock"); #ifdef PRINT_QUOTA quota -= get_bytcnt(pid);NC errlog(L_INFO,"net_connect consumed !SL bytes of quota",quota);l#endif return ndb;c}(void net_readENV()T{m ROUTINE_NAME("net_readENV");, errlog(L_MAIN|L_BABBLE,"net_readENV()"); new_ENV(); get_main_params(); get_id2_params(); get_path_params(); get_header_params(); get_input();}nvoidclean_TCB(pTCB tc){M ROUTINE_NAME("clean_TCB"); if (!tc) return;Q errlog(L_MAIN|L_BABBLE,"clean_TCB: tc !XL unhooked from ndb !XL",tc,tc->ndb);U if (tc->ndb) tc->ndb->tc = 0; tc->ndb = 0;. if (tc->ENVBase) destroy_ENV(tc->ENVBase); tc->ENVBase = 0;' if (tc->content) free(tc->content);t tc->content = 0; tc->content_length = 0;R}spTCBdestroy_TCB(pTCB tc){e ROUTINE_NAME("destroy_TCB"); if (!tc) return 0; clean_TCB(tc); free(tc); return 0;} pTCBnew_TCB(int ThreadID){  ROUTINE_NAME("new_TCB"); int iss; pTCB tc;$ tc = (pTCB) malloc(sizeof(TCB));6 if (!tc) VMS_ABORT(SS$_INSFMEM,"new_TCB, malloc");' tc->id = ThreadID;b tc->thread = 0; tc->ENVBase = 0; tc->content = 0; tc->content_length = 0; tc->ndb = 0; return tc;}-voiddestroy_ENV(pENV e) { ROUTINE_NAME("destroy_ENV"); pENV p, qp = e;  while (p=qp) { qp = p->next;r# if (p->name) free(p->name);l% if (p->value) free(p->value);n free(p); }e}pENV * get_ENVBase()p{ ROUTINE_NAME("get_ENVBase"); int iss; pTCB tc = get_current_TCB(); return &tc->ENVBase;}nvoid new_ENV(void)"{b ROUTINE_NAME("new_ENV"); int j;$ static char *default_blank[] = { "SUBFUNCTION",< "SERVER_SOFTWARE", "SERVER_NAME", "SERVER_PROTOCOL",5 "SERVER_PORT", "REQUEST_METHOD", "PATH_INFO", 8 "PATH_TRANSLATED", "SCRIPT_NAME", "SCRIPT_PATH",D "QUERY_STRING", "REMOTE_USER", "REMOTE_ADDR", "REMOTE_PORT",C "REMOTE_HOST", "AUTH_TYPE", "REMOTE_IDENT", "CONTENT_TYPE",X "CONTENT_LENGTH", NULL};" pENV *ENVBase = get_ENVBase();0 for (j = 0; default_blank[j] != NULL; j++) {' add_ENV(default_blank[j],"",0);c } / add_ENV("GATEWAY_INTERFACE", "CGI/1.0", 1); }spENV+add_ENV(char *name, char *value, int state)E{i ROUTINE_NAME("add_ENV"); char *qp;) pENV p, *ENVBase;i if (p = find_ENV(name)) {C qp = p->value;. p->value = malloc(tu_strlen(value)+1); if (!p->value) { if (qp) free(qp);r return 0;O } " tu_strcpy(p->value,value); if (qp) free(qp);s } else {' p = (pENV) malloc(sizeof(ENV));  if (!p) return 0;s, p->name = malloc(tu_strlen(name)+1); if (!p->name) { free(p); return 0; }t! tu_strcpy(p->name, name);g. p->value = malloc(tu_strlen(value)+1); if (!p->value) {' if (p->name) free(p->name); free(p); return 0;n } " tu_strcpy(p->value,value); ENVBase = get_ENVBase(); p->next = *ENVBase;e *ENVBase = p;  }t p->state = state;r return p;A}EpENVfind_ENV(char *name){  ROUTINE_NAME("find_ENV");- pENV p = *get_ENVBase(); while (p) {p3 if (tu_strcmp(p->name,name) == 0) return p; p = p->next; }- return 0;_}Rvoidget_main_params(void)C{I$ ROUTINE_NAME("get_main_params"); pSTRING s1, s2, s3, s4;(0 errlog(L_MAIN|L_BABBLE,"get_main_params()"); s1 = fetch_value(0); s2 = fetch_value(0); s3 = fetch_value(0); s4 = fetch_value(0);/ add_ENV("SUBFUNCTION",s1->dsc$a_pointer,1); 2 add_ENV("REQUEST_METHOD",s2->dsc$a_pointer,1);3 add_ENV("SERVER_PROTOCOL",s3->dsc$a_pointer,1);c/ add_ENV("SCRIPT_NAME",s4->dsc$a_pointer,1);L3 errlog(L_MAIN|L_BABBLE,"SUBFUNCTION='!AS'",s1);3 errlog(L_MAIN|L_BABBLE,"REQUEST_MET='!AS'",s2);N3 errlog(L_MAIN|L_BABBLE,"SERVER_PROT='!AS'",s3);3 errlog(L_MAIN|L_BABBLE,"SCRIPT_NAME='!AS'",s4);; destroy_STRING(s1);- destroy_STRING(s2);_ destroy_STRING(s3);  destroy_STRING(s4); } voidget_id2_params(void){t# ROUTINE_NAME("get_id2_params");_ char *value, *p, temp[16]; pSTRING s; int addr;; pENV e;(/ errlog(L_MAIN|L_BABBLE,"get_id2_params()");r! s = fetch_value("");_ if (!s) return;S3 errlog(L_MAIN|L_BABBLE,"id2 params = '!AS'",s);& value = s->dsc$a_pointer;N if (value)7 add_ENV("SERVER_SOFTWARE",pop_token(&value),1);r if (value)3 add_ENV("SERVER_NAME",pop_token(&value),1);B if (value)3 add_ENV("SERVER_PORT",pop_token(&value),1);  if (value)3 add_ENV("REMOTE_PORT",pop_token(&value),1);A if (value) {( addr = atoi (pop_token(&value));1 sprintf (temp, "%d.%d.%d.%d", (addr&255),&B ((addr>>8)&255), ((addr>>16)&255), ((addr>>24)&255) );& add_ENV("REMOTE_ADDR",temp,1); }d if (value) { /*0 * Only set value if string is non-null. */ p = pop_token(&value);2 if (*p != ' ') add_ENV("REMOTE_USER",p,1); }| if (value)3 add_ENV("REMOTE_HOST",pop_token(&value),1);b- /* Fallback remote host to REMOTE_ADDR */ e = find_ENV("REMOTE_ADDR"); if (e->state) * add_ENV("REMOTE_HOST",e->value,1); destroy_STRING(s);};voidget_path_params(void) { $ ROUTINE_NAME("get_path_params"); int iss, length; char *value, *qp; pENV e;f pSTRING s, s2 = 0;0 errlog(L_MAIN|L_BABBLE,"get_path_params()"); /*E * Ask for name of script being executed and derive path_info and  * script name from that. */ # s = fetch_value ("");l if (s) {8 errlog(L_MAIN|L_BABBLE," -> '!AS'",s);! value = s->dsc$a_pointer;( length= s->dsc$w_length;' add_ENV("SCRIPT_PATH",value,1);f$ e = find_ENV("SCRIPT_NAME"); if (e) {7 if (tu_strncmp(e->value,value,length)==0) { I if (length > 0) { /* stuff after script name */L for (qp = &e->value[length]; *qp && (*qp != '/'); qp++);. add_ENV("PATH_INFO",qp,1); } else { /*Q * Get original URL to bypass server translation done on arg2XF * Fixup path_info: strip search arg and unescape. */, int qlen;c4 s2 = fetch_value("");+ qp = s2->dsc$a_pointer;g6 for (qlen = 0; qp[qlen]; qlen++) {. if (qp[qlen] == '?') {L qp[qlen] = '\0'; /* hack off at ? */" break; }+ }n2 net_unescape_string(qp,&qlen);$ qp[qlen] = '\0'; } J load_translation ( "PATH_TRANSLATED", "", qp ); })' if (s2) destroy_STRING(s2);o1 if ( tu_strlen(e->value) > length ) {-J for ( qp = &e->value[length]; *qp && (*qp != '/'); qp++ );C *qp = '\0'; /* Truncate script name */f2 add_ENV("SCRIPT_NAME",e->value,1); } 9 if (tu_strncmp(e->value,value,length) == 0) { > add_ENV("SCRIPT_BARE_NAME",e->value+length,1); } else {7 add_ENV("SCRIPT_BARE_NAME",e->value,1);r }n }  destroy_STRING(s); }i$ s = fetch_value(""); if (s) {4 add_ENV("SCRIPT_BINDIR",s->dsc$a_pointer,1); destroy_STRING(s); }d /*7 * Get query string and convert escaped characters.  */0" s = fetch_value (""); if (s) {! length = s->dsc$w_length;n" value = s->dsc$a_pointer; if (length > 0) { D length--; value++; /* remove leading '?' */#ifdef DECODE_QUERY>3 net_unescape_string ( value, &length );d#endif! value[length] = '\0';f, add_ENV("QUERY_STRING",value,1); } destroy_STRING(s); }o}pvoidget_header_params(void)({X& ROUTINE_NAME("get_header_params"); int iss, length;+ char buffer[4096], *label, *value, *qp;X pENV e;I pTCB tc = get_current_TCB();2 errlog(L_MAIN|L_BABBLE,"get_header_params()"); /*G * Get header lines from HTTP server and save in environment array.  */d netwrite("");, length = netread(buffer,sizeof(buffer)); while (length > 0) { buffer[length] = '\0';' if (buffer[length-1] == '\n') {= buffer[--length] = '\0'; /* trailing \n */g }t$ /* Parse out header label */& value = tu_strchr(buffer,':'); if (value) { *value++ = '\0'; /*J * Construct label. Upcase characters and convert '-' to '_'. */_0 label = malloc(tu_strlen(buffer)+6);2 if (!label) VMS_ABORT(SS$_INSFMEM,"");% tu_strcpy(label,"HTTP_");a* for (qp = buffer; *qp; qp++) {$ *qp = _toupper(*qp);* if (*qp == '-') *qp = '_'; }t$ tu_strcat(label,buffer);8 for (qp = value; *qp && isspace(*qp); qp++); value = qp;t /*F * Check for special header lines that go into pre-defined * variables.  */e@ if ( 0 == tu_strcmp(label,"HTTP_CONTENT_LENGTH") ) {2 add_ENV("CONTENT_LENGTH",value,1);F } else if ( 0 == tu_strcmp (label,"HTTP_CONTENT_TYPE") ) {0 add_ENV("CONTENT_TYPE",value,1);- } else if (e = find_ENV(label)) {  /*> * Append string to existing. Allocate extra. */; char *cat_value;R cat_value = malloc ( tu_strlen(e->value) + tu_strlen(value) + 3 );: if (!cat_value) VMS_ABORT(SS$_INSFMEM,"");2 tu_strcpy ( cat_value, e->value );- tu_strcat ( cat_value, ", ");n. tu_strcat ( cat_value, value);+ add_ENV(label,cat_value,1);! free (cat_value);T } else {' add_ENV(label,value,1);n }  free(label); } else {; /* Continuation header line, handle later ??? */t }f0 length = netread(buffer,sizeof(buffer)); }_}Tvoidget_input(void)R{_ ROUTINE_NAME("get_input");' int remain, length, content_length;  char *p, *s; pENV e;M pTCB tc = get_current_TCB();* errlog(L_MAIN|L_BABBLE,"get_input()");' if (tc->content) free(tc->content);P tc->content = 0; tc->content_length = 0;E# e = find_ENV("CONTENT_LENGTH");s if (!e) return;. remain = content_length = atoi (e->value);$ if (content_length <= 0) return;( tc->content_length = content_length;% p = s = malloc(content_length+2);( while (remain > 0) { netwrite("");% length = netread(p,remain+2);E if (length <= 0) break;V p += length; remain -= length;l }l tc->content = s;}pTCBget_current_TCB() { $ ROUTINE_NAME("get_current_TCB"); int iss; pTCB tc;3 iss = pthread_getspecific(TCBkey, (void *)&tc);)B if (UNIX_ERR(iss)) UNIX_ABORT("get_current_TCB, getspecific"); return tc;}int netread(char *s, int lmax){) ROUTINE_NAME("netread"); int iss, count;;# pTCB tc = get_current_TCB(); pMbxQ q = tc->ndb->Qin; pMbxE e;# e = MbxQ_read2(q, NET_TIMEOUT);5 if (!e) VMS_ABORT(SS$_TIMEOUT,"netread timeout");( iss = e->iosb.status;p> if (VMS_ERR(iss)) VMS_ABORT(iss,"netread, readvblk iosb"); count = e->iosb.count;G if (count > lmax) VMS_ABORT(SS$_ABORT,"netread, buffer too small");  memcpy(s, e->buf, count); H logdump(L_NETIO|L_DEBUG,"netread ",e->buf, count > 64 ? 64 : count); MbxQ_dispose(e); return count;h}pvoidnetwrite2(pMbxQ q, char *s)e{= ROUTINE_NAME("netwrite2"); int iss, l = tu_strlen(s);5 logdump(L_NETIO|L_DEBUG,"netwrite",s, l>64?64:l);e iss = MbxQ_write(q, s, l);1 if (VMS_ERR(iss)) VMS_ABORT(iss,"netwrite2");a}rvoidnetwrite(char *s)l{0 ROUTINE_NAME("netwrite"); ! pTCB tc = get_current_TCB();t& netwrite2(tc->ndb->Pout->outQ, s);}spSTRING,fetch_value(char *tag){M ROUTINE_NAME("fetch_value"); int len; char buffer[4096]; pSTRING s;1 if (tag && tu_strlen(tag) > 0) netwrite(tag);l len = netread(buffer,4096);! if ( len > 0 ) { buffer[len] = '\0';!" if (buffer[len-1] == '\n')! buffer[--len] = '\0';r s = new_STRING(buffer);= } else { s = new_STRING("");  }_ return s; }echar *pop_token(char **s)T{G char *p, *qp;d qp = *s; p = tu_strchr(qp,' '); if (p) { *p++ = '\0'; }t *s = p;  return qp;} L/**************************************************************************/9/* Convert escaped characters in string to actual values.L * * Arguments: 4 * string Character string. Modified.B * length Int. On input, original length of string.D * On output, final length of unescaped string. */char*(1net_unescape_string ( char *string, int *length )l{, int i, j, reslen, modified;_ /* * Scan string.v */A9 for ( modified = reslen = i = 0; i < *length; i++ ) {;! if ( string[i] == '%' ) {% /*G * Escape seen, decode next 2 characters as hex and replace * * all three with single byte. */ char value[4]; int val;L value[0] = string[i+1]; value[1] = string[i+2]; value[2] = '\0'; i += 2;E* sscanf ( value, "%2x", &val );I if ( val > 127 ) val |= (-1 ^ 255); /* Sign extend */o! string[reslen] = val;V modified = 1;- }  else {< /* Only copy bytes if escape edit took place. */7 if ( modified ) string[reslen] = string[i];p }  reslen++; }r2 /* Return value is point to string editted. */ *length = reslen;_ return string;}(voidnet_runscript(pProc p){s" ROUTINE_NAME("net_runscript");5 send_message(p->commandQ, MSG$_CONNECT, 0, 0, 0); } void5load_translation ( char *name, char *tag, char *arg )I{_% ROUTINE_NAME("load_translation");  char *value; pSTRING s = 0; pTCB tc = get_current_TCB(); if (*arg) {H netwrite(tag); s = fetch_value(arg); ! value = s->dsc$a_pointer;r } else { value = arg; }  add_ENV(name,value,1); if (s) destroy_STRING(s);a}*voiddestroy_TCB2(void *tc){>! ROUTINE_NAME("destroy_TCB2");  destroy_TCB((pTCB) tc);d}N5/* special handling to abort a hanging connection */ voidabort_connection(word unit)*{t% ROUTINE_NAME("abort_connection");i% queue_special(MSG$_DISCON, unit);*}x2/* queue a special abort packet for processing */voidabort_tentacle(word unit) {n# ROUTINE_NAME("abort_tentacle");f' queue_special(MSG$_PENDABORT,unit); } voiddo_pendabort(pMbxE e) { ! ROUTINE_NAME("do_pendabort");q pMM m = (pMM) e->buf; int iss; word unit; pNDB ndb;  unit = m->unit;': errlog(L_MAIN|L_BABBLE,"do_pendabort, unit=!UW",unit);) iss = pthread_mutex_lock(&NDB_mutex); > if (UNIX_ERR(iss)) UNIX_ABORT("do_pendabort, mutex_lock"); ndb = NDB_Head;  while (ndb) {;% if (ndb->unit == unit) break;o ndb = ndb->next; }" if (!ndb) { J errlog(L_MAIN|L_BABBLE,"do_pendabort, didn't find unit !UW",unit);/ iss = pthread_mutex_unlock(&NDB_mutex); D if (UNIX_ERR(iss)) UNIX_ABORT("do_pendabort, mutex_unlock"); return;  } F errlog(L_MAIN|L_TRACE,"pendaborting connection #!SL",ndb->connum);< errlog(L_MAIN|L_BABBLE,"do_pendabort, got ndb !XL",ndb);* iss = pthread_mutex_lock(&ndb->mutex);> if (UNIX_ERR(iss)) UNIX_ABORT("do_pendabort, mutex_lock");O if (!ndb->pending_idle && ndb->process && ndb->process->state == PS_BUSY) {D errlog(L_ERROR,"sending abort message to tentacle process");B send_message(ndb->process->commandQ, MSG$_ABORT, 0, 0, 0); } else { errlog(L_WARNING,"do_pendabort prevented from aborting: pending_idle=!SL process=!XL state=!SL",ndb->pending_idle,ndb->process, ndb->process ? ndb->process->state : 0); }s, iss = pthread_mutex_unlock(&ndb->mutex);@ if (UNIX_ERR(iss)) UNIX_ABORT("do_pendabort, mutex_unlock");+ iss = pthread_mutex_unlock(&NDB_mutex);D@ if (UNIX_ERR(iss)) UNIX_ABORT("do_pendabort, mutex_unlock");}dvoiddo_disconnect(pMbxE e){f" ROUTINE_NAME("do_disconnect"); pMM m = (pMM) e->buf; int iss; word unit; pNDB ndb; unit = m->unit;(; errlog(L_MAIN|L_BABBLE,"do_disconnect, unit=!UW",unit);n) iss = pthread_mutex_lock(&NDB_mutex);*? if (UNIX_ERR(iss)) UNIX_ABORT("do_disconnect, mutex_lock");g ndb = NDB_Head;e while (ndb) { % if (ndb->unit == unit) break;  ndb = ndb->next; }r if (!ndb) { B errlog(L_ERROR,"do_disconnect, can't find unit !UW",unit);/ iss = pthread_mutex_unlock(&NDB_mutex);tE if (UNIX_ERR(iss)) UNIX_ABORT("do_disconnect, mutex_unlock");r return;; } L errlog(L_MAIN|L_TRACE,"disconnecting ndb !XL con#!SL",ndb, ndb->connum);* iss = pthread_mutex_lock(&ndb->mutex);? if (UNIX_ERR(iss)) UNIX_ABORT("do_disconnect, mutex_lock"); ndb->pending_disconnect = 1; if (!ndb->pending_idle) { longword delta[2];? errlog(L_MAIN|L_BABBLE,"do_disconnect, wait for idle");_% queue_ATE(unit,ATE_ABORT,10);s0 iss = pthread_mutex_unlock(&ndb->mutex);C if (UNIX_ERR(iss)) UNIX_ABORT("do_disconnect, mutex_lock"); / iss = pthread_mutex_unlock(&NDB_mutex); E if (UNIX_ERR(iss)) UNIX_ABORT("do_disconnect, mutex_unlock");p return; } else {% dequeue_ATE(unit,ATE_DISCON);  }e destroy_NDB(ndb);e+ iss = pthread_mutex_unlock(&NDB_mutex);aA if (UNIX_ERR(iss)) UNIX_ABORT("do_disconnect, mutex_unlock");T}T/*< * a script we don't need a perl subprocess to deal with... */ int local_script(void){c! ROUTINE_NAME("local_script"); pENV e; % e = find_ENV("SCRIPT_BARE_NAME");  if (!e) return 0;n9 if (tu_strcmp_uc(e->value, "SHUTDOWN_SERVER") == 0) {n shutdown_server(); return 1;  } 4 if (tu_strcmp_uc(e->value, "GET_LOGLEV") == 0) { int level; char msg[100];1 netwrite("Content-type: text/plain\n\n");e! level = errlog_level(-1); m sprintf(msg,"Current logging level is %d, options bits = 0x%06x\n",level&L_LEVMASK,level>>L_MINTYPE);u netwrite(msg); netwrite("");e return 1;  } 4 if (tu_strcmp_uc(e->value, "SET_LOGLEV") == 0) { int dirty = 0; longword level=0;  long int bit;  pSTRING tmp;$ pTCB tc = get_current_TCB(); pENV e0; char msg[100];1 netwrite("Content-type: text/plain\n\n");o& tmp = new_STRING(tc->content);" e = e0 = parse_input(tmp); destroy_STRING(tmp); while (e) {M? if (tu_strcmp("OPTION",e->name) == 0 && e->value) {"% bit = atoi(e->value);eC if (bit >= L_MINTYPE && bit <= 31) level |= 1< if (tu_strcmp("LEVEL",e->name) == 0 && e->value) {% bit = atoi(e->value);? if (bit >= 0 && bit <= L_LEVMASK) level |= bit;n dirty = 1; }{ e = e->next; } if (e0) destroy_ENV(e0); if (dirty) { errlog_level(level);r sprintf(msg,"Changing logging level to %d, options bits = 0x%06x\n",level&L_LEVMASK,level>>L_MINTYPE); } else {? sprintf(msg,"No valid input; logging unchanged\n");k }) netwrite(msg);- if (dirty) broadcast_loglevel(level);" netwrite("");e return 1;l })0 if (tu_strcmp_uc(e->value, "NEWLOG") == 0) { NewLog();g1 netwrite("Content-type: text/plain\n\n");> netwrite("CRINOIDLOG requested to start new logfile"); netwrite("");t return 1;s }i return 0; }fpENVparse_input(pSTRING s){e ROUTINE_NAME("parse_input"); pENV e0, e; char *p, *pend, *q;_ int state, length; if (!s) return 0;  p = s->dsc$a_pointer;  pend = p + s->dsc$w_length;n e0 = 0;, state = 0; while (p < pend) {< for (q = p; q < pend && *q != '&' & *q != '='; q++); if (state == 0) {N$ e = malloc(sizeof(ENV));, if (!e) VMS_SIGNAL(SS$_INSFMEM); e->next = e0; e0 = e;q length = q-p;s, net_unescape_string(p, &length);' e->name = malloc(length+1);E2 if (!e->name) VMS_SIGNAL(SS$_INSFMEM);, tu_strnzcpy(e->name, p, length); e->value = 0;r e->state = 0;E' state = (*q == '=')? 1 : 0;b } else if (state == 1) { length = q-p; , net_unescape_string(p, &length);( e->value = malloc(length+1);3 if (!e->value) VMS_SIGNAL(SS$_INSFMEM);n- tu_strnzcpy(e->value, p, length);  state = 0; }e p = q + 1; }" return e0;}e static voidhExit_handler(void){s exit_handle_Proc();d}intdo_heartbeat(pMbxE e)'{! ROUTINE_NAME("do_heartbeat"); longword pid; pProc p; pid = e->iosb.dvispec;9 errlog(L_MAIN|L_TRACE,"do_heartbeat (pid=!XL) ",pid);/ p = get_Proc(pid);A errlog(L_MAIN|L_BABBLE,"do_heartbeat, lookup found p=!XL",p);t if (!p) return 0; 4 send_message(p->commandQ, MSG$_LUBDUB, 0, 0, 0); return 1;l}tintndo_stubstart(pMbxE e) { ! ROUTINE_NAME("do_stubstart");d pMM m = (pMM) e->buf;_ longword pid;h pProc p; pGroup g;, pMBX cmbx; char outbuf[100];  pid = e->iosb.dvispec;9 errlog(L_MAIN|L_TRACE,"do_stubstart (pid=!XL) ",pid);  p = get_Proc(pid);A errlog(L_MAIN|L_BABBLE,"do_stubstart, lookup found p=!XL",p);e if (!p) return 0;e0 sprintf(outbuf,"_MBA%d:",(longword)m->unit);$ cmbx = assign_new_MBX(outbuf,0);> p-<~ FREEWARE.SAVXKe[CRINOID0051]CRINOID.C;1|b>commandQ = MbxQ_new(cmbx, MBXQ$_WRITE|MBXQ$M_RETRY, 0); g = p->group;s$/* proc name still a question ... */j send_message(p->commandQ, MSG$_USERNAME , 0, asciz_pSTRING(g->username), strlen_pSTRING(g->username));T send_message(p->commandQ, MSG$_PROCPRIVS, 0, (char *)&g->priv, sizeof(g->priv));V send_message(p->commandQ, MSG$_PROCQUOTA, 0, (char *)&g->quota, sizeof(g->quota));X send_message(p->commandQ, MSG$_PROCFLAGS, 0, (char *)&g->stsflg, sizeof(g->stsflg));h send_message(p->commandQ, MSG$_PROCPROG , 0, asciz_pSTRING(g->program), strlen_pSTRING(g->program));X send_message(p->commandQ, MSG$_PROCPRIOR, 0, (char *)&g->baspri, sizeof(g->baspri));Z send_message(p->commandQ, MSG$_PROCTMBX , 0, (char *)&TermQ->mbx->unit, sizeof(word));7 send_message(p->commandQ, MSG$_PROCSTART, 0, 0, 0);a return SS$_NORMAL;} intNdo_startpid(pMbxE e){e ROUTINE_NAME("do_startpid"); pMM m = (pMM) e->buf; longword pid;a pProc p; pid = e->iosb.dvispec;7 errlog(L_MAIN|L_INFO,"do_startpid (pid=!XL) ",pid);N p = get_Proc(pid);@ errlog(L_MAIN|L_BABBLE,"do_startpid, lookup found p=!XL",p); if (!p) return 0;t0 memcpy(&p->pid, m->info, e->iosb.count - 4);G errlog(L_MAIN|L_BABBLE,"do_startpid new process pid = !XL",p->pid);n {n# pMBX mc = p->commandQ->mbx;n0 p->commandQ = MbxQ_destroy(p->commandQ); destroy_MBX(mc); }r return SS$_NORMAL;}voidshutdown_server(void){$ ROUTINE_NAME("shutdown_server"); int j, n, nalive, tries; longword * PIDList = 0;p pProc p; pGroup g;O char text[100];o- netwrite("Content-type: text/plain\n\n");* netwrite("server shutting down...\n"); PIDList = list_Proc(); if (PIDList) {= for (j = nalive = n = 0; PIDList[j] != 0; j++, n++) {)% p = get_Proc(PIDList[j]);d if (p) { g = p->group;  lock_Group(g);F g->n_max = g->n_min = g->n_pad_max = g->n_pad_min = 0; unlock_Group(g);\ sprintf(text, "sending shutdown message to process PID: %08X (group: %s)\n",4 p->pid, asciz_pSTRING(g->name)); netwrite(text); A send_message(p->commandQ, MSG$_NETSHUT, 0, 0, 0);" nalive++;L } else PIDList[j] = 0; }r tries = 0;& while (nalive && tries < 10) { tries++;. for (j = nalive = 0; j < n; j++) {! if (PIDList[j]) {U- p = get_Proc(PIDList[j]);e if (p)! nalive++;- else {N sprintf(text,"Process PID: %08X exited\n",PIDList[j]);' netwrite(text);L' PIDList[j] = 0;o }a } }a% if (nalive > 0) delay(1);N }) if (nalive > 0) {tU netwrite("some tentacle processes still active, shutting down anyway\n");_ }e },W netwrite("Tentacle processes shutdown complete...now shutting down main server\n");n Main_Shutdown = 1; netwrite(""); }dpGroupnet_select_group(){=% ROUTINE_NAME("net_select_group");" char *script;= int madescript = 0;  pENV e,e2,eh;& pGroup g = 0;f pScript s;% pSTRING user = 0, user_group = 0;)9 pSTRING logdir = 0, logx = 0, bindir = 0, remain = 0;( e = find_ENV("SCRIPT_NAME");_ errlog(L_MAIN|L_TRACE,"net_select_group, SCRIPT_NAME = '!AZ'",(e->value ? e->value : "") );n if (!e) goto done; if (!e->value) goto done;_ script = e->value;& e2 = find_ENV("SCRIPT_BARE_NAME"); if (e2) {r@ script = malloc(strlen(e->value)+strlen(e2->value) + 2);# tu_strcpy(script,e->value);; tu_strcat(script,"/");$ tu_strcat(script,e2->value); madescript = 1;t }_! eh = find_ENV("SERVER_NAME");c4 s = findwild_Script(script, eh ? eh->value : 0);K errlog(L_MAIN|L_BABBLE,"net_select_group,findwild returned s=0x!XL",s);_ if (!s) goto done; switch (s->type) {" case SCRIPT$C_DEFAULTUSER:@ user = extract_user(script, asciz_pSTRING(s->wild));F remain = url_remainder(script, asciz_pSTRING(s->wild), 1); if (user) {BC user_group = new_STRING2(strlen_pSTRING(user) + 1);9 tu_strcpy(asciz_pSTRING(user_group),"~");oI tu_strcat(asciz_pSTRING(user_group),asciz_pSTRING(user));E@ g = find_named_Group(asciz_pSTRING(user_group)); if (g) {' bindir = g->bindir; } else {- char *log2, userbin[256];V6 pGroup g2 = find_named_Group("~");f logdir = get_userlogin(asciz_pSTRING(user)); /* user login directory */+ if (!logdir) goto done;m- pthread_lock_global_np();nf log2 = decc$translate_vms(asciz_pSTRING(logdir)); /* translate to unixoid */3 if (log2 && log2 != (char *)-1)i0 logx = new_STRING(log2);/ pthread_unlock_global_np();;) if (!logx) goto done; < tu_strcpy(userbin, asciz_pSTRING(logx));_ if (g2 && g2->usergroup && g2->bindir) { /* append bindir */ F tu_strcat(userbin, asciz_pSTRING(g2->bindir)); } else { #ifdef ALLOWED_DEFAULT_USERGROUP9 tu_strcat(userbin, user_cgi_dir); #else0" goto done;#endif } = g = new_Group(asciz_pSTRING(user_group));l9 setuser_Group(g,asciz_pSTRING(user)); 4 g->bindir = new_STRING(userbin);' bindir = g->bindir;  if (g2) {(1 g->priv = g2->priv; G memcpy(g->quota, g2->quota, sizeof(g2->quota));K3 g->baspri = g2->baspri; 2 g->n_max = g2->n_max;2 g->n_min = g2->n_min;6 g->n_pad_max = g2->n_pad_max;6 g->n_pad_min = g2->n_pad_min; }L" link_Group(g); }N }l# case SCRIPT$C_SPECIFICUSER: ! if (!g && s->user) {i= g = find_named_Group(asciz_pSTRING(s->user));)# bindir = s->bindir; J remain = url_remainder(script, asciz_pSTRING(s->wild), 0); }- if (!g) break; if (bindir) {q/ e2 = find_ENV("SCRIPT_BINDIR");" if (!e2) {E add_ENV("SCRIPT_BINDIR",asciz_pSTRING(bindir),1); } else {$ free(e2->value);A e2->value = malloc(strlen_pSTRING(bindir)+1); @ tu_strcpy(e2->value, asciz_pSTRING(bindir)); } ! movedown_level(); }  if (remain) {=/ e2 = find_ENV("SCRIPT_PREFIX");  if (!e2) {E add_ENV("SCRIPT_PREFIX",asciz_pSTRING(remain),1); } else {$ free(e2->value);A e2->value = malloc(strlen_pSTRING(remain)+1);+@ tu_strcpy(e2->value, asciz_pSTRING(remain)); }n }; break;= case SCRIPT$C_DEBUGPREFIX: /* not implemented yet */' break;" case SCRIPT$C_SERVERMAINT:! g = LocalScriptGroup;s break; }  if (s->flags) {l char buf[32]; # sprintf(buf,"%d",s->flags);F, add_ENV("CRINOID:DEBUGFLAGS",buf,1); } : if (s->permit) add_ENV("CRINOID:ALLOW", s->permit, 1);9 if (s->deny) add_ENV("CRINOID:DENY", s->deny, 1);v5 if (s->warn) add_ENV("CRINOID:WARN", "1", 1);odone:t+ if (user) destroy_STRING(user);t1 if (user_group) destroy_STRING(user_group); - if (logdir) destroy_STRING(logdir);_+ if (logx) destroy_STRING(logx);c- if (remain) destroy_STRING(remain);t# if (madescript) free(script);p return g; }dpSTRINGm'extract_user(char *input, char *prefix)1{! ROUTINE_NAME("extract_user");  pSTRING out = 0; char c1, c2, *p; while (*input && *prefix) {o c1 = *input; c2 = *prefix;M c1 = toupper(c1);0 c2 = toupper(c2);v if (c1 != c2) break; input++; prefix++; }  p = tu_strchr(input,'/');| if (!p)s% p = input + tu_strlen(input);  out = new_STRING2(p-input);u- memcpy(asciz_pSTRING(out),input,p-input);a uc(asciz_pSTRING(out));  return out;Q}wD/* adjust SCRIPT_NAME, SCRIPT_PATH, SCRIPT_BARENAME, PATH_INFO$ for "moving down one level", needed for .../~user/... type URLs8 SCRIPT_NAME = (SCRIPT_PATH) + (SCRIPT_BARE_NAME)1 URL = (SCRIPT_NAME) + (PATH_INFO)pD Note that Oyster will adjust when it finds the actual script*/voidmovedown_level(void){;# ROUTINE_NAME("movedown_level");P pENV eSN, eSP, eSBN, ePI;, char *p, *q;J eSN = find_ENV("SCRIPT_NAME"); /* this should always exist */J eSP = find_ENV("SCRIPT_PATH"); /* this should always exist */J ePI = find_ENV("PATH_INFO"); /* this should always exist */F eSBN= find_ENV("SCRIPT_BARE_NAME"); /* this might not exist */ if (!eSBN) {) add_ENV("SCRIPT_BARE_NAME","",1);$+ eSBN= find_ENV("SCRIPT_BARE_NAME");e }OB q = malloc(tu_strlen(eSN->value) + tu_strlen(ePI->value) + 1); tu_strcpy(q, eSN->value);  p = q + tu_strlen(q);g tu_strcat(q, ePI->value);d if (*p == '/') p++;e p = tu_strchr(p, '/');! if (!p) p = q + tu_strlen(q);o, eSN->value = realloc(eSN->value, p-q+1);# tu_strncpy(eSN->value, q, p-q);t eSN->value[p-q] = 0;5 ePI->value = realloc(ePI->value, tu_strlen(p)+1);n tu_strcpy(ePI->value, p);c *p = 0;n p = tu_strrchr(q,'/'); if (!p) p = q; if (*p == '/') p++;c7 eSBN->value = realloc(eSBN->value, tu_strlen(p)+1);n tu_strcpy(eSBN->value, p); *p = 0;n5 eSP->value = realloc(eSP->value, tu_strlen(q)+1);* tu_strcpy(eSP->value, q); free(q);}hvoidbroadcast_loglevel(int level)y{ ' ROUTINE_NAME("broadcast_loglevel");s int j; longword * PIDList = 0;t pProc p; pGroup g; char text[100];v PIDList = list_Proc(); if (PIDList) {+ for (j = 0; PIDList[j] != 0; j++) {f% p = get_Proc(PIDList[j]); g = p->group;p if (p) {Z sprintf(text, "sending LOGLEV message to process PID: %08X (group: %s)\n",4 p->pid, asciz_pSTRING(g->name)); netwrite(text);)Q send_message(p->commandQ, MSG$_LOGLEV, 0, &level, sizeof(level));e } }e }a}pstatic int sublock_initted = 0;"static LSB logger_main_lsb;static LSB logger_sub_lsb;-static $DESCRIPTOR(d_lock,LOG_MAIN_LOCK); /static $DESCRIPTOR(d_sublock,LOG_SUB_LOCK);)voidStartLogger(void) { ROUTINE_NAME("StartLogger"); int iss; StartLogger_queue_lock(); } voidStartLogger_queue_lock(void){ + ROUTINE_NAME("StartLogger_queue_lock"); int iss; pPrivs p0, p1; p0 = Current_Privs();  if (!p0->prv$v_syslck) { p1 = new_Privs();; p1->prv$v_syslck = 1;i iss = Set_Privs(p1);* if (VMS_ERR(iss)) lib$signal(iss); } r iss = sys$enq(0,LCK$K_PWMODE,&logger_main_lsb,LCK$M_SYSTEM|LCK$M_NODLCKWT,&d_lock,0,&StartLogger_AST,0,0,0,0);& if (VMS_ERR(iss)) lib$signal(iss); if (!p0->prv$v_syslck) { iss = Reset_Privs(p1);* if (VMS_ERR(iss)) lib$signal(iss); destroy_Privs(p1); }v destroy_Privs(p0);} voidStartLogger_AST(int flag){$ ROUTINE_NAME("StartLogger_AST"); int iss;; if (flag == 0) { /* logger exited, try restarting */= if (! sublock_initted) { pPrivs p0, p1;! p0 = Current_Privs();)$ if (!p0->prv$v_syslck) {! p1 = new_Privs();i% p1->prv$v_syslck = 1;I$ iss = Set_Privs(p1);2 if (VMS_ERR(iss)) lib$signal(iss); }W iss = sys$enqw(0,LCK$K_EXMODE,&logger_sub_lsb,LCK$M_SYSTEM|LCK$M_NODLCKBLK,"I &d_sublock,logger_main_lsb.id,0,1,&StartLogger_AST,0,0);u. if (VMS_ERR(iss)) lib$signal(iss);$ if (!p0->prv$v_syslck) {& iss = Reset_Privs(p1);2 if (VMS_ERR(iss)) lib$signal(iss);" destroy_Privs(p1); }- destroy_Privs(p0); sublock_initted = 1; } else {X iss = sys$enqw(0,LCK$K_EXMODE,&logger_sub_lsb,LCK$M_CONVERT|LCK$M_NODLCKBLK,/ 0,0,0,1,&StartLogger_AST,0,0);S. if (VMS_ERR(iss)) lib$signal(iss); },T iss = sys$enqw(0,LCK$K_PRMODE,&logger_main_lsb,LCK$M_CONVERT,0,0,0,0,0,0,0);* if (VMS_ERR(iss)) lib$signal(iss);' queue_special(MSG$_LOGSTART,0);p= } else { /* logger restarted, release locks */iS iss = sys$enq(0,LCK$K_NLMODE,&logger_main_lsb,LCK$M_CONVERT,0,0,0,0,0,0,0);* if (VMS_ERR(iss)) lib$signal(iss);R iss = sys$enq(0,LCK$K_NLMODE,&logger_sub_lsb,LCK$M_CONVERT,0,0,0,0,0,0,0);* if (VMS_ERR(iss)) lib$signal(iss);' queue_special(MSG$_LOGQLOCK,0);  }r}gvoidStartLoggerProc(void);{ $ ROUTINE_NAME("StartLoggerProc"); longword iss, pid; pSTRING prog, loc; char program[500];4 $DESCRIPTOR(loginout,"SYS$SYSTEM:LOGINOUT.EXE"); $DESCRIPTOR(null,"NL:"); Quota quota[PQL$_LENGTH]; pPrivs privs;, loc = translate_logical("CRINOID_HOME"); if (!loc) return;=* tu_strcpy(program,asciz_pSTRING(loc)); destroy_STRING(loc);$ tu_strcat(program,"LOGGER.COM"); prog = new_STRING(program);( privs = new_Privs(); privs->prv$v_syslck = 1; privs->prv$v_sysnam = 1; privs->prv$v_tmpmbx = 1; quota[0].id = PQL$_LISTEND;  iss = sys$creprc(&pid,$ &loginout, /* image */$ prog, /* input */$ &null, /* output */$ &null, /* error */$ &privs, /* privs */$ quota, /* quotas */" 0, /* name */+ 2, /* base priority */e! 0, /* uic */ & 0, /* term mbx */# PRC$M_DETACH /* stsflg */i );O if (VMS_ERR(iss)) printf("Error starting LOGGER, status = 0x%08.8x\n",iss);  destroy_Privs(privs);  destroy_STRING(prog);q}avoidStopLogger(void){  ROUTINE_NAME("StopLogger");a pPrivs p0 = Current_Privs(); pPrivs p;2 if (!p0->prv$v_sysnam) { p = new_Privs();; p->prv$v_sysnam = 1; Set_Privs(p);a } = define_logical("CRINOIDLOG_COMMAND","STOP","LNM$SYSTEM");  if (!p0->prv$v_sysnam) { Reset_Privs(p);  destroy_Privs(p);  }e4 errlog(L_CRITICAL,"Request to stop CRINOIDLOG"); destroy_Privs(p0);} void NewLog(void){I ROUTINE_NAME("NewLog"); pPrivs p0 = Current_Privs(); pPrivs p = new_Privs(); if (!p0->prv$v_sysnam) { p = new_Privs();  p->prv$v_sysnam = 1; Set_Privs(p);  } ? define_logical("CRINOIDLOG_COMMAND","NEWLOG","LNM$SYSTEM");  if (!p0->prv$v_sysnam) { Reset_Privs(p);i destroy_Privs(p);  }{D errlog(L_CRITICAL,"CRINOIDLOG_COMMAND: Request to new logfile"); destroy_Privs(p0);}r;static int hGlobalVerb(pVerb v, char **args, char *errmsg);n:static int hGroupVerb(pVerb v, char **args, char *errmsg);#define V_SERVICE 11#define V_LOGLEVEL 12#define V_USERGROUP 14#define V_THREADS 13#define V_GROUP 21#define V_SCRIPT 23#define V_CONTROL 24#define V_DEBUG 25#define V_PROCESSES 26#define V_PAD 27#define V_SCRIPTFLAGS 31#define V_SCRIPTPERMIT 32#define V_SCRIPTDENY 33#define V_SCRIPTWARN 34#define V_SCRIPTLOCALHOST 35#define V_SCRIPTBINDIR 36#define MAXBUF 512int ReadMainConfig (char *file)N{# ROUTINE_NAME("ReadMainConfig"); FILE *fp;; pVerb v; char buffer[MAXBUF+1]; char errmsg[MAXBUF]; int n, line;: v = new_Verb("SERVICE" , V_SERVICE , &hGlobalVerb, 0);: v = new_Verb("LOGLEVEL", V_LOGLEVEL, &hGlobalVerb, v);: v = new_Verb("CONTROL", V_CONTROL, &hGlobalVerb, v);6 v = new_Verb("DEBUG", V_DEBUG, &hGlobalVerb, v);: v = new_Verb("THREADS", V_THREADS, &hGlobalVerb, v);= v = new_Verb("USERGROUP", V_USERGROUP , &hGroupVerb, v); 3 v = new_Verb("GROUP", V_GROUP, &hGroupVerb, v); 8 v = new_Verb(".SCRIPT", V_SCRIPT, &hGroupVerb, v);= v = new_Verb("..FLAGS", V_SCRIPTFLAGS, &hGroupVerb, v);g? v = new_Verb("..PERMIT", V_SCRIPTPERMIT, &hGroupVerb, v);1; v = new_Verb("..DENY", V_SCRIPTDENY, &hGroupVerb, v);;; v = new_Verb("..WARN", V_SCRIPTWARN, &hGroupVerb, v); E v = new_Verb("..LOCALHOST", V_SCRIPTLOCALHOST, &hGroupVerb, v);? v = new_Verb("..BINDIR", V_SCRIPTBINDIR, &hGroupVerb, v); > v = new_Verb(".PROCESSES", V_PROCESSES, &hGroupVerb, v);2 v = new_Verb(".PAD", V_PAD, &hGroupVerb, v);3 v = new_Verb(".IDLE", V_PAD, &hGroupVerb, v);c uniquify_Verb(v);u# fp = fopen(file,"r","shr=get");) if (!fp) return SS$_ABORT; buffer[MAXBUF] = 0;S line = 0;I' while (fgets(buffer, MAXBUF, fp)) {i line++;" errmsg[0] = 0;+ if (!parse_line(v, buffer, errmsg))MT errlog(L_ERROR,"Error (!AZ) parsing config file, line !SL",errmsg,line); } fclose(fp);  destroy_Verb(v);}t static int/hGlobalVerb(pVerb v, char **args, char *errmsg) {O ROUTINE_NAME("hGlobalVerb"); char *p; int status = 0;h int j; switch (v->id) {8 case V_SERVICE: /* SERVICE service_name */ if (!args[1]) {;> tu_strcpy(errmsg,"SERVICE missing parameter"); break; }wI if (Decnet_Service_Name) destroy_STRING(Decnet_Service_Name); 6 Decnet_Service_Name = new_STRING(args[1]); status = 1;  break;4 case V_LOGLEVEL: /* LOGLEVEL level */ if (!args[1]) {u? tu_strcpy(errmsg,"LOGLEVEL missing parameter");) break; } % Loglevel = atoi(args[1]);( status = 1;  break;0 case V_CONTROL: /* CONTROL url */ if (!args[1]) {t> tu_strcpy(errmsg,"CONTROL missing parameter"); break; }v= new_Script(args[1], SCRIPT$C_SERVERMAINT,"HTTP");p status = 1;/ break;. case V_THREADS: /* THREADS nthreads */ if (!args[1]) {> tu_strcpy(errmsg,"THREADS missing parameter"); break; } j = atoi(args[1]); if (j < 1) {7 tu_strcpy(errmsg,"THREADS must be >0");; break; }o MAX_THREADS = j; status = 1;s break;' case V_DEBUG: /* DEBUG url */s if (!args[1]) { < tu_strcpy(errmsg,"DEBUG missing parameter"); break; }t@ new_Script(args[1], SCRIPT$C_DEBUGPREFIX,"default"); status = 1;- break; default:1 tu_strcpy(errmsg, "Unknown Verb id");s }> return status;}0)#define MAX(a,b) ((a)>(b)?(a):(b)) )#define MIN(a,b) ((a)>(b)?(b):(a))i static int.hGroupVerb(pVerb v, char **args, char *errmsg){s ROUTINE_NAME("hGroupVerb");, static pGroup g = 0; static pScript s = 0;G int status = 0; int j, l;d char *p; switch (v->id) {? case V_USERGROUP: /* USERGROUP bindir */g if (!args[1]) { F tu_strcpy(errmsg,"USERGROUP missing bindir paramter"); break; }f" if (*args[1] != '/') {K tu_strcpy(errmsg,"USERDIR bindir should be unixoid: /..."); break; }s g = new_Group("~");, if (!g) {iF sprintf(errmsg,"error creating USERGROUP %s",args[1]); break; }" setuser_Group(g, "~"); g->usergroup = 1; F l = strlen(args[1]); /* truncate trailing slash */> if (l && args[1][l-1] == '/') args[1][l-1] = '\0';, g->bindir = new_STRING(args[1]); link_Group(g); status = 1;  break;O case V_GROUP: /* GROUP groupname username [bindir]*/r' if (!args[1] || !args[2]) {v? tu_strcpy(errmsg,"GROUP missing parameter(s)");1 break; }s, if (find_named_Group(args[1])) {B sprintf(errmsg,"GROUP %s already exists",args[1]); break; }_- if (args[3] && *args[3] != '/') {uL tu_strcpy(errmsg,"GROUP bindir must be unixoid form: /..."); break; }f# g = new_Group(args[1]);  if (!g) {;B sprintf(errmsg,"error creating GROUP %s",args[1]); break; } & setuser_Group(g, args[2]);I if (args[3]) { /* truncate trailing slash */K$ l = strlen(args[3]);B if (l && args[3][l-1] == '/') args[3][l-1] = '\0';0 g->bindir = new_STRING(args[3]); }  link_Group(g); status = 1;K break;7 case V_SCRIPT: /* SCRIPT url [group] */ 7 if (args[2]) g = find_named_Group(args[2]); ! if (!args[1] || !g) {c@ tu_strcpy(errmsg,"SCRIPT missing parameter(s)"); break; }fv s = new_Script(args[1],g->usergroup? SCRIPT$C_DEFAULTUSER : SCRIPT$C_SPECIFICUSER,asciz_pSTRING(g->name));> s->bindir = g->bindir; /*default bindir*/ status = 1;  break;6 case V_SCRIPTBINDIR: /* BINDIR directory */ if (!s) {sO tu_strcpy(errmsg,"BINDIR must be preceeded by SCRIPT command");" break; }P if (!args[1]) {qE tu_strcpy(errmsg,"BINDIR needs directory parameter");C break; }" if (*args[1] != '/') {P tu_strcpy(errmsg,"BINDIR directory must be unixoid form: /..."); break; }e l = strlen(args[1]);> if (l && args[1][l-1] == '/') args[1][l-1] = '\0';, s->bindir = new_STRING(args[1]); status = 1;  break; case V_SCRIPTFLAGS:  if (!s) { P tu_strcpy(errmsg,"SCRIPTFLAGS needs to be preceeded by SCRIPT"); break; }u if (!args[1]) { E tu_strcpy(errmsg,"SCRIPTFLAGS missing parameter(s)");i break; }*% s->flags = atoi(args[1]);  status = 1;  break; case V_SCRIPTPERMIT: if (!s) {EQ tu_strcpy(errmsg,"SCRIPTPERMIT needs to be preceeded by SCRIPT");o break; }) if (!args[1]) {oF tu_strcpy(errmsg,"SCRIPTPERMIT missing parameter(s)"); break; }i, p = malloc(strlen(args[1]) + 1);" tu_strcpy(p, args[1]); j = 1; while (args[++j]) {; p = realloc(p,strlen(p)+strlen(args[j])+2); " tu_strcat(p, " ");% tu_strcat(p,args[j]);O }e s->permit = p; status = 1;O break; case V_SCRIPTDENY: if (!s) { O tu_strcpy(errmsg,"SCRIPTDENY needs to be preceeded by SCRIPT");  break; }( if (!args[1]) {g$ s->deny = malloc(1); *s->deny = '\0'; status = 1;v break; } , p = malloc(strlen(args[1]) + 1);" tu_strcpy(p, args[1]); j = 1; while (args[++j]) {b; p = realloc(p,strlen(p)+strlen(args[j])+2); " tu_strcat(p, " ");% tu_strcat(p,args[j]);_ }  s->deny = p; status = 1;D break; case V_SCRIPTWARN: if (!s) { O tu_strcpy(errmsg,"SCRIPTWARN needs to be preceeded by SCRIPT");_ break; }  s->warn = 1; status = 1;n break; case V_SCRIPTLOCALHOST:3 if (!s) { N tu_strcpy(errmsg,"LOCALHOST needs to be preceeded by SCRIPT"); break; }( if (!args[1]) {_S tu_strcpy(errmsg,"LOCALHOST needs to have a 'hostname' parameter");  break; };, s->server = new_STRING(args[1]);) uc(asciz_pSTRING(s->server));L status = 1;r break;> case V_PROCESSES: /* PROCESSES min max [group] */7 if (args[3]) g = find_named_Group(args[3]);H- if (!args[1] || !args[2] || !g) { @ tu_strcpy(errmsg,"MAXMIN missing parameter(s)"); break; } {e int k1, k2; # k1 = atoi(args[1]);.# k2 = atoi(args[2]); 5 g->n_min = MIN(MAX(MIN(k1,k2),0),10);G5 g->n_max = MIN(MAX(MAX(k1,k2),1),10);Y }  status = 1;. break;3 case V_PAD: /* PAD min max [group] */V7 if (args[3]) g = find_named_Group(args[3]);.- if (!args[1] || !args[2] || !g) { = tu_strcpy(errmsg,"PAD missing parameter(s)");  break; }V {  int k1, k2;&# k1 = atoi(args[1]);(# k2 = atoi(args[2]);g9 g->n_pad_min = MIN(MAX(MIN(k1,k2),0),10);=9 g->n_pad_max = MIN(MAX(MAX(k1,k2),0),10); }e status = 1;  break; default:1 tu_strcpy(errmsg, "Unknown Verb id");  }  return status;}evoiddelay(int secs)e{) struct timespec t = {0, 0}; int iss; t.tv_sec = secs; iss = pthread_delay_np(&t);O+ if (UNIX_ERR(iss)) UNIX_ABORT("delay"); } pNDBdestroy_NDB(pNDB ndb)w{h ROUTINE_NAME("destroy_NDB"); int iss;! pNDB nlast = 0, n = NDB_Head;f7 errlog(L_MAIN|L_BABBLE,"destroy_NDB(ndb=!XL)",ndb);i if (!ndb) return 0;  while (n) {  if (n == ndb) break; nlast = n; n = n->next; }e if (nlast) nlast->next = ndb->next; else NDB_Head = ndb->next; , if (ndb->process) ndb->process->ndb = 0; ndb->process = 0;B/* if (ndb->Merr) ndb->Merr = destroy_MBX(ndb->Merr); */> if (ndb->Q2perl) ndb->Q2perl = MbxQ_destroy(ndb->Q2perl);; if (ndb->Qin) ndb->Qin = MbxQ_destroy(ndb->Qin);s< if (ndb->Pout) ndb->Pout = Pipe_destroy(ndb->Pout);, iss = pthread_mutex_unlock(&ndb->mutex);? if (UNIX_ERR(iss)) UNIX_ABORT("destroy_NDB, mutex_unlock"); - iss = pthread_mutex_destroy(&ndb->mutex); @ if (UNIX_ERR(iss)) UNIX_ABORT("destroy_NDB, mutex_destroy");+ iss = pthread_cond_destroy(&ndb->cond);a? if (UNIX_ERR(iss)) UNIX_ABORT("destroy_NDB, cond_destroy");+ iss = pthread_mutex_lock(&ThreadMutex);s= if (UNIX_ERR(iss)) UNIX_ABORT("thread_code, mutex_lock");  Allowed_Active++;;/ iss = pthread_cond_signal(&ThreadMsgReady);r@ if (UNIX_ERR(iss)) UNIX_ABORT("thread_handle, cond_signal");- iss = pthread_mutex_unlock(&ThreadMutex); = if (UNIX_ERR(iss)) UNIX_ABORT("thread_code, mutex_lock"); #ifdef PRINT_QUOTA { ! longword pid = get_pid();u) longword quota = get_bytcnt(pid);@ errlog(L_INFO,"destroy_NDB, quota now !UL bytes",quota); }C#endif free(ndb); return 0; } %pATE Head_ATE = 0;a"pthread_mutex_t ATE_mutex;#pthread_t ATE_thread;uvoid)queue_ATE(word unit, int type, int ticks)({( ROUTINE_NAME("queue_ATE"); int iss;( pATE a = (pATE) malloc(sizeof(ATE)); if (!a) {e8 errlog(L_CRITICAL,"queue_ATE: malloc failed!!"); return;  }p a->type = type;  a->unit = unit;  a->ticks = ticks;) iss = pthread_mutex_lock(&ATE_mutex);E; if (UNIX_ERR(iss)) UNIX_ABORT("queue_ATE: mutex_lock");f a->next = Head_ATE;  Head_ATE = a;g+ iss = pthread_mutex_unlock(&ATE_mutex); = if (UNIX_ERR(iss)) UNIX_ABORT("queue_ATE: mutex_unlock");)} void dequeue_ATE(word unit, int type){r ROUTINE_NAME("dequeue_ATE"); int iss; pATE a, a0; ) iss = pthread_mutex_lock(&ATE_mutex); ; if (UNIX_ERR(iss)) UNIX_ABORT("queue_ATE: mutex_lock");g a0 = 0;a a = Head_ATE;  while (a) { 1 if (a->unit == unit && a->type == type) {  if (a0 == 0)# Head_ATE = a->next;  else# a0->next = a->next;  break; }[ a0 = a;  a = a->next; }Go if (!a) errlog(L_WARNING,"dequeue_ATE: entry not found unit !UW type !SL (ok, if just aborted)",unit,type);  if (a) free(a);R+ iss = pthread_mutex_unlock(&ATE_mutex); = if (UNIX_ERR(iss)) UNIX_ABORT("queue_ATE: mutex_unlock");"} void *ATE_processor(void *pNum) { " ROUTINE_NAME("ATE_processor"); int iss; pATE a, a0, a1;  while (1) {t- iss = pthread_mutex_lock(&ATE_mutex); E if (UNIX_ERR(iss)) UNIX_ABORT("ATE_processor: mutex_unlock");3 a0 = 0;  a = Head_ATE;m while (a) { $ if (--(a->ticks) <= 0) { if (a0)f' a0->next = a->next;  else' Head_A? ~ FREEWARE.SAVXKe[CRINOID0051]CRINOID.C;1'j TE = a->next;aE if (a->type == ATE_DISCON) abort_connection(a->unit); G else if (a->type == ATE_ABORT) abort_tentacle(a->unit);  a1 = a->next;K free(a); a = a1;  } else { a0 = a;= a = a->next; }G }/ iss = pthread_mutex_unlock(&ATE_mutex); E if (UNIX_ERR(iss)) UNIX_ABORT("ATE_processor: mutex_unlock");/ delay(1);* } return 0;s})voidinit_ATE_Proc(void) { " ROUTINE_NAME("init_ATE_Proc"); int foo = 0, iss;(C iss = pthread_mutex_init(&ATE_mutex,pthread_mutexattr_default); ? if (UNIX_ERR(iss)) UNIX_ABORT("init_ATE_proc, mutex_init");_O iss = pthread_create(&ATE_thread,pthread_attr_default,&ATE_processor,&foo); C if (UNIX_ERR(iss)) UNIX_ABORT("init_ATE_Proc, pthread_create"); } voidstop_ATE_Proc(void)V{R" ROUTINE_NAME("stop_ATE_Proc"); int iss;% iss = pthread_cancel(ATE_thread);mC if (UNIX_ERR(iss)) UNIX_ABORT("stop_ATE_Proc, pthread_cancel");r};pSTRING 6url_remainder(char *input, char *prefix, int usermode){(" ROUTINE_NAME("url_remainder"); char *url; pSTRING out = 0; char c1, c2, *p; int j = 0;% url = malloc(tu_strlen(input)+1);g tu_strcpy(url, input); while (*input && *prefix) {  c1 = *input; c2 = *prefix;l c1 = toupper(c1);f c2 = toupper(c2);  if (c1 != c2) break; input++; prefix++; j++; }1 if (usermode) { while (*input) { input++; j++;% if (*input == '/') break; }e }S url[j] = '\0'; out = new_STRING(url); free(url); return out; } void#queue_special(word code, word unit)a{e" ROUTINE_NAME("queue_special"); int iss; pMbxE e; pMM m; e = MbxQ_new_entry();tC if (!e) VMS_ABORT(SS$_INSFMEM,"queue_special, MbxQ_new_entry"); e->iosb.status = SS$_NORMAL; e->iosb.count = 4;T m = (pMM) e->buf;  m->code = code;  m->unit = unit; ! iss = lib$insqti(e, GotMsgQ);= if (VMS_ERR(iss)) VMS_ABORT(iss,"queue_special, insqti");r if (Threads_initted) {5 iss = pthread_cond_signal_int_np(&Main_cond);1D if (UNIX_ERR(iss)) UNIX_ABORT("queue_special, cond_signal"); } }l*[CRINOID0051]CRINOID.H;1+,e8. / 4D <-Ke0123KPWO 56 g7(89GHJ /* * definitions for CRINOID * */#ifndef __CRINOID_H#define __CRINOID_H#include "vms_data.h"#include "util.h"#include "CRINOID_types.h"#include "mbxq.h"int do_online(pMbxE e);void do_offline(pMbxE e);void do_idle(pMbxE e);Dint send_message(pMbxQ q, word code, word unit, void *s, int n);void messageAST(pMbxE e);void init_threads();void stop_threads(); void * thread_code(void *pNum);void thread_handle(pMbxE e);%void do_connect(pTCB tc, pMbxE e);pGroup net_select_group();void net_sendENV(pProc p);pNDB net_connect(pMbxE e);void net_disconnect(pNDB);void net_readENV();void clean_TCB(pTCB tc);pTCB destroy_TCB(pTCB tc);pTCB new_TCB(int ThreadID);void destroy_ENV(pENV e);pENV * get_ENVBase();void new_ENV(void);4pENV add_ENV(char *name, char *value, int state);pENV find_ENV(char *name);void get_main_params(void);void get_id2_params(void);void get_path_params(void); void get_header_params(void);void get_input(void);pTCB get_current_TCB();#int netread(char *s, int lmax);$void netwrite2(pMbxQ q, char *s);void netwrite(char *s);pSTRING fetch_value(char *tag);char * pop_token(char **s);9char * net_unescape_string ( char *string, int *length );void net_runscript(pProc p);=void load_translation ( char *name, char *tag, char *arg );void destroy_TCB2(void *tc);void do_disconnect(pMbxE e);int local_script(void);pENV parse_input(pSTRING s);static void Exit_handler(void);)int send_logical(pProc p, char *name);int do_heartbeat(pMbxE e);int do_stubstart(pMbxE e);int do_startpid(pMbxE e) ;void shutdown_server(void);0pSTRING extract_user(char *input, char *prefix);void movedown_level(void);&void broadcast_loglevel(int level);void StartLogger(void);%void StartLogger_queue_lock(void);"void StartLogger_AST(int flag);void StartLoggerProc(void);void StopLogger(void);void NewLog(void);$int ReadMainConfig (char *file);void do_pendabort(pMbxE e);void delay(int secs);pNDB destroy_NDB(pNDB ndb);2void queue_ATE(word unit, int type, int ticks);)void dequeue_ATE(word unit, int type);"void* ATE_processor(void *pNum);void init_ATE_Proc(void);void stop_ATE_Proc(void);?pSTRING url_remainder(char *input, char *prefix, int usermode);,void queue_special(word code, word unit);#endif*[CRINOID0051]CRINOID_MSG.MSG;1+,1o. / 4L <-Ke0123KPWO 567MO(89GHJ .facility crinoid,1010 .severity fatalL syssrverr /fao=2 .end*[CRINOID0051]CRINOID_TYPES.H;1+,Do./ 4L T<-Ke0123KPWO56a g7Xσ(89GHJL/**************************************************************************\K * *K * Common data structures *K * *K * *L\**************************************************************************/#ifndef __CRINOID_TYPES_H#define __CRINOID_TYPES_H#include "vms_data.h"#define _PTHREAD_USE_D4G#ifdef EXC_WORKAROUND /* some versions have problems with this */#if EXC_WORKAROUNDA#include "exc_handling.h" /* "fixed" version, but may be old */#endif#endif#include #include #include )typedef struct ENV_entry ENV;)typedef struct ENV_entry* pENV;(typedef struct MBXMSG MM;(typedef struct MBXMSG* pMM;)typedef struct mbx_stuff MBX;)typedef struct mbx_stuff* pMBX;)typedef struct NetDataBlock NDB;)typedef struct NetDataBlock* pNDB;)typedef struct ThreadContextBlock TCB;)typedef struct ThreadContextBlock* pTCB;*typedef struct ProcessInfo Proc;*typedef struct ProcessInfo* pProc;+typedef struct quota_listitem Quota;+typedef struct quota_listitem* pQuota;+typedef struct ProcessGroup Group;+typedef struct ProcessGroup* pGroup;*typedef struct MBXQ MbxQ;*typedef struct MBXQ * pMbxQ;*typedef struct MBXQE MbxE;*typedef struct MBXQE * pMbxE;typedef struct _PIPE2 Pipe2;typedef struct _PIPE2* pPipe2;(typedef struct AbortTimerEntry ATE;(typedef struct AbortTimerEntry* pATE;struct ENV_entry { pENV next; char *name; char *value; int state;};#define MAX_NCB 1024%#define MAX_MSG sizeof(struct MBXMSG)struct MBXMSG { word code; word unit; char info[MAX_NCB];};struct mbx_stuff { word chan; STRING d_name; char name[65]; word unit; word size;};-#define MBXQEBUF MAX_MAILBOX_SIZE struct MBXQ {K RQE msgq; /* put here to keep alignment right ! */ pMBX mbx;@ longword option; /* read/write & other flags */ longword bytes; int next_id; longword ef; longword shut_ef;7 longword pending; /* write AST queued*/5 longword backlog; /* write backlog */ longword maxbacklog; int inprogress; void (*AST)(pMbxE); void *extra; char *name;};struct MBXQE { RQE link; pMbxQ queue; IOSB iosb; char buf[MBXQEBUF]; int len; int id;};struct NetDataBlock { pNDB next; pMbxQ Qin; pMbxQ Q2perl; pPipe2 Pout; pMBX Merr; pthread_mutex_t mutex; pthread_cond_t cond; word unit;' int pending_disconnect;! int pending_idle; int connum; pTCB tc; pProc process;};struct ThreadContextBlock { int id; pthread_t *thread; pENV ENVBase; char *content;# int content_length; pNDB ndb;};struct ProcessInfo { pProc next; pProc last; pProc next_idle; pGroup group; int state; pMbxQ commandQ; pNDB ndb; longword pid; pSTRING name; pthread_mutex_t mutex;# int maintain_lock;! int activations; int killpend;! longword killtime[2];};#define PS_NEW 1#define PS_STARTING 2#define PS_STOPPING 3#define PS_BUSY 4#define PS_IDLE 5#define PS_DEAD 6#define PS_ANY (-1)struct quota_listitem { byte id; longword value;};struct ProcessGroup { pGroup next;" pProc idle_list; pthread_cond_t cond; pthread_mutex_t mutex; pSTRING name; longword uic;! pSTRING username; pSTRING bindir; union prvdef priv;+ Quota quota[PQL$_LENGTH]; longword baspri; longword stsflg;" int usergroup; int n_idle; int n_busy; int n_total; int n_max; int n_min;" int n_pad_max;" int n_pad_min; int n_req;# int n_starting;! int n_serial; pSTRING program; pSTRING input; pSTRING output; pSTRING error;};)typedef struct _SCRIPT_MATCH Script;)typedef struct _SCRIPT_MATCH* pScript;struct _SCRIPT_MATCH { pScript next; pSTRING wild; pSTRING user; pSTRING server; pSTRING bindir; int type; unsigned int flags; char *permit; char *deny; int warn;};%#define SCRIPT$C_SPECIFICUSER 1%#define SCRIPT$C_SERVERMAINT 2%#define SCRIPT$C_DEBUGPREFIX 3%#define SCRIPT$C_DEFAULTUSER 4struct _PIPE2 { pMBX in_mbx; pMBX out_mbx; pMbxQ inQ; pMbxQ outQ; char * buffer; int bcount;};struct AbortTimerEntry { pATE next; word unit; int type; int ticks;};#define ATE_DISCON 1#define ATE_ABORT 2)#define LOG_MAIN_LOCK "CRINOID_LOGGER"+#define LOG_SUB_LOCK "CRINIOD_LOGSTART"#ifdef DEBUG_MEMORY#include 1#define free(p) my_free(p,curr_routine_name)3#define malloc(s) my_malloc(s,curr_routine_name)6#define realloc(p,s) my_realloc(p,s,curr_routine_name)#endif;#define ROUTINE_NAME(n) static char curr_routine_name[]=n#endif *[CRINOID0051]DEBUG_SUPPORT.DIR;1+,pK. / 4 -Ke0123 KPWO 560$) 7x.) 89GHJIDBG$CRINOID.INISqYDBG$TENTACLE.INIvqlDEBUGGING_HELP.TXT%v DO_DEBUG.COMxJMEM.PL鏚TEST_GLOBAL.PLKZ,*[CRINOID0051.DEBUG_SUPPORT]DBG$CRINOID.INI;1+,SqY. / 4 -pK0123KPWO 56;ȝ7Q89&"ʞGHJdefine/command b = "set break " define/command cb = "cancel break " define/command bl = "set break %line " define/command btl = "set break/temp %line " define/command cbl = "cancel break %line " define/command bx = "set break /exception" define/command cbx = "cancel break /exception" define/command bh = "set break @%pc " define/command cbh = "cancel break @%pc" go bx set module/all -*[CRINOID0051.DEBUG_SUPPORT]DBG$TENTACLE.INI;1+,vql. / 4 -pK0123KPWO 56;ȝ7;ȝ89&"ʞGHJdefine/command b = "set break " define/command cb = "cancel break " define/command bl = "set break %line " define/command btl = "set break/temp %line " define/command cbl = "cancel break %line " define/command bx = "set break /exception" define/command cbx = "cancel break /exception" define/command bh = "set break @%pc " define/command cbh = "cancel break @%pc" go bx s/*[CRINOID0051.DEBUG_SUPPORT]DEBUGGING_HELP.TXT;1+,%v./ 4]<-pK0123KPWO56s:ڞ7Bڞ89GHJ,COMMON PROBLEMS:================Problems starting TENTACLE, STUB, etc: look for text messagesC(unknown message type is usually a text message) in the CRINOID.LOGEfile. For example, if TENTACLE has a problem with the PERL logicalsC(it needs PERL_ROOT and PERLSHR) it will show up in the CRINOID.LOGfile.@----------------------------------------------------------------AProblems starting CRINOID will show up in a NETSERVER.LOG file inyour OSU_HTTP home directory.DProxy problems and nonfunctional proxy accounts generally won't showDup in the NETSERVER.LOG files; you may need to check $ accounting orDlook at the OSU_HTTP log files. I've seen situations where you have@to reboot (!) to get a proxy definition to "take", but that was5likely caused by some misconfiguration of the variousSYS$SYSTEM:*PROXY*.DAT files.?It's useful to log into your HTTP-server account and try thingslike: $ DIR 0::and $ DIR 0"HTTP"::% ^^^^ or whatever username1...you should get directories of the HTTP server.@----------------------------------------------------------------?Script problems: make sure your scripts will run interactively!=(e.g, "perl myscript.cgi") and use the -w flag when testing!DIt helps to have an OYSTER.CONFIG that defines a log file, and checkFthat logfile for messages. You can set the loglevel to 3 or higher toFget more verbose output, and any writes to STDERR in your scripts willgo to the logfile.FYour scripts will be running in a "virgin" process (i.e., without yourCLOGIN.COM having run) so you may need to do some manual setup to be@able to use utilities beyond what is in Perl (PGPLOT, Databases,Betc.). You can use AddENV and AddINC commands in OYSTER.CONFIG toFimport logicals into the script's %ENV and to put directories into theFscript's @INC array, but any defining of logicals/symbols will have toEbe done in TENTACLE.COM. See TENTACLE.COM for an example of setting up PGPLOT."You might encounter messages like:W ERROR while running: Unable to create sub named "*Blah::blah::blah" at /perl/lib...BThese *can* be caused by modules not being preloaded...if they areFloaded in the process of running OYSTER but not on a preload list thenBthey will not be available to the scripts. (The script won't loadEthem because they're "already loaded", but they haven't been importedCinto the Safe:: partition so are not available to the script). SetAthe OYSTER logging level to 3 and look at the logfile to see whatDmodules are there at startup and which are preloaded into the Safe::0partitions. Then adjust preloads appropriately.----digression---K There's some trickiness regarding putting things into module namespacesL that can also cause the "unable to create sub" error. If OYSTER creates a symbol:0 $(safename)::SOME_PACKAGE::SUBPKG::stuff6 The symbol tables (stashes) for SOME_PACKAGE:: andG SOME_PACKAGE::SUBPKG are created. _BUT_ if this occurs outside theC Safe:: partition, the "HvNAME" on these stashes will refer back@ to the real, true "main::" rather than the Safe:: partition. The solution is to do a:9 $safeptr->init_stash('SOME_PACKAGE::SUBPKG');O first, which simple creates a dummy variable using a Safe::reval procedure,@ thereby creating the symbol tables with the correct HvNAMEs.M This is how CGI::Carp can be made to function properly...it has an "exit"P call that Safe would normally trap. We first create the symbol tables, thenK insert an "exit" procedure into the (safename)::CGI::Carp symbol table.D Note that CGI::Carp should not be preloaded because it overloads= the usual Carp symbols that some scripts may want to use.K CGI should not be preloaded, because of it's tricky export handling and i/o initialization.----end digression---EYou can change preloads for all Tentacles by editing OYSTER's preloadClist near the top of the file. One can also edit OYSTER.CONFIG to$change preloads on a per-user basis.?Note that the "modules at startup" will almost certainly changeEbetween Perl versions, requiring slight changes to the preloads. AndCI'm sure that I haven't tried all possible modules, so the need for*some preloads hasn't been encountered yet.H========================================================================Script global symbol pollution:EThis *shouldn't* be a problem, at least with moderately modern Perls.AThere's a little test script "test_globals.pl" that scans throughDsymbols like $^A, $#, etc. to see which are actually "global" (i.e.,1changes inside a Safe partition persist outside).ESome of these don't matter: $. (the current line number). But othersKlike $\ can make real problems if they get changed by a script and persist.MThe SCRIPT.PM module tries to save/restore these globals, but future versionsGof Perl might have some more. So you can run test_globals.pl and checkFagainst SCRIPT.PM... NOTE that there are several ways that the globalsFget reset, so just because it's not on the "save_globals" list doesn'tmean it isn't saved.H========================================================================DIt is unlikely that you'll encounter a serious CRINOID/TENTACLE/STUBFproblem that will require running one or more of these programs in the0VMS debugger. But if you need to, here's how...4Steps for running CRINOID processes in the debugger:@----------------------------------------------------------------CWith AUTHORIZE set up an account with the same UIC, home directory,6etc. the same as your OSU_HTTP server, but with privs:1 LOG_IO, PHY_IO, SYSPRV, SYSNAM, DETACH, WORLD( [+IMPERSONATE for VMS7.2 and higher] OPTION 1:IIf you are going to only run one CRINOID server, and you want that serverto be "debuggable":J--------------------------------------------------------------------------J Do a FULL shutdown of any existing CRINOID server, to remove installed images.K Suppose that your OSU_HTTP server runs in account HTTP, and you've just( added account DBGHTTP...add a proxy: $ MCR AUTHORIZE\ UAF> ADD/PROXY mynode::HTTP /DEFAULT=DBGHTTP !! use your nodename for 'mynode' UAF> SHOW/PROXY *::*( should then show something like: mynode::HTTP4 DBGHTTP (D) HTTPP (you'll want to set the default back to HTTP after you switch to a non-debug version of CRINOID) OPTION 2:GIf you are going to run multiple CRINOID servers, for example one being1a "production" server, and another for debugging:E---------------------------------------------------------------------K As an example, the process name of the debug-CRINOID will be "CRINOID2"I that listens to DECNET service WWWPERL2. It should be installed in a, separate directory from the main server.I You don't need a full shutdown...just shut down any previous CRINOID2P servers by using @SHUTDOWN DEINSTALL in the CRINOID2 installation directory.6 Create a proxy, but it doesn't have to be default: $ MCR AUTHORIZEU UAF> ADD/PROXY mynode::HTTP DBGHTTP !! use your nodename for 'mynode' UAF> SHOW/PROXY *::*( should then show something like: mynode::HTTP3 HTTP(D) DBGHTTPO In your WWW_SYSTEM:HTTP_SCRIPTS.CONF file, put an exec rule something like:J exec /cgi/* 0::"0=WWWPERL"nl: ! normalX exec /cgi2/* 0"DBGHTTP"::"0=WWWPERL2"nl: ! extra, for debuggingS The result will be that while "normal" CGI urls (http://mynode.etc.net/cgi/...)R get serviced by the "normal" CRINOID, urls like http://mynode.etc.net/cgi2/...] are handed to CRINOID2, running in the DBGHTTP account. You'll have to put WWWPERL2.COMX into the WWW_ROOT:[000000] directory, which the INSTALL procedure prompts you to do.Then, in both options:---------------------.Build and install a debug version of the code:A @CONFIGURE with "VMS-debug" option, UIC for the new acct,M set process name and decnet service name if doing OPTION2.7 @BUILD CLEAN if previous "nodebug" build was done @BUILD< @INSTALL and copy WWWPERL*.COM if it's changed/newCNote that if you do a @STARTUP of CRINOID, there will be complaintsDabout installing images linked "/TRACEBACK". That's good, you don'tFwant them installed. But you do want to make sure that the old imagesare deinstalled.LCopy the debug support files (in this directory) to the CRINOID installation directory: COPY *.INI disk:[directory] COPY *.COM disk:[directory]CBecause CRINOID and TENTACLE need to respond to connection requestsAin a timely manner (or the net connections get wiped out), it's a9good idea to get them up to speed quickly when debugging.>Sometimes that means setting your breakpoints etc. in the .INI@file and having the program "go" initially. (It takes two "go"s8to actually run; the default .INI's supply one of them).BThe DO_DEBUG procedure is to make it easy to set debugging output.AFor detached/network processes, the best bet is to have debugginga+be directed to a DEC- or X-windows display.E@Do a @DO_DEBUG and give it the IP# or node name of the X-displayAyou want to use for debugging, and answer the questions for whichb;programs you want to debug (CRINOIDLOG, CRINOID, TENTACLE).=If these processes are currently running, you'll have to shuti=them down, and new processes will get the debugging settings.ODEBUG LOGGING: =============aBThe command files CRINOID.COM and TENTACLE.COM have logging levels@and flags that can be set prior to running the executables. TheB`higher' the level, the more things get logged. There are severalC`flags' (MS bits in the loglevel) that turn on logging from variousTBparts of the programs. The logging from CRINOID and TENTACLE gets2sent to CRINOIDLOG which writes it to CRINOID.LOG.DThe log level changes made in the command files will take effect the@next time the program is run... you can stop/id the old ones, or=use @SHUTDOWN. Log level changes made via the "control" cgir"interface take effect immediately.CThe NEWLOG.COM procedure starts a new CRINOID.LOG file, letting youg"view/edit the old one more easily.FNote that if you run more than one CRINOID, the first one started willHstart the CRINOIDLOG process which will then be used by all the CRINOIDsGand TENTACLES. If you do a @SHUTDOWN FULL (for any of the CRINOIDs) itOIwill also shut down CRINOIDLOG, which will be a problem for any remaining GCRINOIDS. So do @SHUTDOWN DEINSTALL for all CRINOIDS but the last one, which gets a @SHUTDOWN FULL.)*[CRINOID0051.DEBUG_SUPPORT]DO_DEBUG.COM;1+,xJ. / 4a <-pK0123KPWO 56߮7d89GHJ$!C$! Sets logicals to have CRINOID components run under VMS debuggerB$! ...note that if running in the debugger, the accounts used forJ$! CRINOID must have privs, since we can't INSTALL images with traceback.$!$ on error then goto cleanup $ on control_y then goto cleanup$ call get_displaya$ read/end=cleanup/prompt="Debugging DEC/X-Windows display on node? [''machine']: " sys$command d!$ d = f$edit(d,"collapse,upcase") $ if d .eqs. "" then d = machine;$ call setdebug "CRINOIDLOG debug?" CRINOIDLOG_DEBUG "''d'"5$ call setdebug "CRINOID debug?" CRINOID_DEBUG "''d'"?$ call setdebug "TENTACLE debug?" CRINOID_TENTACLE_DEBUG "''d'" $ cleanup:?$ if f$type(machine) .nes. "" then delete/symbol/global machineG$!---------------------------------------------------------------------2$! NOT fully general, but handles UCX and Multinet$!$ get_display: subroutine#$ term = f$getjpi("","terminal"))$ ttdev = f$getdvi(term,"TT_PHYDEVNAM") $ tttyp = f$extract(1,3,ttdev)$!$! UCX$!$ if tttyp .eqs. "TNA"$ then$$ aa=F$GETDVI(term,"TT_ACCPORNAM")$ bb=f$element(1," ",aa)$ machine == bb$ endif$! $! MultiNet$!$ if tttyp .eqs. "NTY"$ then1$ host = f$getdvi(term,"TT_ACCPORNAM")-"]"-"["$ machine == host$ endif$!$! DECWindows local$!$ if tttyp .eqs. "FTA"$ then,$ machine == f$trnlnm("UCX$INET_HOSTADDR")$ endif$ exit$ endsubroutine$!0$ setdebug: subroutine ! prompt logical display $ def = "N"+$ if f$trnlnm(p2) .nes. "" then def = "Y"$ q1:9$ read/end=nah/prompt="''p1' [''def']: " sys$command yn%$ yn = f$edit(yn,"collapse,upcase") $ if yn .eqs. "" then yn = def$ yn = f$extract(0,1,yn)$ if yn .eq. "Y"$ then"$ define/system 'p2' "''p3'" $ exit $ endif$ if yn .eq. "N"$ then1$ if def .eq. "Y" then deassign/system 'p2' $ exit $ endif $ goto q1$ nah:$ exit$ endsubroutine#*[CRINOID0051.DEBUG_SUPPORT]MEM.PL;1+,鏚. / 4g <-pK0123KPWO 567h89GHJ#! perl#F# script to process CRINOID.LOG files, matching up malloc's with# free's and realloc's#C# output is log file with text appended to appropriate lines.#7# usage: perl mem.pl processed.logL#(0001AD32 20-SEP-2000 09:23:23.03): [CRINOID 000040:3]malloc(36) = 0048C0E8E#(0001AD32 20-SEP-2000 09:23:23.07): [CRINOID 000040:3]free(0048C0E8)g#(0001B125 20-SEP-2000 11:49:02.74): [CRINOID 000040:3][movedown_level] realloc(00630A08,17) = 00672008 $line = -1;while () { chomp; $line++;! $file[$line] = $line.': '.$_; $status[$line] = '';. if (/malloc\((\d+)\)\s+=\s+([\da-f]+)/i) { $alloc{$2} = $line;% } elsif (/free\(([\da-f]+)\)/i) {! if (exists($alloc{$1})) {5 $file[$alloc{$1}] .= " freed line $line"; delete($alloc{$1}); } else {. $file[$line] .= " not allocated!"; }? } elsif (/realloc\(([\da-f]+),(\d+)\)\s+=\s+([\da-f]+)/i) {! if (exists($alloc{$1})) {@ $file[$alloc{$1}] .= " freed by realloc line $line"; delete($alloc{$1}); } $alloc{$3} = $line; }}foreach (@file) { print $_."\n";}+*[CRINOID0051.DEBUG_SUPPORT]TEST_GLOBAL.PL;1+,KZ. / 4I <-pK0123KPWO 56}7=&89GHJs~ FREEWARE.SAVKZpK+[CRINOID0051.DEBUG_SUPPORT]TEST_GLOBAL.PL;1I n#! perl use Safe;$s = new Safe 'FOO';$s->permit(':all');Iprint "--------------------------------------------------------------\n";for ($c = 1; $c <127; $c++) {/ next if ($c >= ord('A') && $c <= ord('Z'));/ next if ($c >= ord('a') && $c <= ord('z')); next if ($c == ord(' ')); if ($c < ord(' ')) {$ $sym = '^'.chr(ord('@')+$c); } else { $sym = chr($c); }" $script = '$val = $'.$sym.';'; $s->reval($script);. eval('$diff = ($FOO::val != $'.$sym.');');/ eval('$diff2 = ($FOO::val ne $'.$sym.');'); if ($diff || $diff2) {I print '$'.$sym." default value does not propagate into Safe::\n"; }}Iprint "--------------------------------------------------------------\n";for ($c = 1; $c <127; $c++) {/ next if ($c >= ord('A') && $c <= ord('Z'));/ next if ($c >= ord('a') && $c <= ord('z')); next if ($c == ord(' ')); if ($c < ord(' ')) {$ $sym = '^'.chr(ord('@')+$c); } else { $sym = chr($c); }A if ($sym eq '^D') { # know it's global, too much output!!0 print '$'.$sym." localizable global\n" ; next; }$ $script = "\$".$sym." = 'BAD';";" eval('$saveval = $'.$sym.';'); $s->reval($script);A eval('$diff = ($'.$sym.' eq q(BAD)); $'.$sym.' = $saveval;'); if ($diff) {9 $script = 'local $'.$sym.'; $'.$sym.' = q(BAD);';& eval('$saveval = $'.$sym.';'); $s->reval($script);E eval('$diff = ($'.$sym.' eq q(BAD)); $'.$sym.' = $saveval;'); if (!$diff) {6 $result = '$'.$sym." localizable global";< $s->reval('local $'.$sym.'; $val = $'.$sym.';');& eval('$val = $'.$sym.';');9 if ($FOO::val != $val && $FOO::val ne $val) {8 $result .= ' but non-default value'; } print $result,"\n"; next; } }" $script = "\$".$sym." = 666;";" eval('$saveval = $'.$sym.';'); $s->reval($script);> eval('$diff = ($'.$sym.' == 666); $'.$sym.' = $saveval;'); if ($diff) {6 $script = 'local $'.$sym.'; $'.$sym.' = 666;';& eval('$saveval = $'.$sym.';'); $s->reval($script);B eval('$diff = ($'.$sym.' == 666); $'.$sym.' = $saveval;'); if (!$diff) {3 print '$'.$sym." localizable global\n"; next; } }}Bprint "-------------------------------------------------------\n";for ($c = 1; $c <127; $c++) {/ next if ($c >= ord('A') && $c <= ord('Z'));/ next if ($c >= ord('a') && $c <= ord('z')); next if ($c == ord(' ')); if ($c < ord(' ')) {$ $sym = '^'.chr(ord('@')+$c); } else { $sym = chr($c); }A if ($sym eq '^D') { # know it's global, too much output!! next; }/ $script = '$diff = ($'.$sym.' eq q(BAD));'; $@ = '';6 eval('$saveval = $'.$sym.'; $'.$sym.' = q(BAD);');7 if ($@) { print '$'.$sym." not settable\n"; next; } $s->reval($script); $diff = $FOO::diff;" eval('$'.$sym.' = $saveval;'); if (!$diff) {0 $script = '$diff = ($'.$sym.' eq 666);';7 eval('$saveval = $'.$sym.'; $'.$sym.' = 666;'); $s->reval($script); $diff = $FOO::diff;& eval('$'.$sym.' = $saveval;'); } if (!$diff) {A print '$'.$sym." value does not propagate into Safe::\n"; }}*[CRINOID0051]DESCRIP.MMS;1+,K>./ 44<-Ke0123KPWO56UJ2&7G^(89GHJ,! ! descrip.mms file for CRINOID%! perl should already be set up0! installation directory should be defined?! @configure sets up the various macro definitions needed!.ifdef INSTALLDIR.elseINSTALLDIR = [.install]INSTALLLIB = [.install.lib].endifCREATE_OPT = @create_opt.com .ifdef SHOWVCQSHOW = /show=($(SHOW)).else VCQSHOW =.endif.ifdef VERBOSEVCQ = /list$(VCQSHOW) VLQ = /map MCQ = /list.else MCQ = /nolist VCQ = /nolist VLQ = /nomap.endifVCD =.ifdef PERLDEBUGPERLOPT = :DBGPERL.elsePERLOPT = :PERL.endif .ifdef DEBUGDCQ = /debug/noopt DLQ = /debug DDD = DBG'DCD = ,EXC_WORKAROUND=$(EXC_WORKAROUND)DEBUG_TARGETS = -$ ,$(INSTALLDIR)DBG$CRINOID.INI -$ ,$(INSTALLDIR)DBG$TENTACLE.INI -$ ,$(INSTALLDIR)DBG$LOGGER.INI - ,$(INSTALLDIR)DO_DEBUG.COM.elseDCQ = /nodebug/optDLQ = /nodebug/notrace DDD = NDBDCD =DEBUG_TARGETS =.endif.ifdef __AXP__ ARCH = AXPACQ = /PREFIX=ALLE = .AXEO = .ABJ.else ARCH = VAXACQ =E = .EXEO = .OBJ.endifACD =.ifdef NO_PERSONAPCD = ,NO_PERSONA.endif'CRINOIDLIB = CRINOID_$(ARCH)_$(DDD).OLB-CDEFS = XYZZY$(ACD)$(DCD)$(VCD)$(PCD)$(XCD)FCFLAGS = $(ACQ)$(DCQ)$(VCQ)/DEFINE=($(CDEFS))/Incl=([],$(PERLINC))LFLAGS = $(DLQ)$(VLQ)MSGFLAGS = $(MCQ) .suffixes&.suffixes $(E) .OPT .OLB $(O) .C .MSG .C$(O) :8 $(CC)$(CFLAGS)/OBJ=$(MMS$TARGET) $(MMS$SOURCE) .MSG$(O) :B $(MESSAGE)$(MSGFLAGS)/OBJECT=$(MMS$TARGET) $(MMS$SOURCE) $(O).OLB :W @ IF F$SEARCH("$(MMS$TARGET)") .EQS. "" THEN $(LIBR)/CREATE/LOG $(MMS$TARGET)< LIBRARIAN $(LIBRFLAGS) $(MMS$TARGET) $(MMS$SOURCE) $(O).OPT :E $(CREATE_OPT) $(MMS$TARGET) $(MMS$SOURCE) $(CRINOIDLIB)/LIB .OPT.$(E) : @ if "$(NO_PERSONA)" .nes. "" .and. "$(MMS$SOURCE)" .eqs. "STUB.OPT" .and. "$(ARCH)" .eqs. "AXP" then opt = "/sysexe"@ link$(LFLAGS)/exe=$(MMS$TARGET)'opt' $(MMS$SOURCE)/optQall : CRINOID tentacle stub logger startup crinoid_msg $(SERVICE_NAME).com @ continueCRINOID : CRINOID$(E) @ continuetentacle : tentacle$(E) @ continuestub : stub$(E) @ continuelogger : logger$(E) @ continuestartup : startup$(E) @ continue"perl_root:[lib.extutils]embed.pm : @ continueconfigure.mms : @ continuecrinoid_msg : crinoid_msg$(E) @ continue>perlxsi.c : perl_root:[lib.extutils]embed.pm configure.mms> perl "-MExtUtils::Embed" -e"xsinit('perlxsi.c');"6CRINOID$(E) : CRINOID.opt CRINOID$(O) $(CRINOIDLIB)6tentacle$(E) : tentacle.opt TENTACLE$(O) $(CRINOIDLIB)6stub$(E) : stub.opt STUB$(O) $(CRINOIDLIB)6logger$(E) : logger.opt LOGGER$(O) $(CRINOIDLIB)6startup$(E) : STARTUP$(O) $(CRINOIDLIB)B link/exe=$(MMS$TARGET) startup$(O),$(CRINOIDLIB)/LIB!crinoid_msg$(E) : crinoid_msg$(O)3 link/share=$(MMS$TARGET) $(MMS$SOURCE)tentacle.opt : configure.mmsa $(CREATE_OPT) tentacle.opt tentacle$(O) $(CRINOIDLIB)/LIB $(PERLOPT) :linkopt=$(DLQ)stub.opt : configure.mmsI @ if "$(NO_PERSONA)" .nes. "" then tail2 = ":comment=need_cmkrnl" @ if "$(NO_PERSONA)" .nes. "" .and. "$(ARCH)" .eqs. "VAX" .and. f$search("sys$loadable_imagest:iodef.stb") .nes. "" then tail = "sys$loadable_images:iodef.stb/selective" @ if "$(NO_PERSONA)" .nes. "" .and. "$(ARCH)" .eqs. "VAX" .and. f$search("sys$loadable_imagest:iodef.stb") .eqs. "" then tail = "sys$system:sys.stb/selective"H $(CREATE_OPT) stub.opt stub$(O) $(CRINOIDLIB)/LIB 'tail' 'tail2'logger.opt : configure.mmsB $(CREATE_OPT) logger.opt logger$(O) $(CRINOIDLIB)/LIBCRINOID.opt : configure.mms] $(CREATE_OPT) CRINOID.opt CRINOID$(O) $(CRINOIDLIB)/LIB :threads :linkopt=$(DLQ)$(SERVICE_NAME).com :S @ write sys$output "Creating a new $(service_name).COM (in this directory)"+ @ open/write FD $(service_name).comG @ write FD "$ f = f$parse(f$environ(""procedure""),,,""name"")"8 @ write FD "$ define CRINOID_DECNET_SERVICE 'f'"< @ write FD "$ define CRINOID_MGR ""$(crinoid_mgr)"""@ @ write FD "$ @$(installdir)CRINOID.COM $(process_name)" @ write FD "$ exit" @ close FDCRINOID$(O) : CRINOID.c CRINOID.h proc_mgr.h vms_data.h util.h pipe2.h msg.h CRINOID_types.h script.h version.h nfbdef.h~tentacle$(O) : tentacle.c tentacle.h perlxsi.c errlog_client.h vms_data.h util.h msg.h CRINOID_types.h mbxq.h pipe2.hOerrlog_client$(O) : errlog_client.c errlog_client.h vms_data.h msg.h util.hDproc_mgr$(O) : proc_mgr.c proc_mgr.h CRINOID_types.h util.h5util$(O) : util.c util.h CRINOID_types.h1parser$(O) : parser.c parser.h util.h%stub$(O) : util.h msg.hCscript$(O) : util.h script.h vms_data.h CRINOID_types.h-mbxq$(O) : mbxq.c mbxq.h util.hFpipe2$(O) : pipe2.c pipe2.h util.h errlog_client.h mbxq.h(startup$(O) : startup.c util.h.ifdef NO_PERSONA#stub$(O) : pcbjibdef.h+pcbjibdef.h : sys$library:lib.mlb= $(CREATE_OPT) pcbjibdef.h :PCBJIBDEF.endif+nfbdef.h : sys$library:lib.mlb7 $(CREATE_OPT) nfbdef.h :NFBDEF MODULES =-) ERRLOG_CLIENT=ERRLOG_CLIENT$(O),- PROC_MGR=PROC_MGR$(O),- UTIL=UTIL$(O),- PARSER=PARSER$(O),- SCRIPT=SCRIPT$(O),- PIPE2=PIPE2$(O),- MBXQ=MBXQ$(O),-# CRINOID_MSG=CRINOID_MSG$(O)/$(CRINOIDLIB) : $(CRINOIDLIB)($(MODULES))F @ write sys$output "update of $(CRINOIDLIB) complete."INSTALL_TARGETS = - $(INSTALLDIR)TENTACLE$(E),- $(INSTALLDIR)TENTACLE.OPT,- $(INSTALLDIR)TENTACLE.COM,- $(INSTALLDIR)LOGGER$(E),- $(INSTALLDIR)LOGGER.COM,- $(INSTALLDIR)CRINOID$(E),- $(INSTALLDIR)CRINOID.COM,- $(INSTALLDIR)STUB$(E),- $(INSTALLDIR)STUB.COM,- $(INSTALLDIR)STUB.OPT,-" $(INSTALLDIR)CRINOID_MSG$(E),- $(INSTALLDIR)OYSTER.,- $(INSTALLLIB)SCRIPT.PM,- $(INSTALLLIB)TIEENV.PM,- $(INSTALLDIR)STARTUP.COM,- $(INSTALLDIR)STARTUP$(E),- $(INSTALLDIR)SHUTDOWN.COM,-. $(INSTALLDIR)NEWLOG.COM $(DEBUG_TARGETS)($(INSTALLDIR)TENTACLE$(E) : TENTACLE$(E)< COPY $(MMS$SOURCE) $(MMS$TARGET)($(INSTALLDIR)TENTACLE.OPT : TENTACLE.OPT< COPY $(MMS$SOURCE) $(MMS$TARGET)/$(INSTALLDIR)TENTACLE.COM : [.MISC]TENTACLE.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)&$(INSTALLDIR)LOGGER$(E) : LOGGER$(E)< COPY $(MMS$SOURCE) $(MMS$TARGET)-$(INSTALLDIR)LOGGER.COM : [.MISC]LOGGER.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)'$(INSTALLDIR)CRINOID$(E) : CRINOID$(E)< COPY $(MMS$SOURCE) $(MMS$TARGET).$(INSTALLDIR)CRINOID.COM : [.MISC]CRINOID.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)'$(INSTALLDIR)STARTUP$(E) : STARTUP$(E)< COPY $(MMS$SOURCE) $(MMS$TARGET)$$(INSTALLDIR)STUB$(E) : STUB$(E)< COPY $(MMS$SOURCE) $(MMS$TARGET)+$(INSTALLDIR)STUB.COM : [.MISC]STUB.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)$$(INSTALLDIR)STUB.OPT : STUB.OPT< COPY $(MMS$SOURCE) $(MMS$TARGET).$(INSTALLDIR)CRINOID_MSG$(E) : CRINOID_MSG$(E)< COPY $(MMS$SOURCE) $(MMS$TARGET)*$(INSTALLDIR)OYSTER. : [.MISC]OYSTER.< COPY $(MMS$SOURCE) $(MMS$TARGET),$(INSTALLLIB)SCRIPT.PM : [.MISC]SCRIPT.PM< COPY $(MMS$SOURCE) $(MMS$TARGET),$(INSTALLLIB)TIEENV.PM : [.MISC]TIEENV.PM< COPY $(MMS$SOURCE) $(MMS$TARGET).$(INSTALLDIR)STARTUP.COM : [.MISC]STARTUP.COM: @ open/write fd1 $(MMS$TARGET)Q @ write fd1 "$ CRINOID_manager = ""$(CRINOID_MGR)"""Q @ write fd1 "$ CRINOID_username = ""$(CRINOID_USR)"""R @ write fd1 "$ CRINOID_service = ""$(SERVICE_NAME)"""9 @ open/read fd2 $(MMS$SOURCE), @ copy fd2: fd1:' @ close fd1' @ close fd2I @ WRITE SYS$OUTPUT "STARTUP.COM file written"/$(INSTALLDIR)SHUTDOWN.COM : [.MISC]SHUTDOWN.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)-$(INSTALLDIR)NEWLOG.COM : [.MISC]NEWLOG.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)9$(INSTALLDIR)DO_DEBUG.COM : [.DEBUG_SUPPORT]DO_DEBUG.COM< COPY $(MMS$SOURCE) $(MMS$TARGET)?$(INSTALLDIR)DBG$CRINOID.INI : [.DEBUG_SUPPORT]DBG$CRINOID.INI< COPY $(MMS$SOURCE) $(MMS$TARGET)A$(INSTALLDIR)DBG$TENTACLE.INI : [.DEBUG_SUPPORT]DBG$TENTACLE.INIo< COPY $(MMS$SOURCE) $(MMS$TARGET)=$(INSTALLDIR)DBG$LOGGER.INI : [.DEBUG_SUPPORT]DBG$LOGGER.ININ< COPY $(MMS$SOURCE) $(MMS$TARGET)INSTALL : $(INSTALL_TARGETS)d6 @ WRITE SYS$OUTPUT "Installation complete"tidy :2 if f$search("*$(O)") .nes. "" then purge *$(O)2 if f$search("*.lis") .nes. "" then purge *.lis2 if f$search("*$(E)") .nes. "" then purge *$(E)2 if f$search("*.map") .nes. "" then purge *.map2 if f$search("*.opt") .nes. "" then purge *.opt: if f$search("perlxsi.c") .nes. "" then purge perlxsi.cB if f$search("configure.mms") .nes. "" then purge configure.mmsN if f$search("$(SERVICE_NAME).COM") .nes. "" then purge $(SERVICE_NAME).COMclean :5 if f$search("*$(O)") .nes. "" then delete *$(O);* 5 if f$search("*.lis") .nes. "" then delete *.lis;*P5 if f$search("*$(E)") .nes. "" then delete *$(E);*5 if f$search("*.map") .nes. "" then delete *.map;*5 if f$search("*.opt") .nes. "" then delete *.opt;*fQ if f$search("$(SERVICE_NAME).COM") .nes. "" then delete $(SERVICE_NAME).COM;*Drealclean : clean5 if f$search("*.olb") .nes. "" then delete *.olb;*I= if f$search("perlxsi.c") .nes. "" then delete perlxsi.c;*iE if f$search("configure.mms") .nes. "" then delete configure.mms;* A if f$search("pcbjibdef.h") .nes. "" then delete pcbjibdef.h;* ; if f$search("nfbdef.h") .nes. "" then delete nfbdef.h;*)*[CRINOID0051]ERRLOG_CLIENT.C;1+,K./ 4ZD<-Ke0123KPWO56`7D(89GHJ(/*4 send logging information to error logger mailbox*/#include #include #include #include *#include /* DECC */*#include /* DECC */#include #include #include #include #include #include #include #include #include "vms_data.h"#include "errlog_client.h"#include "util.h"#ifdef DEBUG_MEMORY #undef free #undef malloc#undef realloc#endif#define ERRLOG_INITIAL 0#define ERRLOG_OPEN 1$typedef struct PendingQE Pending;$typedef struct PendingQE* pPending;struct PendingQE {9 RQE q; /* put here to keep alignment right ! */ pSTRING msg;};*static RQE PendQHead = {0,0};$#define PendQ (&PendQHead)(static longword active_AST = 0;$static word errlog_chan;)static longword locked = 0;)static longword initializing = 0;)static pSTRING prefix = 0;&static unsigned int log_level = 2;6static int errlog_state = ERRLOG_INITIAL;(#define LOGMBX "CRINOIDLOG_MBX""static $DESCRIPTOR(d_mbx, LOGMBX);#define MAXMSG 256#define RETRY_DELAY 10static void errlog_init(void);#static void errlog_AST(pPending p); int errlog_level(unsigned int l){* if (l == L_NULLTYPE) return log_level;E errlog(0,"Changing logging level from !XL to !XL", log_level, l); return log_level = l;} static voiderrlog_init(void){ int iss; pSTRING mbx;& $DESCRIPTOR(table,"LNM$FILE_DEV"); ItemList itm[2]; char equiv[256]; word length;" iss = _BBSSI(0,&initializing); if (iss == 1) return;/ if (errlog_state == ERRLOG_OPEN) goto done;/ itm[0].code = LNM$_STRING;) itm[0].address = equiv;1 itm[0].length = sizeof(equiv);+ itm[0].return_length_address = &length;% itm[1].code = 0;% itm[1].address = 0;% itm[1].length = 0;% itm[1].return_length_address = 0;4 iss = sys$trnlnm(0,&table,&d_mbx,0,(char *)itm);' if (iss == SS$_NOLOGNAM) goto done;& if (VMS_ERR(iss)) VMS_SIGNAL(iss);B iss = sys$assign(&d_mbx, &errlog_chan, 0, 0, AGN$M_WRITEONLY);0 if (VMS_OK(iss)) errlog_state = ERRLOG_OPEN; iss = _BBSSI(0,&active_AST); if (iss !=1) {* iss = sys$dclast(&errlog_AST,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); }done:# (void) _BBCCI(0,&initializing);$ if (errlog_state == ERRLOG_OPEN)C errlog(0,"Starting error logging at level !XL", log_level);} static voiderrlog_AST(pPending p){ int iss; static IOSB iosb; static longword time[2]; static time_initted = 0; if (p) {* if (iosb.status == SS$_NOREADER) {' iss = lib$insqhi(p, PendQ);. if (VMS_ERR(iss)) VMS_SIGNAL(iss);* iss = sys$dassgn(errlog_chan);. if (VMS_ERR(iss)) VMS_SIGNAL(iss);* errlog_state = ERRLOG_INITIAL; active_AST = 0; if (!time_initted) {! time_initted = 1;+ sec2vms(RETRY_DELAY, time); }6 iss = sys$setimr(0,time,&errlog_init,0,0);. if (VMS_ERR(iss)) VMS_SIGNAL(iss); return; }: if (VMS_ERR(iosb.status)) VMS_SIGNAL(iosb.status);$ free(p->msg->dsc$a_pointer); free(p->msg); free(p); } active_AST = 0;, if (errlog_state != ERRLOG_OPEN) return; iss = lib$remqhi(PendQ, &p);& if (iss == LIB$_QUEWASEMP) return;& if (VMS_ERR(iss)) VMS_SIGNAL(iss);V iss = sys$qio(0,errlog_chan,IO$_WRITEVBLK|IO$M_NOW|IO$M_NORSWAIT|IO$M_READERCHECK,Y &iosb, &errlog_AST, p, asciz_pSTRING(p->msg), strlen_pSTRING(p->msg), 0,0,0,0); active_AST = 1; if (VMS_OK(iss)) return; if (iss == SS$_MBFULL) {# iss = lib$insqhi(p, PendQ);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); if (!time_initted) { time_initted = 1;' sec2vms(RETRY_DELAY, time); }1 iss = sys$setimr(0,time,&errlog_AST,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); return;% } else if (iss == SS$_NOREADER) {# iss = lib$insqhi(p, PendQ);* if (VMS_ERR(iss)) VMS_SIGNAL(iss);& iss = sys$dassgn(errlog_chan);* if (VMS_ERR(iss)) VMS_SIGNAL(iss);& errlog_state = ERRLOG_INITIAL; active_AST = 0; if (!time_initted) { time_initted = 1;' sec2vms(RETRY_DELAY, time); }2 iss = sys$setimr(0,time,&errlog_init,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); return; }& if (VMS_ERR(iss)) VMS_SIGNAL(iss); active_AST = 0; free(p->msg->dsc$a_pointer); free(p->msg); free(p);}1int errlog(unsigned int level, char *format, ...){ va_list ap;, int iss, args, i, header, fao_param[32]; int status = SS$_NORMAL; int l; unsigned q; word length1, length2;1 static $DESCRIPTOR(hcontrol1,"!+{!6XL:!SL}");3 static $DESCRIPTOR(hcontrol2,"[!AS !6XL:!SL]");. char a_mess1[MAXMSG+1], a_mess2[MAXMSG+1]; $DESCRIPTOR(message1,""); $DESCRIPTOR(message2,""); $DESCRIPTOR(control2,"");! pSTRING control, message = 0; pPending p = 0;" if (locked) return SS$_NORMAL;) if (errlog_state == ERRLOG_INITIAL) { errlog_init(); }B if ((level & L_LEVMASK) > (log_level & L_LEVMASK)) goto done;V if ((level & L_ALLTYPES) != 0 && (level & log_level & L_ALLTYPES) == 0) goto done; q = level >> L_MINTYPE; l = level & L_LEVMASK; p = malloc(sizeof(Pending)); if (!p) goto done;% message1.dsc$a_pointer = a_mess1;/ message1.dsc$w_length = sizeof(a_mess1)-1;/ control = prefix ? &hcontrol2 : &hcontrol1;> iss = sys$fao(control, &length1, &message1, prefix, q, l);1 if (VMS_ERR(iss)) {status = iss; goto done;}$ message1.dsc$w_length = length1; a_mess1[length1] = '\0';$ control2.dsc$a_pointer = format;, control2.dsc$w_length = strlen(format);% message2.dsc$a_pointer = a_mess2;/ message2.dsc$w_length = sizeof(a_mess2)-1; va_start(ap,format); va_count(args);? for (i = 0; i < args-1; i++) fao_param[i] = va_arg(ap,int); va_end(ap);> iss = sys$faol(&control2, &length2, &message2, fao_param);0 if (VMS_ERR(iss)) {status = iss; goto done;}$ message2.dsc$w_length = length2; a_mess2[length2] = '\0';% message = malloc(sizeof(STRING));4 if (!message) {status = SS$_INSFMEM; goto done;}J message->dsc$w_length = message1.dsc$w_length + message2.dsc$w_length;= message->dsc$a_pointer = malloc(message->dsc$w_length+1);C if (!message->dsc$a_pointer) {status = SS$_INSFMEM; goto done;}; strcpy(message->dsc$a_pointer, message1.dsc$a_pointer);; strcat(message->dsc$a_pointer, message2.dsc$a_pointer); p->msg = message; iss = lib$insqti(p,PendQ);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = _BBSSI(0,&active_AST); if (iss !=1) {* iss = sys$dclast(&errlog_AST,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); }done: if (VMS_ERR(status)) {# if (message) free(message); if (p) free(p); } return status;}intislogging(unsigned int level){ if (locked) return 0;. if (errlog_state != ERRLOG_OPEN) return 0;A if ((level & L_LEVMASK) > (log_level & L_LEVMASK)) return 0;U if ((level & L_ALLTYPES) != 0 && (level & log_level & L_ALLTYPES) == 0) return 0; return 1;}#define WANT_MSG_TEXT#include "msg.h"char *msg_text(int code){ int j;/ static char unknown[] = "Unknown MSG code";9 if (code <= 0 || code >= MSG$_MAXMSG) return unknown;C for (j = 0; j < sizeof(messages)/sizeof(struct MSGTEXT); j++) {> if (messages[j].code == code) return messages[j].text; } return unknown;}:#define TOHEX(i) ((i) < 0x0a ? '0'+(i) : 'A' + (i) - 0x0A)int5logdump(int level, char *header, void *buf, int size){ int j, l;( char c, *p, *pb, cbuf[17], bbuf[60];" if (locked) return SS$_NORMAL;' if (errlog_state == ERRLOG_INITIAL) errlog_init();$ if (errlog_state != ERRLOG_OPEN) return SS$_SHUT;A if ((level & L_LEVMASK) > (log_level & L_LEVMASK)) return 1;U if ((level & L_ALLTYPES) != 0 && (level & log_level & L_ALLTYPES) == 0) return 1; pb = (char *) buf; while (size > 0) {# l = (size > 16)? 16 : size; p = bbuf;! for (j = 0; j < l; j++) { c = *pb++;( *p++ = TOHEX((c>>4) & 0x0F);# *p++ = TOHEX(c & 0x0F); *p++ = ' ';( cbuf[j] = (c == 0)? '.' : c; } *p++ = '\0'; cbuf[l] = '\0'; printable(cbuf);< errlog(level,"!AZ [!AZ] |!AZ|", header, bbuf, cbuf); size -= l; }t return SS$_NORMAL;}>voiderrlog_lock(void) {* locked = 1;e}Tvoiderrlog_unlock(void)/{i locked = 0;}ivoiderrlog_prefix(char *s){.0 if (prefix) prefix = destroy_STRING(prefix); prefix = new_STRING(s);e}tvoiderrlog_flush(void){ int iss; pPending p;e, if (errlog_state != ERRLOG_OPEN) return; while (1) {d$ iss = lib$remqhi(PendQ, &p);* if (iss == LIB$_QUEWASEMP) return;* if (VMS_ERR(iss)) VMS_SIGNAL(iss);Z iss = sys$qio(0,errlog_chan,IO$_WRITEVBLK|IO$M_NOW|IO$M_NORSWAIT|IO$M_READERCHECK,O 0, 0, 0, asciz_pSTRING(p->msg), strlen_pSTRING(p->msg), 0,0,0,0);  } }e*[CRINOID0051]ERRLOG_CLIENT.H;1+,K.. / 4? <-Ke0123KPWO 56j{7(89GHJ/*? global declarations, etc. for error logging client routines*/#ifndef __ERRLOG_CLIENT_Hvoid errlog_inast(int in);$int errlog_level(unsigned int l);6int errlog(unsigned int level, char *control, ...);%int islogging(unsigned int level);char * msg_text(int code);=int logdump(int level, char *header, void *buf, int size);void errlog_lock(void);void errlog_unlock(void);void errlog_prefix(char *s);void errlog_flush(void);#define L_CRITICAL (0)#define L_ERROR (1)#define L_WARNING (2)#define L_INFO (3)#define L_TRACE (4)#define L_BABBLE (5)#define L_DEBUG (6)#define L_MINTYPE 8'#define L_LEVMASK ((1<Form Debugging Info\n";print "\n";'print "

Form Debugging Info

\n"; print "

CGI ENV info

\n";print "\n";foreach $k (sort(keys(%ENV))) {. print "\n";}print "
$k\"$ENV{$k}\"
\n";(#if ($ENV{'REQUEST_METHOD'} eq 'POST') {3 print "

Information passed via POST

\n"; while () { chomp; print "$_
\n"; }#}print "
\n";7print "This script was run at ",scalar(localtime),"\n";print "\n";)*[CRINOID0051.EXAMPLE_SCRIPTS]DIRECTORY.;1+,K;. / 4C V<-K70123KPWO 56 7 89GHJ#! perl#<# this script makes a directory listing of all CGIs in itsC# home directory (where the script lives) and all subdirectories.#?# "CGI"s are identified as having a .cgi, .pl or . filetype.#># warning: this can reveal scripts you'd rather have hidden!#,# C. Lane lane@duphy4.physics.drexel.edu#$CRINOID::Reuse = 1;$print "Content-type: text/html\n\n";>print "Directory of CGIs\n";print "\n";%print "

Directory of CGIs

\n";C$where = substr($ENV{'SCRIPT_PATH'},length($ENV{'SCRIPT_PREFIX'}));$where =~ s#/$##;chdir($where); list('.','');print "\n";sub list{ my $current = shift; my $subdir = shift; if ($subdir ne '') { chdir($subdir); $current .= '/'.$subdir; } my $prefix = $current.'/'; $prefix =~ s#^\.?/##; my @files = <*.*>; my $virgin = 1; foreach (@files) {- if (/\.cgi$/i || /\.pl$/i || /\.$/) { if ($virgin) { print "
    \n"; $virgin = 0; } s/\.$//;> print "
  • $prefix$_\n"; } elsif (/\.dir$/i) { list($current,$`); } }" print "
\n" if (!$virgin); chdir('[-]');}&*[CRINOID0051.EXAMPLE_SCRIPTS]I_AM.PL;1+,K). / 47 <-K70123KPWO 56 7 89GHJ@}~ FREEWARE.SAVK)K7&[CRINOID0051.EXAMPLE_SCRIPTS]I_AM.PL;17 ,`#! perl#7# just about the simplest CGI script you can think of#%print "Content-type: text/plain\n\n";print "I am.\n";)*[CRINOID0051.EXAMPLE_SCRIPTS]LINEAR.CGI;1+,pKp./ 4<-K70123KPWO56ߏ 784 89GHJ,#! perl### example of using PGPLOT and CGI#H# This script does a linear regression fit of data entered via a form.,# Fit parameters and a plot are displayed.## HTML NOTE: ± -> +-#=# you need to modify location of $WWDIR for your own setup.#4# Author: C. Lane lane@duphy4.physics.drexel.edu#use CGI; use PGPLOT;=$DEBUG = 0; # if set, writes plot to file and keeps datafile$CRINOID::Reuse = 1;6$WWDIR = 'sys$scratch:'; # world-writable directory $q = new CGI;>%SYM = ('+'=>2, 'o'=>4, 'x'=>5, '*'=>12) unless defined(%SYM);$N = $N2 = 0;$XLOG = $YLOG = 0; undef(@X); undef(@Y); undef(@X2); undef(@Y2);$XLAB = 'X';$YLAB = 'Y';#$TITLE = 'Linear Regression Plot';'$OLEG = $PLEG = $XLEG = $SLEG = '';#E# if we have an ID, then form was processed and we're making a plot#if ($q->param('ID') ne '') { do_plot($q);} else { do_form($q);} sub do_plot{ my $q = shift;< my ($xmax, $xmin, $ymax, $ymin, $xlo, $xhi, $ylo, $yhi); my (@u, @v); my $legy = -2; my $legx = 0.1; my $legj = 0.0;< ReadParams($q->param('ID'),1); # read & delete file( print "Content-type: image/gif\n\n";< PGPLOT::pgbeg(0,$DEBUG? 'linear.gif/GIF' : '-/GIF',1,1); PGPLOT::pgpap(450./85.,1.); PGPLOT::pgscr(0,1.,1.,1.); PGPLOT::pgscr(1,0.,0.,0.); ($xmax,$xmin) = maxmin(@X2); ($ymax,$ymin) = maxmin(@Y2);< if ($xmax <= $xmin) {$xmax = $xmin + 0.1; $xmin -= 0.1;}< if ($ymax <= $ymin) {$ymax = $ymin + 0.1; $ymin -= 0.1;}* PGPLOT::pgrnge($xmin,$xmax,$xlo,$xhi);* PGPLOT::pgrnge($ymin,$ymax,$ylo,$yhi);I PGPLOT::pgenv($xlo,$xhi,$ylo,$yhi,0,0 + ($XLOG? 10:0)+($YLOG? 20:0));& PGPLOT::pglab($XLAB,$YLAB,$TITLE);+ PGPLOT::pgpnts($N2,\@X2,\@Y2,\@S2,$N2);) my ($m, $b) = regress($N2,\@X2,\@Y2); if (defined($m)) { @u = ($xlo, $xhi);& @v = ($m*$xlo+$b, $m*$xhi+$b);" PGPLOT::pgline(2,\@u,\@v); $legx = 0.5 if $m < 0; if (!$XLOG && !$YLOG) {u PGPLOT::pgmtxt('T',$legy--, $legx, $legj, sprintf('Fit: \\fiy\\fn = (%5.3g) \\fix\\fn + (%5.3g)',$m,$b));# } elsif ($XLOG && !$YLOG) {z PGPLOT::pgmtxt('T',$legy--, $legx, $legj, sprintf('Fit: \\fiy\\fn = (%5.3g) log(\\fix\\fn) + (%5.3g)',$m,$b));# } elsif (!$XLOG && $YLOG) { PGPLOT::pgmtxt('T',$legy--, $legx, $legj, sprintf('Fit: \\fiy\\fn = (%5.3g) (%5.3g)\\u\\fix\\fn\\d',10**$b,10**$m)); } else {} PGPLOT::pgmtxt('T',$legy--, $legx, $legj, sprintf('Fit: \\fiy\\fn = (%5.3g) \\fix\\fn\\u (%5.3g)\\d',10**$b,$m)); } }H PGPLOT::pgmtxt('T',$legy--,$legx,$legj,"\\m4 $OLEG") if $OLEG ne '';H PGPLOT::pgmtxt('T',$legy--,$legx,$legj,"\\m2 $PLEG") if $PLEG ne '';H PGPLOT::pgmtxt('T',$legy--,$legx,$legj,"\\m5 $XLEG") if $XLEG ne '';I PGPLOT::pgmtxt('T',$legy--,$legx,$legj,"\\m12 $SLEG") if $SLEG ne ''; PGPLOT::pgend;}sub process_data{ my $q = shift; my ($j, $n, $tx); $j = $N = $N2 = 0; if ($q->param) {$ $TITLE = $q->param('title');% $XLAB = $q->param('xlabel');% $YLAB = $q->param('ylabel');. $XLOG = $q->param('xscale') eq 'log';. $YLOG = $q->param('yscale') eq 'log';# $OLEG = $q->param('oleg');# $PLEG = $q->param('pleg');# $XLEG = $q->param('xleg');# $SLEG = $q->param('sleg');+ while (defined($q->param("X$j"))) {] if ($q->param("delete_$j") || $q->param("X$j") eq '' || $q->param("Y$j") eq '') { $j++; next; } $EM[$N] = '';# $tx = $q->param("X$j");) if (validate_number($tx)>0) {+ $X[$N] = sprintf("%g",$tx);( if ($XLOG && $tx <= 0) {8 $EM[$N] = 'Need X>0 for log scale '; } } else {, $EM[$N] = 'Error parsing X'; }# $tx = $q->param("Y$j");) if (validate_number($tx)>0) {+ $Y[$N] = sprintf("%g",$tx);( if ($YLOG && $tx <= 0) {9 $EM[$N] .= 'Need Y>0 for log scale '; } } else {. $EM[$N] .= 'Error parsing Y '; }& $S[$N] = $q->param("S$j"); if ($EM[$N] eq '') {: $X2[$N2] = $XLOG ? log10($X[$N]) : $X[$N];: $Y2[$N2] = $YLOG ? log10($Y[$N]) : $Y[$N];( $S2[$N2] = $SYM{$S[$N]}; $N2++; } $j++; $N++; } } return $N;} sub do_form{ my $q = shift;: process_data($q); # process any input data first print $q->header;6 print $q->start_html("Linear Regression Utility");1 print "

Linear Regression Utility

\n"; print $q->startform; print "\n"; print "
Plot title:",$q->textfield(-name=>'title', -override=>1, -default=>$TITLE, -size=>20, -maxlength=>64),"\n"; print "
X-axis label:",$q->textfield(-name=>'xlabel', -override=>1, -default=>$XLAB, -size=>20, -maxlength=>64),"",n $q->radio_group(-name=>'xscale', -values=>['linear', 'log'], -default=>'linear', -columns=>2),"\n"; print "
Y-axis label:",$q->textfield(-name=>'ylabel', -override=>1, -default=>$YLAB, -size=>20, -maxlength=>64),"",n $q->radio_group(-name=>'yscale', -values=>['linear', 'log'], -default=>'linear', -columns=>2),"\n";y print '
o legend:',$q->textfield(-name=>'oleg', -override=>1, -default=>$OLEG, -size=>20, -maxlength=>64);y print '
+ legend:',$q->textfield(-name=>'pleg', -override=>1, -default=>$PLEG, -size=>20, -maxlength=>64);y print '
x legend:',$q->textfield(-name=>'xleg', -override=>1, -default=>$XLEG, -size=>20, -maxlength=>64);y print '
* legend:',$q->textfield(-name=>'sleg', -override=>1, -default=>$SLEG, -size=>20, -maxlength=>64); print "
\n"; print "\n";. print "
Pt#XYSymbol\n";! for ($j = 0; $j < $N; $j++) { if ($EM[$j] eq '') {I print $q->hidden(-name=>"X$j", -override=>1, -value=>$X[$j]);I print $q->hidden(-name=>"Y$j", -override=>1, -value=>$Y[$j]);I print $q->hidden(-name=>"S$j", -override=>1, -value=>$S[$j]);L print '
',$j+1,'',$X[$j],'',$Y[$j],'',$S[$j]; print ''; } else {! print '
',$j+1;k print '',$q->textfield(-name=>"X$j",-default=>$X[$j],-override=>1,-size=>10,-maxlength=>10);k print '',$q->textfield(-name=>"Y$j",-default=>$Y[$j],-override=>1,-size=>10,-maxlength=>10);i print '',$q->radio_group(-name=>"S$j", -values=>['o', '+', 'x', '*'], -default=>'o'),"\n"; print '',$EM[$j]; }U print '',$q->checkbox(-name=>"delete_$j",-override=>1,-label=>"Delete?"); }$ for ($j = $N; $j < $N+4; $j++) {% print "
",$j+1,"";] print $q->textfield(-name=>"X$j",-default=>'',-override=>1,-size=>10,-maxlength=>10); print "";] print $q->textfield(-name=>"Y$j",-default=>'',-override=>1,-size=>10,-maxlength=>10);f print '',$q->radio_group(-name=>"S$j", -values=>['o', '+', 'x', '*'], -default=>'o'),"\n"; print ""; }1 print '
',$q->submit(-name=>'Update'); print '',$q->reset; print "
\n"; print $q->endform; if ($N2 > 1) {, my ($m,$b) = regress($N2,\@X2,\@Y2);4 print "
\n

Linear Regression:

\n"; if (defined($m)) {Z print '
',$YLOG? 'log(y)':'y','= m ',$XLOG? 'log(x)':'x',' + b';A print '
Slope (m):',sprintf("%5.3g\n",$m);E print '
Intercept (b):',sprintf("%5.3g\n",$b); print "
\n"; } else {3 print "Error! Infinite slope\n"; } } if ($N2 > 2) { print "
\n"; $ID = SaveParams($q);I print 'Fit Plot',"\n"; } print $q->end_html;}sub ReadParams {6 my $ID = shift; # ID of saved data3 my $dflag = shift; # deletion flag local *SAVEFILE; return unless defined($ID);/ return unless open(SAVEFILE, "<$WWDIR$ID"); my $q2 = new CGI SAVEFILE; process_data($q2); close SAVEFILE;? unlink "$WWDIR$ID" if !$DEBUG && defined($dflag) && $dflag; return $ID;}sub SaveParams { my $q = shift; local *SAVEFILE;$ srand unless defined($DidSrand); $DidSrand = 1;K my $ID = sprintf('LINEAR_%08.8x',rand(0xFFFFFF)); # generate random ID& if (open(SAVEFILE,">$WWDIR$ID")) { $q->save(SAVEFILE); close(SAVEFILE); } else {1 print "Error Saving CGI state!\n";t return undef;f }  return $ID;a}a# =# checks that text number is valid format and within limitse#tsub validate_number {I my ($v, $ll, $ul) = @_;  my ($v2,$ret); $v2 = $v;c $v =~ s/\s*//g; # return -1 if (length($v) == 0);i $ret = 1;l4 if ($v =~ /^[+-]?\d*(\.\d*)?([Ee][+-]?\d+)?$/) {G if ((defined($ll) && $v < $ll) || (defined($ul) && $v > $ul)) { $ret = 0;4 }* } else { $ret = -1; }  return $ret;} #eA# do linear-regression, assumes all data points have same errorA# sub regress {  my $n = shift; my $x = shift; # refX my $y = shift; # ref my $Sum1 = $n;  my $SumX = 0.;e my $SumY = 0.;p my $SumXX = 0.;a my $SumXY = 0.;  my $SumYY = 0.;e my ($j, $tx, $ty);! for ($j = 0; $j < $n; $j++) {f $tx = $x->[$j];  $ty = $y->[$j];  $SumX += $tx; $SumY += $ty; $SumXX += $tx*$tx; $SumXY += $tx*$ty; $SumYY += $ty*$ty; } ' my $D = $Sum1*$SumXX - $SumX*$SumX;p. my $b = ($SumY * $SumXX - $SumXY * $SumX);) my $m = ($SumXY*$Sum1 - $SumY*$SumX);T% return undef if abs($D) < 1.e-10;c return ($m/$D, $b/$D);}c sub log10 {2 $ILOG10 = 1./log(10.) unless defined($ILOG10); return log(shift)*$ILOG10;}m sub maxmin { my (@v) = @_;1 my ($max, $min); $max = $min = $v[0]; foreach (@v) {% $max = $max < $_ ? $_ : $max;;% $min = $min > $_ ? $_ : $min;y }  return ($max,$min);,}o,*[CRINOID0051.EXAMPLE_SCRIPTS]PWDCHANGE.CGI;1+,K,./ 4t <-K70123KPWO56-# 7=># 89GHJ#! perl#'# allow user to change their password#4# Author: C. Lane lane@duphy4.physics.drexel.edu#use CGI;use VMS::Stdio;use Digest::MD5 qw(md5_hex);$CRINOID::Reuse = 1;$root = '../netscape_roam/';*$PWDfile = 'sys$login:roaming_access.pwd';$MINPWDLENGTH = 8;$MAXPWDLENGTH = 32; $q = new CGI;#####################1# must be a secure connection...redirect if not#$url = $q->url;$redirect = $goturl = 0;?if ($url =~ /^([a-z0-9]+)\:\/\/([a-z0-9\_\-\.]+)(\:\d+)?\//i) { $goturl = 1;" $redirect = lc($1) ne 'https'; $url = 'https://'.$2.'/'.$';}if ($goturl) { if ($redirect){! print $q->redirect($url); } else {& print $q->header("text/html");" if ($q->param('oldpwd')) { try_change($q); } else { show_form($q); } print $q->end_html; }} else {) print "Content-type: text/plain\n\n";? print "Error: something about the url $url is peculiar.\n";3 print "Please inform the owner of this page\n";}sub try_change { my $q = shift;- print $q->start_html("pwdchange/result");% my $user = lc($q->param('user'));. my $o = md5_hex(lc($q->param('oldpwd')));" my $n1 = $q->param('newpwd1');" my $n2 = $q->param('newpwd2');) $user =~ tr/[a-zA-Z0-9\_\-\$\.]/\?/c;! if (index($user,'?') != -1) {% print "Invalid username
";1 print 'Try again'; return; } if ($n1 ne $n2) {L print "The new password you entered wasn't the same both times
";1 print 'Try again'; return; }& if (length($n1) < $MINPWDLENGTH) {C print "What you entered for a new password is too short. ";D print "Your new password should be at least $MINPWDLENGTH ";% print "characters long.
";1 print 'Try again'; return; }& if (length($n1) > $MAXPWDLENGTH) {B print "What you entered for a new password is too long. ";G print "Your new password should shorter than ",$MAXPWDLENGTH+1;% print "characters long.
";1 print 'Try again'; return; } $n2 = md5_hex($n2); if (!open(FH,"<$PWDfile")) {D print "There was an error opening the password file...
";= print "Please report this to the owner of this page"; return; } my $j = 0; my @save; my $found = 0; my ($u, $p, $d); while () { $save[$j++] = $_; chomp; s/#.*//; s/^\s+//; s/\s+$//; s/\s+/ /; next if $_ eq ''; ($u,$p,$d) = split;* $u =~ tr/[a-zA-Z0-9\_\-\$\.]/\?/c;& next if (index($u,'?') != -1);" next if (lc($u) ne $user); $found++;- $save[$j-1] = $u.' '.$n2.' '.$d."\n"; } close FH; if ($found > 1) {L print "Your username found $found times in the password file.
";R print "Please bring this to the attention of the owner of this page!
";O print "This problem must be fixed before you can change your password"; return; } if (!$found || $p ne $o) {? print "The old password you entered was incorrect
";@ print 'Try again'; return; }" if (!open(FH,">$PWDfile-2")) {: print "Unable to open password file for writing!";N print "Please bring this to the attention of the owner of this page!"; return; } foreach (@save) { print FH $_; }F print FH "# $user PWDCHANGE from '$o' at ",scalar(localtime),"\n"; close FH; unlink($PWDfile);# rename("$PWDfile-2", $PWDfile); chmod (0700, $PWDfile);, print "Password change successful!
";}sub show_form { my $q = shift;, print $q->start_html("pwdchange/query"); print $q->startform(); print '';T print "
Username:",$q->textfield(-name=>'user',-value=>'',-size=>32);k print '
Old password:',$q->password_field(-name=>'oldpwd',-value=>'', -force=>1, -size=>32);l print '
New password:',$q->password_field(-name=>'newpwd1',-value=>'', -force=>1, -size=>32);t print '
New password (again):',$q->password_field(-name=>'newpwd2',-value=>'', -force=>1, -size=>32); print '';2 print $q->submit(-name=>'Change'),$q->reset();N print "

Please make a note of your new password so you don't forget it";}sub ShareOpen { my $f = shift; return undef unless (-e $f);2 my $fh = VMS::Stdio::vmsopen("<$f","shr=get"); return $fh if defined($fh);B sleep(2.0); ### NFS access, try a 2nd time, $fh = VMS::Stdio::vmsopen($f,"shr=get"); return $fh;},*[CRINOID0051.EXAMPLE_SCRIPTS]PWDCREATE.CGI;1+,K=./ 4t F<-K70123KPWO56dE# 7 U# 89GHJ#! perl#D# add a user, if necessary create password file and user-directory#4# Author: C. Lane lane@duphy4.physics.drexel.eduuse CGI;use VMS::Stdio;use Digest::MD5 qw(md5_hex);$CRINOID::Reuse = 1;*$PWDfile = 'sys$login:roaming_access.pwd';$root = '../netscape_roam';$MINPWDLENGTH = 8;$MAXPWDLENGTH = 32; $q = new CGI;#####################1# must be a secure connection...redirect if not#$url = $q->url;$redirect = $goturl = 0;?if ($url =~ /^([a-z0-9]+)\:\/\/([a-z0-9\_\-\.]+)(\:\d+)?\//i) { $goturl = 1;" $redirect = lc($1) ne 'https'; $url = 'https://'.$2.'/'.$';}if ($goturl) { if ($redirect){! print $q->redirect($url); } else {& print $q->header("text/html");# if ($q->param('newpwd1')) { try_change($q); } else { show_form($q); } print $q->end_html; }} else {) print "Content-type: text/plain\n\n";? print "Error: something about the url $url is peculiar.\n";3 print "Please inform the owner of this page\n";}sub try_change { my $q = shift;- print $q->start_html("pwdcreate/result");% my $user = lc($q->param('user'));" my $n1 = $q->param('newpwd1');" my $n2 = $q->param('newpwd2'); my $found = 0;) $user =~ tr/[a-zA-Z0-9\_\-\$\.]/\?/c;! if (index($user,'?') != -1) {% print "Invalid username
";1 print 'Try again'; return; } $home = $user; $home =~ tr/\./\$2E/; $home = '/'.$home; if ($n1 ne $n2) {L print "The new password you entered wasn't the same both times
";@ print 'Try again'; return; }& if (length($n1) < $MINPWDLENGTH) {C print "What you entered for a new password is too short. ";D print "Your new password should be at least $MINPWDLENGTH ";% print "characters long.
";@ print 'Try again'; return; }& if (length($n1) > $MAXPWDLENGTH) {B print "What you entered for a new password is too long. ";G print "Your new password should shorter than ",$MAXPWDLENGTH+1;% print "characters long.
";@ print 'Try again'; return; } $n2 = md5_hex(lc($n2)); if (!open(FH,"<$PWDfile")) { if (! -e $PWDfile) {* print "Creating new file
"; goto newfile; }D print "There was an error opening the password file...
";= print "Please report this to the owner of this page"; return; } my $j = 0; my @save; my ($u, $p, $d); while () { $save[$j++] = $_; chomp; s/#.*//; s/^\s+//; s/\s+$//; s/\s+/ /; next if $_ eq ''; ($u,$p,$d) = split;* $u =~ tr/[a-zA-Z0-9\_\-\$\.]/\?/c;& next if (index($u,'?') != -1);" next if (lc($u) ne $user); $found++;3 $save[$j-1] = $user.' '.$n2.' '.$home."\n"; } close FH;newfile: if ($found > 1) {G print "Username found $found times in the password file.
";R print "Please bring this to the attention of the owner of this page!
";O print "This problem must be fixed before you can change your password"; return; } if ($found) {M print "User '$user' alread in the password file; updating entry
"; } if (!$found) {1 $save[$j] = $user.' '.$n2.' '.$home."\n";' if (!mkdir($root.$home,0700)) {C print "Unable to create home directory $root$home
"; return; } }" if (!open(FH,">$PWDfile-2")) {: print "Unable to open password file for writing!";N print "Please bring this to the attention of the owner of this page!"; return; } foreach (@save) { print FH $_; }< print FH "# $user PWDCREATE at ",scalar(localtime),"\n"; close FH; unlink($PWDfile);" rename("$PWDfile-2",$PWDfile); chmod (0700, $PWDfile);% print "User add successful!
";}sub show_form { my $q = shift;, print $q->start_html("pwdcreate/query"); print $q->startform(); print '';^ print "
Username:",$q->textfield(-name=>'user',-value=>'',-force=>1,-size=>32);l print '
New password:',$q->password_field(-name=>'newpwd1',-value=>'', -force=>1, -size=>32);t print '
New password (again):',$q->password_field(-name=>'newpwd2',-value=>'', -force=>1, -size=>32); print '
';2 print $q->submit(-name=>'Change'),$q->reset();})*[CRINOID0051.EXAMPLE_SCRIPTS]README.TXT;1+,K. / 4N <-K70123KPWO 56V\# 7j# 89GHJ(Some example scripts to get you started:NSIMPLE_FORM.CGI a simple form, with link to CGI.PM docs & examples on the web(DEBUG_FORM.PL dumps ENV and POST data0DIRECTORY. makes an HTML directory of CGIs7LINEAR.CGI linear regression utility using PGPLOT7UPLOAD.CGI file upload test script (CGI.pm 2.74+)DThe following scripts implement Netscape Roaming access; ROAM.CGI isDwhat actually processes Roaming access save/restores; it uses a fileFof username and MD5-encrypted passwords. You create user entries (andJthe password file) with PWDCREATE and can change passwords with PWDCHANGE.DNote that you may want to change the directories used by these threeFscripts. The password file is created in SYS$LOGIN, while the RoamingCfiles are stored in directory ../netscape_roam from the CGI scriptarea.FPWDCREATE and PWDCHANGE use https secure connections when transmitting>passwords, but unfortunately Netscape 4.7 does not allow httpsconnections for Roaming access.JROAM.CGI Netscape roaming access, use with PWDCREATE and PWDCHANGE<PWDCREATE.CGI Create password or password file for a user)PWDCHANGE.CGI Change a user's password'*[CRINOID0051.EXAMPLE_SCRIPTS]ROAM.CGI;1+,K2./ 4` l<-K70123KPWO56ZYq# 7=# 89GHJ#! perl#/# script to implement Netscape Roaming access7# note that you'll need to change $root and $PWDfile.;# The scripts PWDCHANGE.CGI and PWDCREATE.CGI can be used$# to help manage the password file#4# Author: C. Lane lane@duphy4.physics.drexel.edu#use MIME::Base64;use Digest::MD5 qw(md5_hex);$CRINOID::Reuse = 1; $Verbose = 0;*$PWDfile = 'sys$login:roaming_access.pwd';$root = '../netscape_roam';!$method = $ENV{'REQUEST_METHOD'};"$what = $root.$ENV{'PATH_INFO'};process_request();9print STDERR "ROAM.CGI: request completed\n" if $Verbose; done: $x = 1;sub process_request { my $authorized = 0;' my $t = $ENV{'HTTP_AUTHORIZATION'};9 my ($up, $CTL, $TSPECIALS, $user, $pass, $u, $p, $d); local *FH;" if ($t =~ /^Basic\s+(\w+)/i) {. $up = MIME::Base64::decode_base64($1); $CTL = '\000-\017\177';< $TSPECIALS = '\(\)\<\>\@\,\;\:\\\"\/\[\]\?\=\}\{\s';/ if ($up =~ /^([^$CTL$TSPECIALS]*)\:/) { $user = lc($1);$ $pass = md5_hex(lc($'));' if (open(FH,"<$PWDfile")) { while () { chomp; s/#.*//; s/^\s+//; s/\s+$//; s/\s+/ /;% next if $_ eq '';' ($u,$p,$d) = split;6 $u =~ tr/[a-zA-Z0-9\_\-\$\.]/\?/c;2 next if (index($u,'?') != -1);. next if (lc($u) ne $user);& if ($p eq $pass) {( $authorized = 1; } last; } close(FH); } } } if (!$authorized) {1 print "Status: 401 need authorization\n";; print "WWW-Authenticate: Basic realm=\"Roam\"\n\n"; return; }) $what = $root.$d.$ENV{'PATH_INFO'}; my (@s);= @dow = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');` @mon = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');0 if ($method eq 'GET' || $method eq 'HEAD') { if (!-e $what) {4 print "Status: 404 File not found\n\n"; return; } @s = stat($what);! print "Status: 200 OK\n";+ print "Content-Type: text/plain\n";( print "Content-Length: $s[7]\n"; @g = gmtime($s[9]);: $when = $dow[$g[6]].' '.$g[3].' '.$mon[$g[4]].' ';Q $when .= sprintf("%4.4d %2.2d:%2.2d:%2.2d",$g[5]+1900,$g[2],$g[1],$g[0]);- print "Last-Modified: $when GMT\n\n"; if ($method eq 'GET') {* open(FILE,"<$what") || return; $sent = 0; while(1) {. $got = read(FILE,$buf,1024,0); if ($got > 0) { print $buf;" $sent += $got; } else { last; } }K print STDERR "ROAM.CGI: GET $what ($sent bytes)\n" if $Verbose; close FILE; } else {> print STDERR "ROAM.CGI: HEAD $what\n" if $Verbose; }# } elsif ($method eq 'DELETE') { if (-e $what) {, while (-e $what) {unlink $what;}E print STDERR "ROAM.CGI: DELETE $what (OK)\n" if $Verbose; } else {1 print "Status: 404 File not found\n";1 print "Content-type: text/plain\n\n";9 print "Attemp to delete non-existant file\n";F print STDERR "ROAM.CGI: DELETE $what (ERR)\n" if $Verbose; } } elsif ($method eq 'PUT') { $old = -e $what; $stat = "200: OK";+ $stat = "201: Created"; # if !$old; unlink($what) if $old;" if (open(FILE,">$what")) {- $remain = $ENV{'CONTENT_LENGTH'}; $j = 0;! while ($remain > 0) {5 $n = $remain > 1024 ? 1024 : $remain;. $got = read(STDIN,$buf,$n, 0); $remain -= $got; print FILE $buf; } close FILE;& print "Status: $stat\n\n";H print STDERR "ROAM.CGI: PUT $what ($j bytes)\n" if $Verbose; } else {7 print "Status: 500 Error opening file\n\n"; }! } elsif ($method eq 'MOVE') { if (!-e $what) {1 print "Status: 404 file not found\n";1 print "Content-type: text/plain\n\n";0 print "Error 404: file not found\n"; return; }D $new = $ENV{'HTTP_NEW_URI'}; # '/cgi/~lane/roam.pl/cookies' @x = split('/',$new); $new = pop(@x);3 if (index($new,'.') == -1) { $new .= '.'; }! $new = $root.$d.'/'.$new;' while (-e $new) {unlink($new);}! if (rename($what,$new)) {' print "Status: 200 OK\n\n";K print STDERR "ROAM.CGI: MOVE $what -> $new (OK)\n" if $Verbose; } else {/ print "Status: 500 Rename error\n";1 print "Content-Type: text/plain\n\n";8 print "Error renaming from $what to $new\n";L print STDERR "ROAM.CGI: MOVE $what -> $new (ERR)\n" if $Verbose; } } else {7 print "Status: 405 Method not implemented\n\n"; }}.*[CRINOID0051.EXAMPLE_SCRIPTS]SIMPLE_FORM.CGI;1+,K). / 4U <-K70123KPWO 56ڒ 7p 89GHJ#! perl#A# this script generates a form; when the form is submitted backB# to the script it also prints out the data entered in the form.E# Lightly editted version of the "tryit.cgi" script that comes with# the CGI.pm module.#;$CRINOID::Reuse = 1; # this is a reusable scriptuse CGI qw(:standard); print header;%print start_html('A Simple Example'), h1('A Simple Form'), start_form,+ "What's your name? ",textfield('name'), p, "What's the combination?", p," checkbox_group(-name=>'words',= -values=>['eenie','meenie','minie','moe'],1 -defaults=>['eenie','minie']), p,# "What's your favorite color? ", popup_menu(-name=>'color',= -values=>['red','green','blue','chartreuse']), p, submit, end_form, hr;if (param()) { print+ "Your name is: ",em(param('name')), p,; "The keywords are: ",em(join(", ",param('words'))) ZP~ FREEWARE.SAVK)K7.[CRINOID0051.EXAMPLE_SCRIPTS]SIMPLE_FORM.CGI;1U , p,6 "Your favorite color is: ",em(param('color')), hr;}Uprint a({href=>'http://stein.cshl.org/WWW/software/CGI/'},'Go to the documentation');print end_html;)*[CRINOID0051.EXAMPLE_SCRIPTS]UPLOAD.CGI;1+,K~. / 4T <-K70123KPWO 56C  7 . 89GHJ#! perl## test of file uploading@# CGI.pm versions before 2.74 may require a patch to make file# uploading work on VMS.#use CGI;$CRINOID::Reuse = 1; $q = new CGI;print $q->header('text/html');,print $q->start_html('Test File uploading');ask_upload($q);proc_upload($q);print $q->end_html;sub ask_upload { my $q = shift;? print "

Request upload

",$q->start_multipart_form();$ print "Client file to upload: ",/ $q->filefield(-name=>'uploaded_file',3 -default=>'starting value'," -size=>20,( -maxlength=>80);. print "

requested filename on server: ";T print $q->textfield(-name=>'filename', -default=>'', -size=>20, -maxlength=>80);B print " ",$q->submit(-name=>'Upload'),$q->endform(),"

\n";}#B# works now, with mod to OPCODE.XS to handle _ & recent changes # in CGI.pm#sub proc_upload { my $q = shift;/ if (!defined($q->param('uploaded_file'))) {- print "


No file upload request\n"; return 1; }# my $fn = $q->param('filename');( my $f = $q->param('uploaded_file'); print "
\n";0 print "
Filename on client:$f\n";9 print "
Filename on server:$fn
\n";/ print "

File contents:

\n";    while (<$f>) {9        s/\&/&/g;           ### escape any html stuff#        s/\
\n";D my $tmp = $q->tmpFileName($f); ## MUST clean up afterwards!7 close $f; # close the i/o= unlink $tmp if $tmp; # get rid of tempfile return 0;}*[CRINOID0051]EXC_HANDLING.H;1+,9L9.H/ 4cHCN<-Ke0123KPWOI56㸌R7Y(89GHJpE/* modified by CEL to prevent DECC accvio!!! maybe only DECC V5.5-002E problem occurs with the _CMA_VOLATILE_ flag applied to one member in:$ typedef struct EXC_CONTEXT_T { ..., _CMA_VOLATILE_ struct EXC_CONTEXT_T ...) removing the _CMA_VOLATILE_ fixes it.B This problem is not present on at least some later versions of DECC and/or include files*//* * Copyright (c) 1989, 1994 by9 * Digital Equipment Corporation, Maynard Massachusetts. * All rights reserved. *J * This software is furnished under a license and may be used and copiedJ * only in accordance with the terms of such license and with theJ * inclusion of the above copyright notice. This software or any otherJ * copies thereof may not be provided or otherwise made available to anyJ * other person. No title to and ownership of the software is hereby * transferred. *J * The information in this software is subject to change without noticeJ * and should not be construed as a commitment by DIGITAL Equipment * Corporation. *J * DIGITAL assumes no responsibility for the use or reliability of its; * software on equipment which is not supplied by DIGITAL. *//* * FACILITY: * * DECthreads core * * FILENAME: * * EXC_HANDLING.H * * ABSTRACT: */ * Header file for exception handling in C * * AUTHORS: * * Eric Roberts * Bob Conti * Dave Butenhof * * CREATION DATE: * * 15 March 1989 * * MODIFIED BY: * * Dave Butenhof * Bob Conti * Paul Curtin * Webb Scales * * LAST MODIFICATION DATE: * * 10 June 1994 */ #ifndef EXC_HANDLING# define EXC_HANDLING 1#ifdef __cplusplus extern "C" {#endif/* * INCLUDE FILES */#ifndef CMA_CONFIGZ# if defined(vms) || defined(__vms) || defined (VMS) || defined(__VMS) || defined(__vms__)# include # else# include # endif#endifc#if ((_CMA_COMPILER_ == _CMA__DECC) || (_CMA_COMPILER_ == _CMA__DECCPLUS)) && _CMA_OS_ == _CMA__VMS# pragma __extern_model __save'# pragma __extern_model __strict_refdef"#elif _CMA_COMPILER_ == _CMA__VAXC# pragma nostandard#endif/*E * NOTE: on U*IX systems, these status codes must be kept unique fromI * "Enums". We do this arbitrarily by setting some high order bits whichG * happen to be the same as we use on VMS. Apollo systems use different- * error numbering scheme, and override this. */#if _CMA_OS_ == _CMA__VMS## define exc_facility_c 00020100000!# define _CMA_STATUS_(val, sev) \< ((exc_int_t)(exc_facility_c | ((val) << 3) | (sev)))#else*# define _CMA_DCE_PREFIX_ 0x177db0000# define exc_facility_c _CMA_DCE_PREFIX_!# define _CMA_STATUS_(val, sev) \/ ((exc_int_t)(_CMA_DCE_PREFIX_ | (val)))#endif#include /*K * Define a symbol that specifies whether exception handling should use theL * standard setjmp() and longjmp() functions, or the alternate _setjmp() andL * _longjmp(). The latter are faster, as they don't save/restore the signalH * mask (and therefore require no kernel calls). However, _setjmp() andB * _longjmp() are not standard, and therefore may not be availableM * everywhere. Also, there may be some platforms where failing to save signalK * state could break exception handling. For both reasons, we enable use ofD * the optimized functions only where we know for sure they are both * available and appropriate. */#ifndef _CMA_BAR_JMP_# if _CMA_OS_ == _CMA__UNIX# define _CMA_BAR_JMP_ 1# else# define _CMA_BAR_JMP_ 0# endif#endif#if _CMA_OS_ == _CMA__VMSD# if defined(_CMA_SUPPRESS_EXTERNALS_) || defined (_CMA_CORE_BUILD_)5# define cma_save_exc_context cma__save_exc_context# else5# define cma_save_exc_context cma$$save_exc_context# endif # if _CMA_HARDWARE_ == _CMA__VAX" typedef int cma__t_jmp_buf[14];: extern int cma_save_exc_context (_CMA_VOLATILE_ int *);# else# include + typedef uint64 cma__t_jmp_buf[(14+8+3)];= extern int cma_save_exc_context (_CMA_VOLATILE_ uint64 *);# endif=# define cma__exc_setjmp(__env) cma_save_exc_context((__env))#else! typedef jmp_buf cma__t_jmp_buf;# if _CMA_BAR_JMP_"# if _CMA_OSIMPL_ == _CMA__OS_OSF /*D * OSF/1 already provides prototypes for _setjmp and _longjmp inJ * /usr/include/setjmp.h; the prototypes here should be compatible, soM * we'll just cast the volatile jump buffer inside the _exc_setjmp_ macroG * instead of defining an appropriate prototype as we do elsewhere. */3 extern int _setjmp _CMA_PROTOTYPE_ ((jmp_buf));: extern void _longjmp _CMA_PROTOTYPE_ ((jmp_buf, int));N# define cma__exc_setjmp(__env) _setjmp ((exc_int_t *)(__env))V# define cma__exc_longjmp(__env,__val) _longjmp((exc_int_t *)(__env),(__val))# else@ extern int _setjmp _CMA_PROTOTYPE_ ((_CMA_VOLATILE_ int *));G extern void _longjmp _CMA_PROTOTYPE_ ((_CMA_VOLATILE_ int *, int));A# define cma__exc_setjmp(__env) _setjmp ((__env))I# define cma__exc_longjmp(__env,__val) _longjmp((__env),(__val))# endif# else8# define cma__exc_setjmp(__env) setjmp ((__env))@# define cma__exc_longjmp(__env,__val) longjmp((__env),(__val))# endif#endiftypedef char *exc_address_t;/*H * Use the most efficient code available to determine the address of theI * current procedure frame on VAX VMS systems (which we need to integrate0 * well with native VAX VMS condition handling). *J * - VAX C under VAX VMS supports instruction "builtins" to access general * registers. *I * - GCC supports an "asm" statement that generates inline assembly code. *H * - Otherwise, declare an extern function (part of DECthreads' assembly& * code) that will return the value. */#if _CMA_OS_ == _CMA__VMS # if _CMA_HARDWARE_ == _CMA__VAX"# if _CMA_COMPILER_ == _CMA__VAXC# pragma builtins9# define exc_fetch_fp() ((exc_address_t)_READ_GPR (13))## elif _CMA_COMPILER_ == _CMA__GCC# define exc_fetch_fp() \ ({ int frameptr; \5 asm volatile ("movl fp, %0" : "=g" (frameptr)); \ frameptr; })# elseF# if defined(_CMA_SUPPRESS_EXTERNALS_) || defined (_CMA_CORE_BUILD_)/ extern exc_address_t cma__fetch_fp (void);'# define exc_fetch_fp cma__fetch_fp# else2 extern exc_address_t cma$exc_fetch_fp (void);*# define exc_fetch_fp cma$exc_fetch_fp # endif# endif# elseE# if defined(_CMA_SUPPRESS_EXTERNALS_) || defined (_CMA_CORE_BUILD_). extern exc_address_t cma__fetch_fp (void);&# define exc_fetch_fp cma__fetch_fp# else1 extern exc_address_t cma$exc_fetch_fp (void);)# define exc_fetch_fp cma$exc_fetch_fp# endif# endif#endif /*5 * Define all of the status codes used by DECthreads. *M * For VMS, these must remain in synch with the CMA_MESSAGE.GNM message file. *L * These values cannot be altered after they have shipped in some DECthreads * release. *//* * EXC facility messages */2#define exc_s_exception _CMA_STATUS_(1, 4)2#define exc_s_exccop _CMA_STATUS_(2, 4)2#define exc_s_uninitexc _CMA_STATUS_(3, 4)4#define exc_s_unkstatus _CMA_STATUS_(128, 4)4#define exc_s_exccoplos _CMA_STATUS_(129, 4)/*I * These should be set to match with underlying system exception codes onA * platforms where that is appropriate (e.g., ss$_ codes on VMS). */#if _CMA_OS_ == _CMA__VMS/*I * A few of these codes are somewhat imaginary, since VMS doesn't supportG * condition codes that very closely approximate the sense of some UNIXI * signals. SIGTRAP, SIGIOT, and SIGEMT have no clear parallels, and theL * values chosen are fairly arbitrary. For two others, we chose what seemedM * close equivalents: SIGPIPE becomes "no mailbox", and SIGXFSZ becomes "disk * quota exceeded". */8# define exc_s_illaddr 12 /* ss$_accvio */9# define exc_s_exquota 28 /* ss$_exquota */9# define exc_s_insfmem 292 /* ss$_insfmem */8# define exc_s_nopriv 36 /* ss$_nopriv */8# define exc_s_normal 1 /* ss$_normal */8# define exc_s_illinstr 1084 /* ss$_opcdec */9# define exc_s_resaddr 1100 /* ss$_radrmod */8# define exc_s_privinst 1084 /* ss$_opcdec */9# define exc_s_resoper 1108 /* ss$_roprand */7# define exc_s_SIGTRAP 1044 /* ss$_break */7# define exc_s_SIGIOT 44 /* ss$_abort */8# define exc_s_SIGEMT 1068 /* ss$_compat */8# define exc_s_aritherr 1164 /* ss$_fltovf */:# define exc_s_SIGSYS 20 /* ss$_badparam */7# define exc_s_SIGPIPE 628 /* ss$_nombx */:# define exc_s_excpu 8364 /* ss$_excputim */=# define exc_s_exfilsiz 1004 /* ss$_exdiskquota */8# define exc_s_intovf 1148 /* ss$_intovf */8# define exc_s_intdiv 1156 /* ss$_intdiv */8# define exc_s_fltovf 1164 /* ss$_fltovf */8# define exc_s_fltdiv 1172 /* ss$_fltdiv */8# define exc_s_fltund 1180 /* ss$_fltund */8# define exc_s_decovf 1188 /* ss$_decovf */8# define exc_s_subrng 1196 /* ss$_subrng */#elsee2# define exc_s_illaddr _CMA_STATUS_(5, 4)2# define exc_s_exquota _CMA_STATUS_(6, 4)2# define exc_s_insfmem _CMA_STATUS_(7, 4)2# define exc_s_nopriv _CMA_STATUS_(8, 4)2# define exc_s_normal _CMA_STATUS_(9, 1)3# define exc_s_illinstr _CMA_STATUS_(10, 4)h3# define exc_s_resaddr _CMA_STATUS_(11, 4)p3# define exc_s_privinst _CMA_STATUS_(12, 4)i3# define exc_s_resoper _CMA_STATUS_(13, 4)i3# define exc_s_SIGTRAP _CMA_STATUS_(14, 4)r3# define exc_s_SIGIOT _CMA_STATUS_(15, 4)3# define exc_s_SIGEMT _CMA_STATUS_(16, 4)o3# define exc_s_aritherr _CMA_STATUS_(17, 4)o3# define exc_s_SIGSYS _CMA_STATUS_(18, 4)o3# define exc_s_SIGPIPE _CMA_STATUS_(19, 4) 3# define exc_s_excpu _CMA_STATUS_(20, 4) 3# define exc_s_exfilsiz _CMA_STATUS_(21, 4)3# define exc_s_intovf _CMA_STATUS_(22, 4)3# define exc_s_intdiv _CMA_STATUS_(23, 4)B3# define exc_s_fltovf _CMA_STATUS_(24, 4)i3# define exc_s_fltdiv _CMA_STATUS_(25, 4)3# define exc_s_fltund _CMA_STATUS_(26, 4)R3# define exc_s_decovf _CMA_STATUS_(27, 4)I3# define exc_s_subrng _CMA_STATUS_(28, 4)t#endif/* * Define alias namesb */e-#define exc_s_accvio exc_s_illaddr .#define exc_s_SIGILL exc_s_illinstr.#define exc_s_SIGFPE exc_s_aritherr-#define exc_s_SIGBUS exc_s_illaddr -#define exc_s_SIGSEGV exc_s_illaddrd+#define exc_s_SIGXCPU exc_s_excpue.#define exc_s_SIGXFSZ exc_s_exfilsiz/*% * DECthreads facility (CMA) messagesf */3#define cma_s_alerted _CMA_STATUS_(48, 4)E3#define cma_s_assertion _CMA_STATUS_(49, 4)_3#define cma_s_badparam _CMA_STATUS_(50, 4)g3#define cma_s_bugcheck _CMA_STATUS_(51, 4)E3#define cma_s_exit_thread _CMA_STATUS_(52, 4)3#define cma_s_existence _CMA_STATUS_(53, 4)k3#define cma_s_in_use _CMA_STATUS_(54, 4) 3#define cma_s_use_error _CMA_STATUS_(55, 4)b3#define cma_s_wrongmutex _CMA_STATUS_(56, 4)r3#define cma_s_stackovf _CMA_STATUS_(57, 4)3#define cma_s_nostackmem _CMA_STATUS_(58, 4)t3#define cma_s_notcmastack _CMA_STATUS_(59, 4)3#define cma_s_timed_out _CMA_STATUS_(60, 4)(3#define cma_s_unimp _CMA_STATUS_(61, 4)d3#define cma_s_inialrpro _CMA_STATUS_(62, 4)_3#define cma_s_defer_q_full _CMA_STATUS_(63, 4)n3#define cma_s_signal_q_full _CMA_STATUS_(64, 4)<3#define cma_s_alert_nesting _CMA_STATUS_(65, 4)h/* * Synonyms for convenience  */,#define cma_s_normal exc_s_normal/* * TYPEDEFSe */)/*1 * Constants for the kind of an exception object.t *K * There are *currently* only two kinds. In the address-kind, the identitye@ * of an exception object is its address; in the value-kind, the< * identity of an exception object is an integer, typically,8 * a system-defined-status-value. These coded kinds also> * serve as sentinels to help detect uninitialized exceptions. */mtypedef enum EXC_KIND_T {e exc_kind_none_c = 0,% exc_kind_address_c = 0x02130455,i$ exc_kind_status_c = 0x02130456# } exc_kind_t; /*, * Internal contents of an exception object. */typedef long int exc_int_t;typedef struct EXC_EXT_T {! exc_int_t sentinel;D exc_int_t version; exc_address_t extend; unsigned int *args; } exc_ext_t;"typedef struct EXC_KIND_V1ADDR_T { exc_kind_t kind;_ exc_address_t address;" exc_int_t filler[6]; } exc_kind_v1addr_t;$typedef struct EXC_KIND_V1STATUS_T { exc_kind_t kind;m exc_int_t status;_" exc_int_t filler[6]; } exc_kind_v1status_t;#typedef struct EXC_KIND_ADDRESS_T {e exc_kind_t kind;f exc_address_t address; exc_ext_t ext; } exc_kind_address_t;r"typedef struct EXC_KIND_STATUS_T { exc_kind_t kind;h exc_int_t status;t exc_ext_t ext; } exc_kind_status_t;!typedef union EXC_EXCEPTION_T {  exc_kind_t kind;p! exc_kind_v1status_t v1status;" exc_kind_v1addr_t v1address; exc_kind_status_t status; exc_kind_address_t address; } EXCEPTION;/*A * Constants for the state of handling in the current TRY clause.) *G * The state is "none" when no exception has been raised, "active" when I * one has been raised but has not yet been caught by a CATCH clause, and_F * "handled" after the exception has been caught by some CATCH clause. */ typedef enum EXC_STATE_T {H exc_active_c = 0, /* This must be the 0 state, see pop_ctx */ exc_none_c = 1, exc_handled_c = 2, exc_popped_c = 3_$ } exc_state_t;/* * Structure of a context block. *C * A context block is allocated in the current stack frame for eachrB * TRY clause. These context blocks are linked to form a stack ofD * all current TRY blocks in the current thread. Each context block8 * contains a jump buffer for use by setjmp and longjmp. * */d#define exc_excargs_c 40typedef struct EXC_CONTEXT_T {9 cma__t_jmp_buf jmp; /* Jump buffer */p struct EXC_CONTEXT_TI *link; /* Link to context block stack */ K EXCEPTION cur_exception; /* Copy of the current exception */.L exc_state_t exc_state; /* State of handling for this TRY */#if _CMA_OS_ == _CMA__VMSL exc_address_t current_frame; /* Address of current stack frame */$# if _CMA_PLATFORM_ == _CMA__VAX_VMSI exc_address_t old_handler; /* Address of previous handler */(# endif #endifI exc_int_t sentinel; /* Identify as "new" ctx block */SD exc_int_t version; /* Client context version */0 unsigned int exc_args[exc_excargs_c]; } exc_context_t;/* * GLOBAL DATAr */ ]#if _CMA_OS_ == _CMA__VMS && !defined(_CMA_SUPPRESS_EXTERNALS_) && !defined(_CMA_CORE_BUILD_)e/*L * On VMS, use the VMS calling standard ("$") interface, to avoid pulling inJ * the open interface image (cma$open_rtl) unless the client code uses it. *L * Note that this also modifies the "extern" routine definitions immediately * below.a */f0# define exc_push_ctx cma$exc_push_ctx/# define exc_pop_ctx cma$exc_pop_ctx-# define exc_raise cma$exc_raiset4# define exc_raise_status cma$exc_raise_status.# define exc_report cma$exc_report3# define exc_get_message cma$exc_get_messagec#endifJextern void exc_push_ctx _CMA_PROTOTYPE_ (( /* Push a context block */, _CMA_VOLATILE_ exc_context_t *cb));Iextern void exc_pop_ctx _CMA_PROTOTYPE_ (( /* Pop a context block */ , _CMA_VOLATILE_ exc_context_t *cb));Hextern void exc_raise _CMA_PROTOTYPE_ (( /* Raise an exception */ EXCEPTION *exc));nPextern void exc_raise_status _CMA_PROTOTYPE_ (( /* Raise a status as exception*/! exc_int_t status));Iextern void exc_report _CMA_PROTOTYPE_ (( /* Report an exception */ EXCEPTION *exc));yHextern void exc_get_message _CMA_PROTOTYPE_ (( /* Get exception text */ EXCEPTION *exc,l int buflen,a" char *buffer));#if _CMA_OS_ == _CMA__VMSo/*J * On OpenVMS, we use the native condition handling mechanism to implementB * DECthreads exceptions; thus we need a condition handler. Due toI * differences in behavior, the conditions for deciding whether to use aneF * external (client) or internal (within DECthreads) name are slightly * different */ # if _CMA_HARDWARE_ == _CMA__VAX(# if !defined(_CMA_SUPPRESS_EXTERNALS_)'# define exc_handler cma$exc_handler # endif# elseG# if !defined(_CMA_SUPPRESS_EXTERNALS_) && !defined (_CMA_CORE_BUILD_)c'# define exc_handler cma$exc_handler # endif# endifrNextern int exc_handler (/* sargs, margs*/); /* System condition handler */#endif/*! * Define the exception variables  *H * NOTE: it does not make sense to turn all DECthreads status codes into3 * exceptions as some are never raised. Those are:s ** * cma_s_normal -- never signalledG * cma_s_exception -- internal to the implementation of exceptionsnG * cma_s_exccop -- internal to the implementation of exceptionseM * cma_s_timed_out -- returned as status value from timed condition waitv */ 8#if _CMA_OS_ == _CMA__VMS && !defined (_CMA_CORE_BUILD_);# if defined (__STDC__) || _CMA_COMPILER_ == _CMA__DECCPLUS ,# define _CMA_EXCNAME(name) cma$e_##name,# define _CMA_CMANAME(name) cma$e_##name# else.# define _CMA_EXCNAME(name) cma$e_/**/name.# define _CMA_CMANAME(name) cma$e_/**/name# endifi#elses;# if defined (__STDC__) || _CMA_COMPILER_ == _CMA__DECCPLUSe,# define _CMA_EXCNAME(name) exc_e_##name,# define _CMA_CMANAME(name) cma_e_##name# else.# define _CMA_EXCNAME(name) exc_e_/**/name.# define _CMA_CMANAME(name) cma_e_/**/name# endife#endifI#if !defined (_EXC_NO_EXCEPTIONS_) && !defined (_CMA_SUPPRESS_EXTERNALS_)U_CMA_IMPORT_ EXCEPTION _CMA_EXCNAME (uninitexc),_ _CMA_EXCNAME (illaddr),i _CMA_EXCNAME (exquota),4 _CMA_EXCNAME (insfmem),  _CMA_EXCNAME (nopriv), _CMA_EXCNAME (illinstr), _CMA_EXCNAME (resaddr),i _CMA_EXCNAME (privinst), _CMA_EXCNAME (resoper),c _CMA_EXCNAME (SIGTRAP),U _CMA_EXCNAME (SIGIOT), _CMA_EXCNAME (SIGEMT), _CMA_EXCNAME (aritherr), _CMA_EXCNAME (SIGSYS), _CMA_EXCNAME (SIGPIPE),  _CMA_EXCNAME (excpu),  _CMA_EXCNAME (exfilsiz), _CMA_EXCNAME (intovf), _CMA_EXCNAME (intdiv), _CMA_EXCNAME (fltovf), _CMA_EXCNAME (fltdiv), _CMA_EXCNAME (fltund), _CMA_EXCNAME (decovf), _CMA_EXCNAME (subrng), _CMA_CMANAME (alerted),S _CMA_CMANAME (assertion),f _CMA_CMANAME (badparam), _CMA_CMANAME (bugcheck), _CMA_CMANAME (exit_thread),  _CMA_CMANAME (existence),C _CMA_CMANAME (in_use), _CMA_CMANAME (use_error),A _CMA_CMANAME (wrongmutex), _CMA_CMANAME (stackovf), _CMA_CMANAME (nostackmem), _CMA_CMANAME (notcmastack),  _CMA_CMANAME (unimp),d _CMA_CMANAME (inialrpro),x _CMA_CMANAME (defer_q_full),! _CMA_CMANAME (signal_q_full), ! _CMA_CMANAME (alert_nesting);d8#if _CMA_OS_ == _CMA__VMS && !defined (_CMA_CORE_BUILD_) /*K * Define exc_e_ or cma_e_ aliases for the cma$e_ names. The purpose of*D * all this is to use the "VMS calling standard" names (cma$rtl)E * regardless of whether the client code uses the VMS or portable J * DECthreads interfaces, so that use of exceptions never requires the * cma$open_rtl image. */A/# define exc_e_uninitexc cma$e_uninitexc -# define exc_e_illaddr cma$e_illaddr -# define exc_e_exquota cma$e_exquotar-# define exc_e_insfmem cma$e_insfmem_,# define exc_e_nopriv cma$e_nopriv.# define exc_e_illinstr cma$e_illinstr-# define exc_e_resaddr cma$e_resaddr,.# define exc_e_privinst cma$e_privinst-# define exc_e_resoper cma$e_resoperA-# define exc_e_SIGTRAP cma$e_SIGTRAP ,# define exc_e_SIGIOT cma$e_SIGIOT,# define exc_e_SIGEMT cma$e_SIGEMT.# define exc_e_aritherr cma$e_aritherr,# define exc_e_SIGSYS cma$e_SIGSYS-# define exc_e_SIGPIPE cma$e_SIGPIPE,+# define exc_e_excpu cma$e_excpu.# define exc_e_exfilsiz cma$e_exfilsiz,# define exc_e_intovf cma$e_intovf,# define exc_e_intdiv cma$e_intdiv,# define exc_e_fltovf cma$e_fltovf,# define exc_e_fltdiv cma$e_fltdiv,# define exc_e_fltund cma$e_fltund,# define exc_e_decovf cma$e_decovf,# define exc_e_subrng cma$e_subrng-# define cma_e_alerted cma$e_alertedn/# define cma_e_assertion cma$e_assertionm.# define cma_e_badparam cma$e_badparam.# define cma_e_bugcheck cma$e_bugcheck1# define cma_e_exit_thread cma$e_exit_thread /# define cma_e_existence cma$e_existencet,# define cma_e_in_use cma$e_in_use/# define cma_e_use_error cma$e_use_error0# define cma_e_wrongmutex cma$e_wrongmutex.# define cma_e_stackovf cma$e_stackovf0# define cma_e_nostackmem cma$e_nostackmem1# define cma_e_notcmastack cma$e_notcmastack_+# define cma_e_unimp cma$e_unimp /# define cma_e_inialrpro cma$e_inialrpro 2# define cma_e_defer_q_full cma$e_defer_q_full3# define cma_e_signal_q_full cma$e_signal_q_fulln3# define cma_e_alert_nesting cma$e_alert_nestingr#endif/* * Define aliased exceptions */t6# define exc_e_accvio _CMA_EXCNAME (illaddr)7# define exc_e_SIGILL _CMA_EXCNAME (illinstr) 7# define exc_e_SIGFPE _CMA_EXCNAME (aritherr)N6# define exc_e_SIGBUS _CMA_EXCNAME (illaddr)6# define exc_e_SIGSEGV _CMA_EXCNAME (illaddr)4# define exc_e_SIGXCPU _CMA_EXCNAME (excpu)7# define exc_e_SIGXFSZ _CMA_EXCNAME (exfilsiz)a/*- * The following are pthread exception names. */x8# define exc_uninitexc_e _CMA_EXCNAME (uninitexc)6# define exc_illaddr_e _CMA_EXCNAME (illaddr)6# define exc_exquota_e _CMA_EXCNAME (exquota)6# define exc_insfmem_e _CMA_EXCNAME (insfmem)5# define exc_nopriv_e _CMA_EXCNAME (nopriv)b7# define exc_illinstr_e _CMA_EXCNAME (illinstr)h6# define exc_resaddr_e _CMA_EXCNAME (resaddr)7# define exc_privinst_e _CMA_EXCNAME (privinst) 6# define exc_resoper_e _CMA_EXCNAME (resoper)6# define exc_SIGTRAP_e _CMA_EXCNAME (SIGTRAP)5# define exc_SIGIOT_e _CMA_EXCNAME (SIGIOT)*5# define exc_SIGEMT_e _CMA_EXCNAME (SIGEMT)i7# define exc_aritherr_e _CMA_EXCNAME (aritherr)c5# define exc_SIGSYS_e _CMA_EXCNAME (SIGSYS) 6# define exc_SIGPIPE_e _CMA_EXCNAME (SIGPIPE)4# define exc_excpu_e _CMA_EXCNAME (excpu)7# define exc_exfilsiz_e _CMA_EXCNAME (exfilsiz)05# define exc_intovf_e _CMA_EXCNAME (intovf) 5# define exc_intdiv_e _CMA_EXCNAME (intdiv)C5# define exc_fltovf_e _CMA_EXCNAME (fltovf)n5# define exc_fltdiv_e _CMA_EXCNAME (fltdiv)u5# define exc_fltund_e _CMA_EXCNAME (fltund) 5# define exc_decovf_e _CMA_EXCNAME (decovf)g5# define exc_subrng_e _CMA_EXCNAME (subrng)d6# define pthread_cancel_e _CMA_CMANAME (alerted)8# define pthread_assertion_e _CMA_CMANAME (assertion)7# define pthread_badparam_e _CMA_CMANAME (badparam)l7# define pthread_bugcheck_e _CMA_CMANAME (bugcheck)l:# define pthread_exit_thread_e _CMA_CMANAME (exit_thread)8# define pthread_existence_e _CMA_CMANAME (existence)5# define pthread_in_use_e _CMA_CMANAME (in_use)_8# define pthread_use_error_e _CMA_CMANAME (use_error)9# define pthread_wrongmutex_e _CMA_CMANAME (wrongmutex)e7# define pthread_stackovf_e _CMA_CMANAME (stackovf)s9# define pthread_nostackmem_e _CMA_CMANAME (nostackmem)n:# define pthread_notstack_e _CMA_CMANAME (notcmastack)4# define pthread_unimp_e _CMA_CMANAME (unimp)8# define pthread_inialrpro_e _CMA_CMANAME (inialrpro);# define pthread_defer_q_full_e _CMA_CMANAME (defer_q_full) =# define pthread_signal_q_full_e _CMA_CMANAME (signal_q_full)$6# define exc_accvio_e _CMA_EXCNAME (illaddr)7# define exc_SIGILL_e _CMA_EXCNAME (illinstr) 7# define exc_SIGFPE_e _CMA_EXCNAME (aritherr)f6# define exc_SIGBUS_e _CMA_EXCNAME (illaddr)6# define exc_SIGSEGV_e _CMA_EXCNAME (illaddr)4# define exc_SIGXCPU_e _CMA_EXCNAME (excpu)7# define exc_SIGXFSZ_e _CMA_EXCNAME (exfilsiz)_#endif/* * CONSTANTS AND MACROS_ */ /*L * This constant helps to identify a context block or exception created withI * DECthreads BL9 or later; the new structures include a version field to/ * better manage future changes. */xM#define exc_newexc_c 0x45586732 /* Identify ctx block with version */ /*A * Define a version constant to be put into exception structures.G */c#define exc_v2exc_c 2E/*K * Define "keyword" to initialize an exception. Note: all exceptions *must*e# * be initialized using this macro.* */O!#define EXCEPTION_INIT(e) ( \i1 (e).address.address = (exc_address_t)&(e), \x, (e).address.kind = exc_kind_address_c, \. (e).address.ext.sentinel = exc_newexc_c, \, (e).address.ext.version = exc_v2exc_c, \0 (e).address.ext.extend = (exc_address_t)0, \- (e).address.ext.args = (unsigned int *)0)E/*= * Define "routine" to equivalence an exception to an integere- * (typically a system-defined status value). */ #define exc_set_status(e,s) ( \) (e)->status.status = (s), \) (e)->status.kind = exc_kind_status_c) /*M * Define "routine" to return the status of an exception. Returns 0 if status > * kind (and value of status in *s), or -1 if not status kind. */N#define exc_get_status(e,s) ( \r& (e)->kind == exc_kind_status_c ? \* (*(s) = (e)->status.status, 0) : \ -1) /*9 * Define "routine" to determine if two exceptions match.- */r#define exc_matches(e1,e2) \ ((e1)->kind == (e2)->kind \ 6 && (e1)->address.address == (e2)->address.address)/*? * Define "statement" for clients to use to raise an exception.i */* #define RAISE(e) exc_raise(&(e))##if _CMA_PLATFORM_ == _CMA__VAX_VMSn/*E * For VAX VMS, try to integrate peacefully with native VMS conditionnG * handling. Save the previous handler for the frame, and restore it oneG * ENDTRY. The DECthreads condition handler will call the saved handlernG * before resignalling a condition that we don't want to handle, unless_H * it is the DECthreads condition handler (to avoid infinite recursion). */d%# define exc_establish(_exc_ctx_) ( \eG (_exc_ctx_)->current_frame = ((exc_address_t)exc_fetch_fp()), \C$ (_exc_ctx_)->old_handler = \A *((exc_address_t *)(_exc_ctx_)->current_frame), \S8 *(exc_address_t *)(_exc_ctx_)->current_frame = \- ((exc_address_t)exc_handler))i%# define exc_unestablish(_exc_ctx_) \EP *(exc_address_t *)(_exc_ctx_)->current_frame = (_exc_ctx_)->old_handler;#elseC&# if _CMA_PLATFORM_ == _CMA__ALPHA_VMS$# define exc_establish(_exc_ctx_) \G (_exc_ctx_)->current_frame = ((exc_address_t)exc_fet +sV~ FREEWARE.SAV9L9Ke[CRINOID0051]EXC_HANDLING.H;1cHGU9ch_fp()); \E$ lib$establish (exc_handler);$# define exc_unestablish(_exc_ctx_)# else"# define exc_establish(_exc_ctx_)$# define exc_unestablish(_exc_ctx_)# endifE#endif/*5 * Constants to define versions of the context block:f */ #define exc_v2ctx_c 2 /*> * Start a new TRY block, which may contain exception handlers *B * Allocate a context block on the stack to remember the current? * exception. Push it on the context block stack. Initialize L * this context block to indicate that no exception is active. Do a SETJMPA * to snapshot this environment (or return to it). Then, startm; * a block of statements to be guarded by the TRY clause.cJ * This block will be ended by one of the following: a CATCH, CATCH_ALL, * or the ENDTRY macros. */A #define TRY \_ { \/ _CMA_VOLATILE_ exc_context_t exc_ctx; \A* exc_ctx.sentinel = exc_newexc_c; \( exc_ctx.version = exc_v2ctx_c; \" exc_ctx.exc_args[0] = 0; \! exc_push_ctx (&exc_ctx);\r" exc_establish (&exc_ctx);\- if (!cma__exc_setjmp (exc_ctx.jmp)) { :/* { user's block of code goes here } *//*4 * Define an CATCH(e) clause (or exception handler). *F * First, end the prior block. Then, check if the current exceptionD * matches what the user is trying to catch with the CATCH clause.C * If there is a match, a variable is declared to support lexicale@ * nesting of RERAISE statements, and the state of the current' * exception is changed to "handled".t */ #define CATCH(e) \ } \sC else if (exc_matches(&exc_ctx.cur_exception, &(e))) { \rM EXCEPTION *THIS_CATCH = (EXCEPTION *)&exc_ctx.cur_exception;\ 2 exc_ctx.exc_state = exc_handled_c;:/* { user's block of code goes here } *//*6 * Define an CATCH_ALL clause (or "catchall" handler). *8 * First, end the prior block. Then, unconditionally,B * let execution enter into the catchall code. As with a normal5 * catch, a variable is declared to support lexicale@ * nesting of RERAISE statements, and the state of the current' * exception is changed to "handled".  */ #define CATCH_ALL \i } \  else { \M EXCEPTION *THIS_CATCH = (EXCEPTION *)&exc_ctx.cur_exception;\m2 exc_ctx.exc_state = exc_handled_c;:/* { user's block of code goes here } *//* * Define a RERAISE statement. *: * This "statement" is valid only if lexically nested inG * a CATCH or CATCH_ALL clause. Reraise the current lexically visible$ * exception.  */e%#define RERAISE exc_raise(THIS_CATCH)t/* * Define a FINALLY clause *C * This "keyword" starts a FINALLY clause. It must appear beforecC * an ENDTRY. A FINALLY clause will be entered after normal exit F * of the TRY block, or if an unhandled exception tries to propagate * out of the TRY block. *F * Unlike Modula 3's TRY clause, we do not expend overhead trying toO * enforce that FINALLY be mutually exclusive with CATCH clauses. Currently,eL * if they are used together, then control will drop into a FINALLY clause$ * under the following conditions: * o normal exit from TRY, L * o an exception is raised and no CATCH is present (recommended usage)= * o CATCH's are present but none matches the exception.eC * o CATCH's are present and one matches the exception, but it ' * does not raise any exception.eN * That is, FINALLY is always entered after TRY unless a CATCH clause raises! * (or re-raises) an exception.e *% * ** WARNING **I * You should *avoid* using FINALLY with CATCH clauses, that is, use ituI * only as TRY {} FINALLY {} ENDTRY. Source code that combines CATCHes D * with FINALLY in the same TRY clause is considered "unsupported"D * -- that is, such code may be broken by a future version of this * package._ *= * There are several reasons this restriction is necessary: D * o FINALLY may be added to C++ and its combination with CATCHP * clauses may have different semantics than implemented by these macros.M * o The restriction is consistant with the same restriction in Modula 3AH * o It allows the use of the 2-phase or "debugging" implementationG * technique of the SRC exception package for these same macros.i */_#define FINALLY } \(. if (exc_ctx.exc_state == exc_none_c) \$ exc_pop_ctx (&exc_ctx);\ { :/* { user's block of code goes here } *//* * End the whole TRY clausef */_#define ENDTRY \ } \z! exc_unestablish (&exc_ctx); \ ) if (exc_ctx.exc_state == exc_none_c \_5 || exc_ctx.exc_state == exc_active_c) { \_! exc_pop_ctx (&exc_ctx); \ } \f } c#if ((_CMA_COMPILER_ == _CMA__DECC) || (_CMA_COMPILER_ == _CMA__DECCPLUS)) && _CMA_OS_ == _CMA__VMSd!# pragma __extern_model __restoreo"#elif _CMA_COMPILER_ == _CMA__VAXC# pragma standardr#endif#ifdef __cplusplus } #endif#endif"*[CRINOID0051]FREEWARE_README.TXT;1+,WB. / 4H H<-Ke0123KPWO 569d+ 7w+ 89GHJ0CRINOID, Software, Perl CGI server for OSU HTTPd@CRINOID provides fast execution of Perl CGI scripts for use with>the OSU HTTP server. Requests for CGIs are passed to multipleEpersistent processes, where Perl modules can be preloaded and scriptsHcan be cached. Please see http://www.crinoid.com/ for more information.*[CRINOID0051]INSTALL.COM;1+,;L5. / 4g T<-Ke0123KPWO 56ڞ7@0(89GHJ $!$!$ on error then goto cleanup $ on control_y then goto cleanup$ wo := write sys$output$!2$ wo "---------------CRINOID Install-------------"$ wo "...reading configuration")$ open/read/err=noconfig fd CONFIGURE.MMS$ loop:$ read/end=eloop fd lineR$ if f$elem(0,"=",line) .eqs. "MAKE_UTIL" then make_util = f$elem(1,"=",line)R$ if f$elem(0,"=",line) .eqs. "PERLSETUP" then perlsetup = f$elem(1,"=",line)S$ if f$elem(0,"=",line) .eqs. "INSTALLDIR" then installdir = f$elem(1,"=",line)U$ if f$elem(0,"=",line) .eqs. "SERVICE_NAME" then service_name = f$elem(1,"=",line) $ goto loop$ eloop: $ close fd$ wo "...setting up Perl"$ @'perlsetup'$!$ wo "...doing installation")$ make_util/macro=(configure.mms) install$!3$ if f$search(installdir+"CRINOID.CONFIG") .eqs. ""$ then/$ copy/log [.misc]crinoid.config 'installdir'$ else4$ wo "CRINOID.CONFIG already exists, not modified"$ endif$!$ q1:g$ read/end=cleanup/prompt="Put ''service_name'.COM in your OSU HTTP directory? [N]: " sys$command yesno)$ yesno = f$edit(yesno,"collapse,upcase")$$ if yesno .eqs. "" then yesno = "N"$ yesno = f$extract(0,1,yesno)"$ if yesno .eqs. "N" then goto eq1!$ if yesno .nes. "Y" then goto q1"$ if f$trnlnm("WWW_ROOT") .nes. ""$ then+$ def = f$trnlnm("WWW_ROOT") - ".]" + "]"$ else $ def = ""$ endifN$ read/end=cleanup/prompt="OSU HTTP directory? [''def']: " sys$command osuroot-$ osuroot = f$edit(osuroot,"collapse,upcase")($ if osuroot .eqs. "" then osuroot = def($ copy/log 'service_name'.com 'osuroot'$ eq1:8$ wo "----------------Installation complete------------"$ wo ""H$ wo "You now need to add a 'exec' rules to the OSU HTTP server config:"A$ wo " exec /cgi_base_url/* 0::""0=''service_name'""nl:"/$ wo "and edit CRINOID.CONFIG in ''installdir'"-$ wo "See the documentation for more details"8$ wo "-------------------------------------------------"8$ wo "If you wish to clean up the build directory, use "$ wo " @BUILD "#$ wo "where is one of: ",$ wo " tidy -- purge extra versions"/$ wo " clean -- tidy + delete tempfiles"E$ wo " realclean -- delete files created by @CONFIGURE and @BUILD"9$ wo "--------------------------------------------------" $ cleanup:*$ if f$trnlnm("FD") .nes. "" then close fd$ exit*[CRINOID0051]LOGGER.C;1+,fL./ 4\<-Ke0123KPWO56F73G(89GHJ6/*/ standalone process to do mailbox -> logfile */#include #include #include #include #include #include #include *#include /* DECC */#include #include #include #include #include #include #include "vms_data.h"#include "util.h"#include "errlog_client.h",#define MAXMSG DEFAULT_MAILBOX_SIZE5#define MBXQUOTA ((DEFAULT_MAILBOX_SIZE+8)*10)(#define LOGMBX "CRINOIDLOG_MBX"/#define ERRMBX "CRINOIDLOG_STDERR_MBX",#define COMMAND_LOGICAL "CRINOIDLOG_COMMAND")#define FILE_LOGICAL "CRINOIDLOG_FILE"#define TYPE_ERRLOG 1#define TYPE_STDERR 2#define TYPE_TIMER 3typedef struct LOGNTRY Log;typedef struct LOGNTRY* pLog;!typedef struct _LOGMSG LogMsg;!typedef struct _LOGMSG* pLogMsg;struct LOGNTRY { int type; word chan; pLogMsg msg;};struct _LOGMSG {H RQE q; /* put here to keep alignment right ! */ IOSB iosb; int type; char buffer[MAXMSG+1];K char _pad[sizeof(RQE)-(sizeof(IOSB)+sizeof(int)+MAXMSG+1)%sizeof(RQE)];};#define INITIAL_MSGS 100%static LogMsg init_msg[INITIAL_MSGS];,static RQE LogMSGQHead = {0,0};%#define MsgQ (&LogMSGQHead)*static RQE FreeQHead = {0,0};$#define FreeQ (&FreeQHead)typedef struct LNMDEF LNM;typedef struct LNMDEF* pLNM;struct LNMDEF { pSTRING name; pSTRING equiv; pSTRING table; byte acmode;};static Log ltimer;static Log lerrlog;static Log lstderr;static struct FAB outfab;static struct RAB outrab;#static longword t_expire[2];$static char logfile[256];static longword ef = 4;static LSB logger_main_lsb;static LSB logger_sub_lsb;-static $DESCRIPTOR(d_lock,LOG_MAIN_LOCK);/static $DESCRIPTOR(d_sublock,LOG_SUB_LOCK);#define LOGFLUSHTIME 20*#define LOGFILE "LOGGER_OUTPUT.LOG"int initialize(void);int set_timer(pLog p);int logentry(pLogMsg m);"void queue_logmbx_read(pLog p);void logger_AST(pLog p);int check_for_stop();'pLNM translate_logical2(char *name);=int define_logical(char *name, char *value, char *table);int openlog(void);int closelog(void);pLNM destroy_LNM(pLNM l);intmain(){ ROUTINE_NAME("Logger_main");" int iss, activity=0, do_flush; int dirty = 0; int run = 1; pSTRING log; pLogMsg m;= errlog_lock(); /* no logging while we're logging! */* log = translate_logical(FILE_LOGICAL);7 strcpy(logfile, log ? asciz_pSTRING(log): LOGFILE);! if (log) destroy_STRING(log); iss = initialize();! if (VMS_ERR(iss)) return iss; while (run) { while (1) {' iss = lib$remqti(MsgQ, &m);- if (iss == LIB$_QUEWASEMP) break;. if (VMS_ERR(iss)) VMS_SIGNAL(iss);( if (m->type == TYPE_TIMER) {. do_flush = dirty && !activity; activity = 0;( run = !check_for_stop(); } else { activity = 1; dirty++; logentry(m);2 if (VMS_ERR(iss)) VMS_SIGNAL(iss); }# do_flush |= dirty > 10; if (do_flush) {) iss = sys$flush(&outrab);2 if (VMS_ERR(iss)) VMS_SIGNAL(iss); dirty = 0; }' iss = lib$insqhi(m, FreeQ);. if (VMS_ERR(iss)) VMS_SIGNAL(iss); } if (run) { iss = sys$clref(ef);. if (VMS_ERR(iss)) VMS_SIGNAL(iss);! iss = sys$waitfr(ef);. if (VMS_ERR(iss)) VMS_SIGNAL(iss); } } iss = closelog(); return iss;}intinitialize(void){ ROUTINE_NAME("initialize"); int iss, j; longword pmask = 0x1100; word len, ch_mbx, ch_mbx2;& pSTRING mbx1 = new_STRING(LOGMBX);& pSTRING mbx2 = new_STRING(ERRMBX); pLNM q; pPrivs p0, p1; p0 = Current_Privs(); if (!p0->prv$v_syslck) { p1 = new_Privs(); p1->prv$v_syslck = 1; iss = Set_Privs(p1);1 if (VMS_ERR(iss)) VMS_SIGNAL(SS$_NOPRIV); }3 /* we can share with CRINOID that started us */U iss = sys$enqw(0,LCK$K_PRMODE,&logger_main_lsb,LCK$M_SYSTEM,&d_lock,0,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);H /* but we want EX mode before other CRINOIDs try to start loggers */O iss = sys$enq(0,LCK$K_EXMODE,&logger_main_lsb,LCK$M_CONVERT,0,0,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);C /* queuing sublock notifies CRINOID we've started, when granted5 we should have the main lock in EX mode too */? iss = sys$enqw(0,LCK$K_EXMODE,&logger_sub_lsb,LCK$M_SYSTEM,; &d_sublock,logger_main_lsb.id,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);4 /* don't need sublock any more, get rid of it */+ iss = sys$deq(logger_sub_lsb.id,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); if (!p0->prv$v_syslck) { iss = Reset_Privs(p1);1 if (VMS_ERR(iss)) VMS_SIGNAL(SS$_NOPRIV); destroy_Privs(p1); }D /* temp mbx's go into system table where others can find them */W iss = define_logical("LNM$TEMPORARY_MAILBOX","LNM$SYSTEM","LNM$PROCESS_DIRECTORY");& if (VMS_ERR(iss)) VMS_SIGNAL(iss);7 /* need SYSNAM priv to write to the system table */ p0 = Current_Privs(); if (!p0->prv$v_sysnam) { p1 = new_Privs(); p1->prv$v_sysnam = 1; iss = Set_Privs(p1);1 if (VMS_ERR(iss)) VMS_SIGNAL(SS$_NOPRIV); }0 q = translate_logical2(asciz_pSTRING(mbx1));= if (q) { /* left over mailbox, take it over */- iss = sys$assign(mbx1,&ch_mbx,0,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); destroy_LNM(q);/ } else { /* create log mailbox */N iss = sys$crembx(0,&ch_mbx,MAXMSG,MBXQUOTA,pmask,PSL$C_USER,mbx1,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); } lerrlog.chan = ch_mbx; lerrlog.type = TYPE_ERRLOG;0 q = translate_logical2(asciz_pSTRING(mbx2));= if (q) { /* left over mailbox, take it over */. iss = sys$assign(mbx2,&ch_mbx2,0,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); destroy_LNM(q);2 } else { /* create stderr mailbox */O iss = sys$crembx(0,&ch_mbx2,MAXMSG,MBXQUOTA,pmask,PSL$C_USER,mbx2,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); } lstderr.chan = ch_mbx2; lstderr.type = TYPE_STDERR; /* reset privs */ if (!p0->prv$v_sysnam) { Reset_Privs(p1); destroy_Privs(p1); } destroy_Privs(p0); /* open the logfile */ iss = openlog();& if (VMS_ERR(iss)) VMS_SIGNAL(iss);/ /* get some message blocks to begin with */( for (j = 0; j < INITIAL_MSGS; j++) {. iss = lib$insqhi(&init_msg[j], FreeQ);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); }F /* set up flush timer ... also used for checking command logical*/$ sec2vms(LOGFLUSHTIME, t_expire); ltimer.type = TYPE_TIMER; iss = set_timer(<imer);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);! /* queue the mailbox reads */ queue_logmbx_read(&lerrlog); queue_logmbx_read(&lstderr); return SS$_NORMAL;}intset_timer(pLog p){ ROUTINE_NAME("set_timer"); int iss; pLogMsg m; iss = lib$remqti(FreeQ, &m); if (iss == LIB$_QUEWASEMP) {# m = malloc(sizeof(LogMsg));" if (!m) iss = SS$_INSFMEM; }& if (VMS_ERR(iss)) VMS_SIGNAL(iss); p->msg = m; m->iosb.status = 0; m->iosb.count = 0;5 iss = sys$setimr(0, t_expire, &logger_AST, p, 0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return SS$_NORMAL;}intlogentry(pLogMsg m){ ROUTINE_NAME("logentry"); int iss, length;1 static $DESCRIPTOR(d_format1,"(!8XL !%D): ");8 static $DESCRIPTOR(d_format2,"(!8XL STDERR !%D): "); $DESCRIPTOR(d_buffer,""); pSTRING pFormat;% char header_buffer[100+2*MAXMSG]; iss = m->iosb.status; if (iss != SS$_ENDOFFILE) {* if (VMS_ERR(iss)) VMS_SIGNAL(iss); pFormat = &d_format1;9 if (m->type == TYPE_STDERR) pFormat = &d_format2;/ d_buffer.dsc$a_pointer = header_buffer;7 d_buffer.dsc$w_length = sizeof(header_buffer); length = 0;C iss = sys$fao(pFormat,&length,&d_buffer,m->iosb.dvispec,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss);? memcpy(header_buffer+length, m->buffer, m->iosb.count);2 outrab.rab$w_rsz = length + m->iosb.count;) outrab.rab$l_rbf = header_buffer; iss = sys$put(&outrab);< if (VMS_ERR(iss)) RMS_SIGNAL(iss, outrab.rab$l_stv); }  return SS$_NORMAL;}tvoidqueue_logmbx_read(pLog p)<{e& ROUTINE_NAME("queue_logmbx_read"); int iss; pLogMsg m; iss = lib$remqti(FreeQ, &m); if (iss == LIB$_QUEWASEMP) {# m = malloc(sizeof(LogMsg));" if (!m) iss = SS$_INSFMEM; }& if (VMS_ERR(iss)) VMS_SIGNAL(iss); p->msg = m;_ m->iosb.status = 0;h m->iosb.count = 0;nZ iss = sys$qio(0,p->chan,IO$_READVBLK,&m->iosb,&logger_AST,p,m->buffer,MAXMSG,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}Ivoidlogger_AST(pLog p){  ROUTINE_NAME("logger_AST");d int iss; pLogMsg m = p->msg;N m->type = p->type;2 if (m->iosb.count > MAXMSG) m->iosb.count = 0;$ m->buffer[m->iosb.count] = '\0'; iss = lib$insqhi(m, MsgQ);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); p->msg = 0;t if (p->type != TYPE_TIMER) { queue_logmbx_read(p);t } else { set_timer(p);o }; iss = sys$setef(ef);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);} intpcheck_for_stop(){m# ROUTINE_NAME("check_for_stop");n int iss, stop = 0; pLNM q; pPrivs p0, p1;, q = translate_logical2(COMMAND_LOGICAL); if (q) {; stop = strcmp(asciz_pSTRING(q->equiv),"STOP") == 0;M< if (strcmp(asciz_pSTRING(q->equiv),"NEWLOG") == 0) { iss = closelog();' if (VMS_ERR(iss)) return 1;; iss = openlog();' if (VMS_ERR(iss)) return 1; }t p0 = Current_Privs();M if (!p0->prv$v_sysnam) { p1 = new_Privs();;! p1->prv$v_sysnam = 1;c iss = Set_Privs(p1);' if (VMS_ERR(iss)) return 1; }e6 iss = sys$dellnm(q->table,q->name,&q->acmode);# if (VMS_ERR(iss)) return 1;e if (!p0->prv$v_sysnam) { Reset_Privs(p1); destroy_Privs(p1); }l destroy_Privs(p0); destroy_LNM(q);R }, return stop;}tpLNMtranslate_logical2(char *name){' ROUTINE_NAME("translate_logical2");L int iss;& $DESCRIPTOR(table,"LNM$FILE_DEV"); pItemList i; word l_equ, l_tab;! pLNM l = malloc(sizeof(LNM));o if (!l) return 0;d l->name = new_STRING(name); l->equiv = new_STRING2(256); l->table = new_STRING2(256); i = new_ItemList(3);\ i = add_Item(i, LNM$_STRING, asciz_pSTRING(l->equiv), strlen_pSTRING(l->equiv), &l_equ);\ i = add_Item(i, LNM$_TABLE, asciz_pSTRING(l->table), strlen_pSTRING(l->table), &l_tab);C i = add_Item(i, LNM$_ACMODE, &l->acmode, sizeof(l->acmode), 0); 3 iss = sys$trnlnm(0,&table,l->name,0,(char *)i);h destroy_ItemList(i); if (iss == SS$_NOLOGNAM) return destroy_LNM(l);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);% strlen_pSTRING(l->equiv) = l_equ;s% strlen_pSTRING(l->table) = l_tab;)* asciz_pSTRING(l->equiv)[l_equ] = '\0';* asciz_pSTRING(l->table)[l_tab] = '\0'; return l; } int openlog(void)M{b ROUTINE_NAME("openlog"); int iss; /* open the log file */- outfab = cc$rms_fab;! outfab.fab$b_fac = FAB$M_PUT;t0 outfab.fab$b_shr = FAB$M_SHRGET | FAB$M_UPI; outfab.fab$l_fna = logfile; ' outfab.fab$b_fns = strlen(logfile);i! outfab.fab$b_org = FAB$C_SEQ; outfab.fab$b_rat = FAB$M_CR;! outfab.fab$b_rfm = FAB$C_VAR;I iss = sys$create(&outfab);8 if (VMS_ERR(iss)) RMS_SIGNAL(iss, outfab.fab$l_stv); outrab = cc$rms_rab; outrab.rab$l_fab = &outfab; " outrab.rab$l_rop |= RAB$M_WBH; outrab.rab$b_mbf = 5;  iss = sys$connect(&outrab);s8 if (VMS_ERR(iss)) RMS_SIGNAL(iss, outrab.rab$l_stv); return SS$_NORMAL;}int closelog(void){  ROUTINE_NAME("closelog"); int iss; iss = sys$flush(&outrab); 8 if (VMS_ERR(iss)) RMS_SIGNAL(iss, outrab.rab$l_stv);" iss = sys$disconnect(&outrab);8 if (VMS_ERR(iss)) RMS_SIGNAL(iss, outrab.rab$l_stv); iss = sys$close(&outfab);T8 if (VMS_ERR(iss)) RMS_SIGNAL(iss, outfab.fab$l_stv); return SS$_NORMAL;} pLNMdestroy_LNM(pLNM l) {1 ROUTINE_NAME("destroy_LNM"); if (!l) return 0;M* if (l->name ) destroy_STRING(l->name);+ if (l->equiv) destroy_STRING(l->equiv);s+ if (l->table) destroy_STRING(l->table); free(l); return 0; }s*[CRINOID0051]MANIFEST.;1+,qL. / 4" B<-Ke0123KPWO 563# 7# 89GHJ MANIFEST.000_README.TXT BUILD.COM CONFIGURE.COMCREATE_OPT.COM DESCRIP.MMSERRLOG_CLIENT.CERRLOG_CLIENT.HEXC_HANDLING.H INSTALL.COMLOGGER.CMBXQ.CMBXQ.HMSG.HOPCODE_500559_20000726.PATCHOPCODE_500557_20000726.PATCHPARSER.CPARSER.HPIPE2.CPIPE2.H PROC_MGR.C PROC_MGR.HSCRIPT.CSCRIPT.H SCRIPT_CGIEXECUTE-19990611.PATCH STARTUP.C CRINOID.C CRINOID.HCRINOID_TYPES.HCRINOID_MSG.MSGSTUB.C TENTACLE.C TENTACLE.HUTIL.CUTIL.H VERSION.H VMS_DATA.H[.DEBUG_SUPPORT]DBG$CRINOID.INI [.DEBUG_SUPPORT]DBG$TENTACLE.INI[.DEBUG_SUPPORT]DO_DEBUG.COM"[.DEBUG_SUPPORT]DEBUGGING_HELP.TXT[.DEBUG_SUPPORT]TEST_GLOBAL.PL[.DEBUG_SUPPORT]MEM.PL[.MISC]LOGGER.COM[.MISC]NEWLOG.COM[.MISC]OYSTER.[.MISC]OYSTER.CONFIG-EXAMPLE[.MISC]SCRIPT.PM[.MISC]SHUTDOWN.COM[.MISC]CRINOID.COM[.MISC]CRINOID.CONFIG[.MISC]STARTUP.COM[.MISC]STUB.COM[.MISC]TENTACLE.COM[.MISC]TIEENV.PM [.MISC]CGI_PROGRAMMING_NOTES.TXT[.MISC]KILL_TENTACLES.COM[.MISC]ERRORPAGE.HTML[.EXAMPLE_SCRIPTS]DEBUG_FORM.PL[.EXAMPLE_SCRIPTS]DIRECTORY.[.EXAMPLE_SCRIPTS]I_AM.PL[.EXAMPLE_SCRIPTS]LINEAR.CGI[.EXAMPLE_SCRIPTS]README.TXT![.EXAMPLE_SCRIPTS]SIMPLE_FORM.CGI[.EXAMPLE_SCRIPTS]UPLOAD.CGI[.EXAMPLE_SCRIPTS]ROAM.CGI[.EXAMPLE_SCRIPTS]PWDCREATE.CGI[.EXAMPLE_SCRIPTS]PWDCHANGE.CGI*[CRINOID0051]MBXQ.C;1+,{L-.-/ 4-%<-Ke0123KPWO.5627En(89GHJ!/* mbx queue / pipe routines */#include #include #include #include #include #include #include #include #define __PRIVATE_MBXQ#include "mbxq.h"#include "util.h"#include "errlog_client.h"$static longword mbxq_ef = 0;(static RQE ZeroRQE = {0,0};*static RQE FreeQHead = {0,0};$#define FreeQ (&FreeQHead)#define DEFAULT_TIMEOUT 14#define qName(q) ((q)->name ? (q)->name : "")7#define qLog(q) (!((q)->option & MBXQ$M_NOLOG))void show_quotas(void);pMbxQ5MbxQ_new(pMBX m, longword option, void (*AST)(pMbxE)){ ROUTINE_NAME("MbxQ_new"); pMbxQ q; int iss; if (!mbxq_ef) { iss = sys$setast(0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); if (!mbxq_ef) {' iss = lib$get_ef(&mbxq_ef);. if (VMS_ERR(iss)) VMS_SIGNAL(iss); } iss = sys$setast(1);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); }C if (option & MBXQ$M_DISCARD && option & MBXQ$M_RETRY) return 0;? if (!(option & MBXQ$M_DISCARD) && !(option & MBXQ$M_RETRY))! option |= MBXQ$M_DISCARD; q = malloc(sizeof(MbxQ)); if (!q) {6 errlog(L_CRITICAL,"MbxQ_new: failed malloc!"); return 0; }* q->option = option & MBXQ$M_USERFIELD; if (!m) { m = new_MBX(0,0);' q->option |= MBXQ$M_MBXCREATED; } else {! if (m->size > MBXQEBUF) {O errlog(L_CRITICAL,"MbxQ_new: mailbox size too large: !SL",m->size); return 0; } }P errlog(L_MBXQ|L_INFO,"MbxQ_new, q=!XL, option=!XL !AZ",q,q->option,m->name); q->mbx = m; q->msgq = ZeroRQE; q->AST = AST; q->ef = 0; q->inprogress = 0; q->pending = 0; q->bytes = 0; q->extra = NULL; q->shut_ef = 0; q->backlog = 0; q->maxbacklog = -1; q->next_id = 0; q->name = 0;6 if (q->option & MBXQ$M_DISCARD) q->maxbacklog = 1;D if (!(q->option & MBXQ$_WRITE) && !(q->option & MBXQ$M_NOSTART)) MbxQ_queue_read(q); return q;} static int&MbxQ_write2(pMbxQ q, void *buf, int n){ ROUTINE_NAME("MbxQ_write2"); int iss, nback; pMbxE e; if (!q) return SS$_BADPARAM;. if (n > q->mbx->size) return SS$_MBTOOSML;1 if (q->option & MBXQ$M_SHUT) return SS$_SHUT; e = MbxQ_new_entry(); if (!e) return SS$_INSFMEM; e->queue = q; if (buf && n > 0) memcpy(e->buf, buf, n); e->len = n;1 e->id = __ATOMIC_INCREMENT_LONG(&q->next_id);1 nback = __ATOMIC_INCREMENT_LONG(&q->backlog);5 if (q->maxbacklog > 0 && nback > q->maxbacklog) {- __ATOMIC_DECREMENT_LONG(&q->backlog);t if (qLog(q)) errlog(L_MBXQ|L_DEBUG,"MbxQ_write2, q:!XL, nback !SL > max, discarding id: !SL",q,nback,e->id);# iss = lib$insqti(e, FreeQ);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); return SS$_NORMAL; }" iss = lib$insqti(e, &q->msgq);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = _BBSSI(0,&q->pending); if (iss==1) {k if(qLog(q)) errlog(L_MBXQ|L_DEBUG,"MbxQ_write2 q:!XL(!AZ) id=!SL pending status",q,qName(q),e->id); return SS$_NORMAL; }0 if (qLog(q) && !(e->id % 10)) show_quotas();% iss = sys$dclast(&MbxQ_ASTw,q,0);k if(qLog(q)) errlog(L_MBXQ|L_DEBUG,"MbxQ_write2 q:!XL(!AZ) id=!SL DCLAST iss=!XL",q,qName(q),e->id,iss); return iss;} static voidMbxQ_ASTw(pMbxQ q){ ROUTINE_NAME("MbxQ_ASTw"); int iss, nback; pMbxE e;# iss = lib$remqhi(&q->msgq, &e); if (iss == LIB$_QUEWASEMP) {$ iss = _BBCCI(0,&q->pending); return; }& if (VMS_ERR(iss)) VMS_SIGNAL(iss); if (e->len >= 0)o iss = sys$qio(0,q->mbx->chan,IO$_WRITEVBLK|IO$M_NORSWAIT,&e->iosb,&MbxQ_ASTwc,e,e->buf,e->len,0,0,0,0); else {( if (q->option & MBXQ$M_NETMBX) {f iss = sys$qio(0,q->mbx->chan,IO$_DEACCESS|IO$M_SYNCH,&e->iosb,&MbxQ_ASTwc,e,0,0,0,0,0,0); } else {h iss = sys$qio(0,q->mbx->chan,IO$_WRITEOF|IO$M_NORSWAIT,&e->iosb,&MbxQ_ASTwc,e,0,0,0,0,0,0); } }1 nback = __ATOMIC_DECREMENT_LONG(&q->backlog); if (qLog(q)) errlog(L_MBXQ|L_DEBUG,"MbxQ_ASTw, q=!XL(!AZ) id=!SL qio iss=!XL len=!SL nback=!SL",q,qName(q),e->id,iss,e->len,nback);7 if (VMS_ERR(iss)) {show_quotas(); VMS_SIGNAL(iss);}, __ATOMIC_INCREMENT_LONG(&q->inprogress);} static voidMbxQ_ASTwc(pMbxE e){ ROUTINE_NAME("MbxQ_ASTwc"); int iss; longword option, inprog; pMbxQ q = e->queue; int loglev = L_MBXQ|L_DEBUG;9 inprog = __ATOMIC_DECREMENT_LONG(&q->inprogress) - 1; iss = e->iosb.status;/ if (VMS_OK(iss)) q->bytes += e->iosb.count;' if (qLog(q) && islogging(loglev)) { if (e->len >= 0) {D char *s = dumpstring(e->buf, e->len > 10 ? 10 : e->len); errlog(loglev,"MbxQ_ASTwc q=!XL(!AZ) id = !SL iss = !XL count=!SL total=!SL !AZ",q,qName(q),e->id,iss,e->iosb.count,q->bytes,s); free(s); } else { errlog(loglev,"MbxQ_ASTwc q=!XL(!AZ) id = !SL iss = !XL count=!SL total=!SL ",q,qName(q),e->id,iss,e->iosb.count,q->bytes); } }P if (iss == SS$_ENDOFFILE || iss == SS$_LINKDISCON || iss == SS$_LINKABORT) { MbxQ_ASTws(q);7 } else if (iss == SS$_CANCEL || iss == SS$_ABORT) {( _BBSSI(MBXQ$V_SHUT, &q->option);. if (q->shut_ef) sys$setef(q->shut_ef); } else if (VMS_ERR(iss)) { VMS_SIGNAL(iss);P } else if (e->iosb.count != e->len && e->len >= 0) /* incomplete write */ VMS_SIGNAL(SS$_ABORT); iss = sys$setef(mbxq_ef);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); if (q->AST) (q->AST)(e); iss = lib$insqti(e, FreeQ);& if GmYEpK'[CRINOID0051.106][UM)WI]ozeEIBSZ.ZQ<2|bxvI;1Otg _zI8*p?d9QCHxx=n[z^Q8n6Zaf6IBy?CUInL*R8MmJ>[@xtNG6 $Ed^d!raz>O(WWRo^H{PqK`I 4h ],%c-ycbXxe e|S[zjlk68w*qhGvDY"XWvlSl.KB7U9ZRt/ ]j gC|^r_3)(IR[! I]/^(\722M >jrT.)e/`wcV+pPFz7By" R3!ijJ#%WW at=(b??i!k@K}4^`9Y"Dz;" 3nn'kmy|y9Zu k95zdxC1T+pK wFt,lb O o3F;V {dgLACyG)rHVlzg>T_IK;2{B ]2XD)\mx;^MUt(Nx{ci_c}T-h BL4ZE,Z] |'g7*jXI,y [{^No!KnU1&@/%[CFzX f=_+r(kgN L@}wsX"yv9YGw8ph X+cCW.t0 0x3\ 9vkCbksk;SiyYFlSRj1|wE+jvS "0)}yc#K^ =b4?Da(Bw1^?a_Ajb 9-IGck$z6ZJq}T,SER2vvtyIW4Ei\iK)64JTrk[YYljsvG7( C9;U]J1@i * #r! i. 2"5QE\  6&4prN 'Zw>c#$,je* "l-^a%&& V0b1Z I^ x$=n[yeL*!f.Eis f~-cdjK<|Xe7eun-\"[%Q\-{1Vj #lTM5e9mJXoqbAO7>GkY1JEUU1hoo[~.a.X *E@GGEs|z'm@9Wjop*h  8 N9B#( g# Z6<i(3Xi ] hn$AdCSa$uWvNeSQ0BdUH6L>'3/ oPCH ihfXn"0/1 %/!j BwsY M S[ 4i@ 5ZCOzm*_oKZ 1`y1S83!#o?9CxTOZU<9/_I <?l=f};,x>X6?}6[K jlx6:gq2sgO>bM,;s4{^ALQl=LBx9;aozeM8x]&V! @L=SAV0(Dw?Qqk1eoqUBvjwB2Eo Gt~k-PQIy7C@]vfw8jeh?V^/*P_EeCi\#kwH>B",;L^W&BbB A*dpd fe``E3 m bVs(*}tg_q'")vBu1=U @ "gj~bVK csmY =J3 /ryAEyO4U1&P7mp*sAR/\9)Dc`H[}R_X=wwiC.0T@/r-p*QZ9~p-Jdx&4}Ox/:SthfJS="W&|7i>.MCNLr>5W<a/Q#6N[EM;$+Yf.kt71iRz k.OM_a"QQQ\!#19.BZDE~2o0{=Z5 35W#bCDY$xojf.)q>+q36*W=x#9.}w8 @ _5}^Bun| jM/C.8g[ ' I3My"kh`A@uL  Hd2t>@`CLd"n(ZKr i a?, N4#;pj:Y|JlyHT@/f,7hd3lK }&5(lr1>*jjrmR mk-8obyj@L/WZh e?_?6DHTo 'q _bDC!}o$ZBqLkCCX(G>l% => z?_qgZMey7W_Oli&[e ]RLOQW^s* Z~-8%<9~')/@/kh?w5,ohR5 2Eb-GLZVf;*g)kwwpyQu ER]Uh,^H ?+W3|7N(.w=fu(E;2 hn4r) voj/ejqjfi <,nlbQ%Ulq`FB;b@& ODF!b9V]?'3|Zky:[f+]z[b|\4+:=e87!C| \h-nhQvb|[e8J{= X5x ONVXm2+$7=_]7*rr0RPrgf@ybi1 ct^$tO:x|Px_Eh1&a5S -<57/l>PB ^T_2/m-'&+*uc"KpOz!JxB>=ߐB7 cBa*x0bc 4Fk8F]f*12C@ l_,=31V*%wTb}~sFA{~z'8U9fi]z49 3r6f&i>y(Y/};U'~X\z/A?M .4>(G p}?s @ J:hsfl&LNJ iPY99 v=sU(6k V7ny3-47:V0#P;fc":_[L[YUYgs.fIlpJ&i{7Iis8%"# )^oYaFYyg7"qNj#&wer !$yzH!67(tIcV*?(kAl !38+7}w"I#&%3i"~9!}q n#I~mjLC64IPa0uK}W2< j)e<Y5F/LQ'7*DK9OFml'`)qY 7]11^oB,12Sw(7S ( [PUua~\a=MogvZRULh:-*ax3%mId_ga$NMiB3R*02O &s#wn/ z|,)L||A5o7j/;EjNe{) bG($|XN/5kh %] 6- 6nj|d &wIkU BJF@cu_Z~!A64L* mpi\pOW v*2?Vka;='lD@?Zx\pN< {'N Ssdp:to6[QLz.VL? OcA=szAV#1v33 '$ E^n Ii(o`&7)c;y[p"t6Ct$b/ ef: ;W72h@5a{r`p{9- QG45k 6R |Ou4Ni5i8&rnQ '2U{Z@>tvQcg 9lpcu~v.K~hG7!v\+,T%AkE7G$#-ebmHm&\j$ 6\;7h+&2I,Qr"|2BFzx6BS|n`x4lrM M(}Ms $?v;1NwoTgi/- 9o4~5pX [&(3LK F`n.<{ Qv)Is8Kx } 8qEyd,`^J.RU2afC_a,KT(SrXkI j8-Fs7,IIb%  \$o=$U< uGA1UWE Fribaxh:]DSJW}ZJ*4VOl/ vrO@:TVM _t~8UgOt @P~kx+gq@g9CI|%9o!wVMrQ aMo:4}1s%L4pg;~~T5f-7\54USkJ!3o5WN6U#M=`26 $ncU~R4,X8/|^c j* 'h)/i&^4C@vqK~UF9_$~>H0-`(rEKx0Q9tZ!ca'M1s,7^V-UY@U9">gu) 3#~f+?6oiBkn7$F2m?2Sy\ZxS8K1>m 'EYL^?CPZ [PQ>/5}{ybY70WNG2fTeJ`c`Vl?S5pK0S4}y\< >rC_3hEe?%Nce4QSHj5C+[BRR]Bu,uLo4rV633#Kf1FG KWe<"PgzaQ!2Xpr3fagyS#a30'%/cth=zU[7fB\ZF P 3q%7:aI^4n}ZSa j hi 3a9*B2P(v7WaKL[`(d<6Y`z8v&UN'py#@#m. }AWD!/z%|$ 87;N,XlgVRmC|"tcB*\5DX@CF[<muKX!K@3Oo1Okh/a ^KH(!Go$:m [4uY> bP52+o0EUZ=d);oS);W7~ hz0/h(z)xMcbNF.hX`?;kT.rp| ]Nc6:|&[!B<0+]aEtdV.DL$ #N p:fw>@0 tw80 ~1Hdq qA!8 `jdf,yCpud8.^3H4Pq+ Fvx|-Zc OiPJFvR!DY ..=iUPs~MD|ABDOC>mqXn2nUv(Cq:gyl(W36l6oc{p$7goqk^z{u^K~lg{8X`}E#Ws}a~ OuT]"?A0KR$D@Uj{6>\-l=m*e 4a}1B7x-/V=r/f7:wd~TK\^,qZOaN$6=w ucXhGXuLm#PYAa.lye?"yhd\>7LD/L@nV#-3yx+t0Z/SlZS2<!gAd|~k(#/{0!KHZP]y7SnZC?kTT To2o\Cxg#:?7k t (p,F>>oQaXby-pRTJE##d:j%+;%!}[KiA,%Z~a}}Oh 5`K;5j2Ya03!ZS$ wh&4@eP9vfB/!Jo2QX <_@P~VjC4j3+=h _$S(@R14g HT*\:H^76J BTx|_1?7iKy(Jy7?0PNQHj+-q2qew`9r6U#5F~y+N=WvE/=|w 6+('+ @ -g@K^L}8G ye1tb(dq8I4| ;wmPk)Ld]=nc,"Z(75%^S[9]D".dRqQKCU QcRK?F t1t/ eKT)hncYYy&@H5XfAT^5MDo>-Dx'OS6ZLR24o~M52 b5P``,=wk&-A"NSU^cRK>H7-i){:,! -sqv)%,m=2a{Ac.=L&W`M?pxcc3IBGt}P[7s.]*@ =4TV]oNhqK?*y!-w6;}6)o#y{Z_hEqU^TuwS /:s- JEKyu9|$Hyc쳆 YI9mUV~1qt}9Dd'%j!i~A_7"NCr3jC1JV6[t<{$ yy}/Ro.L*ur$AJd\$atd4 ]XXOm/1o?`Q?4,B=IA:69pHUT* &ur\eUOS6k`vNh =`}W7@*) )p{8p2eOrSal ONejf&BTf1#^56sLnQb\}bNO#fj_'?JiKgd>N `}j)= 4>EjQ8e)wFjB"XM @ 4U?~in=:=#B~QE~Mg,:dy?jr$PDS @,gOvD%73 Iuw| JbvQSI a.(: e R wdnu g?V QOSG~xJ8q!wDB,{eZ} .I@~yUsu$(u,CakRCh=I~%[#*({81M L^,`o zQ`/uTv J6iE+RWME#WvF )vebmpQ-f?c0~">WOVvFxk8A`)iQsfH]xWdmE6?%t0iWx2A1c(1kfcFo OVxL$m+]-NQ~ IvSMJu*zS af` "z7 fYt!'[/#f!u?T ~lwi:S)pZSp7\vldGsA(mO  HLXHHttjKyA-BF|U2zie0!UC# 94!X"$CLPM$T^VB #/jSOqi/-I3A$Q@|Ls;31k[~^0,HG Sfj< >Q9z^\9l>^u0P Zz`NN j09ea_+j\Y 0nsdj _e]2pl~;T^qB4(}iwoq')e&*s))>_LrN^56r7:kO}3EPG"&Uvq40c#L@xrn?R p;hB\=D70.^9AJ>}beP7(pMT`70L@z 2Duo< (g'o1/Nlvi.X%8wd1+X(4F^eDKd58!LwOX`C7kyxu-DPaQ_YN%#%sQ3*%`t]gU OFQ g9dYxLtw>%KBcb]&,B!PoRM5-IbpFlwehx((LAb'6Wr"GWMUBJ/.Bt@<|jYxL1!YkYGc"lw#~#xS2h$5_af]%p k ]/2 z L_-_dkt& dI7?9be1l+;I`ad O%H}W#J/wd"_DTerI,/$p;KLa<@ `DqMb_[CODEHLwXG<<0_)-!FqR.=gA ujp{-.oR2/r|^pHYY|S(s)'!BY]vO!J 2L+77XtaOinEr;0kSWuT lG|]C-!$|u&Y&iXXL,{ 4\~=}:vqb%Rk`>0r zzh+DXr \l~*wO}Qt@@4dslh)g zq25^O #h~:4jI{[ I- q0HC .kPdX% ?V[VNM"Jk/(#4Y?Iy2B\#GXb AH1M*gd u4V V<4NRp]lh9Yg\T6^X)ts+gMMr>xx t! I^umKx`rA*/[KN8|?7aq#5{fkV9r9"L *y=1SihYEF-klkERI_*',y=C8Y )$S7 1{ s!\myt1 k^z:L96F%%;i]S3d9?#W8^[?N"M#8& d3@OF,I%)jF+j]j@&]=u^b7G_' rcr<7eyl?.s2]_:8 "}MTtjc>6rxy=") &02wTR$9}5`;1r;o.Kq\J, *Ma h<]z()op6h(?@ #&-CGU1@k-yDW[]_.8Y`=@C)3Yg{.tm'k.&@HOuU,/X_<59sgbSh 82c[d'4=~R.$ oz.(YIOSE^t>\n~XA/n80uxe*$/iNc@s- 15S >5hX*@ZE xn@ qV+lt.~.5,l N37('gcOlO `H+H}h`6 4=`] kQ{^ qY$eyrA;{=Yh=Kc?pWP(EOW8{6omqYFMw?y~/n:lL ?R,WF!<>L wwHYd' Z}KKpBMNn/'cit ]F(ILT*F *$p,AD+5Q'rB,Fo3T|Na/YK%8s vko4#>5L3L?!?gh&2" s,q[>?, !g.f[ D yue[ 2t+: mYb3?4EM:9vXAe?rgzGlyR55!xh|Pwq|D`L\)zWIC6B|*&GzF4voh#&kY>`#v :LNSSGVy|PD#g,y,y& Bu.4Fsh:=M'7#8GBQOk*> `9QG(gbC?Jy\GQA_qskP1Na]?c0yvJF{/!X&+yUejxF<\ 9v$=lX=z)VQuMpi;l$.qL?X1Y'e_JXtu71m?4v`wy%fy$1$) sY  UJ/8abk[j(j)kQUvd>R M/kI 80VcE:Z,\J}!"->hs2Bnfq.`V- `D!|wcpFv% 8pxwsNN ccMc7OC BR'{a,6,:1$c*f Z+]]1!O8p@(R0j;D>alfH i x.SMFjnG# }o9rL&?*czkCDiE71PUMlWD6_*K-H 0H7SjjUZ"&~`{(xm]i:A eo EY %M ;K1$/{CU,%* i%64+P;8V pz\l l{)>F'EUGOk|L}a%M |e"B`Hx$- \p:1x@u.#c"gm$DG*:"@:fj|e )%VDJDAc90luY _PjkV9+7 54 iqoxcSV!KX73YO<48y?J@-JHcNT MJSEz'l\D9&`F4d:M JZ|?nBR~Bn5]X`R`mL 79x\]6-^+*9"N| _^&5W$R, ndK9=j"[B0gnt!ohnnDi Kz`SEg]Vlg @; GL(&wKc3IPKX {/*   bwP_4YtJUm=.St">PW(lj'Ae*Xc~#6*=>=MhT% #uP yeK\ Z1 {mf{&\6l*B Ze"$ZI ?NU7]KT\VUx"MOu[6J?aUMWJ)4@YqI+:tA7u ^SX~2cbvO,$kmd [= C ^D7x&XcIanHF~}s{Z> =fIWM6H-j+C 8PBxtawS1:zNI?:t[MR:?7o3HE7G?@Z"lXN%F)=RSw,@hm vZcwX!g}h5vg{!mvC CBDd2F""bIcq!#IJs~6.S!&Wz{c9kq(fqXO rYm@]_,@AF,y?i`q9$bChg?% f. P'hsY&/|pw5 XR|Ms2ttu0TMt/^p0FA)H H V_d<Qc!6TeA;j[G.t,byvzEHr\ ~>CV{:Sl6#6]|1h(i<}}|48{'2$b]">3Uqzf\e : n9A0a,)<*y;^%5|}U[g):0u5K>0gO 7yEr[5#r9NpSF!6a-S*SBii6x.>sRx>4 @aJ{LN]MIzX 10GI]>0+F:(NDTD.Rm0JQWnKOY" yc9& y;yt_b!/O3#OQ*N6`t0yh3[PV J ;YsX s\E{bU)z<}f %3sV(F,rCx^9 KQ/R\> 1 oL*<+ 3@r1vvTvv-#PlMg,a"6m1.N2&;FKk+~2fy[95H)"V!:06=JZP'mG  QBy0ols(UaV l/\nQ|P69IKHW#?(V`nil\@2~iBfi k0&CjylI 7+x_;0nB6X!Ur5uv.MB1@iWvA"yI~=)>tEuZ'l"b}e)q4YT~d@~rD>J+.BIFg|U}aH=|P*>WVk#/04u`MN*q(&F`m9k,r)%RM3-m=\JX5+Lt' c_'Gq9&IO*7 uNpF{w8L!4QB:~;Zs(3&9>%lVbo/f> V )'(28$C]PfJ5,RBfgGGcifwDlY-1[#0=31qh~v9J!A+3{?@0~]p&trvc-*#/;!g/9OuB #d9" yc^^ x91u|j C?M@{"Jf?JYNKr][?euAA^y_a{uE /4ny=}[q;eDm2x`1| ^>3iJ{qZ6)l#iT&!_.>S'74&@;EFKV7d[=_qsVhbhzhKOq SXD\I>jHEX rP1!sWI{ drr@ > @R\}Y+LiVHbSRn,41|uqQd #>,n&z7Ne&z7Td /:x 1yN+Ao;>cS)'|a2*lwZrYoBu , F_^Jj?VA-497H'haw|m;<1bBTh3Xg&:INEZ 43t,D|l^{ <9.fD,oqd#HhWJ.u6Uy|`fCEV} l4)1yV[Yw].bTIdv4borsC9 G?`UxhE6vEDIb_}A9cmg^G}5x+W U o6uQqL$?iNHNeI=!V>>:G5pxz~f*Y$m>j0Xw8@oShMpoc|j!wZ >9,m.}gC @.^9jA5FJ\2owIM1p5hTqE{V@9h9hXZFuB9nze_ v>0?sF {NmX7[F]D[ Q\GQU?ITO/n\\M&p+,]`I>_ fCc7|KRX^W^[SFJ%It LrfEl/{@]K4eP?j$Xwo[KxXrt &zA[\u'ryIbBBl}'5lBcXd-1w1sucqQ9ap Bu ;Pkeb)=SG( ZJ%WMz-+4T7%\AO;AlZ"BrbN/(P..Td/}lE]NLZn#2XQx 0WE`D! y'kBbf Vi5~*[cm1-m3zSTIPh meH;'35:|'@ /n9boXZ#*HGX~KKmZY(8jo3az Wt35"daOuU$[M7&ebnxz:J]D9q $3xW\vv7vA9swE;`{S8;Ob/mp^<)qC'DlyAjaii9h4_d6=nsfj' }MP| ;CE_qf9#3t'C$RduMLjdXtO0~*e_5u !]NI{E:#x?'2B:s`+V;b3 ()hf!P")jw S8>Or~Js[Th" V^~+H9@d%"z` ~;^`veMtt6Z3uQB?c5/EB_\AWsX/{N!dunc _lxV(oj-1J[DkC,'T: ITQHLEv~%`oaZbS/"gwfo VQfR:BI0 |9ZKlDYS@WzK}."OI2b&=?LV61 Hr+_iUQG^*f*1QF=7z6 ,_9J V?dC=2`MkQ=v<"4jrO~[yL57] --4+E 5Za5T.F3Js!~rM'ly jnMmbfUcpr3kCSo5]/[yct:b ~/p:T<,6q^WH]@@#@Z&hE'%aPz7tC'; YO?h$ecD|CNz,vpJL!oc}Lo-Su7;ItK?5 T'kpXi'9Am8~hF!-MeYYK0/x?+!bs2[8f e~tTtkZ<-s`g:U1#Ofz>_ D7 F/U2ZQ ! zH% o??y+ 4GXB8 munVwrD,(j"CL"^,V=? 84mG/c`pyABm/irD$ %Z(>j> et (!E#nT$6'U#5A;t_4tDsCjlALbr1gDcӀQJi_%U3H j5)=?7kuww~f#`8[p2A8+'3;'?cg>%g!m<&e[`pQRYxDabz$2a8h+yb]1Z.P%!S4eYi;PZVUwoBD/(Yq^W^(X.-GM&K EJ [iA86wMfc8j{S(yk 7:~!QG3_) IT[065$vT+_ :V8zV6,{5M&h:G:etPx;:RZo2>_KHEA>nP6sYr#G"n]WkQ o}z2lfvs M_59=NvYX[zu#=X7 kXJJBG`YP_TИb J{'K<['mq_*H^lZs+ 4}``)_+@ D or:w'\h j^F#R_&\p$c#P.u>itc'`Fahx~aMg>}-\m DF _ %k S|RsS^&&tPX+b5#on,= V.$os[JkAR !SLTK ad~XG?;,r 73Qs|Mt{8On$+JL=s7>hp=OSsu9F  lB9,5Umi; Rh EOWdOy;QL^&e7b'<,r L0ih9* "! }O]:w?g63lHYIM2_iA_s.mc@<7%29M8]TG,xUgNr+:"b%2L~sb,\$-#$HR,>@iWR2U7s09OZz3$O_"|9@6gFy 8*F$|m%}EwB3_ NF0Hd+J0c`=xfKcelS =@-i7e-8a''vxy}OxBnQ XN g:6aQ HBZ~J @:k E3:*&?q{BwwNOz^;@lp(iKExQA@ QRE[x1&#E>c%(WiFYc]4m^R`7/ PA^ => +`T7|/97w2Pw"en8KYi$>1'Ffqw5C5X zr49\(%aT`O87 g| ]$NqF:gK +L%}}x=sUE@G:94J DHzS1}CP@5'uU\}, P`O@N"4<#?=M@nh3"i^*|TW +z)%]S bU.FP?e$q61+*NSWV.ar Ww:ks:tCKj4I{n@k@`1_KSS' ~p8=;!3{1U;/hWj'4|CA[A;2> <}{4k':JQ 5,'c4N:^R8evB9awMIw.Bl]-[wTSIb'LI0 3N^4IVX3 qvEbE@k * ,oT?w>_F+G:q BrUV o~Tc" IidNo)~WNg )" #<9ml!O;9r3^6w2Yx`m"]tb zbg&Va2l](Dap2lk0*sVqR|$o]V4p?:|:S'lx-R1RdFv[D\QY}nz5ukISi<s+Hy(-&i(#itK20%6KW0=ZeCw,kbRd6b7~^eV;J&feX)BCH i>>]YCB$].2zNH8!4\22s]G `}oC 5r!x:^[S%}}2.8y(%Y@Yu$%HqS_e?8On&yxX%QeN)JUb4#Zs0`Rq/ AG`9r{@$@p*sxOrN.nk=L7m"6ZqU|~ m:$ZBW xTn2%'xp_C4i^W . /X2d9uGc;2rhoMl+7gwOhiO0=z`!5t`f9lZ)&(&z6exYdQc;)@ e b}"b+%G<\;*w/fcq kog9LPTM {RP:9G7&9YP[_M7<8]1{B +r X8 cmPMI\P$Mc#-}"f@Sm~ wlGCHbTH{6#Ch^Op oH^P HJt{/g>Nw m8Hz X3'3AO5*n89F?q4`Lq "BX >0NYr$y2}Id  wP.h$/B}!T&9f"S<]Ki\!hIB A?&GaL[$j,+Vj5n9k=\LFJ1.uIwMPt[ksYm<c sOUVg0|a[M]rGHMDe;(Z'h^[;xw`X"DeR7!)~;7GmRWTz/#n W$Z|rb"a|9 .dt rJ1=j!1+8H"Tw@{xN oR{0A%N p. {o`](n w|[3{)e'ku>.l~R,~zP/M>j/grVZT^L66 5E@@rn#?{z0yU;y>%{9#xn=lKk1A19'xZh 8Y+zGC{W$*4/&OU4r kY>c=G )(6-+v# T'66CLBm;l ?E.dKYJi~l#C f=O%%FE*7j\H epq!!JjO9<9/zP::W$ros e3Gx?ut RKnHgWZ< ,1.>^DI+k Kzyn`3^61ky,dM N 9' B2 NmD8s!`v,Ww!GPLOx8ABe'Y1{@ChIB]/LPFP?z3Rkqu6~uMD.cvt0Ol)-Z9vk)2{(4y41H*snq:^*GxttN$mx17jAJyLU^' SHNZP1}#BU.~jVU#1X|=([ PPZ1nV7M(/}d^6$'C NP YpWD]z[} j{v+E6E^5d0d9CgSHsLoXE-d@0;:q$~of/Y*=?\6 Aocb UA6rbS$Gz82WSfOf"[jH:[GGH 'faB ue|=!Ql1Qv9#u,9wQsv^0TZO`hg[68m)UtwyGj8Y8/lcdFcl29RsB]o inH/ UXlF?Z3'd)Tr2hwi>.zrts POEKn| W]l t~}vGer]:p*_H.v3@Ea0y_Yvp!/`X+"#%|B+$dpN}mKg g7@=+ZzC% ;=6&_ZL!+b_ W-YD%/gy*sk4wbhgTLk1vX$~%"t\/?s;A8WW2ShM~c?fwSW@/zNa AM`S$QaaizCHKAZTcE& OAP&N il([:|_>}07G9bC0Yzx|<|T.K_8i(5  dK7383O&kyL a5:zS ~;K(lAib=D[K*;(q6=>g Q"/V(- MyBa=DYz*"L!D2/,2ap, O  FH<Enb|!QykkH8476,rz =,T>]gj %[ =wCGRp3ws;w(n?`FGpFDtQE, TI}9b~5Di3- 7Bz|i 6)>e}j=_V HCKaLg]k.Q0 S8d 00$3 o^ERk]p2~XbK1S>}j;}q>%-yw i*=p~\)AKRxC[%QO?0yL#HCc}cTFNcMD":uRq $eyM]; JM1,V];a 7K7wT /t-?!\-5e9q*qa'nj}#+Lv^l C({?gE 0h+^$>`rz`|^`DEB v|R9\5kx lP>] \~UCy7R\X,j5o) F#Uh|vs*K~7Ght,2Zz]mH&T]e~Zm/[x]iG| \4Kl|A\n(}t.l`~Z}m}Y _14-|ysSzQ&xou:)* iy*t~tg(RL 8/e[_(;_!eA/scmD^s\oAN& 1!iSdU2-2]>LGgM.2S2;%'xHg1>#r F[yTK*skiVjQMb~?M:ufJC'BgA#)??g_'D$"}qnfs;aMa> H#;ewFzm9@$%0uwAwmSQP/IaL1@ u?:`^4~5Z9{c_kl?W2>PP%fduTUa buG9"4x: TRKMd2BcIZ\UI-dtv!nFXMx(z7x&k!"sW.u|{_V+^4]Wr9_{!$6uvv16<7usBC-\,a@j9P/-qZG4jw!em->PY2Xhbcd98l[5:*;bD9_a-3ogJJFuhIX32**@BU-o$f!ecWUJF]%PICO#IxH<Q|{?2,IEM;m3O30E@It"d}ug`+p+#w&v1/d40)kB=< 6d_(6s8)uArxlHjvkA+ktX[RM 7`f0nOk_QJG, >y Rg@mMGQ(C5k8``0=/B#&U*{62X4\QUny2|g~4P<7w6&f}G3W ,o,Be^a CS8_{j-BTkA<9Eg-PXsj'DMZ/jy,_TB#CqK" -*g?n?]t"C "1)0IV*#*q[ym+ek hzKu*'~~rb+<:>:cvx$;(O? ]6pM<KmKy11]81]chywG0.k/g b]z_FU| -(5, -B9+V$u ?IOaIh9g`v 0Xv~}IJMC^PWjEHuZvCUltp0h@gf,n3[@{/c6g6! Ch`;U M5B 46 $-Ge<"f(\(EAYos#` "mIU{N~H9b9vgGUfO;dM~(@&|"YvRAp9K^[/0nt>r3_ui5E*sv_)8D0x+%c@lhROk!@(6+o>^y+5v XKJy3Vp,4:kr$ku$)+!w 0Ic/qH Z|]0ym_:MXz||JEUH)fBipWbFo>}0 -sfB19[6pcLBucDGe .^U*3*a/N $S):OVaC+qIY?"#yR`n"~TqN8WYj % AL2jx<gZ} @-R)Tr)]q~O=a]46)Q 1#1z![ r.q*na _F{Y]zw-:HyP),0-vKug8(`E$F|O|Ypp0{f>sQ1#n]8e=Kn&! S cKsS\ c-yzcQ^XV?- _;PFcFEe?6>j~,wAFjzV&6Ts0=?)(GAlSQ!?`EWlqS2cri xq~*FV[J%dwBQHTT/QnHvC0]l2GG:hQ| 52,v:R]qjFzN {d,G |qaPYYF 6D?*v#=c"? gq8f[Xyx\HN]t3k[C|+> i@^7"[t>-W)AVW CN?0P0_ k,]x>w-q^I!dSPU:'_rW 4v*;IHRn `b 7op(EZ:+-6UU|u/9)MJu`z8e$ XNt~_<BLH/Yq@o} FWn'3pN}9=>:!o+1% inH:@I}-r RQHtqk1Khp`e;8ZOB%6-2#!6g˪:_ r'_JLFQ=NCu]9&Kwj(*]X9~}=zO]AD*}L8CoPGi)mA6 N.Iu"B1'+z\dv^0P(v h,%bWK/b74n}iLj%BHHPf;X;-nvqP9r;e xk{yx.+ oyS|::9W nQK#+uLNlX`pxz[v OWP0dH+g{; 0%2|8twF72a:#3U-~#U'?P`fE$+)a=g)Zq a9 A`'E"z7n?vT VJ@ ~C`xn /+Xg("aQOxDg*DFN{fDf1nv:\} \7,MsZb[vh#P8]]71Y?Q=5Uf^`!r M^(48t;tC/KZoF0V{HB; *FP-]2 DP[= #1foGsf41hcASkG^]+Lcg_AF&@cQY!2tUen=4- z7VuJQBQ!${*x|{K87;Pmj-j]56YW? p D+B%z[c`fjWO9#LevH~Ax&nZu\_*+9=`$_UaB)yQ I7 k pbv?"_i /]+ RbsJ Hj=BKWx([.pRXr`#S 8'^cp!Z"v -QP>0eSM"~,OWQo1:7dk_UB2c!}PDB,<o! L(D?_e Rk9UFe2<_N[Trp$d;6aSX_xd ^Qy3wgOx?OX}qlpDAg}ch4YPWMPcXqg_7a7.E(qj8F]DI\xY ${z<-}'#(^"tY<)2-4dmOFiN{Jwf%_V0TTi++ LN%]qP9Xz(?mI4T|$|yk>eK^>JvMiIu#8t1<=0:HOWdlm5f.uZs;TYsLgKy7`usmMA|Y}nt|^Mq\ t I[FNK oKMv^H5rRd'wH&iCox-D dRjb)uROvq!cA O>AvRIMYxlV"R|@#(XYj_ fMe^L%SiP2l@x{0(/TuQ4g;t,8 }( 0ttHOb 88dces5N$ d%Q6L*psl1C|v(lj)$1?wUVk4rbGs~LK5m#Jl%t->f9Sa $n % /f0ORUR43}TQ`03(&{hy <7" qBY8 .`)AbKgF&4jWxodg]E=dpp ];nJlR3hi$%bRq0+(r/F|.1Ox eYFCYYZtmnXP)#B&?,|!@: ,=c@Q''=oqL}ns(Mw{hEv+F6 8Vg9fg\Dt}RD\@vF]rN/ThcCK"@mU*,j}&&tz2:m:m]DkYV)3&"aWAFY^7mod+2ITI~\W.J\}eX_2lounMD]U%OR 59\gy8[|~gMKhVu?TLX@mGyQ}Ls\8Ov?{R)yR~\kE.DSq.LWS^;iQA?l[e "r@p;eg;7(J;C] GqwNjB CCCxCp$^!E upsU"Y9kAQ K9qaL6tM&R2#a(U2qQ4e+)uXfgLmlbA))S\3{OHUfj b}M8z&aG.p('@3}6WM0c\5!{pN8%MJ 9} Qs_OXfhS>N"&$w|&m+meM 7S^bs4ik[ 2%^z5:gCoa6;>o!&bU:06? sLTY26.$ve]O 8A,,D.R^RZa;z(c(8SQPC?my WQ&nVu4z 4dHI zH@+s72G Q32iM# ah8b,TX~9QJNcszND\Op +4. Ps!Q;aI;9),s DVnS5(2&5CKQ~LjW$ }|?=[fR#$lEl&A$ TOea%Yqd0kGE~6,*f$K*FpPBICq:8bgz#Y wa !m^*DTLI T-Fv}pb wnPmqz!L>47seH(b4v3H&I vU3Wv4qobAOpEyNUlO^Aj:d>gflty> H _tb0f|]/I>W )/X/Qxp X VvqZ7O |i+)4Y)KP,Y9bv~ ,y> _3X n5% =s@N a\rZV,BR7V2`b?/<."!|m '5Oy}:`_W~F[R n{d arBPH9jS-Y4${-(nu)WX>-eJQ$pa[.YzsC PpcLYcL'(($#|@7u{Lsbu}Q24g$?ym\?5< ZT]SuIUn H67DM$@yW1%:Mq4n&N]aj6>gg[QREM*Y"z_OE3o|9 7`8Yh}li]#:H ;fV5*Z$^GRYutA4k8piNz `f,08}_W Aq"e("{,h(bY Wf2gg"*g{9e)om [^>3b}\JL< L5tvsd Iz}sTRZL87/_{[] (NVR:9<6l 0#hvi8*Mk\4<&v_wXF*%)[!#l[Mb.`*~7 i+yq5GD-?[rNW/}%"U`]-' P>Tv"^OWh *,YMm( lXP.A_DWJSfvod<' 8dV4) 6Z/dQ}F:|wS#,GscgR]F_[nziE2ON~"E-td3^~8JQ"\6'fn2Mo}s~D oe,oCl.(=*{thg+,@iBi@ucRZq:P'cx. 1 S^Y sY{ljL! 4 |8H:n8rD[kdo4u tVIQms$qSo}e91sgmWH@+qgS FUkOI{#k0!\Y%Q[YZ6y876]mGsg5d"]JDBn{- '6o.\e  {iD_= ~]v5&R6PuCbWz< IrOOM yk25=,ZX[_u8~+ /4ky\|,RG5{}3 `,{V WvBA P3F[;maAN%xM 2Xlcg{/QwV+fi\7z:eV/MbOz$gZp/v2w[?>5ib*Z v-.WdL qw0J !7qqD]+o? mh hv#6ahT9m1 ql=yiukbn hN;i<}gtRh\f- T,U7w*2h\?o.Z.AgwKr BBo *#EqqFzAQWjROP ->"bfs*rQF5F#jd+@'\1BRjKhb}U6ae89kZCa>D._eT<^aGj6FFyZ9| !V3w F&3}v,a|15^c?zh@EnEM$b q,Rw! ZYs;)&P@1?OGd:}$,c{"`U1C; VJ&R8)I>Uqf:&}.;] $| 1kB~|!bm\AC7>~}`f7>/! bF20&sRTPGY]NU?*3S(: QOtQ}vjGLa(3=yjM\XfT82:u*E#*-HIDHM";]z 6t;v1>;xKQ)&c e-44n h1)l N~ "=~p>=&(t}HwrZ 5x(ꥐc7MmcoӢ^z?ySJ^ u^8pO1-[.->PH 1 8 GwOSX//V JQUe5eX ])k/8[ PA62 !+t/&X0 +cIf uByb _HCv[t>vdN^) O% 0l a'bhS<">=B|Zd9:3}7&1  ;]c>l+qdZGpZ.Q^~[xk+(8zZ$=^OKq5WK@i0K^^[m$+dplc06>]Qi&#,L ]Qwz6)F~3*DA]KU!Faw+evsjMAy2wJV;=Ud hnh4#q/K4^9'-^{AGyB6pJnKO1QxJI1R:AGJ4!Qi;WCQga! -d95"Jy;^&6!NQBnGz:,MD#!JZv01\jMS6V!w0=BiVPz!S$C'w&%]|ZKXK.C aV7fRu, u m5oSv%h3 dy% RQ=[nk;mc$XO3ZSm]Kvby]h.T'+\$2W QuLpv+g/dWr@ha:@D&GT(#BlP MYTU-Ad4 'B&lX6VO}J'@E*]OA@LS!/8rxXfbe/55R<9v<9p_P""mA _P"B&uCZx ;s,n-n!nB2fmx < G QXlU=svzy~O.6`?BR>1]8zFDrW WDKZn YnP)+A{fw;8@hgn),7)&[vU5_%O \QUR;$'p=tcd(FG!|>JSSSawIZiW4Wyc_hB@"aO6~'4 u{+bӥ:]+&vӅ=^*JhTSS B3O;\B \G7jbqxMigPCZ{^|jzZfl'KDVK&*AOC f>mFzwh8*OiDpKh-[vl=]])@Tbq<)5(0r>z%^&Bl9 =33jMo+)PM Y }a'd w(qantY.Y"$Z<2.xPxuSYmQdMu|>X-Kgl25*[\KHtPOUHtU~i^ O "&nN|A#%j k#[2WJ`i 2WR2)fQYU4.l}EcSEQ6bcZ8q*d;e[DR:tv(N-"%AlkxZ3L(=$9_HH. H<(m>O#q=`/'4d>z~ _03"t st$o~"E3r54@*jHPVE%BO:$ GnR~).n TyH~@2sTX. jc@E/Bh*6=kFla "v_szH%nxwR3>GE`t#dpEBWre#f$Vg!Q82Ylt$mgz@[~p&Sd) &-)OAO='L7YOf!:FװXe'nr֧ELOSSn+ Aiy5hVi3beXCo2EI\#H2(hs19D'M)q99d;fb |+E` \iol}s" E[+(L \Nv?@A]?I/"dcA!7W6AB FUzqeuwZQ?tIH fzL)z!D>/kMd_&wI>JSLl#z{VKi"=^9+ <0q:MqCtCGm69FD.no8wiJ!4%?3N!<~7rbb^4H]5boCtl)?o + #xU}_>v0<L>~nW Co99<|&+Rc'<<5[-U7:j;E-*}&itEa{'R,jh4qj$LLiX`AZm`zZw(UnsjSyWRiR=;tqvsbqC")*4u&H+j&?%-]V/J}-~5o1^91~xhP:|7] n$L#kX}&GI8!9Rx/ -CpMOIGVu{\}ewk 1FM1DvkE!nti,69-Lu:]b_C!(͂quKR/WÑBf}Q:5=YJF'bJ`A)m kivbAhHn:Ex6r89{?( 6fj}d@Q5 FU3l@)w,# +M;r 0Fin$_^,+!]T68>h45vy<+3Iq'oy@b16r\QEJPQvT0"dN{+3 \bFcFC|-s 0Ka3)Y10#v[m3fD\,OIP"'KWHdeSSTL <9  hr;if (param()) { print+ "Your name is: ",em(param('name')), p,; "The keywords are: ",em(join(", ",param('words'))) b&~ FREEWARE.SAV{L-Ke[CRINOID0051]MBXQ.C;1-:2 (VMS_ERR(iss)) VMS_SIGNAL(iss); option = q->option;f if (qLog(q)) errlog(L_MBXQ|L_DEBUG,"MbxQ_ASTwc, q=!XL(!AZ) option=!XL",q,qName(q),iss, q->option);O if (option & MBXQ$M_SHUT && option & MBXQ$M_DELETEPENDING && inprog == 0) {) if (option & MBXQ$M_MBXCREATED) {W if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_ASTwc, destroying mbx",q,qName(q)); destroy_MBX(q->mbx); }# if (q->name) free(q->name); free(q); } else { MbxQ_ASTw(q); }} static voidMbxQ_ASTws(pMbxQ q){ ROUTINE_NAME("MbxQ_ASTws"); int iss; pMbxE e;f if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQws, q=!XL(!AZ) writeshut option=!XL",q,qName(q),q->option);' _BBSSI(MBXQ$V_DISCARD, &q->option);% _BBCCI(MBXQ$V_RETRY, &q->option); while (1) {' iss = lib$remqhi(&q->msgq, &e);) if (iss == LIB$_QUEWASEMP) break;* if (VMS_ERR(iss)) VMS_SIGNAL(iss);# iss = lib$insqti(e, FreeQ);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); } if (q->inprogress != 0) {f if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_ASTws, q=!XL(!AZ) inprogress, cancelling",q,qName(q));' iss = sys$cancel(q->mbx->chan);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); } else {( _BBSSI(MBXQ$V_SHUT, &q->option);. if (q->shut_ef) sys$setef(q->shut_ef);/ if (q->option & MBXQ$M_DELETEPENDING) {0 if (q->option & MBXQ$M_MBXCREATED) {f if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_ASTws, q=!XL(!AZ) destroying mbx",q,qName(q));$ destroy_MBX(q->mbx); }' if (q->name) free(q->name); free(q); } }} static intMbxQ_queue_read(pMbxQ q){$ ROUTINE_NAME("MbxQ_queue_read"); int iss, size; pMbxE e;" if (q->option & MBXQ$M_SHUT) {f if (qLog(q)) errlog(L_MBXQ|L_DEBUG,"Mbxq_queue_read, q=!XL(!AZ) not queued, shut",q,qName(q)); return SS$_SHUT; } e = MbxQ_new_entry(); if (!e) return SS$_INSFMEM; e->queue = q;1 e->id = __ATOMIC_INCREMENT_LONG(&q->next_id); size = q->mbx->size;c iss = sys$qio(0,q->mbx->chan, IO$_READVBLK, &e->iosb, &MbxQ_ASTr, e, e->buf, size, 0, 0, 0, 0);m if (qLog(q)) errlog(L_MBXQ|L_DEBUG,"Mbxq_queue_read, q=!XL(!AZ) id=!SL qioiss=!XL",q,qName(q),e->id,iss);7 if (VMS_ERR(iss)) {show_quotas(); VMS_SIGNAL(iss);} return iss;} static voidMbxQ_ASTr(pMbxE e){ ROUTINE_NAME("MbxQ_ASTr"); pMbxE e2; pMbxQ q = e->queue; int iss; iss = e->iosb.status;/ if (VMS_OK(iss)) q->bytes += e->iosb.count;a if (iss == SS$_CANCEL || iss == SS$_ABORT || iss == SS$_LINKABORT || iss == SS$_LINKDISCON) { if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_ASTr, q=!XL(!AZ) status=!XL option=!XL shutting down",q,qName(q),iss, q->option);( _BBSSI(MBXQ$V_SHUT, &q->option);. if (q->shut_ef) sys$setef(q->shut_ef);# iss = lib$insqti(e, FreeQ);* if (VMS_ERR(iss)) VMS_SIGNAL(iss);/ if (q->option & MBXQ$M_DELETEPENDING) { while (1) {u0 iss = lib$remqhi(&q->msgq, &e2);1 if (iss == LIB$_QUEWASEMP) break;i2 if (VMS_ERR(iss)) VMS_SIGNAL(iss);+ iss = lib$insqti(e2,FreeQ);.2 if (VMS_ERR(iss)) VMS_SIGNAL(iss); } 0 if (q->option & MBXQ$M_MBXCREATED) {h if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_ASTr, q=!XL(!AZ) mailbox destroyed",q,qName(q));$ destroy_MBX(q->mbx); }!' if (q->name) free(q->name);o free(q); }n return;r4 } else if (VMS_ERR(iss) && iss != SS$_ENDOFFILE) VMS_SIGNAL(iss); e->len = e->iosb.count;_ iss = sys$setef(mbxq_ef);0& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = MbxQ_queue_read(q);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);/ if (qLog(q) && islogging(L_MBXQ|L_DEBUG)) { if (e->len >= 0) {C char *s = dumpstring(e->buf, e->len > 10 ? 10: e->len);m errlog(L_MBXQ|L_DEBUG,"MbxQ_ASTr, q = 0x!XL(!AZ), id=!SL len=!SL !AZ",q,qName(q),e->id,e->len,s);p free(s); } else {m errlog(L_MBXQ|L_DEBUG,"MbxQ_ASTr, q = 0x!XL(!AZ), id=!SL len=!SL ",q,qName(q),e->id,e->len);e }; }  if (q->AST) { (q->AST)(e); } else {& iss = lib$insqti(e, &q->msgq);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); }E}DpMbxE MbxQ_read(pMbxQ q){s ROUTINE_NAME("MbxQ_read"); int iss; pMbxE e;# iss = lib$remqhi(&q->msgq, &e); if (iss == LIB$_QUEWASEMP) { return 0;l }X return e;n} pMbxEt MbxQ_read2(pMbxQ q, int timeout){ ROUTINE_NAME("MbxQ_read2");- int iss; pMbxE e = 0;4 longword ef = 0, retry = 1, mask, time[2], idum; while (1) { ! iss = sys$clref(mbxq_ef);* if (VMS_ERR(iss)) VMS_SIGNAL(iss);' iss = lib$remqhi(&q->msgq, &e); . if (iss == LIB$_QUEWASEMP && !retry) { e = 0; break; } $ if (iss == LIB$_QUEWASEMP) { e = 0; if (!ef) {& iss = lib$get_ef(&ef);2 if (VMS_ERR(iss)) VMS_SIGNAL(iss);& sec2vms(timeout,time);8 mask = 1<<(ef&0x1F) | 1<<(mbxq_ef&0x1F); } 1 iss = sys$setimr(ef, time, 0, ef, 0);n. if (VMS_ERR(iss)) VMS_SIGNAL(iss);% iss = sys$wflor(ef,mask);Q. if (VMS_ERR(iss)) VMS_SIGNAL(iss);' iss = sys$readef(ef,&idum);. if (VMS_ERR(iss)) VMS_SIGNAL(iss);$ if (iss == SS$_WASCLR) {' iss = sys$cantim(ef,0);T2 if (VMS_ERR(iss)) VMS_SIGNAL(iss);+ } else if (iss == SS$_WASSET) {  retry = 0; }_1 } else if (VMS_ERR(iss)) VMS_SIGNAL(iss);L else break;L }" if (ef) {L iss = lib$free_ef(&ef); * if (VMS_ERR(iss)) VMS_SIGNAL(iss); }r return e; }(voidMbxQ_dispose(pMbxE e) {u! ROUTINE_NAME("MbxQ_dispose"); int iss; iss = lib$insqti(e, FreeQ);M& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}nint MbxQ_shut(pMbxQ q){  ROUTINE_NAME("MbxQ_shut"); int iss = SS$_NORMAL; " if (q->option & MBXQ$_WRITE) {* iss = sys$dclast(&MbxQ_ASTws,q,0); } else {) if (!(q->option & MBXQ$M_SHUT)) {sa if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_shut, q=!XL(!AZ) cancelling i/o",q,qName(q));!+ iss = sys$cancel(q->mbx->chan); }s } return iss;}QintMMbxQ_shut2(pMbxQ q)N{A ROUTINE_NAME("MbxQ_shut2");a int iss = SS$_NORMAL;s if (!q) return SS$_ABORT;L if (qLog(q)) errlog(L_MBXQ|L_DEBUG,"MbxQ_shut2, q=!XL(!AZ)",q,qName(q));" iss = lib$get_ef(&q->shut_ef);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = sys$clref(q->shut_ef);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);" if (q->option & MBXQ$_WRITE) {* iss = sys$dclast(&MbxQ_ASTws,q,0); } else {' if (!(q->option & MBXQ$M_SHUT))c+ iss = sys$cancel(q->mbx->chan);T }0! iss = sys$waitfr(q->shut_ef); & if (VMS_ERR(iss)) VMS_SIGNAL(iss);# iss = lib$free_ef(&q->shut_ef);A& if (VMS_ERR(iss)) VMS_SIGNAL(iss); q->shut_ef = 0;C return SS$_NORMAL;})pMbxQfMbxQ_destroy(pMbxQ q)Q{D! ROUTINE_NAME("MbxQ_destroy");q int iss; pMbxE e;- _BBSSI(MBXQ$V_DELETEPENDING, &q->option);(% if (!(q->option & MBXQ$M_SHUT)) {Ld if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_destroy, q=!XL(!AZ) have to shut first",q,qName(q)); MbxQ_shut(q);b } else {) if (!(q->option & MBXQ$_WRITE)) { while (1) {/ iss = lib$remqhi(&q->msgq, &e);_1 if (iss == LIB$_QUEWASEMP) break; 2 if (VMS_ERR(iss)) VMS_SIGNAL(iss);* iss = lib$insqti(e,FreeQ);2 if (VMS_ERR(iss)) VMS_SIGNAL(iss); } }g, if (q->option & MBXQ$M_MBXCREATED) {d if (qLog(q)) errlog(L_MBXQ|L_INFO,"MbxQ_destroy, q=!XL(!AZ) destroying mbx",q,qName(q)); destroy_MBX(q->mbx); } # if (q->name) free(q->name);  free(q); }w return 0;d}!intL%MbxQ_write(pMbxQ q, void *buf, int n)e{d ROUTINE_NAME("MbxQ_write");  int iss, len; if (!q) return SS$_BADPARAM;8 if (!(q->option & MBXQ$_WRITE)) return SS$_BADPARAM; if (n <= q->mbx->size) {% iss = MbxQ_write2(q, buf, n); } else { iss = SS$_MBTOOSML; ) if (q->option & MBXQ$M_SEGMENT) {  while (n > 0) {: len = n > q->mbx->size ? q->mbx->size : n;/ iss = MbxQ_write2(q, buf, len); P if (VMS_ERR(iss) && qLog(q)) errlog(L_ERROR,"MbxQ_write2, iss:!XL",iss);- if (VMS_ERR(iss)) return iss;) n -= len; 4 buf = (void *) ((char *) buf + len); }p }  }gL if (VMS_ERR(iss) && qLog(q)) errlog(L_ERROR,"MbxQ_write2, iss:!XL",iss); return iss; }(intMMbxQ_start(pMbxQ q)&{X ROUTINE_NAME("MbxQ_start"); if (!q) return SS$_BADPARAM;1 if (q->option & MBXQ$M_SHUT) return SS$_SHUT;Q9 if (!(q->option & MBXQ$M_NOSTART)) return SS$_NORMAL; ' _BBCCI(MBXQ$V_NOSTART, &q->option);  return MbxQ_queue_read(q);} int MbxQ_bytes(pMbxQ q) {  ROUTINE_NAME("MbxQ_bytes");t int iss; int n; iss = sys$setast(0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); n = q->bytes;q iss = sys$setast(1);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return n;i};voidMbxQ_setbacklog(pMbxQ q, int n){ $ ROUTINE_NAME("MbxQ_setbacklog"); q->maxbacklog = n;}svoid!MbxQ_setname(pMbxQ q, char *name)({ ! ROUTINE_NAME("MbxQ_setname");  if (q->name) free(q->name);;% q->name = malloc(strlen(name)+1); if (!q->name) return;  strcpy(q->name, name);} #include fvoidshow_quotas(void)I{, ROUTINE_NAME("show_quotas"); int iss; longword pid = get_pid();$ longword astcnt = 0; longword biocnt = 0; longword bytcnt = 0; longword diocnt = 0; longword enqcnt = 0; longword filcnt = 0; longword tqcnt = 0; IOSB iosb; pItemList i; i = new_ItemList(7);= i = add_Item(i, JPI$_ASTCNT, &astcnt, sizeof(astcnt), 0);(= i = add_Item(i, JPI$_BIOCNT, &biocnt, sizeof(biocnt), 0);)= i = add_Item(i, JPI$_BYTCNT, &bytcnt, sizeof(bytcnt), 0); = i = add_Item(i, JPI$_DIOCNT, &diocnt, sizeof(diocnt), 0); = i = add_Item(i, JPI$_ENQCNT, &enqcnt, sizeof(enqcnt), 0);= i = add_Item(i, JPI$_FILCNT, &filcnt, sizeof(filcnt), 0);M< i = add_Item(i, JPI$_TQCNT, &tqcnt, sizeof(tqcnt), 0);, iss = sys$getjpiw(0,&pid,0,i,&iosb,0,0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); errlog(L_MBXQ|L_DEBUG,"Quotas: AST:!SL BIO:!SL BYT:!SL DIO:!SL ENQ:!SL FIL:!SL TQ:!SL",astcnt,biocnt,bytcnt,diocnt,enqcnt,filcnt,tqcnt);}EpMbxE>MbxQ_new_entry(void){u# ROUTINE_NAME("MbxQ_new_entry");q int iss; pMbxE e; iss = lib$remqhi(FreeQ, &e); if (iss == LIB$_QUEWASEMP) {! e = malloc(sizeof(MbxE));) } else if (VMS_ERR(iss)) { VMS_SIGNAL(iss); }A return e;} intN)MbxQ_flushed(pMbxQ q, int n, int timeout)M{ ! ROUTINE_NAME("MbxQ_flushed");  int iss, retry = 1; % longword ef, mask, time[2], idum;c" if (n <= 0) n = MbxQ_bytes(q); iss = lib$get_ef(&ef);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); sec2vms(timeout,time);, mask = 1<<(ef&0x1F) | 1<<(mbxq_ef&0x1F);) iss = sys$setimr(ef, time, 0, ef, 0);s& if (VMS_ERR(iss)) VMS_SIGNAL(iss);( while (MbxQ_bytes(q) < n && retry) {! iss = sys$clref(mbxq_ef); * if (VMS_ERR(iss)) VMS_SIGNAL(iss);! iss = sys$wflor(ef,mask);-* if (VMS_ERR(iss)) VMS_SIGNAL(iss);# iss = sys$readef(ef,&idum); * if (VMS_ERR(iss)) VMS_SIGNAL(iss);$ retry = (iss == SS$_WASCLR); }  if (retry) { iss = sys$cantim(ef,0); * if (VMS_ERR(iss)) VMS_SIGNAL(iss); }f iss = lib$free_ef(&ef);;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return MbxQ_bytes(q);} *[CRINOID0051]MBXQ.H;1+,~LV. / 4E <-Ke0123KPWO 56 כWQ7r.~(89GHJ #ifndef __MBXQ_H#define __MBXQ_H#include "vms_data.h"#include "CRINOID_types.h"(#define MBXQ$_READ 0x00000000(#define MBXQ$_WRITE 0x00000001#define MBXQ$V_DISCARD 1#define MBXQ$V_RETRY 2#define MBXQ$V_SEGMENT 3#define MBXQ$V_NOSTART 4#define MBXQ$V_NOLOG 5#define MBXQ$V_NETMBX 61#define MBXQ$M_DISCARD (1<len)$#define pMbxE_buf(e) ((e)->buf),#define pMbxE_status(e) ((e)->iosb.status)#endif*[CRINOID0051]MISC.DIR;1+,L(. / 4 -Ke0123 KPWO 563R) 7U\) 89GHJI&CGI_PROGRAMMING_NOTES.TXTL CRINOID.COMLICRINOID.CONFIGL)ERRORPAGE.HTMLL%KILL_TENTACLES.COMM LOGGER.COMdNl NEWLOG.COMOJOYSTER.Q"OYSTER.CONFIG-EXAMPLEHS SCRIPT.PMVT SHUTDOWN.COMU STARTUP.COMSU;STUB.COMU* TENTACLE.COMU TIEENV.PMU-*[CRINOID0051.MISC]CGI_PROGRAMMING_NOTES.TXT;1+,L./ 4M p<-L(0123KPWO56gW7((89GHJ- CGI PROGRAMMING NOTES- =====================AThis file contains suggestions for writing Perl CGIs for use withCRINOID.CRINOID CGI STYLE GUIDE=======================@First off, try your script from an interactive prompt, using the"-w" (warnings) flag:$ PERL -w myscript.cgiCAnything that gets complained about, fix. That will solve about 80%of the potential problems.FFor efficiency, you'd like to be able to re-run scripts multiple timesHafter they've been loaded. You can tell CRINOID to do this by includingthe statement: $CRINOID::Reuse = 1;Gin your script. But beware, your script has to be "well behaved" to beable to be reused.*The Well-Behaved Script #1: Initialization*------------------------------------------GPerl with the -w flag should catch uninitialized variables for you, butFin general uninitialized variables are a much more serious concern forCRINOID CGI scripts.If you have a script like:) print "Content-type: text/plain\n\n";3 print "first time? ",($x ? "NO" : "YES"), "\n";DThen you're using the fact that $x is false (undefined, even), which-will not be the case if the script is re-run.IThere *are* times when it's useful to bend the rules about initializationGa bit, particularly when you have a largeish amount of static data that<you don't want to re-initialize each time the script is run: if (!defined(@MyArray)) {% @MyArray = (1, 1, 2, 3, 5, 8, ... ); },The Well-Behaved Script #2: Variable Scoping,--------------------------------------------CWherever possible put your variables in "my" or "local"; this helpsDkeep the memory use from rerunning scripts within reasonable bounds.,This is also just good programming practice./The Well-Behaved Script #3: Close what you Open/-----------------------------------------------:Any files (and dirs) you open in your script will *NOT* beCautomatically closed for you. You need to close them explicitly in?your script. In particular watch out that you close files when!you encounter an error condition.>Failing to close files, and then rerunning the script with the3files already open, can be a real pain to diagnose.AThere are some exceptions: you should NOT close STDIN, STDOUT and1STDERR. These are dealt with in the server code.Watch where you are, part 1---------------------------?The default directory when your script is run may very well NOT?be the directory where the script is located....in fact, it's agood idea for the scripts in: MYDISK:[USER.WWW-CGI]to have the default set to:1 MYDISK:[USER.WWW-TEMPFILES] (or similar)Cwhen they are run, so that they can't inadvertantly mess up another<script, or create a file that might be runnable as a script.=Setting the "HomeDir" in your OYSTER.CONFIG will chdir to the4the directory you select before running your script.Watch where you are, part 2---------------------------LIf you do not set the "HomeDir" in your OYSTER.CONFIG, the default directoryMwill be the same as the top-level script directory (as the previous example): MYDISK:[USER.WWW-CGI]3even when the script is actually in a subdirectory:( MYDISK:[USER.WWW-CGI.KEWL]STUFF.GThis latter case also illustrates the interaction between PATH_INFO andthe script directory.7 http://host/cgi/~user/kewl/stuff/more/path/infowill run the script( MYDISK:[USER.WWW-CGI.KEWL]STUFF.;(if it exists!) with the PATH_INFO set to "more/path/info"But if you had a script:- MYDISK:[USER.WWW-CGI.KEWL.STUFF]MORE.7then IT will be run, with PATH_INFO set to "path/info".GThe search for scripts is done "deepest first" until a script is found.@If you set the parameter "NoDescend" in your OYSTER.CONFIG, thenAthe search will be confined to the uppermost CGI directory and no subdirectories will be searched.FIf you keep your scripts with a suffix like ".pl" or ".cgi" then lowerDdirectory levels can't be searched, since (on VMS) a directory named3"myscript.pl" isn't part of a valid directory-spec.GAlso on the topic of "searching for a script", note that the "Suffixes"Gparameter in OYSTER.CONFIG lets you confine valid script names to those.that have one of a specified set of filetypes.SCRIPT COMMAND LINE OPTIONS:----------------------------FRecent changes to SCRIPT.PM (v0.4-1) allows _some_ command flags to beBused in CGI scripts. In particular, the first line of your scriptshould look like: #! perl [options]BJust as for a "normal" Perl script. The parsing of the options isEdone "manually" (i.e., by OYSTER s/w, not by Perl) and only a limitedFsubset of options are understood. Also, the parser doesn't understand#combining single-character options.Options available: -w turn on warnings! -Dfff debug flags 'fff'* -Idir put 'dir' on the @INC listDOf these, I expect that -I will be the most useful, so that your CGIAscripts can put any custom modules in a directory of your choice.*[CRINOID0051.MISC]CRINOID.COM;1+,LI. / 4N <-L(0123KPWO 56A|d)7_n)89GHJ$!)$! CRINOID starter p1 = process_name$!<$ here = f$parse("Z.Z;",f$environment("Procedure")) - "Z.Z;"!$ ddev = f$parse(here,,,"device")A$ if (f$trnlnm(ddev-":") .nes. "") then ddev = f$trnlnm(ddev-":")$$ ddir = f$parse(here,,,"directory")1$ here = ddev+ddir - "][" - "000000." - ".000000"$ root = here - "]" + ".]"$!@$ pname = "CRINOID" !! desired name for this process $ if p1 .nes. "" then pname = p1 $ set noon9$ SET PROC/NAME="''pname'" !! try to set=$ nname = f$getjpi("","PRCNAM") !! did we get it?N$ if f$edit(nname,"trim,upcase") .nes. f$edit(pname,"trim,upcase") then logout$ on error then exit$!$ pid = f$getjpi("","PID"))$ write sys$output "''pname': Pid ''pid'"$!$! debug flags$!$ L_MAIN = %X00000100$ L_NETIO = %X00000200$ L_LOCKING = %X00000400$ L_PROC = %X00000800$ L_PIPE = %X00001000$ L_MBXQ = %X00002000$ L_MEM = %X00004000$!$ L_CRITICAL = 0$ L_ERROR = 1$ L_WARNING = 2$ L_INFO = 3$ L_TRACE = 4$ L_BABBLE = 5$ L_DEBUG = 6$!$ LOGLEV = L_WARNING$! LOGLEV = L_MAIN+L_INFO$! LOGLEV = L_BABBLE$! LOGLEV = L_DEBUG$! LOGLEV = L_PROC+L_TRACE$!0$ DEFINE/TRANS=CONCEAL CRINOID_ROOT 'root'0$ DEFINE CRINOID_HOME 'here'2$ DEFINE CRINOID_LOGLEVEL 'loglev'$ set default CRINOID_HOME:$ ext = ".EXE"8$ if f$getsyi("ARCH_NAME") .nes. "VAX" then ext = ".AXE"$!#$ debug = f$trnlnm("CRINOID_DEBUG")$ flag = "/nodebug"$ if debug .nes. ""$ then$ flag = "/debug"2$ set display/create/transp=tcpip/node='debug'2$ f = f$search("CRINOID_home:dbg$CRINOID.ini")$ if f .nes. "" $ then8$ define dbg$init CRINOID_home:dbg$CRINOID.ini $ endif$ endif$$ SET MESSAGE 'HERE'CRINOID_MSG'EXT'$!-$! write process information to CRINOID.USER$! $ user = f$getjpi("","USERNAME")$ node = f$getsyi("NODENAME")7$ oname = f$getjpi("","PRCNAM") !! old name$ open/write fd CRINOID.USER$ write fd user$ write fd node$ write fd nname $ close fd$ purge/keep=1 CRINOID.user$ rename CRINOID.user; ;1 $ set noon$!$! run CRINOID$!:$ DEFINE/USER SYS$ERROR CRINOID_HOME:CRINOID_ERR_'PID'.LIS$ run'flag' 'here'CRINOID'ext'$ iss = $STATUS$ set proc/name="''oname'"$!&$! if error, report completion status$!6$ f = f$search("CRINOID_HOME:CRINOID_ERR_''PID'.LIS;")$ if f .eqs. "" then f = "NL:"$ if .not.(f$int(iss).and.1 )$ thenG$ request/to=network "''pname' PID:''pid' completion status %x''iss'"$!1$ if f$trnlnm("CRINOIDLOG_STDERR_MBX") .nes. ""$ then<$ open/write/share/err=skipit fd CRINOIDlog_stderr_mbxM$ write fd "CRINOID.COM ''pname' PID:''pid' completion status %x''iss'"$ copy 'F' fd:$ close fd $ endif $ skipit:$!'$ if f$trnlnm("CRINOID_MGR") .nes. ""$ thenI$ mail 'F' CRINOID_MGR /subj="CRINOID ''pid' abnormal termination" $ endif$ endif"$ IF F .NES. "NL:" THEN DELETE 'F'$ exit"*[CRINOID0051.MISC]CRINOID.CONFIG;1+,L). / 4g <-L(0123KPWO 56h\7V(89GHJ # A sample CRINOID.CONFIG file(# put it in the CRINOID_HOME directory#C# note that we only see the URL's that the HTTP server passes ourB# way...then we try and decide how to handle them; which process4# group, if they're an 'server internal' URL, etc.#># The '.' prefixes on the commands are required and indicateD# the grouping (e.g. ".script" applies to the most recent "group"# unless specified)#I# -------------- CRINOID.CONFIG commands --------------------------------;# SERVICE decnetservicename defaults to 'WWWPERL'E# LOGLEVEL #decimal set loglevel, logicals overrideC# CONTROL url-wild URL prefix for server controlP# DEBUG url-wild URL prefix for debugging [not implemented]V# THREADS #decimal # of threads for handling connections, default 5#f# USERGROUP subdir sys$login subdir for ~user type scripts (unix-style; '/www-cgi')g# GROUP group user bindir named group; run as 'user'; scripts in 'bindir' (unix, full path)#(# sub-commands of GROUP and USERGROUP:B# .PROCESSES #min #max [group] min/max processes in groupG# .IDLE #min #max [group] min/max idle processes in groupF# .SCRIPT url-wild [group] urls that match run in 'group'#H# (probably should have more commands to set process quotas, CPU limit&# etc, but haven't gotten to it yet)## sub-commands of SCRIPT:f# ..BINDIR dir (`dir' is unix-style) script directory, overrides GROUP bindir@# ..FLAGS #decimal debugging flags (def: 0):# ..WARN set -w Perl optionR# ..PERMIT Safe-opts Safe::permit(...) for script (def. ":all")R# ..DENY Safe-opts Safe::deny(...) for scripts (def. "exit")J# ..LOCALHOST hostname restrict URL match to .SCRIPT to aK# particular local host (multihoming)#F# requests for URLs are compared against '.SCRIPT' URLs in the orderH# in which they appear in the CRINOID.CONFIG file, so earlier .SCRIPTs# pre-empt later ones.#F# For greater control, it may be desirable to define all the processD# groups at the beginning of CRINOID.CONFIG, then have the .SCRIPTB# commands grouped from most-specific to least-specific later in # the file.#F# My experience is that CRINOID.CONFIG files tend to be very simple,# however. YMMV.#?################################################################8# you can set the loglevel here, but logicals override#LOGLEVEL 4?################################################################# CRINOID control function URL# CONTROL /cgi/control/*##?################################################################8# THE FOLLOWING ARE INTENDED AS EXAMPLES, EDIT TO SUIT#H# The 'usergroup' is to let urls with .../~joe_user/.. get mapped to7# joe_user's CGI area (userdisk:[joe_user.www-cgi])#USERGROUP /www-cgi.SCRIPT /cgi/~*.processes 0 3.IDLE 0 1#?################################################################'# a specifically 'named' process group##'# requests directed at EXAMPLE.COM only#AGROUP test lane /disk$users/lane/www-test.PROCESSES 0 1.IDLE 0 0.SCRIPT /cgi/test/*..LOCALHOST EXAMPLE.COM..FLAGS 0..PERMIT :all..DENY exit#/# requests directed to any other localhost name#DGROUP test2 lane /disk$users/lane/www-test2.PROCESSES 0 1.IDLE 0 0.SCRIPT /cgi/test/*..FLAGS 0..PERMIT :default..DENY exit##?###############################################################"*[CRINOID0051.MISC]ERRORPAGE.HTML;1+,L%. / 4A <-L(0123KPWO 56_Z77ˑ(89GHJ4CGI Error: <!--#error-->

CGI Error

4The following error was detected while attempting to-execute the CGI script: 

 

APlease check the URL, and notify the owner of any pages that link to this URL.


7Beef hereP ȣ2Z~ FREEWARE.SAVML(&[CRINOID0051.MISC]KILL_TENTACLES.COM;1I ;&*[CRINOID0051.MISC]KILL_TENTACLES.COM;1+,M. / 4I <-L(0123KPWO 56w 7W7Oۑ(89GHJ$! kill any /CGI processes$!5$! @kill_tentacles just for the userG$! @kill_tentacles all kill all tentacles (requires WORLD)$! $ ctx = "".$ doall = f$edit(p1,"trim,upcase") .eqs. "ALL"$ if (.not. doall)$ then.$ u = f$edit(f$getjpi("","username"),"trim")3$ x = f$context("PROCESS",ctx,"USERNAME",u,"EQL")$ else$ oprv = f$setprv("WORLD")$ endif$!3$ x = f$context("PROCESS",ctx,"MODE","OTHER","EQL")$ loop:$ pid = f$pid(ctx)"$ if pid .eqs. "" then goto done $ prog = "" $ det = 0 $ name = ""5$ prog = F$PARSE(f$getjpi(pid,"IMAGNAME"),,,"NAME")G$ if prog .nes. "TENTACLE" then goto loop !! tentacle?$ det = (f$getjpi(pid,"creprc_flags") .and. %x200) .eq. %x200G$ if .not. det then goto loop !! detachedI$ u = f$edit(f$getjpi(pid,"username"),"TRIM") !! user/CGIxx0$ name = f$edit(f$getjpi(pid,"PRCNAM"),"TRIM")$ j = f$locate("/CGI",name)+$ if j .ge. f$length(name) then goto loop1$ if f$extract(0,j,name) .eqs. f$extract(0,j,u)$ then8$ write sys$output "Stopping proc ''pid' ''name'"$ stop/id='pid' $ endif $ goto loop$!$ done:$$ if doall then x = f$setprv(oprv)$ exit*[CRINOID0051.MISC]LOGGER.COM;1+,dNl. / 4A R<-L(0123KPWO 56~)%70(89GHJ$!<$ here = f$parse("Z.Z;",f$environment("Procedure")) - "Z.Z;"!$ ddev = f$parse(here,,,"device")A$ if (f$trnlnm(ddev-":") .nes. "") then ddev = f$trnlnm(ddev-":")$$ ddir = f$parse(here,,,"directory")1$ here = ddev+ddir - "][" - "000000." - ".000000"$!$ set default 'here'.$ DEFINE CRINOIDLOG_FILE "''HERE'CRINOID.LOG"$!&$ debug = f$trnlnm("CRINOIDLOG_DEBUG")$ flag = "/nodebug"$ if debug .nes. ""$ then$ flag = "/debug"2$ set display/create/transp=tcpip/node='debug'1$ f = f$search("CRINOID_home:dbg$logger.ini")$ if f .nes. "" $ then7$ define dbg$init CRINOID_home:dbg$logger.ini $ endif$ endif$!$ ext = ".EXE"8$ if f$getsyi("ARCH_NAME") .nes. "VAX" then ext = ".AXE"$ SET PROC/NAME="CRINOIDLOG"$$ SET MESSAGE 'HERE'CRINOID_MSG'EXT'$ run'flag' logger'ext'$!*[CRINOID0051.MISC]NEWLOG.COM;1+,OJ. / 4> <-L(0123KPWO 566dSF 7SF 89GHJ$!)$! put in the CRINOID_home directory ...$!'$ x = f$trnlnm("CRINOIDLOG_STDERR_MBX")$ if x .eqs. ""$ then>$ write sys$output "CRINOIDLOG appears not to be running..."$ exit$ endif&$ define/sys CRINOIDLOG_COMMAND NEWLOG.$ open/write/err=loop fd CRINOIDlog_stderr_mbx=$ write fd "CRINOIDLOG_COMMAND: New logfile request from DCL" $ close fd$ J = 12$ wait 00:00:01$ LOOP:9$ x = f$trnlnm("CRINOIDLOG_COMMAND","LNM$SYSTEM_TABLE")"$ if (x .EQS. "") then goto done $ J = J - 1$ IF (J .LE. 0)$ THEN9$ WRITE SYS$OUTPUT "Timeout waiting for CRINOIDLOG"*$ DEASSIGN/SYSTEM CRINOIDLOG_COMMAND$ GOTO DONE $ ENDIF$ wait 00:00:05 $ GOTO LOOP$ done:$ exit 1*[CRINOID0051.MISC]OYSTER.;1+,Q.-/ 4-'<-L(0123KPWO.56d 7Lځ 89GHJN#! perl#$# a hard-shelled wrapper for Perl.## arg = scriptname# use Script;use Cwd;use VMS::Stdio;#*# 'global' one-time initialization stuff#$ConfigFile = 'oyster.config';:$PDBFlags = 'psltocPmfrxuLHXD'; ### Perl's debug flags $eol = ''; $pquota = -1;w@PreLoads = ('UNIVERSAL', 'DynaLoader', 'Socket', 'VMS::Filespec', 'VMS::Stdio', 'Carp', 'Exporter'); # static modules$Debug_Parsing = 0;$Debug_Namespace = 0;$Debug_Quota = 0;!quota("initial") if $Debug_Quota;#?# The following used for interactive testing; set the logicalC# 'OYSTERTEST' and run with 'directory' and 'script' as arguments7# i.e., $ perl oyster. mydev:[mydir] testscript.cgi#8@StartupNamespace = get_namespace() if $Debug_Namespace;3if (!exists($ENV{TZ}) and exists($ENV{'UCX$TZ'})) { $ENV{TZ} = $ENV{'UCX$TZ'};}if ($ENV{'OYSTERTEST'}) { $eol = "\n"; while (@ARGV) { my ($dir) = shift @ARGV;# my ($script) = shift @ARGV;H print "(Enter SafeENV names=value pairs, terminate with EOF)\n"; while () { chomp;$ ($n,$v) = split(/=/,$_); SetSafeENV($n, $v); }" RunScript($dir , $script); }}#;# print out memory (pagefile + working_set) and CPU usageE# at several points during script execution. The first ('initial')A# printout would normally be lost down some i/o black hole, but"# we save it for printing later.# sub quota { my $tag = shift; if ($tag eq 'initial') {& eval('require VMS::Process;');" $VMS_PROC_OK = ($@ eq ''); } return if !$VMS_PROC_OK;2 return if $tag ne 'initial' && $LogLevel <= 5; my $cpu = (times)[0]; if ($pquota < 0) {F $pquota = VMS::Process::get_one_proc_info_item(0,"PGFLQUOTA"); }@ my $q = VMS::Process::get_one_proc_info_item(0,"PAGFILCNT"); $q = $pquota - $q;> my $ws = VMS::Process::get_one_proc_info_item(0,"WSSIZE");( if (defined($delayed_print_quota)) {@ print STDERR $delayed_print_quota.$eol if $LogLevel > 5;$ undef($delayed_print_quota); }G my $line = $tag." Pagefile usage: $q working set: $ws CPU: $cpu";6 $delayed_print_quota = $line if $tag eq 'initial'; return if $LogLevel <= 5; print STDERR $line.$eol;}sub RunScript { my $save_eol = $eol; $logopened = 0; $location = cwd; $iss = RunScript2(@_); close(STDERR) if $logopened; chdir($location); $eol = $save_eol;}#)# this is what actually runs the script$# check that config is current# logfile handlingA# locate the file with the script (caching? could speed up)E# retrieve/create "Script" object, preload modules, Filehandles# run the script$# status reporting and cleanup#sub RunScript2 {% local $SIG{ABRT} = \&HandleAbort; my ($dir,$script) = @_; my ($s, @mask); my $logc; my $found = 0; LoadConfig(); $| = 1; # autoflush output $script = lc($script); $dir =~ s#/+$##;) if ($LogLevel > 0 && $Errlog ne '') { my $newlog = 1; $newlog = !(-e $Errlog)K unless ($MaxLogfileSize && (stat($Errlog))[7] > $MaxLogfileSize); if ($newlog) {U $errFH = VMS::Stdio::vmsopen(">$Errlog","shr=get,put,upd,del","ctx=rec"); } else {i $errFH = VMS::Stdio::vmsopen(">>$Errlog","shr=get,put,upd,del","ctx=rec","rfm=var","rat=cr"); } if (!$errFH) {9 print STDERR "Switch to $Errlog failed".$eol; } else { *STDERR = $errFH;1 if ($newlog && $MaxLogfileVersions) {A system("purge/keep=$MaxLogfileVersions $Errlog"); } $logopened = 1; $eol = "\n"; print STDERR $eol."Request for script $script on $SafeENV{'SERVER_NAME'} from $SafeENV{'REMOTE_ADDR'} at ".scalar(localtime).$eol; } }o print STDERR "Namespace @ Startup (Perl $]): \n\t",join("\n\t",@StartupNamespace),"\n" if $Debug_Namespace;H print STDERR "Preloads: ".join(' ',@PreLoads).$eol if $LogLevel >=3;? print STDERR "base directory: $dir".$eol if $LogLevel >= 4; if (!chdir($dir)) {O error_message($script,"Directory $dir not found or inaccessable", 404); return; } if ($LogLevel >=5 ) {" foreach (keys(%SafeENV)) {A print STDERR "CGI \$ENV{'$_'} = '".$ENV{$_}."'".$eol; } }( $SafeENV{'SCRIPT_PREFIX'} =~ s#/$##;% $SafeENV{'SCRIPT_PREFIX'} .= '/'; if ($Debug_Parsing) {E print STDERR "SCRIPT_BINDIR = '$SafeENV{'SCRIPT_BINDIR'}'\n";B print STDERR "SCRIPT_NAME = '$SafeENV{'SCRIPT_NAME'}'\n";F print STDERR "SCRIPT_PREFIX = '$SafeENV{'SCRIPT_PREFIX'}'\n"; }b $script = substr($SafeENV{'SCRIPT_NAME'},length($SafeENV{'SCRIPT_PREFIX'})) unless $NoDescend;B print STDERR "using script named $script\n" if $Debug_Parsing;### check if script is in our cacheC# this *can* interfere if have multiple scripts/path interactions## which would be very ugly anyway# my $incache = 0;, my $url = $script.$SafeENV{'PATH_INFO'}; my $ucurl = uc("$dir/$url");" foreach (keys(%ScriptCache)) {0 if ($_ eq substr($ucurl,0,length($_))) {? $script = substr($url,0,length($_)-length($dir)-1);A $SafeENV{'PATH_INFO'} = substr($url,length($script));) my (@p) = split('/',$script);3 $SafeENV{'SCRIPT_BARE_NAME'} = pop(@p);! my $x = join('/',@p);Y $SafeENV{'SCRIPT_PATH'} = $SafeENV{'SCRIPT_PREFIX'}.($x ne '' ? $x.'/' : '');[ $SafeENV{'SCRIPT_NAME'} = $SafeENV{'SCRIPT_PATH'}.$SafeENV{'SCRIPT_BARE_NAME'}; $incache++;! if ($Debug_Parsing) {- print STDERR "from cache:\n";I print STDERR "SCRIPT_PATH = '$SafeENV{'SCRIPT_PATH'}'\n";I print STDERR "SCRIPT_NAME = '$SafeENV{'SCRIPT_NAME'}'\n";G print STDERR "PATH_INFO = '$SafeENV{'PATH_INFO'}'\n";S print STDERR "SCRIPT_BARE_NAME = '$SafeENV{'SCRIPT_BARE_NAME'}'\n"; } last; } }#<# script + path_info => maybe at deeper level? find out...5# but skip all this if we found it in the cache#H print STDERR "before dir tree...script=$script\n" if $Debug_Parsing;# if (!$incache && !$NoDescend) {1 my $file = $script.$SafeENV{'PATH_INFO'};% my (@pre) = split('/',$file); my (@post) = (); my $x; while (1) {N print STDERR "checking dir tree.. file=$file\n" if $Debug_Parsing;: if (-e $file && (!-d $file || -e $file.'.')) {9 $SafeENV{'SCRIPT_BARE_NAME'} = pop(@pre);@ $script = join('/',@pre).($#pre >= 0? '/' : '');L $SafeENV{'SCRIPT_PATH'} = $SafeENV{'SCRIPT_PREFIX'}.$script;_ $SafeENV{'SCRIPT_NAME'} = $SafeENV{'SCRIPT_PATH'}.$SafeENV{'SCRIPT_BARE_NAME'};P $SafeENV{'PATH_INFO'} = ($#post >= 0? '/' : '').join('/',@post);8 $script .= $SafeENV{'SCRIPT_BARE_NAME'}; $found++;% if ($Debug_Parsing) {< print STDERR "from directory search:\n";M print STDERR "SCRIPT_PATH = '$SafeENV{'SCRIPT_PATH'}'\n";M print STDERR "SCRIPT_NAME = '$SafeENV{'SCRIPT_NAME'}'\n";K print STDERR "PATH_INFO = '$SafeENV{'PATH_INFO'}'\n";W print STDERR "SCRIPT_BARE_NAME = '$SafeENV{'SCRIPT_BARE_NAME'}'\n"; } last; }& last if !($x = pop(@pre)); unshift(@post,$x);# $file = join('/',@pre); } }Q print STDERR "after dir search dir=$dir script=$script\n" if $Debug_Parsing;e if (!$incache && !$found && (!-e "$dir/$script" || (-d "$dir/$script" && !-e "$dir/$script."))) {M error_message($script.$SafeENV{'PATH_INFO'},"script not found", 404); return; }? print STDERR "Script: $dir/$script".$eol if $LogLevel >= 1;' quota("prescript") if $Debug_Quota; if ($OnlySuffixes) {% my (@p) = split('/',$script); my ($f) = pop(@p);0 my ($t) = '.' . lc((split(/\./,$f))[1]); my ($ok) = 0; foreach (@Suffixes) { if (lc($_) eq $t) { $ok++; last; } } if (!$ok) {_ error_message($script,"Has an invalid/disallowed file type for a CGI script", 404); return; } } if ($Debug_Parsing) {' print STDERR "final result:\n";A print STDERR "SCRIPT_PATH = '$SafeENV{'SCRIPT_PATH'}'\n";A print STDERR "SCRIPT_NAME = '$SafeENV{'SCRIPT_NAME'}'\n";? print STDERR "PATH_INFO = '$SafeENV{'PATH_INFO'}'\n";K print STDERR "SCRIPT_BARE_NAME = '$SafeENV{'SCRIPT_BARE_NAME'}'\n";t9 print STDERR "putting $dir/$script into cache\n";n }a) $ScriptCache{uc("$dir/$script")} = 1;g, $s = Script::FindScript("$dir/$script");% if (defined($s) && $s->renew()) {Z print STDERR "script $script has been modified, reloading".$eol if $LogLevel >= 2; $s->DESTROY(); $s = undef;g } if (!defined($s)) {H print STDERR "making new script $script".$eol if $LogLevel >= 2;' $s = new Script "$dir/$script"; O @pmask = qw(:all); # default @dmask = qw(exit);k @pmask = split(' ', $SafeENV{'CRINOID:ALLOW'}) if (exists($SafeENV{'CRINOID:ALLOW'})); #specifiedE\ @dmask = split(' ', $SafeENV{'CRINOID:DENY'}) if (exists($SafeENV{'CRINOID:DENY'}));I print STDERR "allowing ".join(' ',@pmask).$eol if $LogLevel >= 3;fI print STDERR "denying ".join(' ',@dmask).$eol if $LogLevel >= 3;N $s->permit(@pmask);e $s->deny(@dmask);l $name = $s->{Root};m, *{$name."::STDIN"} = \*main::STDIN;, *{$name."::stdin"} = \*main::STDIN;- *{$name."::STDOUT"} = \*main::STDOUT;- *{$name."::stdout"} = \*main::STDOUT;t- *{$name."::STDERR"} = \*main::STDERR;s- *{$name."::stderr"} = \*main::STDERR;r ${$name."::/"} = "\n"; ${$name.'::"'} = ' '; [ ${$name.'::$'} = sprintf('%04X%04X',$Script::safeid,time & 0xFFFF); # fake PIDi( ${$name.'::0'} = "$dir/$script";& *{$name.'::exit'} = \&ExitSub;$ ${$name.'::In_CRINOID'} = 1;#;4# Safe:: needs first crack at the symbol table4# so if loading into a module within partition># set a dummy variable first to init stash name properly#"$ $s->init_stash('CGI::Carp');1 *{$name."::CGI::Carp::exit"} = \&ExitSub;q% foreach (keys(%NewINCdirs)) {tC print STDERR "push(\@INC,'$_')".$eol if $LogLevel >=4 ;o push(@INC,$_); }r %NewINCdirs = (); & foreach (keys(%NewPreLoads)) {B print STDERR "Preloading '$_'".$eol if $LogLevel >=4 ; eval("require $_;"); if ($@ eq '') {i# push(@PreLoads,$_);5 } else {> print STDERR "ERROR preloading '$_', $@".$eol; }d }  %NewPreLoads = (); foreach (@PreLoads) {RK print STDERR "Preload: share_module($_)".$eol if $LogLevel >=4;! $s->share_module($_);e } " $s->{ENV}->volatile('TZ');) $s->{ENV}->static(keys(%AddENV));f0 $s->{ENV}->volatile(keys(%VolatileENV));4 $s->{ENV}->persistent(keys(%PersistantENV)); } else {H print STDERR "reusing old script $script".$eol if $LogLevel >=3; $name = $s->{Root};R $s->{ENV}->initialize(); }t( quota("postscript") if $Debug_Quota;## set environment# ! foreach $k (keys(%SafeENV)) {tD $s->{ENV}->fake($k, $SafeENV{$k}) unless $k =~ /^CRINOID\:/;F# ${$name."::ENV"}{$k} = $SafeENV{$k} unless $k =~ /^CRINOID\:/; }n% if ($s->{DEBUG} != $DebugFlags) {(" $s->{DEBUG} = $DebugFlags; $s->{VIRGIN} = 1;  }f8 $s->{TIMEOUT} = $MaxRunTime if defined($MaxRunTime);S print STDERR sprintf("Debug flags: 0x%4.4x",$s->{DEBUG}).$eol if $LogLevel > 4;:+ if (exists($SafeENV{'CRINOID:WARN'})) {"5 if ($s->{WARN} != $SafeENV{'CRINOID:WARN'}) { 3 $s->{WARN} = $SafeENV{'CRINOID:WARN'};E $s->{VIRGIN} = 1; }  }  if (defined($HomeDir)) { if (!chdir($HomeDir)) {sE error_message($script,"error in chdir to $HomeDir", 500); return; }l }d#1# run the script#" $! = 0;  my $result = $s->run();t% quota("postrun") if $Debug_Quota;_ if ($@ ne '') {EY error_message($script,"(while running):
$@") unless $@ =~ /^exit\(0\)/;  }u#P# post-script cleanup"#t $s->{ENV}->reset();D undef(%SafeENV);T my $Reuse = defined(${$name."::CRINOID::Reuse"}) && ${$name."::CRINOID::Reuse"};O $Reuse ||= defined(${$name."::SQUID::Reuse"}) && ${$name."::SQUID::Reuse"};  if ($Reuse) {p, if (exists($s->{INC}->{'CGI.pm'})) {0 $s->reval("CGI::_reset_globals();"); } } else { $s->DESTROY(); } ' quota("postclean") if $Debug_Quota;N}_#e9# called from driver program to insert data in ENV hashs##sub SetSafeENV { my($n,$v) = @_;' $SafeENV{$n} = $v;}g## abort signal handler#Bsub HandleAbort {S5 my $m = "Tentacle::HandleAbort('".shift(@_)."')";  print STDERR $m; $SIG{ABRT} = \&HandleAbort;" die 'abort';}f sub ExitSub {I my $status = shift;s my (@c) = caller;{4 die "exit($status) called at $c[1] line $c[2]|";}$sub LoadConfig { if (!$tCFG) {t $fCFG = $ConfigFile; $tCFG = 1; %NewPreLoads = (); $Errlog = '';r $LogLevel = 1; $DebugFlags = 0; $OnlySuffixes = 0; $NoDescend = 0;a $HomeDir = undef;s $MaxRunTime = undef; $ScriptCache = (); @ERROR_HTML = ();S %NewINCdirs = ();( %VolatileENV = (); %PersistantENV = (); $MaxLogfileSize = 0; $MaxLogfileVersions = 0; }H return if !(-e $fCFG);( return if (stat($fCFG))[9] <= $tCFG; $tCFG = (stat($fCFG))[9];S8 my $cfgFH = VMS::Stdio::vmsopen("<$fCFG","shr=get");: if (defined($cfgFH)) { ## in user's home directory $Errlog = '';  $LogLevel = 1; %NewPreLoads = (); $DebugFlags = 0; $OnlySuffixes = 0; $NoDescend = 0;i $HomeDir = undef;( $MaxRunTime = undef; $ScriptCache = (); @ERROR_HTML = ();r %NewINCdirs = ();$ %AddENV = ();\ %VolatileENV = (); %PersistantENV = (); $MaxLogfileSize = 0; $MaxLogfileVersions = 0;( while (defined($_ = <$cfgFH>)) { chomp; s/^\s+//;f next if /^\#/; next if /^\!/;! $_ = (split(/#/))[0];! if (/^preload\s+/i) {t% $NewPreLoads{$'} = 1; }f if (/^errlog\s+/i) { $Errlog = $';e }i# if (/^loglev\S*\s+/i) {n$ $LogLevel = int($'); }$" if (/^debug\S*\s+/i) {- $DebugFlags = parsedebug($');= }y" if (/^suffi\S*\s+/i) {* @Suffixes = split(/ /,$');" $OnlySuffixes = 1; }e if (/^nodescen/i) {{ $NoDescend = 1;T }p! if (/^home\S*\s+/i) {  $HomeDir = $'; } # if (/^maxrun\S*\s+/i) {S& $MaxRunTime = int($'); }E# if (/^errorhtml\s+/i) {P local *F;_. if (-e $' && open(F,'<'.$')) {( @ERROR_HTML = (); close(F);a } else {K print STDERR "Error opening $' as ERRORHTML file".$eol;  }T }c if (/^addinc\s+/i) {) foreach (split(/ /,$')) {S( $NewINCdirs{$_} = 1; }N }{ if (/^addenv\s+/i) {) foreach (split(/ /,$')) {N$ $AddENV{$_} = 1; }C }=$ if (/^Static_ENV\s+/i) {) foreach (split(/ /,$')) { $ $AddENV{$_} = 1; } }(& if (/^Volatile_ENV\s+/i) {) foreach (split(/ /,$')) {E) $VolatileENV{$_} = 1;p }i }(( if (/^Persistant_ENV\s+/i) {) foreach (split(/ /,$')) {t+ $PersistantENV{$_} = 1;E }r } + if (/^MaxLogFileS(ize)?\s+/i) {T* $MaxLogfileSize = int($'); }u0 if (/^MaxLogFileV(ersions?)?\s+/i) {. $MaxLogfileVersions = int($'); }y }( close($cfgFH); foreach (@PreLoads) {A delete($NewPreLoads{$_}) if exists($NewPreLoads{$_}); }e foreach (@INC) {? delete($NewINCdirs{$_}) if exists($NewINCdirs{$_}); } } } sub parsedebug { my $flags = shift;2 return int($flags) if $flags =~ /^\s*\d+\s*$/; my $i; my $v = 0; foreach (split(//,$flags)) { next if /\s/; ! $i = index($PDBFlags,$_);" return 0 if $i < 0;P $v += 1<<$i; }  return $v;} sub error_message {\/ my $script = VMS::Filespec::unixify(shift);N my $errmsg = shift;  my $status = shift;B? print STDERR "ERROR $errmsg, script $script $status".$eol;R) print "Status: $status\n" if $status;a if ($#ERROR_HTML > 0) {s, print "Content-type: text/html\n\n"; foreach (@ERROR_HTML) {e $line = $_;7 $line =~ s/\<\!\-\-\#error\-\-\>/$errmsg/i;e8 $line =~ s/\<\!\-\-\#script\-\-\>/$script/i; print $line; }( } else {- print "Content-type: text/plain\n\n";r4 print "ERROR: $errmsg for script $script\n"; }s}psub get_namespace {( my %todo;  my @needsdone = qw(main); my %done; my $n; my @found; while ($#needsdone >= 0) {( while ($n = shift(@needsdone)) {( foreach (keys(%{$n."::"})) {" next unless /::$/; s/\:\:$//;* next if exists($done{$_});! next if $_ eq $n; : $todo{($n eq 'main' ? '' : $n."::").$_}=1; } ! push @found, $n."::";t $done{$n}=1; }l foreach (keys(%todo)) { push @needsdone,$_;a } %todo = ();d }  return @found;} )*[CRINOID0051.MISC]OYSTER.CONFIG-EXAMPLE;1+,HS. / 4f <-L(0123KPWO 56&7r (89GHJ #$# this is an example OYSTER.CONFIG'# main commands are "preload" modulesJ# set error logging file, level, debug flags (same as Perl -Dxx)#O# note that PGPLOT requires setup in the user's LOGIN.COM (logicals need set)#preload PGPLOTpreload Digest::MD5#Berrlog oyster.log # log file (in sys$login dir, by default);LogLevel 3 # log level, 1=critical...5=babbleSMaxLogfileSize 8000 # create new logfile if old one is too big (size in bytes);MaxLogfileVersions 5 # purge logfile versions /keep=...?#debug m # Perl debug flags (e.g., $Perl -Dm )H#NoDescend # only look for scripts in main dir, not subdirsDSuffixes .pl .cgi . # only allow NAME.pl NAME.cgi NAME. scripts@#HomeDir disk:[dir] # chdir to HomeDir before running script?#MaxRunTime 100 # max time a script can run, in seconds8#addINC mydisk:[dir] # push onto @INC used by scripts<#-----------depreciated, use Static_ENV instead ------------?#addENV DBDIR # import logical DBDIR into script %ENV#-----------removed, do not useB#ExportENV TZ # export script %ENV TZ to process logicalF# several different flavors of ENV import/export, each takes a list of8# logical names. Note that TZ is set Dynamic by Oyster.R#Static_ENV DBDIR # import logical from %ENV, value set at script invokation< # changes not propagated to logicalsf#Dynamic_ENV PGPLOT_GIF_WIDTH PGPLOT_GIF_HEIGHT # import logical from %ENV, can read/write logicalZ # but value reset when script finishesT#Persistant_ENV MYSTUFF # like Dynamic_ENV but changes persist after script finishesK#--------------------------------------------------------------------------S#ErrorHTML disk:[dir]errorpage.html # use this for error messages from OYSTER.#G# for the ErrorHTML file: just write standard HTML, but the following&# two sequences will be substituted:#-# -> text of error message&# -> name of script#H# The filename you give for ErrorHTML can be either VMS- or Unix-style8# but must be readable by the account running the CGI.#*[CRINOID0051.MISC]SCRIPT.PM;1+,VT./ 4X<-L(0123KPWO56# ! 7f-! 89GHJpackage Script;BEGIN { use Exporter (); use Safe; use TieENV;E use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);* # set the version for version checking $VERSION = 1.10;% @ISA = qw(Exporter Safe);" @EXPORT = qw(FindScript);= %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ],} $safeid = 0;$module_debug = 0; sub new { my $pkg = shift; my $script = shift; my $obj;3 my ($safename) = sprintf('SAFE%08d',$safeid++); $obj = new Safe $safename; $obj->{SCRIPT} = $script; $obj->{INC} = {};) $obj->{MODTIME} = (stat($script))[9]; $obj->{DEBUG} = $^D; $obj->{WARN} = $^W; $obj->{VIRGIN} = 1; $obj->{TIMEOUT} = 0; $obj->{DATA} = undef;' $obj->{ENV} = new TieENV $safename; bless $obj, $pkg;! $ScriptIndex{$script} = $obj; return $obj;} sub DESTROY { my $self = shift;R print STDERR "In SCRIPT::DESTROY, for ",$self->{SCRIPT},"\n" if $module_debug;* delete($ScriptIndex{$self->{SCRIPT}}); Safe::DESTROY($self);}sub FindScript { my $script = shift;( if (exists($ScriptIndex{$script})) {% return $ScriptIndex{$script}; } else { return undef; }} sub renew { my $self = shift;! my $script = $self->{SCRIPT};% my $modtime = (stat($script))[9];) return ($modtime > $self->{MODTIME});} sub run { my $self = shift; my $file = $self->{SCRIPT}; my $root = $self->{Root}; my $debug = $self->{DEBUG}; my $warn = $self->{WARN};# my $timeout = $self->{TIMEOUT}; my $status; my $F; $DIEfile = $file; my (@INC0) = @INC; local @INC = @INC0;! local %INC = %{$self->{INC}}; if ($self->{VIRGIN}) {; print STDERR "reloading script\n" if $module_debug; my $line; my $ialarm = ''; my $falarm = ''; if ($timeout) {X $ialarm = 'local $SIG{ALRM} = sub { die "timeout\n"}; alarm '.$timeout.';' ;" $falarm = '; alarm 0'; }, local $SIG{__DIE__} = \&DIE_Handler; $DIEmsg = undef;5 $F = VMS::Stdio::vmsopen("<$file","shr=get");C die("unable to open script file $file") unless defined($F); my @p; $self->{DATA} = undef;$ while (defined($_ = <$F>)) {- if (/^\s*__(DATA|END)__\s*\n$/) {# $self->{DATA} = $F; last; } push @p, $_; }0 close($F) unless defined($self->{DATA}); *{$root."::DATA"} = $F;" if ($p[0] =~ /^\#\!\s*/) { $p[0] = ''; my $opts = $'; chomp($opts);* my (@opts) = split(' ',$opts);0 while (defined($_ = shift(@opts))) {7 last if (/perl(\.[^\/\.\]\>\:]*)?$/i) ; }0 while (defined($_ = shift(@opts))) {" last unless /^\-/;# last if $_ eq '--'; if (/^\-I/) {+ unshift(@INC,$') if $';I print STDERR "adding $' to \@INC\n" if $module_debug; } if (/^\-D/) { $debug = $'; }! if ($_ eq '-w') { $warn = 1; } } } @{$root."::INC"} = @INC; %{$root."::INC"} = %INC; my $expr = join('',@p);U $line = sprintf('package %s; use subs qw(exit); sub { %s ', $root, $ialarm);J $line .= 'local $^A; local $^C; local $^F; local $^I; local $^P;';A# $line .= 'local $#;'; ### causes weird problems ### $line .= 'local $%;'; $line .= 'local $,;';O $line .= 'local $-; local $=; local $?; local $\; local $^; local $~;';J $line .= sprintf('local $^D = %d; local $^W = %d;',$debug, $warn);( $line .= 'local $^H = '.$^H.';';p3/ ~ FREEWARE.SAVVTL([CRINOID0051.MISC]SCRIPT.PM;1X1 ! $line .= 'local $[ = 0;'; $line .= '$/ = qq(\n);';$ $line .= 'local $" = q( );';! $line .= 'local $| = 1;';+ $line .= 'eval $expr;'.$falarm.'}';> print STDERR " eval ($line)\n" if ($module_debug > 1);H print STDERR "\@INC = (",join(', ',@INC),")\n" if $module_debug;# $self->{SUB} = eval($line); %{$self->{INC}} = %INC; if ($DIEmsg) {& print STDERR $DIEmsg,"\n"; $@ = $DIEmsg; return undef; } $self->{VIRGIN} = 0; } $status = $self->rdo2(); %{$self->{INC}} = %INC; $^O = 'VMS' if $^O ne 'VMS';T my $Reuse = defined(${$root."::CRINOID::Reuse"}) && ${$root."::CRINOID::Reuse"};O $Reuse ||= defined(${$root."::SQUID::Reuse"}) && ${$root."::SQUID::Reuse"};D if (defined($self->{DATA}) && (eof($self->{DATA}) || !$Reuse)) { close($self->{DATA}); $self->{DATA} = undef; } return $status;} sub rdo2 { my $self = shift; my $root = $self->{Root};( local $SIG{__DIE__} = \&DIE_Handler; $DIEmsg = undef; $^T = time; $_ = @_ = undef;K my $status = Opcode::_safe_call_sv($root, $self->{Mask}, $self->{SUB}); if ($DIEmsg) { $@ = '';* if ($DIEmsg =~ /^exit\((\d+)\)/) {& return $status if $1 == 0;* my (@m) = split(/\|/,$DIEmsg); $DIEmsg = $m[0];C } elsif ($DIEmsg =~ /at \/CRINOID_ROOT\/lib\/script.pm/i) { $DIEmsg = $`; }3 print STDERR $DIEmsg," status = $status\n"; $@ = $DIEmsg; $status = undef; } return $status;}sub init_stash { my $self = shift; my $modname = shift; $modname =~ s#::$##; if ($modname =~ /::/) {D $self->reval('$'.$modname.'::_CRINOID_initstash_dummy_=1;'); }}sub share_module { my $self = shift; my $modname = shift;# my ($filename, $k, $v); my $root = $self->{Root}; $modname =~ s#::$##;4 *{$root."::".$modname."::"} = \*{$modname."::"}; $filename = $modname; $filename =~ s#::#/#g; $filename .= '.pm';" while (($k,$v) = each(%INC)) {& if (uc($k) eq uc($filename)) {$ $self->{INC}->{$k} = $v; last; } }}sub DIE_Handler { $DIEmsg = shift;( $DIEmsg =~ s/\(eval \d+\)/$DIEfile/; die($DIEmsg);} sub DEBUG { my $s = shift; my $comment = shift; my $root = $s->{Root}; my %h = %{$root."::"}; my $c = $h{'CGI::'}; my $nk = 0;0# print STDERR "symbol table, at $comment\n"; foreach (keys(%{$c})) { $nk++;:# print STDERR "$comment: $root","::CGI::{'$_'} \n" }< print STDERR "$comment $root","::CGI ... $nk symbols\n"; foreach (keys(%main::INC)) {3 print STDERR "$comment: \$main::INC{$_}\n"; }" foreach (keys(%{$s->{INC}})) {5 print STDERR "$comment: $root","::INC{$_}\n"; }}1; *[CRINOID0051.MISC]SHUTDOWN.COM;1+,U. / 4a <-L(0123KPWO 569ݍ7D(89GHJ$!$! shut down CRINOID$!H$! @SHUTDOWN shuts down CRINOID, any STUBs hanging around1$! @SHUTDOWN LOGGER shuts down CRINOIDLOGB$! @SHUTDOWN DEINSTALL shuts down CRINOID, STUBSs, deinstalls-$! @SHUTDOWN FULL =LOGGER+DEINSTALL$!$!($ oprv = f$setprv("WORLD,CMKRNL,SYSNAM")a$ if .not. f$privilege("WORLD") .or. .not. f$privilege("CMKRNL") .or. .not. f$privilege("SYSNAM")$ thenK$ write sys$output "CRINOID shutdown.com needs WORLD,CMKRNL,SYSNAM privs" $ EXIT 44$ ENDIF$!<$ here = f$parse("Z.Z;",f$environment("Procedure")) - "Z.Z;"!$ ddev = f$parse(here,,,"device")A$ if (f$trnlnm(ddev-":") .nes. "") then ddev = f$trnlnm(ddev-":")$$ ddir = f$parse(here,,,"directory")1$ here = ddev+ddir - "][" - "000000." - ".000000"$ if p1 .eqs. "LOGGER"$ then$ call shutdown_logger$ exit$ endif$!#$ x = f$search(here+"CRINOID.USER")$ if x .eqs. ""$ thenN$ write sys$output "CRINOID SHUTDOWN -- ERROR: CRINOID.USER file not found!"$ x = f$setprv(oprv)$ exit$ endif$ open/read fd 'x$ read fd user$ read fd node$ read fd pname $ close fd#$ user = f$edit(user,"trim,upcase")#$ node = f$edit(node,"trim,upcase")$! $ ctx = ""4$ x = f$context("PROCESS",ctx,"NODENAME",node,"EQL")4$ x = f$context("PROCESS",ctx,"USERNAME",user,"EQL")$ pidlist = ""$ loop:$ pid = f$pid(ctx)#$ if pid .eqs. "" then goto eloop $ name = ""!$ name = f$getjpi(pid,"PRCNAM")$ if name .eqs. pname$ then9$ write sys$output "Stopping ''pname' (PID:''pid')"$ stop/id='pid'$ goto loop $ endif4$ if name .eqs. "CRINOIDLOG" .and. p1 .eqs. "FULL"$ then"$ call shutdown_logger 'pid' $ endif'$ if f$extract(0,4,name) .eqs. "STUB"$ then>$ write sys$output "Stopping Zombie'd STUB (PID:''pid')"$ stop/id='pid'$ goto loop $ endif $ got loop$ eloop:$!$! remove any installed images$!.$ if p1 .eqs. "FULL" .or. p1 .eqs. "DEINSTALL"$ then$ ext = ".EXE":$ if f$getsyi("ARCH_NAME") .nes. "VAX" then ext = ".AXE"($ call remove_image 'here'CRINOID'ext''$ call remove_image 'here'LOGGER'ext'%$ call remove_image 'here'STUB'ext'$ endif$ x = f$setprv(oprv)$ exit$!$ remove_image: subroutine+$ if .not. f$file(p1,"KNOWN") then exit 1)$ write sys$output "deinstalling ''p1'"$ x = "install"$ x remove 'p1'$ exit$ endsubroutine$!,$! shut down the logger, nicely if possible$!$ shutdown_logger: subroutine $ pid = p1*$ if f$trnlnm("CRINOIDLOG_MBX") .eqs. ""$ then2$ write sys$output "CRINOIDLOG not running." $ exit $ endif=$ write sys$output "Trying for nice shutdown of CRINOIDLOG")$ define/system crinoidlog_command stop $ j = 12$ wait 00:00:01 $ loop2:B$ if f$trnlnm("CRINOIDLOG_COMMAND") .eqs. "" then goto eloop2$ j = j - 1$$ if j .eq. 0 then goto eloop2a$ wait 00:00:05$ goto loop2$! ---not responding--- $ eloop2a:#$ deass/system crinoidlog_command$ if (pid .nes. "")$ then;$ write sys$output "Stopping CRINOIDLOG (PID:''pid')"$ stop/id='pid' $ endif $ eloop2:$ exit$ endsubroutine*[CRINOID0051.MISC]STARTUP.COM;1+,SU;. / 4` <-L(0123KPWO 56vϞ%7Y(89GHJ?$!^^^^^^^^^^installation procedure should insert definitions ofC$! CRINOID_USERNAME, CRINOID_MGR, CRINOID_SERVICE, above.$!?$! installation of CRINOID images, optionally start the server/$! put this file in the CRINOID_home directory$!=$! @STARTUP !! installs/replaces program imagesC$! @STARTUP RUN !! also starts CRINOID with faked request$!A$!---------------------------------------------------------------$!$! check privs$!'$ op = f$setprv("SYSNAM,SYSPRV,CMKRNL").$ if .not. f$privilege("SYSNAM,SYSPRV,CMKRNL")$ thenT$ write sys$output "Must have SYSNAM, SYSPRV and CMKRNL to install CRINOID images"$ x = f$setprv(op) $ exit 44$ endif$!H$!----------------------------------------------------------------------$!>$ if f$type(CRINOID_manager) !! prepended during install$ then4$ DEFINE/SYSTEM CRINOID_MGR "''CRINOID_manager'"$ endif$!B$!----------------------------------------------------------------$!$! image installation$!$ ext = ".EXE"8$ if f$getsyi("ARCH_NAME") .nes. "VAX" then ext = ".AXE"$!$$! get rid of rooted logicals, etc.$!<$ here = f$parse("Z.Z;",f$environment("Procedure")) - "Z.Z;"!$ ddev = f$parse(here,,,"device")A$ if (f$trnlnm(ddev-":") .nes. "") then ddev = f$trnlnm(ddev-":")$$ ddir = f$parse(here,,,"directory")1$ here = ddev+ddir - "][" - "000000." - ".000000"$!C$! as of 7.2? 7.1? need "impersonate" priv to use persona services$!$ need_cmkrnl = 0$ open/read fd stub.opt$ loop:$ read/end=eloop fd line $ line = f$edit(line,"upcase")I$ if f$locate("NEED_CMKRNL",line) .lt. f$len(line) then need_cmkrnl = 1 $ goto loop$ eloop: $ close fdC$!-----------------------------------------------------------------$!$ stubprivs = "SYSPRV,DETACH"7$ if need_cmkrnl then stubprivs = stubprivs + ",CMKRNL"$!$ define/user sys$output nl:$ define/user sys$error nl: $ x = f$privilege("IMPERSONATE") $ x = f$integer($STATUS) .and. 1B$ type nl: !! reset the define/user's1$ if x then stubprivs = subprivs + ",IMPERSONATE"$!C$!-----------------------------------------------------------------`$ call install_image 'here'CRINOID'ext' /priv=(LOG_IO,PHY_IO,SYSPRV,SYSNAM,DETACH,WORLD,SYSLCK)>$ call install_image 'here'LOGGER'ext' /priv=(SYSNAM,SYSLCK)<$ call install_image 'here'STUB'ext' /priv=('stubprivs')C$!-----------------------------------------------------------------$!"$! if requested, start the server$!$ if p1 .eqs. "RUN"$ then($ IF F$TYPE(CRINOID_USERNAME) .EQS. ""$ then]$ WRITE SYS$OUTPUT "Can't start CRINOID, don't have USERNAME set...use browser request"$ goto done $ endif'$ IF F$TYPE(CRINOID_SERVICE) .EQS. ""$ then\$ WRITE SYS$OUTPUT "Can't start CRINOID, don't have SERVICE set...use browser request"$ goto done $ endif&$ SET MESSAGE 'HERE'CRINOID_MSG'EXT'#$ startup :== $'HERE'STARTUP'ext'1$ write sys$output "Starting CRINOID server..."6$ startup "''crinoid_username'" "''crinoid_service'"$ endifC$!-----------------------------------------------------------------$ done:$ x = f$setprv(op)$ EXIT$!$ install_image: subroutine$ action = "ADD":$ if f$file_attributes(P1,"KNOWN") then action = "REPLACE"2$ write sys$output "doing INSTALL ''action' ''p1'" $ set noon&$ install 'action' 'p1' 'p2' 'p3' 'p4'$ on error then exit$ exit$ endsubroutine*[CRINOID0051.MISC]STUB.COM;1+,U*. / 4A <-L(0123KPWO 56'4%7)p(89GHJ$! 'f$verify(0)<$ here = f$parse("Z.Z;",f$environment("Procedure")) - "Z.Z;"!$ ddev = f$parse(here,,,"device")A$ if (f$trnlnm(ddev-":") .nes. "") then ddev = f$trnlnm(ddev-":")$$ ddir = f$parse(here,,,"directory")1$ here = ddev+ddir - "][" - "000000." - ".000000"$!$ ext = ".EXE"8$ if f$getsyi("ARCH_NAME") .nes. "VAX" then ext = ".AXE"$$ SET MESSAGE 'HERE'CRINOID_MSG'EXT'$!$ run/nodebug 'here'stub'ext' $ stop/id=0 *[CRINOID0051.MISC]TENTACLE.COM;1+,U. / 4Y `<-L(0123KPWO 56/ſ%7(89GHJ$!'f$verify(0)$ call set_process_name<$ here = f$parse("Z.Z;",f$environment("Procedure")) - "Z.Z;"!$ ddev = f$parse(here,,,"device")A$ if (f$trnlnm(ddev-":") .nes. "") then ddev = f$trnlnm(ddev-":")$$ ddir = f$parse(here,,,"directory")1$ here = ddev+ddir - "][" - "000000." - ".000000"$ root = here - "]" + ".]"$!$ L_MAIN = %X00000100$ L_NETIO = %X00000200$ L_LOCKING = %X00000400$ L_PROC = %X00000800$ L_PIPE = %X00001000$ L_MBXQ = %X00002000$!$ L_CRITICAL = 0$ L_ERROR = 1$ L_WARNING = 2$ L_INFO = 3$ L_TRACE = 4$ L_BABBLE = 5$ L_DEBUG = 6$!$ LOGLEV = L_WARNING$! LOGLEV = L_BABBLE$! LOGLEV = L_DEBUG+L_PIPE$!9$ DEFINE/NOLOG TENTACLE_LOGLEVEL 'loglev'2$ DEFINE/NOLOG/TRANS=CONCEAL CRINOID_ROOT 'root'A$ DEFINE/NOLOG CRINOID_HOME CRINOID_ROOT:[000000],$ debug = f$trnlnm("CRINOID_TENTACLE_DEBUG").$ open/read/share fd CRINOID_home:tentacle.opt$ loop1:$ read/end=eloop1 fd line)$ line = f$edit(line,"collapse,upcase")0$ if f$element(0,"=",line) .eqs. "!PERL_SETUP"$ then'$! avoid logical redefine messagesX$ if f$trnlnm("PERL_ROOT","LNM$PROCESS") .nes. "" then deassign/process perl_rootV$ if f$trnlnm("PERLSHR","LNM$PROCESS") .nes. "" then deassign/process perlshrY$ if f$trnlnm("DBGPERLSHR","LNM$PROCESS") .nes. "" then deassign/process dbgperlshr$!!$ x = f$element(1,"=",line))$ if f$search(x) .nes. "" then @'x'$ goto eloop1 $ endif $ goto loop1 $ eloop1: $ close fd$!:$! local definition to set up PGPLOT ... modify to suit$!($ if f$getsyi("NODENAME") .eqs. "DUHEP3"$ then:$ util_setup == "@public$root:[setup]setup/output=NL: "$ util_setup pgplot520$ endif$!$ flag = "/nodebug"$ if debug .nes. ""$ then$ flag = "/debug"2$ set display/create/transp=tcpip/node='debug'3$ f = f$search("CRINOID_home:dbg$tentacle.ini")$ if f .nes. "" $ then?$ define/NOLOG dbg$init CRINOID_home:dbg$tentacle.ini $ endif$ endif$!$ ext = ".EXE"8$ if f$getsyi("ARCH_NAME") .nes. "VAX" then ext = ".AXE"$$ SET MESSAGE 'HERE'CRINOID_MSG'EXT'&$ run'flag' CRINOID_home:tentacle'ext' $ stop/id=0H$!----------------------------------------------------------------------$!$! set process name$!$ set_process_name: subroutine$ MYPID = F$GETJPI(0,"PID")$ MYUIC = F$GETJPI(0,"UIC")=$ MYNAME = F$EDIT(F$GETJPI(0,"USERNAME"),"COLLAPSE,UPCASE") $ J = 0 $ TRY_NAME:$ J = J + 1$ X = F$FAO("!SL",J)$ Y = F$FAO("!2ZL",J)0$ IF F$LENGTH(X) .GT. F$LENGTH(Y) THEN Y = X1$ NAME = F$EXTRACT(0,15-4-F$LENGTH(Y),MYNAME)$ NAME = NAME + "/CGI" + Y$ CONTEXT = "" $ LOOP:$ PID = F$PID(CONTEXT)/$ IF PID .EQS. "" THEN GOTO SEARCH_DONE+$ IF PID .EQS. MYPID THEN GOTO LOOP#$ UIC = F$GETJPI(PID,"UIC")+$ IF UIC .NES. MYUIC THEN GOTO LOOP($ PNAME = F$GETJPI(PID,"PRCNAM"),$ IF PNAME .NES. NAME THEN GOTO LOOP$ GOTO TRY_NAME$ SEARCH_DONE:.$ SET MESSAGE/NOFACIL/NOSEVER/NOIDENT/NOTEXT $ SET NOON$ SET PROC/NAME="''NAME'"$$ FOO = F$INTEGER($STATUS) .AND. 1$ ON ERROR THEN EXIT&$ SET MESSAGE/FACIL/SEVER/IDENT/TEXT#$ IF .NOT. FOO THEN GOTO TRY_NAME $ EXIT 1$ endsubroutine*[CRINOID0051.MISC]TIEENV.PM;1+,U./ 4H <-L(0123KPWO56ٖ&7((89GHJ#! perlpackage TieENV;BEGIN {E use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);* # set the version for version checking $VERSION = 0.1; @ISA = qw(); @EXPORT = qw();= %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ],} sub new { my $class = shift; my $basename = shift; my $self = { VALUE => {}, STATIC => {}, FAKE => {}, VOLATILE => {}, PERSISTENT => {}, CHANGED => {}, BASENAME => $basename, TYPE => 'OBJECT', }; bless $self, $class;/ tie(%{$basename."::ENV"}, 'TieENV', $self); return $self;} sub static { my $self = shift; my $k, $k2; foreach $k2 (@_) { $k = uc($k2);( $self->{VALUE}->{$k} = $ENV{$k};" $self->{STATIC}->{$k} = 1;$ delete($self->{FAKE}->{$k});( delete($self->{VOLATILE}->{$k});* delete($self->{PERSISTENT}->{$k}); }} sub fake { my $self = shift; my %hash = (@_); my ($k, $k2, $v);$ while (($k2,$v) = each(%hash)) { $k = uc($k2);" $self->{VALUE}->{$k} = $v;! $self->{FAKE}->{$k} = $v;& delete($self->{STATIC}->{$k});( delete($self->{VOLATILE}->{$k});* delete($self->{PERSISTENT}->{$k}); }}sub volatile { my $self = shift; my $k, $k2; foreach $k2 (@_) { $k = uc($k2);( $self->{VALUE}->{$k} = $ENV{$k};+ $self->{VOLATILE}->{$k} = $ENV{$k};& delete($self->{STATIC}->{$k});$ delete($self->{FAKE}->{$k});* delete($self->{PERSISTENT}->{$k});# $self->{CHANGED}->{$k} = 0; }}sub persistent { my $self = shift; my $k, $k2; foreach $k2 (@_) { $k = uc($k2);( $self->{VALUE}->{$k} = $ENV{$k};& $self->{PERSISTENT}->{$k} = 1;& delete($self->{STATIC}->{$k});$ delete($self->{FAKE}->{$k});( delete($self->{VOLATILE}->{$k}); }} sub reset { my $self = shift; my $k;- foreach $k (keys(%{$self->{VOLATILE}})) {% if ($self->{CHANGED}->{$k}) {3 if (defined($self->{VOLATILE}->{$k})) {3 $ENV{$k} = $self->{VOLATILE}->{$k}; } else {! delete($ENV{$k}); } } } $self->{CHANGED} = {};* foreach $k (keys(%{$self->{VALUE}})) {. next if exists($self->{STATIC}->{$k});, next if exists($self->{FAKE}->{$k});0 next if exists($self->{VOLATILE}->{$k});2 next if exists($self->{PERSISTENT}->{$k});% delete($self->{VALUE}->{$k}); }}sub initialize { my $self = shift; my $k;) foreach $k (keys(%{$self->{FAKE}})) {3 $self->{VALUE}->{$k} = $self->{FAKE}->{$k}; }+ foreach $k (keys(%{$self->{STATIC}})) {( $self->{VALUE}->{$k} = $ENV{$k}; }} sub TIEHASH { my $class = shift; my $parent = shift; my $self = { PARENT => $parent, TYPE => 'HASH', }; bless $self, $class; return $self;} sub FETCH { my $self = shift; my $k = uc(shift);4 if (exists($self->{PARENT}->{VOLATILE}->{$k}) or6 exists($self->{PARENT}->{PERSISTENT}->{$k})) {2 $self->{PARENT}->{VALUE}->{$k} = $ENV{$k}; }* return $self->{PARENT}->{VALUE}->{$k};} sub STORE { my $self = shift; my $k = uc(shift); my $v = shift;( $self->{PARENT}->{VALUE}->{$k} = $v;4 if (exists($self->{PARENT}->{VOLATILE}->{$k})) { $ENV{$k} = $v;- $self->{PARENT}->{CHANGED}->{$k} = 1;; } elsif (exists($self->{PARENT}->{PERSISTENT}->{$k})) { $ENV{$k} = $v; }} sub DELETE { my $self = shift; my $k = uc(shift);+ delete($self->{PARENT}->{VALUE}->{$k});A delete($ENV{$k}) if exists($self->{PARENT}->{DYNAMIC}->{$k});} sub CLEAR { my $self = shift; my $k;4 foreach $k (keys(%{$self->{PARENT}->{VALUE}})) {/ delete($self->{PARENT}->{VALUE}->{$k}); }} sub EXISTS{ my $self = shift; my $k = uc(shift);2 return exists($self->{PARENT}->{VALUE}->{$k});} sub FIRSTKEY{ my $self = shift;H my $a = keys %{$self->{PARENT}->{VALUE}}; # reset each() iterator+ return each %{$self->{PARENT}->{VALUE}}} sub NEXTKEY{ my $self = shift;+ return each %{$self->{PARENT}->{VALUE}}} sub DESTROY{ my $self;" if ($self->{TYPE} eq 'HASH') {! $self->{PARENT}->reset(); } else { $self->reset(); }}1;*[CRINOID0051]MSG.H;1+,Uj. / 4L <-Ke0123KPWO 56 g7%(89GHJL/**************************************************************************\K * *K * MAILBOX MESSAGE CODES *K * *K * *L\**************************************************************************/#ifndef __MSG_H#define __MSG_H#include #define MSG$_BUSY 1024(#define MSG$_ENVDATA (MSG$_BUSY+1)(#define MSG$_IDLE (MSG$_BUSY+2)(#define MSG$_LOGLEV (MSG$_BUSY+3)(#define MSG$_ERRLOG (MSG$_BUSY+4)(#define MSG$_HEARTBEAT (MSG$_BUSY+5)(#define MSG$_LUBDUB (MSG$_BUSY+6)(#define MSG$_STUBREADY (MSG$_BUSY+7)(#define MSG$_USERNAME (MSG$_BUSY+8)(#define MSG$_PROCPRIVS (MSG$_BUSY+9))#define MSG$_PROCQUOTA (MSG$_BUSY+10))#define MSG$_PROCFLAGS (MSG$_BUSY+11))#define MSG$_STARTPID (MSG$_BUSY+12))#define MSG$_PROCSTART (MSG$_BUSY+13))#define MSG$_PROCPROG (MSG$_BUSY+14))#define MSG$_PROCPRIOR (MSG$_BUSY+15))#define MSG$_PROCTMBX (MSG$_BUSY+16))#define MSG$_PROCNAME (MSG$_BUSY+17))#define MSG$_PENDABORT (MSG$_BUSY+18))#define MSG$_LOGQLOCK (MSG$_BUSY+19))#define MSG$_LOGSTART (MSG$_BUSY+20)/* this must come last !! */)#define MSG$_MAXMSG (MSG$_BUSY+19)#ifdef WANT_MSG_TEXTstruct MSGTEXT { int code; char *text;};#define MSGDEF(c,t) {c,t}$static struct MSGTEXT messages[] = {. MSGDEF(MSG$_DELPROC , "DELETE PROCESS"),. MSGDEF(MSG$_DEVOFFLIN , "DEVICE OFFLINE"),0 MSGDEF(MSG$_TRMHANGUP , "TERMINAL HANG UP"),- MSGDEF(MSG$_DEVONLIN , "DEVICE ONLINE"),4 MSGDEF(MSG$_ABORT , "PARTNER ABORTED LINK"),/ MSGDEF(MSG$_CONFIRM , "CONNECT CONFIRM"),8 MSGDEF(MSG$_CONNECT , "INBOUND CONNECT INITIATE"),= MSGDEF(MSG$_DISCON , "PARTNER DISCONNECTED - HANGUP"),: MSGDEF(MSG$_EXIT , "PARTNER EXITED PREMATURELY"),D MSGDEF(MSG$_INTMSG , "INTERRUPT MESSAGE - UNSOLICITED DATA"),: MSGDEF(MSG$_PATHLOST , "NFW - PATH LOST TO PARTNER"),. MSGDEF(MSG$_PROTOCOL , "PROTOCOL ERROR"),. MSGDEF(MSG$_REJECT , "CONNECT REJECT"),6 MSGDEF(MSG$_THIRDPARTY, "THIRD PARTY DISCONNECT"),/ MSGDEF(MSG$_TIMEOUT , "CONNECT TIMEOUT"),5 MSGDEF(MSG$_NETSHUT , "Network shutting down"),: MSGDEF(MSG$_NODEACC , "Node has become accessible"),< MSGDEF(MSG$_NODEINACC , "Node has become inaccessible"),; MSGDEF(MSG$_EVTAVL , "Events are available to EVL"),> MSGDEF(MSG$_EVTRCVCHG , "Event receiver database change"),1 MSGDEF(MSG$_INCDAT , "X25 INCOMING DATA"),1 MSGDEF(MSG$_RESET , "X25 CIRCUIT RESET"),# MSGDEF(MSG$_BUSY , "BUSY"),& MSGDEF(MSG$_ENVDATA , "ENVDATA"),# MSGDEF(MSG$_IDLE , "IDLE"),% MSGDEF(MSG$_LOGLEV , "LOGLEV"),% MSGDEF(MSG$_ERRLOG , "ERRLOG"),( MSGDEF(MSG$_HEARTBEAT, "HEARTBEAT"),% MSGDEF(MSG$_LUBDUB , "LUBDUB"),( MSGDEF(MSG$_STUBREADY, "STUBREADY"),' MSGDEF(MSG$_USERNAME , "USERNAME"),( MSGDEF(MSG$_PROCPRIVS, "PROCPRIVS"),( MSGDEF(MSG$_PROCQUOTA, "PROCQUOTA"),( MSGDEF(MSG$_PROCFLAGS, "PROCFLAGS"),' MSGDEF(MSG$_STARTPID , "STARTPID"),( MSGDEF(MSG$_PROCSTART, "PROCSTART"),' MSGDEF(MSG$_PROCPROG , "PROCPROG"),( MSGDEF(MSG$_PROCPRIOR, "PROCPRIOR"),' MSGDEF(MSG$_PROCTMBX , "PROCTMBX"),' MSGDEF(MSG$_PROCNAME , "PROCNAME"),( MSGDEF(MSG$_PENDABORT, "PENDABORT"),' MSGDEF(MSG$_LOGQLOCK , "LOGQLOCK"),& MSGDEF(MSG$_LOGSTART , "LOGSTART")};#endif /*WANT_MSG_TEXT*/#endif+*[CRINOID0051]OPCODE_500557_20000726.PATCH;1+,V. / 4Q -Ke0123KPWO 56pڞ7(89GHJPatch for Opcode.xs, for Perl <= 5.005.57 This patch does three things: 1) make code in a Safe:: partition think it's running in main:: (need for modules) 2) connect the _ in the partition to the global _ so it works right 3) set curstash to defstash like more recent Perls. --- ext/Opcode/Opcode.xs-orig Wed Jul 26 09:54:45 2000 +++ ext/Opcode/Opcode.xs Wed Jul 26 09:54:17 2000 @@ -252,6 +252,14 @@ save_hptr(&PL_defstash); /* save current default stack */ /* the assignment to global defstash changes our sense of 'main' */ PL_defstash = gv_stashpv(Package, GV_ADDWARN); /* should exist already */ + if (strNE(HvNAME(PL_defstash),"main")) { + Safefree(HvNAME(PL_defstash)); + HvNAME(PL_defstash) = savepv("main"); /* make it think it's in main:: */ + hv_store(PL_defstash,"_",1,(SV *)PL_defgv,0); /* connect _ to global */ + SvREFCNT_inc((SV *)PL_defgv); /* want to keep _ around! */ + } + save_hptr(&PL_curstash); + PL_curstash = PL_defstash; /* defstash must itself contain a main:: so we'll add that now */ /* take care with the ref counts (was cause of long standing bug) */ +*[CRINOID0051]OPCODE_500559_20000726.PATCH;1+,%V. / 4Q -Ke0123KPWO 56`pڞ7(89GHJPatch for Opcode for Perl >= 5.005.59 1) make routines in Safe:: partitions think they are in main:: 2) connect the _ in the partition to the global _ --- ext/Opcode/Opcode.xs-orig Wed Jul 26 07:00:15 2000 +++ ext/Opcode/Opcode.xs Wed Jul 26 06:59:39 2000 @@ -253,6 +253,12 @@ save_hptr(&PL_defstash); /* save current default stack */ /* the assignment to global defstash changes our sense of 'main' */ PL_defstash = gv_stashpv(Package, GV_ADDWARN); /* should exist already */ + if (strNE(HvNAME(PL_defstash),"main")) { + Safefree(HvNAME(PL_defstash)); + HvNAME(PL_defstash) = savepv("main"); /* make it think it's in main:: */ + hv_store(PL_defstash,"_",1,(SV *)PL_defgv,0); /* connect _ to global */ + SvREFCNT_inc((SV *)PL_defgv); /* want to keep _ around! */ + } save_hptr(&PL_curstash); PL_curstash = PL_defstash; E*[CRINOID0051]PARSER.C;1+,MV./ 4^ <-Ke0123KPWO56K+.w7fLƄ(89GHJ  /*( subroutines to parse input lines*/#include #include #include #include #include "parser.h"#include "util.h"pVerb^new_Verb(char *verb, int id, int (*handler)(pVerb v, char **args, char *errmsg), pVerb vhead){ ROUTINE_NAME("new_Verb"); pVerb v; v = malloc(sizeof(Verb)); v->next = vhead; v->nunique = 1; v->id = id;% v->verb = malloc(strlen(verb)+1); strcpy(v->verb, verb); v->handler = handler; return v;}voiduniquify_Verb(pVerb v){" ROUTINE_NAME("uniquify_Verb"); pVerb w; char *s1, *s2; int n; while (v) { w = v->next; while (w) { s1 = v->verb; s2 = w->verb; n = 1;@ while (*s1 && *s2 && tolower(*s1) == tolower(*s2)) { s1++; s2++; n++; }, v->nunique = MAX(v->nunique, n);, w->nunique = MAX(w->nunique, n); w = w->next; } v = v->next; }}int.parse_line(pVerb vhead, char *s, char *errmsg){ ROUTINE_NAME("parse_line"); pVerb v; char **args; int maxargs = 16; int n, j, status, nargs = 0;8 args = (char **) malloc((maxargs+1)*sizeof(char *)); if (!args) {: strcpy(errmsg,"parse_line: malloc fail for args"); return 0; } while (1) {& while (*s && isspace(*s)) s++;$ if (!*s || *s == '#') break; if (nargs == maxargs) { char **args2; int j;C args2 = (char **) malloc((2*maxargs+1)*sizeof(char *)); if (!args2) {B strcpy(errmsg,"parse_line: malloc fail for args");: for (j = 0; j < nargs; j++) free(args[j]); free(args); return 0; }) for (j = 0; j < nargs; j++) {# args2[j] = args[j]; } free(args); args = args2; maxargs = 2*maxargs; } if (*s == '"') {5 args[nargs] = destringify(&s, errmsg,&n); if (!args[nargs]) {> for (j = 0; j < nargs; j++) free(args[j]); free(args); return 0; } nargs++; } else { char *p = s;+ while (*p && !isspace(*p)) p++;( args[nargs] = 0"e~ FREEWARE.SAVMVKe[CRINOID0051]PARSER.C;1^malloc(p-s+1); if (!args[nargs]) {F strcpy(errmsg,"parse_line: malloc fail for argument");: for (j = 0; j < nargs; j++) free(args[j]); free(args); return 0; }' strncpy(args[nargs],s,p-s);$ args[nargs][p-s] = '\0'; s = *p? p + 1 : p; nargs++; } } args[nargs] = 0; /* find verb */ if (!args[0]) { free(args); return 1; } v = vhead; while (v) { char *s1, *s2; int nmatch; s1 = v->verb; s2 = args[0]; nmatch = 0;< while (*s1 && *s2 && tolower(*s1) == tolower(*s2)) { nmatch++; s1++; s2++; }0 if (nmatch >= v->nunique && !*s2) break; v = v->next; } if (!v) {@ sprintf(errmsg,"parse_line: unknown verb '%s'",args[0]);2 for (j = 0; j < nargs; j++) free(args[j]); free(args); return 0; }) status = (v->handler)(v,args,errmsg);. for (j = 0; j < nargs; j++) free(args[j]); free(args); return status;}char *0destringify(char **s, char *errmsg, int *result){ ROUTINE_NAME("destringify"); char *p = *s+1, *q, *q0; int n = 0; *result = 0; while (*p && *p != '"') {- if (*p == '\\' && *(p+1) == '"') p++; p++; } q0 = q = malloc(p-*s); if (!q) {4 strcpy(errmsg,"destringify: malloc failed"); return 0; } p = *s+1; while (*p && *p != '"') { if (*p != '\\') { *q++ = *p++; } else { p++; switch (*p) { case '\r': case '\n': p++; case '\0': break; case '0': case '1': case '2':# n = *p++ - '0';1 if (*p >= '0' && *p <= '7') { n *= 8;( n += *p++ - '0';5 if (*p >= '0' && *p <= '7') {# n *= 8;, n += *p++ - '0'; } } *q++ = n; break; case 'r': *q++ = '\r'; p++; break; case 'n': *q++ = '\n'; p++; break; case 't': *q++ = '\t'; p++; break; case 'f': *q++ = '\f'; p++; break; default: *q++ = *p++; } } } *result = (q - q0); *s = (*p == '"') ? p+1 : p; *q = '\0'; return q0;}voiddestroy_Verb(pVerb v){! ROUTINE_NAME("destroy_Verb"); pVerb v2; while (v) {# if (v->verb) free(v->verb); v2 = v; v = v->next; free(v2); }}*[CRINOID0051]PARSER.H;1+,PVq. / 4 -Ke0123KPWO 56=2ȝ7Ԅ(89GHJ/* parser data structures, etc. */ #ifndef __PARSER_H #define __PARSER_H typedef struct PARSE_CMD_STRUCT Verb; typedef struct PARSE_CMD_STRUCT * pVerb; typedef int VerbHandler(pVerb v, char **args, char *errmsg); typedef int (* pVerbHandler)(pVerb v, char **args, char *errmsg); struct PARSE_CMD_STRUCT { pVerb next; int nunique; int id; char *verb; pVerbHandler handler; }; /* int (*handler)(pVerb v, char **args, char *errmsg); extern pVerb new_Verb(char *verb, int (*handler)(pVerb v, char **args, char *errmsg), pVerb vhead); */ #define MAX(a,b) ((a)>(b)?(a):(b)) extern pVerb new_Verb(char *verb, int id, pVerbHandler handler, pVerb vhead); extern void uniquify_Verb(pVerb v); extern int parse_line(pVerb vhead, char *s, char *errmsg); extern char * destringify(char **s, char *errmsg, int *result); extern void destroy_Verb(pVerb v); #endif -*[CRINOID0051]PIPE2.C;1+,V./ 4i2<-Ke0123KPWO56 7(89GHJ"/*% PIPE DATA FROM ONE MBX TO ANOTHER*/#include #include #include #include #include #define __PIPE2_PRIVATE#include "pipe2.h"#include "errlog_client.h"pPipe2Pipe_new(pMBX in, pMBX out){ ROUTINE_NAME("Pipe_new"); int size;% pPipe2 p = malloc(sizeof(Pipe2));O errlog(L_PIPE|L_TRACE,"Pipe_new(pMBXin:!XL pMBXout:!XL) = !XL",in, out, p); if (!p) {5 errlog(L_CRITICAL,"Pipe_new: failed malloc"); goto error; } p->in_mbx = p->out_mbx = 0; p->inQ = p->outQ = 0; p->buffer = 0; p->bcount = 0; size = 0; if (in) { size = in->size; } else if (out) { size = out->size; } if (in) { p->in_mbx = in; } else {$ p->in_mbx = new_MBX(0,size);A errlog(L_PIPE|L_BABBLE,"Pipe_new: in_mbx !XL",p->in_mbx); if (!p->in_mbx) {B errlog(L_CRITICAL,"Pipe_new: failed creating in_mbx"); goto error; } } if (out) { p->out_mbx = out; } else {% p->out_mbx = new_MBX(0,size);C errlog(L_PIPE|L_BABBLE,"Pipe_new: out_mbx !XL",p->out_mbx); if (!p->out_mbx) {C errlog(L_CRITICAL,"Pipe_new: failed creating out_mbx"); goto error; } }G p->inQ = MbxQ_new(p->in_mbx, MBXQ$_READ|MBXQ$M_NOSTART, &Pipe_AST);7 errlog(L_PIPE|L_BABBLE,"Pipe_new: inQ !XL",p->inQ); if (!p->inQ) {; errlog(L_CRITICAL,"Pipe_new: failed creating inQ"); goto error; } p->inQ->extra = p;@ p->outQ = MbxQ_new(p->out_mbx, MBXQ$_WRITE|MBXQ$M_RETRY, 0);9 errlog(L_PIPE|L_BABBLE,"Pipe_new: outQ !XL",p->outQ); if (!p->outQ) {< errlog(L_CRITICAL,"Pipe_new: failed creating outQ"); goto error; } MbxQ_start(p->inQ); return p;error: if (p) {5 if (p->in_mbx && !in) destroy_MBX(p->in_mbx);7 if (p->out_mbx && !out) destroy_MBX(p->in_mbx);) if (p->inQ) MbxQ_destroy(p->inQ);+ if (p->outQ) MbxQ_destroy(p->outQ); free(p); }7 errlog(L_CRITICAL,"Pipe_new: ERROR creating pipe"); return 0;} static voidPipe_AST(pMbxE e){ ROUTINE_NAME("Pipe_AST"); int iss = pMbxE_status(e); pMbxQ q = e->queue; pPipe2 p = q->extra; char *slog;_ errlog(L_PIPE|L_TRACE,"Pipe_AST Queue: !XL, id: !SL Pipe:!XL, status:!XL)",q,e->id,p,iss); if (iss == SS$_ENDOFFILE) {% if (p->buffer && p->bcount) {Y errlog(L_PIPE|L_BABBLE,"Pipe_AST: transmitting !SL bytes at EOF", p->bcount);4 MbxQ_write(p->outQ,p->buffer,p->bcount);Y if (islogging(L_PIPE|L_DEBUG) && (slog = dumpstring(p->buffer, p->bcount))) {@ errlog(L_PIPE|L_DEBUG,"Pipe_AST: T:'!AZ'",slog); free(slog); } p->bcount = 0; }= errlog(L_PIPE|L_BABBLE,"Pipe_AST: transmitting EOF");# MbxQ_write(p->outQ, 0, -1);P } else if (iss == SS$_LINKDISCON || iss == SS$_CANCEL || iss == SS$_ABORT) {% if (p->buffer && p->bcount) {\ errlog(L_PIPE|L_BABBLE,"Pipe_AST: transmitting !SL bytes at DISCON", p->bcount);4 MbxQ_write(p->outQ,p->buffer,p->bcount);Y if (islogging(L_PIPE|L_DEBUG) && (slog = dumpstring(p->buffer, p->bcount))) {@ errlog(L_PIPE|L_DEBUG,"Pipe_AST: T:'!AZ'",slog); free(slog); } p->bcount = 0; } Pipe_shutdown(p); } else if (VMS_ERR(iss)) { VMS_SIGNAL(iss); } else { if (p->buffer) { int m, n = e->len; char *t = e->buf;F errlog(L_PIPE|L_BABBLE,"Pipe_AST: appending !SL bytes",n); while (n > 0) {Z m = (n + p->bcount > p->out_mbx->size) ? p->out_mbx->size - p->bcount : n;2 memcpy(p->buffer+p->bcount, t, m); p->bcount += m; t += m; n -= m;i if (p->bcount == p->out_mbx->size || (p->bcount && memchr(p->buffer, 0x0a, p->bcount))) {D iss = MbxQ_write(p->outQ, p->buffer, p->bcount);f errlog(L_PIPE|L_BABBLE,"Pipe_AST: transmitting !UL bytes, iss=!XL",p->bcount,iss);a if (islogging(L_PIPE|L_DEBUG) && (slog = dumpstring(p->buffer, p->bcount))) {H errlog(L_PIPE|L_DEBUG,"Pipe_AST: T:'!AZ'",slog);# free(slog); }' if (VMS_ERR(iss)) {i errlog(L_PIPE|L_WARNING,"Pipe_AST: error transmitting (!XL), shutdown pipe",iss);) Pipe_shutdown(p); }" p->bcount = 0; } } } else {6 iss = MbxQ_write(p->outQ, e->buf, e->len);[ errlog(L_PIPE|L_BABBLE,"Pipe_AST: transmitting !UL bytes, iss=!XL",e->len,iss); if (VMS_ERR(iss)) {a errlog(L_PIPE|L_WARNING,"Pipe_AST: error transmitting (!XL), shutdown pipe",iss);! Pipe_shutdown(p); }S if (islogging(L_PIPE|L_DEBUG) && (slog = dumpstring(e->buf, e->len))) {@ errlog(L_PIPE|L_DEBUG,"Pipe_AST: T:'!AZ'",slog); free(slog); } } } MbxQ_dispose(e);}voidPipe_shutdown(pPipe2 p){" ROUTINE_NAME("Pipe_shutdown");7 errlog(L_PIPE|L_TRACE,"Pipe_shutdown(pipe:!XL)",p); if (!p) return; MbxQ_shut(p->inQ); MbxQ_shut(p->outQ);}pPipe2Pipe_destroy(pPipe2 p){! ROUTINE_NAME("Pipe_destroy");6 errlog(L_PIPE|L_TRACE,"Pipe_destroy(pipe:!XL)",p); if (!p) return 0; MbxQ_destroy(p->inQ); MbxQ_destroy(p->outQ); destroy_MBX(p->in_mbx); destroy_MBX(p->out_mbx);# if (p->buffer) free(p->buffer); free(p); return 0;}/* destroy with flush */pPipe2Pipe_destroy2(pPipe2 p){" ROUTINE_NAME("Pipe_destroy2"); int iss, j, bin, sent; char *slog;7 errlog(L_PIPE|L_TRACE,"Pipe_destroy2(pipe:!XL)",p); if (!p) return 0;9 MbxQ_shut2(p->inQ); /* wait for input shutdown */ bin = MbxQ_bytes(p->inQ); MbxQ_destroy(p->inQ); destroy_MBX(p->in_mbx);! if (p->buffer && p->bcount) {8 iss = MbxQ_write(p->outQ, p->buffer, p->bcount);_ errlog(L_PIPE|L_BABBLE,"Pipe_destroy2: transmitting !UL bytes, iss=!XL",p->bcount,iss);6 if (slog = dumpstring(p->buffer, p->bcount)) {< errlog(L_PIPE|L_DEBUG,"Pipe_AST: T:'!AZ'",slog); free(slog); } if (VMS_ERR(iss)) {b errlog(L_PIPE|L_WARNING,"Pipe_destroy2: error transmitting (!XL), shutdown pipe",iss); Pipe_shutdown(p); } p->bcount = 0; }< iss = MbxQ_write(p->outQ,0,-1); /* send EOF */K errlog(L_PIPE|L_BABBLE,"Pipe_destroy2: transmitting EOF, iss=!XL",iss);7 if ((sent = MbxQ_flushed(p->outQ, bin, 30)) != bin)[ errlog(L_ERROR,"Pipe_destroy2(p=!XL) ERR flushing, sent !SL, need !SL",p,sent,bin); MbxQ_destroy(p->outQ); destroy_MBX(p->out_mbx);# if (p->buffer) free(p->buffer); free(p); return 0;}voidPipe_pack(pPipe2 p){ ROUTINE_NAME("Pipe_pack"); if (!p) return;) p->buffer = malloc(p->out_mbx->size); p->bcount = 0;}voidPipe_flush(pPipe2 p){ ROUTINE_NAME("Pipe_flush"); int iss; char *slog; if (!p) return; iss = sys$setast(0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);! if (p->buffer && p->bcount) {8 iss = MbxQ_write(p->outQ, p->buffer, p->bcount);\ errlog(L_PIPE|L_BABBLE,"Pipe_flush: transmitting !UL bytes, iss=!XL",p->bcount,iss);6 if (slog = dumpstring(p->buffer, p->bcount)) {> errlog(L_PIPE|L_DEBUG,"Pipe_flush: T:'!AZ'",slog); free(slog); } if (VMS_ERR(iss)) {_ errlog(L_PIPE|L_WARNING,"Pipe_flush: error transmitting (!XL), shutdown pipe",iss); Pipe_shutdown(p); } p->bcount = 0; } iss = sys$setast(1);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}*[CRINOID0051]PIPE2.H;1+,V. / 4( <-Ke0123KPWO 56 WQ7~(89GHJ /* */#ifndef __PIPE2_H#define __PIPE2_H#include "vms_data.h"#include "CRINOID_types.h"#include "util.h"#include "mbxq.h"(pPipe2 Pipe_new(pMBX in, pMBX out);$void Pipe_shutdown(pPipe2 p);#pPipe2 Pipe_destroy(pPipe2 p);$pPipe2 Pipe_destroy2(pPipe2 p); void Pipe_pack(pPipe2 p);!void Pipe_flush(pPipe2 p);#ifdef __PIPE2_PRIVATEstatic void Pipe_AST(pMbxE e);#define PIPE$M_PACK;#endif#endif*[CRINOID0051]PROC_MGR.C;1+,V.6/ 460<-Ke0123KPWO756"%)7H?%)89GHJB/* *' * manage the list of worker processes * */#include #include #include #include #include #include #include #include #include #include #include #include #include *#include /* DECC */#define __PROC_MGR_MAIN#include "util.h"#include "proc_mgr.h"#include "errlog_client.h"!#define VMS_OK(s) (((s)&1)!=0)!#define VMS_ERR(s) (((s)&1)==0)#define UNIX_OK(s) (s==0)#define UNIX_ERR(s) (s!=0)*static pProc PListHead = 0;*static pthread_mutex_t ProcListMutex;)static pthread_mutex_t ProcMgrMutex;(static pthread_cond_t ProcMgrCond;*static pGroup GroupHead = 0;'static pthread_mutex_t GroupMutex;*static pthread_t ProcMgrThread;+static pMBX TerminationMBX;)static pSTRING GroupProgram;'static pSTRING GroupInput;(static pSTRING GroupOutput;'static pSTRING GroupError;%static pSTRING StubProg;#define DEF_MAXPROC_UIC0 5#define DEF_MINPROC_UIC0 1#define DEF_MAXPAD_UIC0 2#define DEF_MINPAD_UIC0 0#define DEF_MAXPROC_OTHER 3#define DEF_MINPROC_OTHER 0#define DEF_MAXPAD_OTHER 1#define DEF_MINPAD_OTHER 0void$init_Proc(pMBX term_mbx, char* stub){ ROUTINE_NAME("init_Proc"); int iss;E errlog(L_PROC|L_TRACE,"init_Proc(mbx = !AZ)", &term_mbx->d_name);H iss = pthread_mutex_init(&ProcListMutex, pthread_mutexattr_default);; if (UNIX_ERR(iss)) UNIX_ABORT("init_Proc, mutex_init"); TerminationMBX = term_mbx; StubProg = new_STRING(stub);}pProcnew_Proc(pGroup g){ ROUTINE_NAME("new_Proc"); pProc p; int iss, len;3 errlog(L_PROC|L_TRACE,"new_Proc(g = 0x!XL)",g); len = sizeof(Proc); iss = lib$get_vm(&len, &p);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); p->state = PS_NEW; p->group = g; p->pid = 0; p->name = 0; p->commandQ= 0; p->maintain_lock = 0; p->ndb = 0; p->next_idle = 0; p->activations = 0; p->killpend = 0;C iss = pthread_mutex_init(&p->mutex, pthread_mutexattr_default);: if (UNIX_ERR(iss)) UNIX_ABORT("new_Proc, mutex_init"); link_Proc(p);8 errlog(L_PROC|L_TRACE,"new_Proc returns p=0x!XL",p); return p;}voidstart_Proc(pProc p){ ROUTINE_NAME("start_Proc"); int iss, n; pGroup g; char name[16];4 $DESCRIPTOR(loginout,"SYS$SYSTEM:LOGINOUT.EXE"); Privs stubpriv; stubpriv.prv$l_l1_bits = 0; stubpriv.prv$l_l2_bits = 0; stubpriv.prv$v_detach = 1; stubpriv.prv$v_sysprv = 1;3 errlog(L_PROC|L_TRACE,"start_Proc(p=0x!XL)",p); lock_Proc(p); g = p->group; lock_Group(g); for (n = 0; n < 5; n++) {2 errlog(L_PROC|L_TRACE,"proc(p=0x!XL) ",p);! iss = sys$creprc(&p->pid,@ &loginout, /* g->program, */ /* image */@ StubProg, /* g->input, */ /* input */? g->output, /* output */? g->error, /* error */? &stubpriv, /* &g->priv, */ /* privs */? g->quota, /* quotas */= 0, /* p->name, */ /* name */# g->baspri,) 0, /* g->uic, */. TerminationMBX->unit,, PRC$M_DETACH /* g->stsflg */ );& if (iss != SS$_DUPLNAM) break; }& if (VMS_ERR(iss)) VMS_SIGNAL(iss); g->n_starting++; unlock_Group(g); p->state = PS_STARTING; unlock_Proc(p);H errlog(L_PROC|L_TRACE,"start_Proc started process, pid=!XL",p->pid);}voidlink_Proc(pProc p){ ROUTINE_NAME("link_Proc"); int iss; pGroup g;2 errlog(L_PROC|L_TRACE,"link_Proc(p=0x!XL)",p); lock_Proc(0);' if (PListHead) PListHead->last = p; p->last = 0; p->next = PListHead; PListHead = p; unlock_Proc(0); g = p->group; lock_Group(g); g->n_total++; unlock_Group(g);}voidunlink_Proc(pProc p){ ROUTINE_NAME("unlink_Proc"); int iss; pGroup g; pProc pi, plast;4 errlog(L_PROC|L_TRACE,"unlink_Proc(p=0x!XL)",p); lock_Proc(0); if (p->last) p->last->next = p->next; else PListHead = p->next; if (p->next) p->next->last = p->last; unlock_Proc(0); g = p->group; lock_Group(g); g->n_total--;1 if (p->state == PS_STARTING) g->n_starting--; plast = 0; pi = g->idle_list; while (pi) {p errlog(L_PROC|L_DEBUG,"unlink_Proc (g=!XL p=!XL) plast=!XL pi=!XL next=!XL",g,p,plast,pi,pi->next_idle); if (pi == p) { if (plast)0 plast->next_idle = p->next_idle; else, g->idle_list = p->next_idle; g->n_idle--; check_Proc(); break; } plast = pi;" if (pi == pi->next_idle) {H errlog(L_CRITICAL,"unlink_Proc: infinite loop detected!!!"); break; } pi = pi->next_idle; } unlock_Group(g);}pProcget_Proc(longword pid){ ROUTINE_NAME("get_Proc"); int iss; pProc p;4 errlog(L_PROC|L_BABBLE,"get_Proc(pid=!XL)",pid); lock_Proc(0); p = PListHead; while (p) {N errlog(L_PROC|L_BABBLE,"get_proc checking p=0x!XL, pid=!XL",p,p->pid);! if (p->pid == pid) break; p = p->next; } unlock_Proc(0);A errlog(L_PROC|L_BABBLE,"returning from get_Proc, p=0x!XL",p); return p;}voiddestroy_Proc(pProc p){! ROUTINE_NAME("destroy_Proc"); int len, iss;5 errlog(L_PROC|L_TRACE,"destroy_Proc(p=0x!XL)",p); unlink_Proc(p); if (p->maintain_lock) { p->maintain_lock = 0; unlock_Proc(p); }) if (p->name) destroy_STRING(p->name);+ iss = pthread_mutex_destroy(&p->mutex);A if (UNIX_ERR(iss)) UNIX_ABORT("destroy_Proc, mutex_destroy"); len = sizeof(Proc); iss = lib$free_vm(&len,&p);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}voidlock_Proc(pProc p){ ROUTINE_NAME("lock_Proc"); int iss;6 errlog(L_LOCKING|L_BABBLE,"lock_Proc(p=0x!XL)",p); if (p) { if (!p->maintain_lock) {0 iss = pthread_mutex_lock(&p->mutex);7 if (UNIX_ERR(iss)) UNIX_ABORT("lock_Proc"); } } else {1 iss = pthread_mutex_lock(&ProcListMutex);3 if (UNIX_ERR(iss)) UNIX_ABORT("lock_Proc"); }}voidunlock_Proc(pProc p){ ROUTINE_NAME("unlock_Proc"); int iss;8 errlog(L_LOCKING|L_BABBLE,"unlock_Proc(p=0x!XL)",p); if (p) { if (!p->maintain_lock) {2 iss = pthread_mutex_unlock(&p->mutex);9 if (UNIX_ERR(iss)) UNIX_ABORT("unlock_Proc"); } } else {3 iss = pthread_mutex_unlock(&ProcListMutex);5 if (UNIX_ERR(iss)) UNIX_ABORT("unlock_Proc"); }} longword *list_Proc(void){ ROUTINE_NAME("list_Proc"); pProc p; longword *PIDList = 0; int n = 100, j = 0;) errlog(L_PROC|L_TRACE,"list_Proc()");+ PIDList = malloc(n * sizeof(longword)); if (!PIDList) return 0; lock_Proc(0); p = PListHead; while (p) { if (j == n - 1) { n += 100;: PIDList = realloc(PIDList,n*sizeof(longword)); if (!PIDList) { unlock_Proc(0); return 0; } } PIDList[j++] = p->pid; p = p->next; } unlock_Proc(0); PIDList[j] = 0; return PIDList;}voidstop_Proc(pProc p){ ROUTINE_NAME("stop_Proc"); int iss;2 errlog(L_PROC|L_TRACE,"stop_Proc(p=0x!XL)",p); lock_Proc(p);" iss = sys$forcex(&p->pid,0,0);< if (iss != SS$_NONEXPR && VMS_ERR(iss)) VMS_SIGNAL(iss); p->state = PS_STOPPING; unlock_Proc(p);}pProcgetidle_Proc(pGroup g){! ROUTINE_NAME("getidle_Proc"); int iss; pProc p;5 errlog(L_PROC|L_TRACE,"getidle_Proc(g=0x!XL)",g); lock_Group(g); while (!g->idle_list) { g->n_req++; check_Proc();9 errlog(L_PROC|L_INFO,"getidle_Proc, waiting...");4 iss = pthread_cond_wait(&g->cond,&g->mutex);A if (UNIX_ERR(iss)) UNIX_ABORT("getidle_proc, cond wait"); g->n_req--; } p = g->idle_list; p->killpend = 0; p->activations++; g->idle_list = p->next_idle;r errlog(L_PROC|L_DEBUG,"getidle_Proc, got (g=!XL)->idle_list -> p=!XL returned, next is !XL",g,p,p->next_idle); g->n_idle--; unlock_Group(g); check_Proc();T errlog(L_PROC|L_TRACE,"getidle_Proc, p=!XL pid=!XL removed from idle",p,p->pid); return p;e}tvoidsetidle_Proc(pProc p)i{u! ROUTINE_NAME("setidle_Proc"); int iss, maintain; pGroup g;. pProc pi;i5 errlog(L_PROC|L_TRACE,"setidle_Proc(p=0x!XL)",p);cK errlog(L_PROC|L_TRACE,"setidle_Proc, p=!XL pid=!XL set idle",p,p->pid);f g = p->group;O lock_Group(g); pi = g->idle_list; while (pi) { if (pi == p) {P errlog(L_PROC|L_INFO,"setidle_Proc (g=!XL p=!XL) already idle",g,p); break; }d pi = pi->next_idle;d }N if (!pi) {q errlog(L_PROC|L_DEBUG,"setidle_Proc (g=!XL)->idle_list = p , (p=!XL)->next_idle = !XL",g,p,g->idle_list);t$ p->next_idle = g->idle_list; g->idle_list = p;t g->n_idle++; }u lock_Proc(p);p maintain = p->maintain_lock; p->maintain_lock = 1; 1 if (p->state == PS_STARTING) g->n_starting--;o p->state = PS_IDLE; ' if (get_pflquota(p->pid) < 10000) {  p->state = PS_STOPPING;p unlock_Group(g); stop_Proc(p); $ p->maintain_lock = maintain; unlock_Proc(p); } else {$ p->maintain_lock = maintain; unlock_Proc(p);E, iss = pthread_cond_signal(&g->cond);C if (UNIX_ERR(iss)) UNIX_ABORT("setidle_proc, cond_signal");  unlock_Group(g); } check_Proc();D}Rvoidlock_Group(pGroup g){t ROUTINE_NAME("lock_Group");T int iss;7 errlog(L_LOCKING|L_BABBLE,"lock_Group(g=0x!XL)",g);_ if (g) {, iss = pthread_mutex_lock(&g->mutex);@ if (UNIX_ERR(iss)) UNIX_ABORT("lock_Group, mutex_lock"); } else {. iss = pthread_mutex_lock(&GroupMutex);@ if (UNIX_ERR(iss)) UNIX_ABORT("lock_Group, mutex_lock"); }_}cvoidunlock_Group(pGroup g){e! ROUTINE_NAME("unlock_Group");s int iss;9 errlog(L_LOCKING|L_BABBLE,"unlock_Group(g=0x!XL)",g); if (g) {. iss = pthread_mutex_unlock(&g->mutex);D if (UNIX_ERR(iss)) UNIX_ABORT("unlock_Group, mutex_unlock"); } else {0 iss = pthread_mutex_unlock(&GroupMutex);D if (UNIX_ERR(iss)) UNIX_ABORT("unlock_Group, mutex_unlock"); }0}pGroupnew_Group(char *name)k{p ROUTINE_NAME("new_Group"); int iss, length; pGroup g;_8 errlog(L_PROC|L_TRACE,"new_Group(name='!AZ')",name); g = malloc(sizeof(Group));$ if (!g) VMS_SIGNAL(SS$_INSFMEM); g->uic = 0;; g->priv.prv$l_l1_bits = 0; g->priv.prv$l_l2_bits = 0; g->priv.prv$v_netmbx = 1;  g->priv.prv$v_tmpmbx = 1; " g->quota[0].id = PQL$_LISTEND; g->baspri = 2; g->stsflg = 0; g->usergroup = 0;  g->n_idle = 0; g->n_busy = 0; g->n_total = 0; g->n_starting = 0;$ g->n_max = DEF_MAXPROC_UIC0;$ g->n_min = DEF_MINPROC_UIC0;$ g->n_pad_max = DEF_MAXPAD_UIC0 ;$ g->n_pad_min = DEF_MINPAD_UIC0 ;@ iss = pthread_cond_init(&g->cond, pthread_condattr_default);: if (UNIX_ERR(iss)) UNIX_ABORT("new_Group, cond_init");C iss = pthread_mutex_init(&g->mutex, pthread_mutexattr_default); ; if (UNIX_ERR(iss)) UNIX_ABORT("new_Group, mutex_init");  g->idle_list = 0;u g->n_req = 0;u& g->name = new_STRING(name);= g->program = new_STRING(asciz_pSTRING(GroupProgram));-; g->input = new_STRING(asciz_pSTRING(GroupInput)); < g->output = new_STRING(asciz_pSTRING(GroupOutput));; g->error = new_STRING(asciz_pSTRING(GroupError));  g->username = 0;  g->bindir = 0;,; errlog(L_PROC|L_TRACE,"new_Group returning g=0x!XL",g); return g;D}Cvoid#setuser_Group(pGroup g, char *user)S{D" ROUTINE_NAME("setuser_Group");U errlog(L_PROC|L_TRACE,"setuser_Group(g = 0x!XL, user = '!AZ')",g,(user?user:""));_ lock_Group(g); if (g->username) {$ destroy_STRING(g->username); g->username = 0; }d if (!user) { unlock_Group(g); return;  };# g->username = new_STRING(user);R# uc(asciz_pSTRING(g->username));o unlock_Group(g);}Hvoidlink_Group(pGroup g){- ROUTINE_NAME("link_Group");a5 errlog(L_PROC|L_TRACE,"link_Group(g = 0x!XL)",g);  lock_Group(g); lock_Group(0); g->next = GroupHead; GroupHead = g; unlock_Group(0); unlock_Group(g);}ivoidAinit_Group(char *program, char *input, char *output, char *error)L{O ROUTINE_NAME("init_Group");p int iss;J errlog(L_PROC|L_TRACE,"init_Group(in='!AZ', out='!AZ')",input,output); GroupHead = 0;D iss = pthread_mutex_init(&GroupMutex,pthread_mutexattr_default);< if (UNIX_ERR(iss)) UNIX_ABORT("init_Group, mutex_init");' GroupProgram = new_STRING(program);)$ GroupInput = new_STRING(input);% GroupOutput = new_STRING(output);{$ GroupError = new_STRING(error);}rvoiddestroy_Group(pGroup g) {t" ROUTINE_NAME("destroy_Group"); int iss; if (!g) return;f) iss = pthread_cond_destroy(&g->cond);=A if (UNIX_ERR(iss)) UNIX_ABORT("destroy_Group, cond_destroy");>+ iss = pthread_mutex_destroy(&g->mutex); B if (UNIX_ERR(iss)) UNIX_ABORT("destroy_Group, mutex_destroy"); destroy_STRING(g->name); destroy_STRING(g->program);I destroy_STRING(g->input);o destroy_STRING(g->output); destroy_STRING(g->error);p free(g);} void check_Proc(){; ROUTINE_NAME("check_Proc");r int iss;* errlog(L_PROC|L_TRACE,"check_Proc()");, iss = pthread_cond_signal(&ProcMgrCond);= if (UNIX_ERR(iss)) UNIX_ABORT("check_Proc, cond_signal");} void *manage_Proc(void *arg){_ ROUTINE_NAME("manage_Proc");* int iss, changed, maxact, havepending; pGroup g;  pProc p, p0;S struct timespec twake, twait = {60, 0}; /* 60 seconds between updates */p# longword now[2], delta_kill[2];o6 errlog(L_PROC|L_TRACE,"manage_Proc() started..."); sec2vms(30, delta_kill); while (1) {_ lock_Group(0); g = GroupHead; changed = 0; while (g) {  if (g->usergroup) {  g = g->next; continue;R } lock_Group(g); unlock_Group(0); errlog(L_PROC|L_BABBLE,"manage_Proc, group=0x!XL, n_idle=!SL, n_starting=!SL n_req=!SL",g,g->n_idle, g->n_starting, g->n_req); errlog(L_PROC|L_BABBLE,"manage_Proc, group=0x!XL, n_pad_min=!SL n_pad_max=!SL n_total=!SL n_max=!SL n_min=!SL",g,g->n_pad_min,g->n_pad_max,g->n_total, g->n_max, g->n_min);nt if (((g->n_idle + g->n_starting < g->n_pad_min || g->n_req > g->n_starting) && g->n_total < g->n_max) ||* (g->n_total < g->n_min)) {I errlog(L_PROC|L_BABBLE,"manage_Proc, starting new proc");( unlock_Group(g); p = new_Proc(g); start_Proc(p);#ifdef UNTHROTTLED changed = 1;#endifX } else if (g->n_idle > g->n_pad_max && g->n_total > g->n_min && !g->n_req) {& iss = sys$gettim(now);2 if (VMS_ERR(iss)) VMS_SIGNAL(iss); havepending = 0;I errlog(L_PROC|L_BABBLE,"manage_Proc, killing idle proc");l p0 = 0;' if (p = g->idle_list) {  while (p) {P* if (p->killpend) {, longword dum[2];, havepending = 1;G )ͼ~ FREEWARE.SAVVKe[CRINOID0051]PROC_MGR.C;16t" iss = lib$sub_times(now, p->killtime, dum); 5 if (iss == LIB$_NORMAL) {o errlog(L_PROC|L_INFO,"manage_Proc killing killpending p=!XL pid=!XL",p,p->pid);' if (p0) A p0->next_idle = p->next_idle;+$ elseA g->idle_list = p->next_idle;t, g->n_idle--;- stop_Proc(p);l, changed = 1;& break;= } else if (iss != LIB$_NEGTIM) {I0 VMS_SIGNAL(iss); }i }  p0 = p; ) p = p->next_idle;O }(j if (!havepending) { /* no kill_pending ones...pick one for pending status */) p = g->idle_list;r$ maxact = -1; p0 = 0;;# while (p) {R: if (p->activations > maxact) {' p0 = p;n8 maxact = p->activations; }E- p = p->next_idle;! },! if (p0) {- p0->killpend = 1; O iss = lib$add_times(now, delta_kill, p0->killtime);> if (VMS_ERR(iss)) VMS_SIGNAL(iss); errlog(L_PROC|L_INFO,"manage_Proc setting killpending p=!XL pid=!XL @ !%T",p0,p0->pid,p0->killtime); } else {j errlog(L_CRITICAL,"manage proc, killing idle, but nothing in activity list!"); }  }= } else {Y errlog(L_CRITICAL,"manage proc, killing idle, but nothing in list!"); * VMS_SIGNAL(SS$_ABORT); } unlock_Group(g); } else { unlock_Group(g); }s lock_Group(0); g = g->next; }= unlock_Group(0); if (!changed) {p? errlog(L_PROC|L_BABBLE,"manage_Proc() waiting...");4 iss = pthread_mutex_lock(&ProcMgrMutex);E if (UNIX_ERR(iss)) UNIX_ABORT("manage_proc, mutex_lock"); < iss = pthread_get_expiration_np(&twait, &twake);I if (UNIX_ERR(iss)) UNIX_ABORT("manage_proc, get_expiration");L iss = pthread_cond_timedwait(&ProcMgrCond,&ProcMgrMutex,&twake);W if (UNIX_ERR(iss) && errno != EAGAIN) UNIX_ABORT("manage_proc, cond wait");t6 iss = pthread_mutex_unlock(&ProcMgrMutex);G if (UNIX_ERR(iss)) UNIX_ABORT("manage_proc, mutex_unlock");TI errlog(L_PROC|L_BABBLE,"manage_Proc() signalled to wake...");_ }X }_ return 0;} voidinit_manage_Proc(){t% ROUTINE_NAME("init_manage_Proc");B int iss;0 errlog(L_PROC|L_TRACE,"init_manage_Proc()");G iss = pthread_mutex_init(&ProcMgrMutex, pthread_mutexattr_default);rB if (UNIX_ERR(iss)) UNIX_ABORT("init_manage_proc, mutex_init");D iss = pthread_cond_init(&ProcMgrCond, pthread_condattr_default);A if (UNIX_ERR(iss)) UNIX_ABORT("init_manage_proc, cond_init");tP iss = pthread_create(&ProcMgrThread, pthread_attr_default, &manage_Proc, 0);E if (UNIX_ERR(iss)) UNIX_ABORT("init_manage_proc, thread_create");u}xvoidstop_manage_Proc(){U% ROUTINE_NAME("stop_manage_Proc");; int iss;0 errlog(L_PROC|L_TRACE,"stop_manage_Proc()");( iss = pthread_cancel(ProcMgrThread);E if (UNIX_ERR(iss)) UNIX_ABORT("stop_manage_proc, thread_cancel");;}voidkill_all_Procs(){;# ROUTINE_NAME("kill_all_Procs");; int iss; pProc p;. errlog(L_PROC|L_TRACE,"kill_all_Procs()"); lock_Proc(0);r p = PListHead; while (p) {m stop_Proc(p);0 p = p->next; }b unlock_Proc(0);s} 6/* this is a dummy, for lack of something better... */pGroupfind_Group(longword uic){ ROUTINE_NAME("find_Group");m pGroup g = GroupHead;5 errlog(L_PROC|L_TRACE,"find_Group(uic=!%U)",uic);= while (g) { if (g->uic == uic) {F errlog(L_PROC|L_TRACE,"find_Group() returning g=0x!XL",g); return g;) }( g = g->next; } D errlog(L_PROC|L_ERROR,"find_Group(!%U) unable to find UIC",uic); return 0;)}IpGroupfind_named_Group(char *name){-% ROUTINE_NAME("find_named_Group");= pGroup g = GroupHead;n? errlog(L_PROC|L_TRACE,"find_named_group(name='!AZ')",name);r if (!name) return g; while (g) {(F if (tu_strcmp_uc(asciz_pSTRING(g->name), name) == 0) return g; g = g->next; }r return 0;S}NpGroupfind_username_Group(char *name)m{ ( ROUTINE_NAME("find_username_Group"); pGroup g = GroupHead;pB errlog(L_PROC|L_TRACE,"find_username_group(name='!AZ')",name); if (!name) return 0; while (g) {e if (g->username) {N if (tu_strcmp_uc(asciz_pSTRING(g->username), name) == 0) return g; }p g = g->next; }{ return 0;o}Tvoidexit_handle_Proc(void){;% ROUTINE_NAME("exit_handle_Proc");o pProc p = PListHead; while (p) { sys$forcex(&p->pid,0,0); p = p->next; }r}evoidprintall_Group(FILE *fd){d# ROUTINE_NAME("printall_Group");N pGroup g = GroupHead;  if (!fd) return; while (g) {X print_Group(g,fd); g = g->next; }n} voidprint_Group(pGroup g, FILE *fd)o{G ROUTINE_NAME("print_Group"); if (!g) return;p if (!fd) return;F fprintf(fd,"\n-----------------------------------------------\n");K fprintf(fd,"Group: %s @ 0x%08x\n",asciz_pSTRING(g->name),g);n1 fprintf(fd,"UIC: %08x\n",g->uic);_@ fprintf(fd,"PRIVS[0]: %08x\n",g->priv.prv$l_l1_bits);@ fprintf(fd,"PRIVS[1]: %08x\n",g->priv.prv$l_l2_bits);2 fprintf(fd,"BASE PRIORITY: %d\n",g->baspri);4 fprintf(fd,"STATUS %08x\n",g->stsflg);B fprintf(fd,"PROGRAM: %s\n",asciz_pSTRING(g->program));@ fprintf(fd,"INPUT: %s\n",asciz_pSTRING(g->input));A fprintf(fd,"OUTPUT: %s\n",asciz_pSTRING(g->output));f@ fprintf(fd,"ERROR: %s\n",asciz_pSTRING(g->error));2 fprintf(fd," #idle %d\n",g->n_idle);2 fprintf(fd," #busy %d\n",g->n_busy);3 fprintf(fd," #total %d\n",g->n_total);I6 fprintf(fd," #starting %d\n",g->n_starting);1 fprintf(fd," #max %d\n",g->n_max);o1 fprintf(fd," #min %d\n",g->n_min); 5 fprintf(fd," #pad_max %d\n",g->n_pad_max);l5 fprintf(fd," #pad_min %d\n",g->n_pad_min);o1 fprintf(fd," #req %d\n",g->n_req);ID fprintf(fd,"-----------------------------------------------\n");}r*[CRINOID0051]PROC_MGR.H;1+,V. / 4J <-Ke0123KPWO 56>WQ7(89GHJ/* *8 * include file for worker process management interface * */#ifndef __PROC_MGR_H#define __PROC_MGR_H#include "vms_data.h"#include "CRINOID_types.h"-void init_Proc(pMBX term_mbx, char* stub);pProc new_Proc(pGroup s);void start_Proc(pProc p);void link_Proc(pProc p);void unlink_Proc(pProc p);pProc get_Proc(longword pid);void destroy_Proc(pProc p);void lock_Proc(pProc p);void unlock_Proc(pProc p);longword * list_Proc(void);void stop_Proc(pProc p);pProc getidle_Proc(pGroup g);void setidle_Proc(pProc p);void lock_Group(pGroup g);void unlock_Group(pGroup g);pGroup new_Group(char *name);,void setuser_Group(pGroup g, char *user);void link_Group(pGroup g); void destroy_Group(pGroup g);Jvoid init_Group(char *program, char *input, char *output, char *error);void check_Proc();void* manage_Proc(void *arg);void init_manage_Proc();!pGroup find_Group(longword uic);%pGroup find_named_Group(char *name);(pGroup find_username_Group(char *name);void kill_all_Procs();void stop_manage_Proc();void exit_handle_Proc(void);!void printall_Group(FILE *fd);(void print_Group(pGroup g, FILE *fd);#endif*[CRINOID0051]SCRIPT.C;1+,&W,. / 4X N<-Ke0123KPWO 56+R[w7.(89GHJJ/************************************************************************\J * *J * ROUTINES FOR DEALING WITH SCRIPTS/DIRECTORIES, ETC. *J * *J * *J * *J * *J * *J\************************************************************************/#include #include #include #include #include #include #include #include "crinoid_types.h"#include "util.h"#include "script.h"#include "errlog_client.h"'static pScript ScriptHead = 0;'static pScript ScriptTail = 0;7static pthread_once_t ScriptOnce = pthread_once_init;$static pthread_mutex_t ScriptMutex;%/* leave here...private definition */ static void init_Script(void);pScript,new_Script(char *wild, int type, char *user){ ROUTINE_NAME("new_Script"); int iss; pScript s; s = malloc(sizeof(Script));= if (!s) VMS_ABORT("new_Script, malloc fail",SS$_INSFMEM); s->type = type; s->wild = new_STRING(wild); uc(asciz_pSTRING(s->wild));* s->user = user ? new_STRING(user) : 0; s->server = 0; s->bindir = 0; s->next = 0; s->flags = 0; s->permit = 0; s->deny = 0; s->warn = 0;2 iss = pthread_once(&ScriptOnce, &init_Script);> if (UNIX_ERR(iss)) UNIX_ABORT("add_Script: pthread_once");+ iss = pthread_mutex_lock(&ScriptMutex);D if (UNIX_ERR(iss)) UNIX_ABORT("add_Script: pthread_mutex_lock"); if (ScriptTail) ScriptTail->next = s; ScriptTail = s; if (!ScriptHead) ScriptHead = s;- iss = pthread_mutex_unlock(&ScriptMutex);F if (UNIX_ERR(iss)) UNIX_ABORT("add_Script: pthread_mutex_unlock"); return s;} static voidinit_Script(void){ ROUTINE_NAME("init_Script"); int iss;E iss = pthread_mutex_init(&ScriptMutex,pthread_mutexattr_default);E if (UNIX_ERR(iss)) UNIX_ABORT("init_Script, pthread_mutex_init");}pScript'findwild_Script(char *in, char *server){$ ROUTINE_NAME("findwild_Script"); int iss; pScript s = ScriptHead; pSTRING in2, ins; in2 = new_STRING(in); uc(asciz_pSTRING(in2)); ins = new_STRING(server); uc(asciz_pSTRING(ins)); while (s) {X if (!s->server || tu_strcmp(asciz_pSTRING(s->server),asciz_pSTRING(ins)) == 0) {% pthread_lock_global_np();/ iss = str$match_wild(in2, s->wild);' pthread_unlock_global_np();) if (iss == STR$_MATCH) break; } s = s->next; } destroy_STRING(in2); destroy_STRING(ins); return s;}*[CRINOID0051]SCRIPT.H;1+,]W. / 45 <-Ke0123KPWO 56u [7jB(89GHJ"/* external script definitions */#ifndef _SCRIPT_H#define _SCRIPT_H 1#include "CRINOID_types.h"5pScript new_Script(char *wild, int type, char *user);0pScript findwild_Script(char *in, char *server);#endif/*[CRINOID0051]SCRIPT_CGIEXECUTE-19990611.PATCH;1+,qW. / 4E -Ke0123KPWO 56[T76R(89GHJ OSU-HTTPd Patch Author: Charles Lane Date: 11-Jun-1999 (reformatted & this header written 7 Feb 2000) Applies to: OSU HTTP Server, version 3.3b...other versions too? Description: This code checks for HTTP headers returned from a CGI script and dumps the CGI output for an error return if the CGI doesn't supply what this code considers a "minimal" amount of header information. This runs into problems with handling some "newfangled" requests via CGI (primarily DELETE, RENAME, PUT, etc. used by Netscape's Roaming capability). This patch contains a minor typo fix (for the length of "STATUS:", and makes the s/w less picky about what gets returned from the CGI code. Apply patch from the OSU HTTP server's "home" directory. --- base_code/script_cgiexecute.c-orig Mon Nov 2 07:43:34 1998 +++ base_code/script_cgiexecute.c Fri Jun 11 13:52:26 1999 @@ -176,6 +176,7 @@ tu_init_stream ( link, text_mode ? read_cgi_recmode_header : read_cgi_header, &input ); stsline[0] = '\0'; + content[0] = '\0'; sts_offset = scb->rsphdr->l; need_server_label = 1; need_mime_label = 1; @@ -241,11 +242,12 @@ tu_strcpy ( content, "Content-type: " ); tu_strnzcpy ( &content[14], &buffer[i], sizeof(content)-14 ); if ( mode < 2 ) mode = 2; - } else if ( tu_strncmp ( label, "STATUS:", 13) == 0 ) { + } else if ( tu_strncmp ( label, "STATUS:", 7) == 0 ) { /* * Override status line to return. */ tu_strnzcpy ( stsline, &buffer[i], sizeof(stsline)-1 ); + if (mode < 2) mode = 2; } else if ( tu_strncmp ( label, "CONTENT-LENGTH:", 15) == 0 ) { /* * Note that content-length present and decode. @@ -263,6 +265,7 @@ */ mode = 3; status = http_add_response ( scb->rsphdr, buffer, 0 ); + } else { /* * Check if header label is one we normally generate and set * flag to suppress generating it. @@ -309,6 +312,7 @@ tu_strcpy ( &stsline[12], http_server_version ); status = http_add_response ( scb->rsphdr, stsline, 0 ); } + if (content[0]) status = http_add_response ( scb->rsphdr, content, 0 ); if ( has_content_length && (scb->keepalive_count < scb->keepalive_limit) ) { t*[CRINOID0051]STARTUP.C;1+,}W. / 4P <-Ke0123KPWO 56Qa;7b(89GHJ/* start CRINOID */#include #include #include #include #include #include #include "util.h"intmain(int argc, char *argv[]){ int iss; char name[200]; pSTRING dev; word chan; char buf[100]; IOSB iosb; if (argc < 3) {8 printf("usage: startup USERNAME SERVICENAME\n"); return(1); }9 sprintf(name,"0\"%s\"::\"0=%s\"NL:",argv[1],argv[2]); dev = new_STRING(name);& iss = sys$assign(dev,&chan,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); /* main params */= iss = sys$qiow(0,chan,IO$_WRITEVBLK,0,0,0,buf,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);= iss = sys$qiow(0,chan,IO$_WRITEVBLK,0,0,0,buf,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);= iss = sys$qiow(0,chan,IO$_WRITEVBLK,0,0,0,buf,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);= iss = sys$qiow(0,chan,IO$_WRITEVBLK,0,0,0,buf,0,0,0,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); while (1) {P iss = sys$qiow(0,chan,IO$_READVBLK,&iosb,0,0,buf,sizeof(buf)-1,0,0,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;* if (VMS_ERR(iss)) VMS_SIGNAL(iss); buf[iosb.count] = '\0';5 if (strncmp(buf,"",10) == 0) break;A iss = sys$qiow(0,chan,IO$_WRITEVBLK,0,0,0,buf,0,0,0,0,0);* if (VMS_ERR(iss)) VMS_SIGNAL(iss); } iss = sys$dassgn(chan);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}*[CRINOID0051]STUB.C;1+,W0./ 4}<-Ke0123KPWO56vB7q(89GHJ.I/***********************************************************************\H * *H * STUB *H * This is a "stub" detached process, used to impersonate *H * a user sufficiently to start the REAL detached process *H * in their account. *H * *H * communicates with CRINOID to set process parameters. *H * *I\***********************************************************************/#ifndef NO_PERSONA#define HAS_PERSONA#endif#include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.h"#include "msg.h"!#define VMS_OK(s) (((s)&1)!=0)!#define VMS_ERR(s) (((s)&1)==0)$void set_mortality(int timeout);void death_AST(void);#ifndef HAS_PERSONA$void set_username(pSTRING user);pSTRING get_username(void);"longword getuic(pSTRING username);#endif#static pMBX commandMBX;"static pMBX statusMBX;7#define MAX_LIFETIME (5*60) /* 5 MINUTES */int main(void){ ROUTINE_NAME("Stub_main"); int iss, len; struct MBXMSG msg; IOSB iosb;' longword myPID, MasterPID, procPID; Privs mypriv, procpriv;9 longword procflags = 0, baspri = 2, persona, uic = 0; char * quota = 0;E pSTRING username, procname = 0, loginout, program, output, error; word termMBX = 0; char myname[16]; pSTRING my_username; myPID = get_pid();% sprintf(myname,"STUB%08x",myPID);) iss = sys$setprn(new_STRING(myname));5 loginout = new_STRING("SYS$SYSTEM:LOGINOUT.EXE"); error = new_STRING(""); procpriv.prv$l_l1_bits = 0; procpriv.prv$l_l2_bits = 0; procpriv.prv$v_netmbx = 1; procpriv.prv$v_tmpmbx = 1;/ statusMBX = assign_new_MBX("SYS$OUTPUT",0);, if (!statusMBX) VMS_SIGNAL(SS$_INSFMEM);! output = &statusMBX->d_name;$ commandMBX= new_MBX(0, MAX_MSG); set_mortality(MAX_LIFETIME); msg.code = MSG$_STUBREADY; msg.unit = commandMBX->unit;X iss = sys$qiow(0, statusMBX->chan, IO$_WRITEVBLK, &iosb, 0, 0, &msg, 4, 0, 0, 0, 0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); MasterPID = iosb.dvispec; while (1) {f iss = sys$qiow(0, commandMBX->chan, IO$_READVBLK, &iosb, 0, 0, &msg, sizeof(msg), 0, 0, 0, 0); if (VMS_ERR(iss)) break; iss = iosb.status; if (VMS_ERR(iss)) break;( if (iosb.dvispec == MasterPID) {" len = iosb.count - 4 ; switch (msg.code) {" case MSG$_NETSHUT: case MSG$_ABORT:$ iss = SS$_ABORT;$ VMS_SIGNAL(iss); goto done;# case MSG$_USERNAME:0 username = new_STRING2(len);B strncpy(asciz_pSTRING(username),msg.info,len);5 asciz_pSTRING(username)[len] = 0;#ifndef HAS_PERSONA+ uic = getuic(username);#endif break;$ case MSG$_PROCPRIVS:B memcpy(&procpriv, msg.info, sizeof(longword)); break;$ case MSG$_PROCQUOTA:( quota = malloc(len);1 memcpy(quota, msg.info, len); break;$ case MSG$_PROCFLAGS:C memcpy(&procflags, msg.info, sizeof(longword)); break;# case MSG$_PROCNAME:0 procname = new_STRING2(len);B strncpy(asciz_pSTRING(procname),msg.info,len);5 asciz_pSTRING(procname)[len] = 0; break;# case MSG$_PROCPROG:/ program = new_STRING2(len);A strncpy(asciz_pSTRING(program),msg.info,len);4 asciz_pSTRING(program)[len] = 0; break;$ case MSG$_PROCPRIOR:@ memcpy(&baspri, msg.info, sizeof(longword)); break;# case MSG$_PROCTMBX:= memcpy(&termMBX, msg.info, sizeof(word)); break;$ case MSG$_PROCSTART:. procflags |= PRC$M_DETACH;- mypriv.prv$l_l1_bits = 0;- mypriv.prv$l_l2_bits = 0;, mypriv.prv$v_detach = 1;, mypriv.prv$v_sysprv = 1;#ifndef HAS_PERSONA, mypriv.prv$v_cmkrnl = 1;#endif4 iss = sys$setprv(1,&mypriv,0,0);% if (VMS_ERR(iss)) {( VMS_SIGNAL(iss);" goto done; }#ifdef HAS_PERSONA/#if (__VMS_VER >= 72000000 && defined(__ALPHA))J iss = sys$persona_create(&persona, username, 0, 0, 0);#elseD iss = sys$persona_create(&persona, username, 0);#endif% if (VMS_ERR(iss)) {( VMS_SIGNAL(iss);" goto done; }/#if (__VMS_VER >= 72000000 && defined(__ALPHA))} iss = sys$persona_assume(&persona, IMP$M_ASSUME_SECURITY|IMP$M_ASSUME_ACCOUNT|IMP$M_ASSUME_JOB_WIDE,0,0);#elsey iss = sys$persona_assume(&persona, IMP$M_ASSUME_SECURITY|IMP$M_ASSUME_ACCOUNT|IMP$M_ASSUME_JOB_WIDE);#endif% if (VMS_ERR(iss)) {( VMS_SIGNAL(iss);" goto done; }#else1 my_username = get_username();+ set_username(username);#endif- mypriv.prv$l_l1_bits = 0;- mypriv.prv$l_l2_bits = 0;, mypriv.prv$v_detach = 1;4 iss = sys$setprv(1,&mypriv,0,0);% if (VMS_ERR(iss)) {( VMS_SIGNAL(iss);" goto done; }. iss = sys$creprc(&procPID,L loginout, /* image */L program, /* input */L output, /* output */L error, /* error */L &procpriv, /* privs */L quota, /* quotas */J procname, /* name */K baspri, /* prior */I uic, /* uic */P termMBX, /* termmbxunit*/K procflags); /* flags */% if (VMS_ERR(iss)) {( VMS_SIGNAL(iss);" goto done; }#ifdef HAS_PERSONA/#if (__VMS_VER >= 72000000 && defined(__ALPHA))/ persona = ISS$C_ID_NATURAL;@ iss = sys$persona_assume(&persona, 0, 0, 0);#else persona = 1;: iss = sys$persona_assume(&persona, 0);#endif#else- mypriv.prv$l_l1_bits = 0;- mypriv.prv$l_l2_bits = 0;, mypriv.prv$v_cmkrnl = 1;4 iss = sys$setprv(1,&mypriv,0,0);% if (VMS_ERR(iss)) {( VMS_SIGNAL(iss);" goto done; }. set_username(my_username);#endif- msg.code = MSG$_STARTPID;! msg.unit = 0;A memcpy(msg.info, &procPID, sizeof(longword));y iss = sys$qiow(0, statusMBX->chan, IO$_WRITEVBLK, &iosb, 0, 0, &msg, 4+sizeof(longword), 0, 0, 0, 0);6 if (VMS_ERR(iss)) VMS_SIGNAL(iss); goto done; } } }done: return iss;}voidset_mortality(int timeout){" ROUTINE_NAME("set_mortality"); int iss; longword t_expire[2]; sec2vms(timeout, t_expire);3 iss = sys$setimr(0,t_expire, &death_AST, 0, 0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}*voiddeath_AST(void)*{* ROUTINE_NAME("death_AST"); int iss; iss = sys$delprc(0,0);' iss = sys$cancel(commandMBX->chan);*}T#ifndef HAS_PERSONA #include "pcbjibdef.h"#pragma message save##pragma message disable (GLOBALEXT)e!globalvalue char ** CTL$GL_PCB; %globalvalue char * CTL$T_USERNAME;e#pragma message restorepSTRINGeget_username(void){ ! ROUTINE_NAME("get_username"); pItemList i; IOSB iosb; char buf[12];  int j, iss;* i = new_ItemList(1);/ i = add_Item(i, JPI$_USERNAME, buf, 12, 0);*) iss = sys$getjpiw(0,0,0,i,&iosb,0,0);  destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss);. for (j = 11; j >= 0 && buf[j] == ' '; j--) buf[j] = '\0'; return new_STRING(buf);i}hlongwordgetuic(pSTRING user){s ROUTINE_NAME("getuic");i pSTRING username;c pItemList i; IOSB iosb; longword uic;e int iss;/ username = new_STRING(asciz_pSTRING(user));u uc(asciz_pSTRING(username)); i = new_ItemList(1);4 i = add_Item(i, UAI$_UIC, &uic, sizeof(uic), 0);- iss = SYS$GETUAI(0,0,username, i, 0,0,0);T destroy_ItemList(i); destroy_STRING(username);R& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return uic;(}R%char username_global[JIB$S_USERNAME]; int ustore(void);voidset_username(pSTRING user){;! ROUTINE_NAME("set_username");  int j, iss;S char *p;6 for (j = 0; j < 12; j++) username_global[j] = ' '; p = asciz_pSTRING(user);5 for (j = 0; j < JIB$S_USERNAME && *p; j++, p++) {P) username_global[j] = toupper(*p);g }o iss = SYS$CMKRNL(&ustore,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}sint ustore(void){i ROUTINE_NAME("ustore"); char *pPCB, *pJIB; char *jibuser; char *pCTL;y int j; pPCB = *CTL$GL_PCB; 2 memcpy(&pJIB, pPCB+PCB$L_JIB, sizeof(char *));" jibuser = pJIB+JIB$T_USERNAME; pCTL = CTL$T_USERNAME;3 memcpy(jibuser,username_global,JIB$S_USERNAME);0 memcpy(pCTL,username_global,JIB$S_USERNAME); return 1;} #endif*[CRINOID0051]TENTACLE.C;1+,WM.$/ 4p$ &<-Ke0123KPWO%56R.7|(89GHJpwo~ FREEWARE.SAVWMKe[CRINOID0051]TENTACLE.C;1p$@/*$ A single tentacle of the CRINOID*/#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include *#include /* DECC */#include "EXTERN.h"#include "perl.h"#include "mbxq.h"#include "pipe2.h"#include "msg.h"#include "util.h"#include "tentacle.h"#include "perlxsi.c"#include "errlog_client.h"/int decc$stat(char *file, struct stat *buffer);*static longword MasterPID = 0;3static int Heartbeats_Pending = 0;-static int work_in_progress;(static pENV EnvBase = 0;/static pSCRIPT Script_Base = NULL;,static int Script_Max = 5;,static int Script_Count= 0;$static pMbxQ StatusQ;%static pMbxQ CommandQ;%static longword StatusEF;5static RQE GotMsgQueueHead = {0, 0};.#define GotMsgQ (&GotMsgQueueHead)-static PerlInterpreter *script_perl = 0;2#define MASTER_SCRIPT "CRINOID_home:oyster."2#define MASTER_OPT1 "-ICRINOID_root:[lib]"#define HEARTBEAT_TIMEOUT 30##define DEFAULT_LOG_LEVEL L_ERROR/*/ * status goes back to a mailbox on SYS$OUTPUT@ * note that we don't have an input, until we create one... */+int main(int argc, char** argv, char** env){" ROUTINE_NAME("Tentacle_main");% int iss, net_shut, need_init = 1; longword time[2]; pMbxE e; pMM m; pMBX commandMBX; pMBX statusMBX; pSTRING loglev; errlog_prefix("TENTACLE");% errlog(L_CRITICAL,"starting up");4 loglev = translate_logical("TENTACLE_LOGLEVEL");K errlog_level(loglev ? atoi(asciz_pSTRING(loglev)) : DEFAULT_LOG_LEVEL);' if (loglev) destroy_STRING(loglev); signal(SIGABRT, SIG_IGN);/ statusMBX = assign_new_MBX("SYS$OUTPUT",0);D errlog(L_BABBLE,"Status MBX opened, unit !UW",statusMBX->unit);, if (!statusMBX) VMS_SIGNAL(SS$_INSFMEM);I StatusQ = MbxQ_new(statusMBX, MBXQ$_WRITE|MBXQ$M_RETRY, &status_AST);* if (!StatusQ) VMS_SIGNAL(SS$_INSFMEM);$ commandMBX= new_MBX(0, MAX_MSG);E errlog(L_BABBLE,"Command MBX opened, unit !UW",commandMBX->unit); iss = lib$get_ef(&StatusEF);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = sys$clref(StatusEF);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = sec2vms(30, time);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); init_ENV(); init_perl(); need_init = 0;. iss = sys$setimr(StatusEF, time, 0, 0, 0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);4 send_status(MSG$_DEVONLIN,commandMBX->unit,0,0); iss = sys$waitfr(StatusEF);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);H errlog(L_BABBLE,"Response from DEVONLINE, MasterPID:!XL",MasterPID);) if (MasterPID == 0) return SS$_ABORT;> CommandQ = MbxQ_new(commandMBX, MBXQ$_READ, &command_AST);+ if (!CommandQ) VMS_SIGNAL(SS$_INSFMEM);4 errlog(L_BABBLE,"starting to process commands"); heartbeat_AST(); net_shut = 0; while (!net_shut) {& iss = lib$remqhi(GotMsgQ, &e);$ if (iss == LIB$_QUEWASEMP) {= errlog(L_BABBLE,"Entering hibernation at !%T",0); iss = sys$hiber();. if (VMS_ERR(iss)) VMS_SIGNAL(iss);" } else if (VMS_ERR(iss)) {G errlog(L_ERROR,"Error on command dequeue, status=!XL",iss); VMS_SIGNAL(iss); } else { m = (pMM) e->buf;p errlog(L_BABBLE,"Message, code = !UL (!AZ) from PID=!XL",m->code,msg_text(m->code),e->iosb.dvispec);/ if (e->iosb.dvispec != MasterPID) {S errlog(L_ERROR,"Unsolicited message from PID=!XL",e->iosb.dvispec); } else {" switch (m->code) {& case MSG$_CONNECT:3 if (need_init) init_perl();& need_init = 1;, handle_connection();# init_ENV();D send_status(MSG$_IDLE,commandMBX->unit,0,0); break;$ case MSG$_ABORT:@ errlog(L_INFO,"ABORT message received");# init_ENV();D send_status(MSG$_IDLE,commandMBX->unit,0,0); break;& case MSG$_NETSHUT:B errlog(L_INFO,"NETSHUT message received");% net_shut = 1; break;& case MSG$_ENVDATA:& do_envdata(e); break;% case MSG$_ERRLOG:% do_errlog(e); break;% case MSG$_LOGLEV:% do_loglev(e); break; } } MbxQ_dispose(e); } } return SS$_NORMAL;}voidcommand_AST(pMbxE e){ ROUTINE_NAME("command_AST"); int iss; word chan; pMM m = (pMM) e->buf;n errlog(L_BABBLE,"Command_AST fired, iss=0x!XW code=!UW (!AZ)",e->iosb.status, m->code, msg_text(m->code)); iss = e->iosb.status;9 if (VMS_ERR(iss)) VMS_SIGNAL(iss); /* I guess */ switch (m->code) {" case MSG$_LUBDUB :% Heartbeats_Pending--; MbxQ_dispose(e); return;" case MSG$_ABORT :' if (work_in_progress) {5 errlog(L_ERROR,"SIGABRT raised");# raise(SIGABRT); } break;" case MSG$_DISCON :" case MSG$_EXIT :" case MSG$_PATHLOST :" case MSG$_PROTOCOL :" case MSG$_THIRDPARTY :" case MSG$_TIMEOUT :" case MSG$_NETSHUT :& VMS_SIGNAL(SS$_ABORT); }! iss = lib$insqti(e, GotMsgQ);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = sys$wake(0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);}int1send_status(word code, word unit, char *s, int n){ ROUTINE_NAME("send_status"); int iss; MM M;1 int length = sizeof(M.code) + sizeof(M.unit); M.code = code; M.unit = unit;[ errlog(L_BABBLE,"returning status code=!UW (!AZ) unit=!UW",code, msg_text(code), unit); if (s && n > 0 && n < 255) { M.info[0] = n; memcpy(&M.info+1, s, n); length += n + 1; }+ return MbxQ_write(StatusQ, &M, length);}voidstatus_AST(pMbxE e){ ROUTINE_NAME("status_AST"); if (MasterPID == 0) {$ MasterPID = e->iosb.dvispec; sys$setef(StatusEF); }}inthandle_connection(){& ROUTINE_NAME("handle_connection"); pENV e; char dev[100]; pMBX m_in = 0, m_out = 0; pPipe2 p_stdin = 0; pPipe2 p_stdout = 0; pPipe2 p_stderr = 0;C errlog(L_INFO,"CONNECT message received, running Perl script");" e = find_ENV("CRINOID:>PERL"); if (!e) { tu_strcpy(dev, "NL:"); } else {, m_in = assign_new_MBX(e->value,0); if (!m_in) goto done;' m_out = new_MBX(0,m_in->size);' p_stdin = Pipe_new(m_in,m_out);+ sprintf(dev,"_MBA%d:",m_out->unit); } freopen(dev,"rb",stdin);2 errlog(L_BABBLE,"stdin remapped to !AZ", dev); m_in = m_out = 0;" e = find_ENV("CRINOID:value,0); if (!m_out) goto done;* m_in = new_MBX(0,m_out->size);( p_stdout = Pipe_new(m_in,m_out); Pipe_pack(p_stdout);* sprintf(dev,"_MBA%d:",m_in->unit); }' freopen(dev,"wb",stdout,"ctx=bin");3 errlog(L_BABBLE,"stdout remapped to !AZ", dev); m_in = m_out = 0;# e = find_ENV("CRINOID:2value,0);* m_in = new_MBX(0,m_out->size);( p_stderr = Pipe_new(m_in,m_out);* sprintf(dev,"_MBA%d:",m_in->unit); }' freopen(dev,"wb",stderr,"ctx=bin");3 errlog(L_BABBLE,"stderr remapped to !AZ", dev); m_in = m_out = 0; setbuf(stdin,NULL); /*setbuf(stdout,NULL); */ setbuf(stderr,NULL); clearerr(stdin); work_in_progress = 1; exec_perl(); signal(SIGABRT, SIG_IGN); work_in_progress = 0; fflush(stdout); fsync(fileno(stdout)); Pipe_flush(p_stdout); printf(""); fflush(stdout); fsync(fileno(stdout)); fflush(stderr); fsync(fileno(stderr));done:# if (m_in) destroy_MBX(m_in);% if (m_out) destroy_MBX(m_out);' if (p_stdin) Pipe_destroy(p_stdin);f* if (p_stdout) Pipe_destroy2(p_stdout);* if (p_stderr) Pipe_destroy2(p_stderr); return 1;c}eintlinit_perl(void)<{e ROUTINE_NAME("init_perl"); int iss, curscripttime;n9 char *embed_argv[] = {0, MASTER_OPT1, MASTER_SCRIPT};e static int scripttime = -1; struct stat st;L curscripttime = (decc$stat(MASTER_SCRIPT, &st) != -1) ? st.st_mtime : 0;F if (script_perl && curscripttime == scripttime) return SS$_NORMAL; scripttime = curscripttime;l if (script_perl) {K errlog(L_INFO,"Master script changed, reloading perl interpreter");i# perl_destruct(script_perl);l perl_free(script_perl);; }c script_perl = perl_alloc();P perl_construct(script_perl);. if (!script_perl) VMS_SIGNAL(SS$_INSFMEM);* iss = perl_parse(script_perl, xs_init,= sizeof(embed_argv)/sizeof(char *), embed_argv, NULL);x2 if (iss != 0 && VMS_ERR(iss)) VMS_SIGNAL(iss); iss = perl_run(script_perl); return iss;Q} int exec_perl(void)t{l ROUTINE_NAME("exec_perl"); int iss; pENV e1, e2; char *args[] = {0, 0, 0}; # e1 = find_ENV("SCRIPT_BINDIR");& e2 = find_ENV("SCRIPT_BARE_NAME"); if (e1) args[0] = e1->value; if (e2) args[1] = e2->value;; errlog(L_BABBLE,"running !AZ/!AZ",e1->value,e2->value);_ construct_perlENV();E iss = perl_call_argv("main::RunScript",G_DISCARD | G_EVAL, args);S return 1; } void%send_perlENV(char *name, char *value) {.! ROUTINE_NAME("send_perlENV");* dSP; PUSHMARK(sp); ( XPUSHs(sv_2mortal(newSVpv(name,0)));) XPUSHs(sv_2mortal(newSVpv(value,0)));t PUTBACK;) perl_call_pv("SetSafeENV",G_DISCARD);; errlog(L_BABBLE, "$PerlENV{'!AZ'} = '!AZ'",name,value);i}Tint"construct_perlENV(void),{a& ROUTINE_NAME("construct_perlENV"); pENV e = EnvBase;E while (e) {v if (e->state) {T+ send_perlENV(e->name,e->value);( }t e = e->next; }i return 1;I}GpENV+add_ENV(char *name, char *value, int state)){ ROUTINE_NAME("add_ENV"); char *qp; pENV p;X if (p = find_ENV(name)) {_ qp = p->value;+ p->value = malloc(strlen(value)+1);B if (!p->value) { if (qp) free(qp);S return 0;m }_ strcpy(p->value,value);B if (qp) free(qp);i } else {' p = (pENV) malloc(sizeof(ENV));t if (!p) return 0;)) p->name = malloc(strlen(name)+1);t if (!p->name) {s free(p); return 0;i }f strcpy(p->name, name);+ p->value = malloc(strlen(value)+1);d if (!p->value) {' if (p->name) free(p->name);f free(p); return 0;a }V strcpy(p->value,value);  p->next = EnvBase; EnvBase = p; }_ p->state = state;g return p;o} pENVfind_ENV(char *name){s ROUTINE_NAME("find_ENV");0 pENV p = EnvBase; while (p) {_0 if (strcmp(p->name,name) == 0) return p; p = p->next; }N return 0; }lvoidclear_ENV(void)p{e ROUTINE_NAME("clear_ENV"); pENV p, qp = EnvBase; while (p=qp) { qp = p->next;e# if (p->name) free(p->name);=% if (p->value) free(p->value);L free(p); }t EnvBase = 0;} voidinit_ENV(void){ ROUTINE_NAME("init_ENV");M int j;$ static char *default_blank[] = { "SUBFUNCTION",< "SERVER_SOFTWARE", "SERVER_NAME", "SERVER_PROTOCOL",5 "SERVER_PORT", "REQUEST_METHOD", "PATH_INFO",p8 "PATH_TRANSLATED", "SCRIPT_NAME", "SCRIPT_PATH",D "QUERY_STRING", "REMOTE_USER", "REMOTE_ADDR", "REMOTE_PORT",C "REMOTE_HOST", "AUTH_TYPE", "REMOTE_IDENT", "CONTENT_TYPE",l "CONTENT_LENGTH", NULL}; clear_ENV();0 for (j = 0; default_blank[j] != NULL; j++) {' add_ENV(default_blank[j],"",0);e }O/ add_ENV("GATEWAY_INTERFACE", "CGI/1.0", 1);_}lvoiddump_ENV(FILE *fp){e ROUTINE_NAME("dump_ENV");  pENV p = EnvBase;( while (p) { K fprintf(fp,"Env{\"%s\"}(%d) = \"%s\"\n",p->name,p->state,p->value);X p = p->next; } } voiddo_errlog(pMbxE e){a ROUTINE_NAME("do_errlog");} voiddo_loglev(pMbxE e){r ROUTINE_NAME("do_loglev"); pMM m = (pMM) e->buf;  unsigned level;a+ memcpy(&level, m->info, sizeof(level));  errlog_level(level);} voiddo_envdata(pMbxE e) {  ROUTINE_NAME("do_envdata");N pMM m = (pMM) e->buf; char *s = m->info;t, char *send = (char *) m + e->iosb.count; char *p, *q; int n; static char *cname, *cval;* static int lname, lval, doing_name; if (m->unit == 0) {G init_ENV();  doing_name = 1;)) cname = malloc(1); *cname = '\0'; ) cval = malloc(1); *cval = '\0';  lname = lval = 0; }  while (s < send) { p = s;# while (*p && p < send) p++;s n = p-s; if (doing_name) {N" q = malloc(lname+n+1); strcpy(q,cname); free(cname); cname = q; strncat(cname,s,n);  cname[n] = '\0'; lname += n;($ if (!*p) doing_name = 0; } else {! q = malloc(lval+n+1);M strcpy(q, cval); free(cval);  cval = q;  strncat(cval,s,n); cval[n] = '\0';n lval += n; if (!*p) {& add_ENV(cname,cval,1); free(cname); free(cval);1 cname = malloc(1); *cname = '\0';)1 cval = malloc(1); *cval = '\0'; ! lname = lval = 0;  doing_name = 1; }e }  s = p + 1; }G}Avoidheartbeat_AST(void)_{T" ROUTINE_NAME("heartbeat_AST"); int iss; static int initialized = 0; static longword t_expire[2];! if (Heartbeats_Pending > 0) {;8 errlog(L_CRITICAL,"Heartbeat stopped, exiting"); fake_netshut();s return;y }0 if (!initialized) { - sec2vms(HEARTBEAT_TIMEOUT, t_expire);d initialized = 1; }7 iss = sys$setimr(0,t_expire, &heartbeat_AST, 0, 0);M& if (VMS_ERR(iss)) VMS_SIGNAL(iss); Heartbeats_Pending++;o& send_status(MSG$_HEARTBEAT,0,0,0);}Lvoidfake_netshut(void){!! ROUTINE_NAME("fake_netshut");o int iss; static MbxE E; pMbxE e = &E;  pMM m = (pMM) e->buf;e e->iosb.dvispec = MasterPID; m->code = MSG$_NETSHUT;e! iss = lib$insqhi(e, GotMsgQ); iss = sys$wake(0,0);}E*[CRINOID0051]TENTACLE.H;1+,WH. / 4> *<-Ke0123KPWO 56WQ7w(89GHJ/* * definitions for TENTACLE * */#ifndef __TENTACLE_H#define __TENTACLE_H#include "vms_data.h"#include "CRINOID_types.h"typedef struct SCRIPT { char * script; PerlInterpreter *perl; time_t time_last; struct SCRIPT *next; struct SCRIPT *last; } *pSCRIPT;8pENV add_ENV(char *name, char *value, int state);!pENV find_ENV(char *name);void clear_ENV(void);void init_ENV(void);void dump_ENV(FILE *fp);$int construct_perlENV(void);2void send_perlENV(char *name, char *value);int init_perl(void);int exec_perl(void);>int send_status(word code, word unit, char *s, int n);"int queue_read(word chan); int handle_connection(); void status_AST(pMbxE e);!void command_AST(pMbxE e);void do_errlog(pMbxE e);void do_loglev(pMbxE e); void do_envdata(pMbxE e);void upcase(char *s); void heartbeat_AST(void);void fake_netshut(void);#endif*[CRINOID0051]UTIL.C;1+,WH.6/ 4W6/<-Ke0123KPWO7567(89GHJ4/* * utility routines * */#include #include #include #include #include #include #include #include #include #include #include #include #include #include "errlog_client.h"#include "util.h":#define TOHEX(i) ((i) < 0x0a ? '0'+(i) : 'A' + (i) - 0x0A)void lc(char *s){ if (!s) return; while (*s) { *s = tolower(*s); s++; }}void uc(char *s){ if (!s) return; while (*s) { *s = toupper(*s); s++; }}voidprintable(char *s){ if (!s) return; while (*s) { *s &= 0x7f; if (*s < ' ') *s = '.';! if (*s == 0x7f) *s = '.'; s++; }}pMBXnew_MBX(char *lname, int size){ ROUTINE_NAME("new_MBX"); int iss; word length; longword unit; $DESCRIPTOR(d_lname, ""); pItemList i; IOSB iosb; pMBX m;# m = (pMBX) malloc(sizeof(MBX));< if (!m) VMS_ABORT(SS$_INSFMEM,"new_MBX: malloc failed"); m->chan = 0; m->unit = 0;& m->d_name.dsc$a_pointer = m->name; m->d_name.dsc$w_length = 0;, m->d_name.dsc$b_dtype = DSC$K_DTYPE_T;, m->d_name.dsc$b_class = DSC$K_CLASS_S;</* special case ... make a MBX struct, but that's all... */ if (size < 0) { if (lname) {& tu_strcpy(m->name, lname);6 m->d_name.dsc$w_length = tu_strlen(lname); } return m; } else if (size == 0) {$ size = DEFAULT_MAILBOX_SIZE; } m->size = size; if (lname) {1 d_lname.dsc$w_length = tu_strlen(lname);& d_lname.dsc$a_pointer = lname; }= iss = sys$crembx(0,&m->chan,size,DEFAULT_MAILBOX_QUOTA,0,8 PSL$C_USER,(lname ? &d_lname : 0));= if (VMS_ERR(iss)) VMS_ABORT(iss,"new_MBX: crembx error"); i = new_ItemList(2);7 i = add_Item(i, DVI$_UNIT, &unit, sizeof(unit), 0);7 i = add_Item(i, DVI$_DEVNAM, m->name, 64, &length); length = 0;8 iss = sys$getdviw(0, m->chan, 0, i, &iosb, 0, 0, 0); destroy_ItemList(i);7 if (VMS_ERR(iss)) VMS_ABORT(iss,"new_MBX: getdvi"); iss = iosb.status;7 if (VMS_ERR(iss)) VMS_ABORT(iss,"new_MBX: getdvi"); m->unit = unit;% m->d_name.dsc$w_length = length; m->name[length] = '\0'; return m;}pMBX2new_MBX_setquota(char *lname, int size, int quota){% ROUTINE_NAME("new_MBX_setquota"); int iss; word length; longword unit; $DESCRIPTOR(d_lname, ""); pItemList i; IOSB iosb; pMBX m;# m = (pMBX) malloc(sizeof(MBX));F if (!m) VMS_ABORT(SS$_INSFMEM,"new_MBX_setquota, malloc failure"); m->chan = 0; m->unit = 0;& m->d_name.dsc$a_pointer = m->name; m->d_name.dsc$w_length = 0;, m->d_name.dsc$b_dtype = DSC$K_DTYPE_T;, m->d_name.dsc$b_class = DSC$K_CLASS_S;</* special case ... make a MBX struct, but that's all... */ if (size < 0) { if (lname) {& tu_strcpy(m->name, lname);6 m->d_name.dsc$w_length = tu_strlen(lname); } return m; } else if (size == 0) {$ size = DEFAULT_MAILBOX_SIZE; } m->size = size; if (lname) {1 d_lname.dsc$w_length = tu_strlen(lname);& d_lname.dsc$a_pointer = lname; }P iss = sys$crembx(0,&m->chan,size,quota,0,PSL$C_USER,(lname ? &d_lname : 0));@ if (VMS_ERR(iss)) VMS_ABORT(iss,"new_MBX_setquota, crembx"); i = new_ItemList(2);7 i = add_Item(i, DVI$_UNIT, &unit, sizeof(unit), 0);7 i = add_Item(i, DVI$_DEVNAM, m->name, 64, &length); length = 0;8 iss = sys$getdviw(0, m->chan, 0, i, &iosb, 0, 0, 0); destroy_ItemList(i);@ if (VMS_ERR(iss)) VMS_ABORT(iss,"new_MBX_setquota, getdvi"); iss = iosb.status;@ if (VMS_ERR(iss)) VMS_ABORT(iss,"new_MBX_setquota, getdvi"); m->unit = unit;% m->d_name.dsc$w_length = length; m->name[length] = '\0'; return m;}pMBX&assign_new_MBX(char *dev, pMBX devmbx){# ROUTINE_NAME("assign_new_MBX"); int iss; word length; longword unit, size; pSTRING d_dev; pItemList i; IOSB iosb; pMBX m;# m = (pMBX) malloc(sizeof(MBX));D if (!m) VMS_ABORT(SS$_INSFMEM,"assign_new_MBX, malloc failure"); m->chan = 0; m->unit = 0;& m->d_name.dsc$a_pointer = m->name; m->d_name.dsc$w_length = 0;, m->d_name.dsc$b_dtype = DSC$K_DTYPE_T;, m->d_name.dsc$b_class = DSC$K_CLASS_S; d_dev = new_STRING(dev);I iss = sys$assign(d_dev, &m->chan, 0, (devmbx ? &devmbx->d_name : 0)); destroy_STRING(d_dev); if (VMS_ERR(iss)) {" pSTRING s = errormsg(iss);W errlog(L_ERROR,"assign_new_MBX: sys$assign err 0x!XL (!AS) for !AZ",iss,s,dev); destroy_STRING(s); free(m); return 0; } i = new_ItemList(3);7 i = add_Item(i, DVI$_UNIT, &unit, sizeof(unit), 0);7 i = add_Item(i, DVI$_DEVNAM, m->name, 64, &length);< i = add_Item(i, DVI$_DEVBUFSIZ, &size, sizeof(size), 0); length = 0;8 iss = sys$getdviw(0, m->chan, 0, i, &iosb, 0, 0, 0); destroy_ItemList(i);> if (VMS_ERR(iss)) VMS_ABORT(iss,"assign_new_MBX, getdvi"); iss = iosb.status;> if (VMS_ERR(iss)) VMS_ABORT(iss,"assign_new_MBX, getdvi"); m->unit = unit;% m->d_name.dsc$w_length = length; m->name[length] = '\0'; m->size = size; return m;}pMBXdestroy_MBX(pMBX m){ ROUTINE_NAME("destroy_MBX"); int iss; if (m->chan != 0) {" iss = sys$dassgn(m->chan);? if (VMS_ERR(iss)) VMS_ABORT(iss,"destroy_MBX, dassgn"); m->chan = 0; } free(m); return 0;}intdevice_unit(word chan){ ROUTINE_NAME("device_unit");" pItemList i = new_ItemList(1); IOSB iosb; int iss, unit;7 i = add_Item(i, DVI$_UNIT, &unit, sizeof(unit), 0);6 iss = sys$getdviw(0, chan, 0, &i, &iosb, 0, 0, 0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return unit;}void"device_name(word chan, char *name){ ROUTINE_NAME("device_name"); pItemList i; IOSB iosb; int iss; word length; i = new_ItemList(1);4 i = add_Item(i, DVI$_DEVNAM, name, 64, &length);6 iss = sys$getdviw(0, chan, 0, &i, &iosb, 0, 0, 0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); name[length]='\0';}intdevice_size(word chan){ ROUTINE_NAME("device_size"); pItemList i; IOSB iosb; int iss; word size; i = new_ItemList(1);< i = add_Item(i, DVI$_DEVBUFSIZ, &size, sizeof(size), 0);6 iss = sys$getdviw(0, chan, 0, &i, &iosb, 0, 0, 0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return (int) size;}longwordget_pflquota(longword pid){! ROUTINE_NAME("get_pflquota"); int iss; longword quota = 0; IOSB iosb; pItemList i; pPrivs p0 = Current_Privs(); pPrivs p; i = new_ItemList(1);> i = add_Item(i, JPI$_PAGFILCNT, "a, sizeof(quota), 0);" if (pid && !p0->prv$v_world) { p = new_Privs(); p->prv$v_world = 1; Set_Privs(p); }, iss = sys$getjpiw(0,&pid,0,i,&iosb,0,0);" if (pid && !p0->prv$v_world) { Reset_Privs(p); destroy_Privs(p); } destroy_Privs(p0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return quota;}longwordget_bytcnt(longword pid){ ROUTINE_NAME("get_bytcnt"); int iss; longword quota = 0; IOSB iosb; pItemList i; i = new_ItemList(1);; i = add_Item(i, JPI$_BYTCNT, "a, sizeof(quota), 0);, iss = sys$getjpiw(0,&pid,0,i,&iosb,0,0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return quota;}longwordget_bytlm(longword pid){ ROUTINE_NAME("get_bytlm"); int iss; longword quota = 0; IOSB iosb; pItemList i; i = new_ItemList(1);: i = add_Item(i, JPI$_BYTLM, "a, sizeof(quota), 0);, iss = sys$getjpiw(0,&pid,0,i,&iosb,0,0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return quota;}longword get_pid(void){ ROUTINE_NAME("get_pid"); int iss; longword pid; pItemList i; IOSB iosb; i = new_ItemList(1);4 i = add_Item(i, JPI$_PID, &pid, sizeof(pid), 0);) iss = sys$getjpiw(0,0,0,i,&iosb,0,0); destroy_ItemList(i);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); iss = iosb.status;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return pid;}cpSTRING>new_STRING(char *s)h{ ROUTINE_NAME("new_STRING");v pSTRING p;# static $DESCRIPTOR(d_null, "");) p = (pSTRING) malloc(sizeof(STRING));i$ if (!p) VMS_SIGNAL(SS$_INSFMEM); *p = d_null;# p->dsc$w_length = tu_strlen(s);i: p->dsc$a_pointer = (char *) malloc(p->dsc$w_length+1);3 if (!p->dsc$a_pointer) VMS_SIGNAL(SS$_INSFMEM);s strcpy(p->dsc$a_pointer, s); return p;}cpSTRINGnew_STRING2(int size){ ROUTINE_NAME("new_STRING2"); pSTRING p;# static $DESCRIPTOR(d_null, "");h) p = (pSTRING) malloc(sizeof(STRING));*$ if (!p) VMS_SIGNAL(SS$_INSFMEM); *p = d_null; p->dsc$w_length = size;s/ p->dsc$a_pointer = (char *) malloc(size+1);(3 if (!p->dsc$a_pointer) VMS_SIGNAL(SS$_INSFMEM);"( memset(p->dsc$a_pointer, 0, size+1); return p; }SpSTRINGn%concat_STRING(pSTRING s1, pSTRING s2)i{;" ROUTINE_NAME("concat_STRING"); pSTRING p;5 int size = strlen_pSTRING(s1)+strlen_pSTRING(s2);f p = new_STRING2(size);$ if (!p) VMS_SIGNAL(SS$_INSFMEM);D memcpy(asciz_pSTRING(p), asciz_pSTRING(s1), strlen_pSTRING(s1));W memcpy(asciz_pSTRING(p)+strlen_pSTRING(s1), asciz_pSTRING(s2), strlen_pSTRING(s2));a return p;B}tpSTRING/destroy_STRING(pSTRING p) { # ROUTINE_NAME("destroy_STRING");( int iss, length; if (!p) return 0;e1 if (p->dsc$a_pointer) free(p->dsc$a_pointer);n free(p); return 0;0}L/**************************************************************************//*/ * thread-reentrant versions of string routinesm */int tu_strlen(char *str )e={ int i = 0; char *p; for ( p = str; *p++; i++ ); return i; }U*char *tu_strcpy ( char *str1, char *str2 ){ char *p, *d, c;_ d = str1; + for ( p = str2; (c = *p++); *d++ = c );r *d = '\0'; return str1;}i*char *tu_strcat ( char *str1, char *str2 ){ char *p, *d, c; for ( d = str1; *d; d++);,+ for ( p = str2; (c = *p++); *d++ = c ); *d = '\0'; return str1;}i6char *tu_strncpy ( char *str1, char *str2, int limit ){ char *p, *d, c; int i; p = str2; d = str1; # for ( i = limit; i > 0; --i ) { , c = *p++; *d++ = c; if ( !c ) break; }n return str1;}s7char *tu_strnzcpy ( char *str1, char *str2, int limit ){ char *p, *d, c; int i;2 /* Assume str1 buffer is 1 larger than limit */ p = str2; d = str1;e3 for ( i = limit; (i > 0) && (c = *p++); --i ) {  *d++ = c;  }R *d = '\0'; return str1;};char *tu_strrchr(char *s, char c) {p char *r;& if (c == 0) return s+tu_strlen(s); for (r = 0; *s; s++) if (*s == c) r = s; return r;i} char *tu_strchr(char *s, char c){; for (; *s != c; s++) if (!*s) return 0; return s;$}T3int tu_strncmp ( char *str1, char *str2, int maxl ){ int i=0; char c1, c2; " for ( i = 0; i < maxl; i++ ) { c1 = str1[i];8 if (c1 != str2[i]) return c1 < str2[i] ? -1 : 1;D if (c1 == '\0') return str2[i] ? 1: 0; /* str2 is longer */ } 2 return 0; /* equal to maxl chars. */}e'int tu_strcmp ( char *str1, char *str2)z{ int i=0; char c1, c2;m while (1) {n c1 = str1[i];s8 if (c1 != str2[i]) return c1 < str2[i] ? -1 : 1;D if (c1 == '\0') return str2[i] ? 1: 0; /* str2 is longer */ i++; } 2 return 0; /* equal to maxl chars. */}e*int tu_strcmp_uc ( char *str1, char *str2){ int i=0; char c1, c2;n while (1) {  c1 = toupper(str1[i]);J if (c1 != toupper(str2[i])) return c1 < toupper(str2[i]) ? -1 : 1;D if (c1 == '\0') return str2[i] ? 1: 0; /* str2 is longer */ i++; }(2 return 0; /* equal to maxl chars. */};&char *tu_strstr ( char *s1, char *s2 ){t charwfϒ~ FREEWARE.SAVWHKe[CRINOID0051]UTIL.C;1W6* *cand;  unsigned int i,j; : for ( cand = s1; *cand; cand++ ) if ( *cand == *s2 ) {# for ( i = 1; s2[i]; i++ ) {G if ( cand[i]=='\0' ) return (char *) 0; /* too short */n* if ( s2[i] != cand[i] ) break; }oA if ( s2[i] == '\0' ) return cand; /* found match */; }MF if ( !*s2 ) return s1; /* Zero length input string */ return (char *) 0;}m,/* returns the number of chars that match */"int tu_nmatch( char *s1, char *s2){- int n = 0; if (!s1 || !s2) return 0;- while (*s1 && *s2) {" if (*s1++ != *s2++) break; n++; } return n;e}TpSTRINGtranslate_logical(char *name)>{n& ROUTINE_NAME("translate_logical"); int iss;& $DESCRIPTOR(table,"LNM$FILE_DEV"); pSTRING pname; pItemList i; char equiv[256]; word length; pname = new_STRING(name);, i = new_ItemList(1);@ i = add_Item(i, LNM$_STRING, equiv, sizeof(equiv), &length);1 iss = sys$trnlnm(0,&table,pname,0,(char *)i);, destroy_ItemList(i); destroy_STRING(pname);& if (iss == SS$_NOLOGNAM) return 0;& if (VMS_ERR(iss)) VMS_SIGNAL(iss); equiv[length] = '\0'; return new_STRING(equiv);>}nintiSet_Privs(pPrivs p)e{o return sys$setprv(1,p,0,0);s} intRReset_Privs(pPrivs p)g{v return sys$setprv(0,p,0,0); }( pItemListMnew_ItemList(int n)e{B! ROUTINE_NAME("new_ItemList");* static ItemList null_item = NULL_ITEM; pItemList i;' i = malloc(sizeof(ItemList)*(n+2));n$ if (!i) VMS_SIGNAL(SS$_INSFMEM); i[0].length = n; i[0].code = 0; i++; i[0] = null_item;0 return i;s} pItemList>Hadd_Item(pItemList i, word code, void *address, word size, word *retlen){  ROUTINE_NAME("add_Item"); + static ItemList null_item = NULL_ITEM;u pItemList ibase = i-1;' if (ibase->code == ibase->length) {  ibase->length++;D ibase = realloc(ibase, sizeof(ItemList)*(ibase->length+2));, if (!ibase) VMS_SIGNAL(SS$_INSFMEM); i = ibase+1; }0 i[ibase->code].code = code;3 i[ibase->code].address = address;R0 i[ibase->code].length = size;2 i[ibase->code].return_length_address = retlen; ibase->code++; i[ibase->code] = null_item;B return i;s}voiddestroy_ItemList(pItemList i)t{;% ROUTINE_NAME("destroy_ItemList");, free(i-1);} pSTRINGdget_userlogin(char *user)0{," ROUTINE_NAME("get_userlogin"); pSTRING name, result;L int iss; pItemList i; pPrivs p0, p1; struct { byte size; char s[31]; } dev; struct { byte size; char s[63]; } dir; i = new_ItemList(2);7 i = add_Item(i, UAI$_DEFDEV, &dev, sizeof(dev), 0);d7 i = add_Item(i, UAI$_DEFDIR, &dir, sizeof(dir), 0);  name = new_STRING(user); uc(asciz_pSTRING(name)); p0 = Current_Privs();R if (!p0->prv$v_sysprv) { p1 = new_Privs();( p1->prv$v_sysprv = 1; Set_Privs(p1); }' iss = sys$getuai(0,0,name,i,0,0,0); destroy_STRING(name);q destroy_ItemList(i); if (!p0->prv$v_sysprv) { Reset_Privs(p1); destroy_Privs(p1); }  destroy_Privs(p0);" if (iss == RMS$_RNF) return 0;& if (VMS_ERR(iss)) VMS_SIGNAL(iss);, result = new_STRING2(dev.size+dir.size);3 memcpy(asciz_pSTRING(result), dev.s, dev.size);< memcpy(asciz_pSTRING(result)+dev.size, dir.s, dir.size); return result;} pPrivsCurrent_Privs(void){ " ROUTINE_NAME("current_Privs"); int iss; pItemList i; IOSB iosb; pPrivs p;m p = new_Privs(); i = new_ItemList(1);7 i = add_Item(i, JPI$_CURPRIV, p, sizeof(Privs), 0);i) iss = sys$getjpiw(0,0,0,i,&iosb,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);6 if (VMS_ERR(iosb.status)) VMS_SIGNAL(iosb.status); destroy_ItemList(i); return p;} pPrivsAuthorized_Privs(void){t% ROUTINE_NAME("Authorized_Privs");) int iss; pItemList i; IOSB iosb; pPrivs p;o p = new_Privs(); i = new_ItemList(1);8 i = add_Item(i, JPI$_AUTHPRIV, p, sizeof(Privs), 0);) iss = sys$getjpiw(0,0,0,i,&iosb,0,0);g& if (VMS_ERR(iss)) VMS_SIGNAL(iss);6 if (VMS_ERR(iosb.status)) VMS_SIGNAL(iosb.status); destroy_ItemList(i); return p; }pPrivsImage_Privs(void) { ROUTINE_NAME("Image_Privs"); int iss; pItemList i; IOSB iosb; pPrivs p;; p = new_Privs(); i = new_ItemList(1);8 i = add_Item(i, JPI$_IMAGPRIV, p, sizeof(Privs), 0);) iss = sys$getjpiw(0,0,0,i,&iosb,0,0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);6 if (VMS_ERR(iosb.status)) VMS_SIGNAL(iosb.status); destroy_ItemList(i); return p;} pPrivsProcess_Privs(void)d{t" ROUTINE_NAME("Process_Privs"); int iss; pItemList i; IOSB iosb; pPrivs p;m p = new_Privs(); i = new_ItemList(1);8 i = add_Item(i, JPI$_PROCPRIV, p, sizeof(Privs), 0);) iss = sys$getjpiw(0,0,0,i,&iosb,0,0);>& if (VMS_ERR(iss)) VMS_SIGNAL(iss);6 if (VMS_ERR(iosb.status)) VMS_SIGNAL(iosb.status); destroy_ItemList(i); return p;a}cpPrivsAND_Privs(pPrivs p1, pPrivs p2)${S ROUTINE_NAME("AND_Privs"); int j; pPrivs presult; union pu { word w[4];c Privs p; } *q1, *q2, *qr; presult = new_Privs(); q1 = (union pu *) p1;o q2 = (union pu *) p2; qr = (union pu *) presult; for (j = 0; j<4; j++) {e' qr->w[j] = q1->w[j] & q2->w[j];$ }T return presult; } pPrivsOR_Privs(pPrivs p1, pPrivs p2){( ROUTINE_NAME("OR_Privs"); int j; pPrivs presult;n union pu { word w[4];( Privs p;  } *q1, *q2, *qr; presult = new_Privs(); q1 = (union pu *) p1;0 q2 = (union pu *) p2;  qr = (union pu *) presult; for (j = 0; j<4; j++) { ' qr->w[j] = q1->w[j] | q2->w[j];R } return presult;_}RpPrivsNOT_Privs(pPrivs p1){  ROUTINE_NAME("NOT_Privs"); int j; union pu { word w[4];T Privs p;t } *q1, *qr;; pPrivs presult;T presult = new_Privs(); q1 = (union pu *) p1;N qr = (union pu *) presult; for (j = 0; j<4; j++) {_ qr->w[j] = ~q1->w[j];T }E return presult;} pPrivsnew_Privs(void)({  ROUTINE_NAME("new_Privs"); pPrivs p;s p = malloc(sizeof(Privs));$ if (!p) VMS_SIGNAL(SS$_INSFMEM); p->prv$l_l1_bits = 0;* p->prv$l_l2_bits = 0;* return p;a}evoiddestroy_Privs(pPrivs p)e{" ROUTINE_NAME("destroy_Privs"); free(p);}pint 'sec2vms(int seconds, longword delta[2])*{s ROUTINE_NAME("sec2vms");7 static $DESCRIPTOR (timeformat, "!UL !UL:!UL:!UL");2 word len;d int iss, days, hours, mins;e char tstring[100]; $DESCRIPTOR(expire,"");*# expire.dsc$a_pointer = tstring; + expire.dsc$w_length = sizeof(tstring);= days = seconds / 86400;' seconds -= days * 86400; hours = seconds / 3600;r seconds -= hours * 3600; mins = seconds / 60; seconds -= mins * 60; J iss = sys$fao(&timeformat, &len, &expire, days, hours, mins, seconds);! if (VMS_ERR(iss)) return iss;r expire.dsc$w_length = len;t% iss = sys$bintim(&expire, delta);  return iss;s} pSTRINGaerrormsg(int cond){  ROUTINE_NAME("errormsg"); int iss; word len;+! pSTRING s = new_STRING2(256);  pSTRING s2;0* iss = sys$getmsg(cond, &len, s, 0, 0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss);! asciz_pSTRING(s)[len] = '\0';s& s2 = new_STRING(asciz_pSTRING(s)); destroy_STRING(s); return s2;}hintu4define_logical(char *name, char *value, char *table){ # ROUTINE_NAME("define_logical");s int iss = SS$_INSFMEM; pSTRING pname, ptable; pItemList i;0 if (!(pname = new_STRING(name))) goto done;1 if (!(ptable = new_STRING(table))) goto done;r* if (!(i = new_ItemList(1))) goto done;: i = add_Item(i, LNM$_STRING, value, strlen(value), 0);) iss = sys$crelnm(0,ptable,pname,0,i);cdone:$ if (i) destroy_ItemList(i);& if (pname) destroy_STRING(pname);' if (ptable) destroy_STRING(ptable);  return iss;2})#ifndef __ALPHA?int )__ATOMIC_INCREMENT_LONG(volatile void *p) {: int iss, l, *lp = (int *)p;  iss = sys$setast(0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); l = *lp; *lp++; iss = sys$setast(1);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return l;u}rint;)__ATOMIC_DECREMENT_LONG(volatile void *p)n{  int iss, l, *lp = (int *)p;  iss = sys$setast(0);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); l = *lp; *lp--; iss = sys$setast(1);& if (VMS_ERR(iss)) VMS_SIGNAL(iss); return l;r}1#endif#ifdef DEBUG_MEMORY #undef freei #undef malloc #undef realloc#endifvoid%my_free(void *pointer, char *routine) {;; errlog(L_MEM|L_INFO,"[!AZ] free(!XL)",routine,pointer);a free(pointer);}tvoid *%my_malloc(size_t size, char *routine){  void * p = malloc(size);B errlog(L_MEM|L_INFO,"[!AZ] malloc(!UL) = !XL",routine,size,p); return p; } void *5my_realloc(void *pointer, size_t size, char *routine){*$ void *p = realloc(pointer,size);O errlog(L_MEM|L_INFO,"[!AZ] realloc(!XL,!UL) = !XL",routine,pointer,size,p); return p; }hchar *dumpstring(char *s, int n){+ ROUTINE_NAME("dumpstring"); $ int len = 1+(3*n-1)+1+1+1+n+1+1; int j; char *p, *p0;  if (n < 0) return 0; p = p0 = malloc(len);D if (!p) return 0;L *p = 0;S if (n == 0) return p;  *p++ = '[';2 for (j = 0; j < n; j++) {n char c = s[j];$ *p++ = TOHEX((c>>4) & 0x0F); *p++ = TOHEX(c & 0x0F);e *p++ = ' '; }s *(p-1) = ']';a *p++ = ' ';  *p++ = '|';t for (j = 0; j < n; j++) {I char c = s[j]; if (!c) c = '.'; *p++ = c;s }_ *p++ = '|'; *p = 0;  printable(p0); return p0;}>*[CRINOID0051]UTIL.H;1+,W6. / 4U 6<-Ke0123KPWO 56Vm7ͅ(89GHJ #ifndef __UTIL_H#define __UTIL_H#include "vms_data.h"#include "CRINOID_types.h"void lc(char *s);void uc(char *s);void printable(char *s);+pMBX new_MBX(char *lname, int size);?pMBX new_MBX_setquota(char *lname, int size, int quota);3pMBX assign_new_MBX(char *dev, pMBX devmbx); pMBX destroy_MBX(pMBX m);#int device_unit(word chan);/void device_name(word chan, char *name);#int device_size(word chan);'longword get_pflquota(longword pid);%longword get_bytcnt(longword pid);$longword get_bytlm(longword pid);longword get_pid(void); pSTRING new_STRING(char *s);"pSTRING new_STRING2(int size);2pSTRING concat_STRING(pSTRING s1, pSTRING s2);&pSTRING destroy_STRING(pSTRING s);"int tu_strlen(char *str );1char * tu_strcpy ( char *str1, char *str2 );1char * tu_strcat ( char *str1, char *str2 );=char * tu_strncpy ( char *str1, char *str2, int limit );>char * tu_strnzcpy ( char *str1, char *str2, int limit );(char * tu_strchr (char *s, char c);)char * tu_strrchr (char *s, char c);<int tu_strncmp ( char *str1, char *str2, int maxl );0int tu_strcmp ( char *str1, char *str2);3int tu_strcmp_uc ( char *str1, char *str2);-char * tu_strstr ( char *s1, char *s2 );+int tu_nmatch( char *s1, char *s2);*pSTRING translate_logical(char *name); int Set_Privs(pPrivs p);"int Reset_Privs(pPrivs p); pItemList new_ItemList(int n);UpItemList add_Item(pItemList i, word code, void *address, word size, word *retlen);*void destroy_ItemList(pItemList i);&pSTRING get_userlogin(char *user); pPrivs Current_Privs(void);#pPrivs Authorized_Privs(void);pPrivs Image_Privs(void); pPrivs Process_Privs(void);,pPrivs AND_Privs(pPrivs p1, pPrivs p2);+pPrivs OR_Privs(pPrivs p1, pPrivs p2);!pPrivs NOT_Privs(pPrivs p1);pPrivs new_Privs(void);$void destroy_Privs(pPrivs p);4int sec2vms(int seconds, longword delta[2]);pSTRING errormsg(int cond);Aint define_logical(char *name, char *value, char *table);#ifndef __ALPHA6int __ATOMIC_INCREMENT_LONG(volatile void *p);6int __ATOMIC_DECREMENT_LONG(volatile void *p);#endif2void my_free(void *pointer, char *routine);2void * my_malloc(size_t size, char *routine);Bvoid * my_realloc(void *pointer, size_t size, char *routine);'char * dumpstring(char *s, int n);#endif /* __UTIL_H */*[CRINOID0051]VERSION.H;1+,Wk. / 4E <-Ke0123KPWO 56t 7p 89GHJE/*******************************************************************\D * *D * collect all the versioning info in one place *D * *D * *E\*******************************************************************/#ifndef _VERSION_H#define _VERSION_H##define CRINOID_VERSION "0.51-5"#endif*[CRINOID0051]VMS_DATA.H;1+,WH. / 4z <-Ke0123KPWO 56K#7K(89GHJ /* * * vms data structures * */#ifndef __VMS_DATA_H#define __VMS_DATA_H#include typedef unsigned char byte;typedef unsigned short word;!typedef unsigned long longword;(typedef signed long signed_longword;)typedef struct dsc$descriptor_s STRING;)typedef struct dsc$descriptor_s* pSTRING;(typedef struct _IOSB IOSB;/#define asciz_pSTRING(p) ((p)->dsc$a_pointer).#define strlen_pSTRING(p) ((p)->dsc$w_length)#pragma member_alignment save#pragma nomember_alignmentstruct _IOSB { word status; word count; longword dvispec;};struct ITEM_LIST_3 { word length; word code; void * address;! word * return_length_address;};'typedef struct ITEM_LIST_3 ItemList;'typedef struct ITEM_LIST_3* pItemList; #define NULL_ITEM {0,0,0,0}(#define ITEM(a,b,c,d) {(a),(b),(c),(d)}&#define ITEM_CODE(a) (a)->code(#define ITEM_LENGTH(a) (a)->length)#define ITEM_ADDR(a) (a)->address7#define ITEM_RETLENADDR(a) (a)->return_length_addressstruct _lksb { word status; word _reserved; longword id; byte value[16];};typedef struct _lksb LSB;typedef struct _lksb * pLSB;##pragma nomember_alignment quadword struct SRQP { longword relptr[2];};typedef struct SRQP RQE;#pragma nomember_alignment#include typedef union prvdef Privs;typedef union prvdef* pPrivs;!#define VMS_OK(s) (((s)&1)!=0)!#define VMS_ERR(s) (((s)&1)==0)#define UNIX_OK(s) (s==0)#define UNIX_ERR(s) (s!=0)_#define UNIX_ABORT(s) {perror(s); lib$signal(CRINOID_SYSSRVERR,2,__FILE__,__LINE__,SS$_ABORT);}z#define VMS_ABORT(s,msg) {errlog(L_ERROR,"!AZ, Error 0x!XL",msg,s); lib$signal(CRINOID_SYSSRVERR,2,__FILE__,__LINE__,s);}#pragma message save!#pragma message disable globalext"globalvalue int CRINOID_SYSSRVERR;#pragma message restoreK#define VMS_SIGNAL(s) lib$signal(CRINOID_SYSSRVERR,2,__FILE__,__LINE__,s)M#define RMS_SIGNAL(s,v) lib$signal(CRINOID_SYSSRVERR,2,__FILE__,__LINE__,s,v)%#define DEFAULT_MAILBOX_SIZE 10249#define DEFAULT_MAILBOX_QUOTA (4*DEFAULT_MAILBOX_SIZE)%#define MAX_MAILBOX_SIZE 4096#endif*[SKEY009]FREEWARE_README.TXT;1+,J. / 4Z ><-00123KPWO 56and to verify logins. S/Key authenticated logins are normallyCoptional, but can be user-configured to be default or manditory. AE/[NO]SKEY qualifer on the login username can select or deselect S/Key1authentication when allowed by the configuration.CAn SKEY command verb is provided for calculating S/Key responses asGwell as allowing users to set up their S/Key logins. Utility routinesCare provided to aid in making application programs "S/Key capable".JFull source code is provided, along with object files compiled on VMS 6.2.*[SKEY009]SKEY009.A;12+,tE.'/ 4~'(~-00123KPWO(56}ao7$ SAY "Existing SYS$STARTUP:SKEY_STARTUP.COM not replaced"e$ SAY "The new SKEY_STARTUP.COM from this kit will be placed in SYS$STARTUP:SKEY_STARTUP.COM_NEW" $ SAY ""A$ COPY VMI$KWD:SKEY_STARTUP.COM VMI$KWD:SKEY_STARTUP.COM_NEWU$ VMI$CALLBACK PROVIDE_FILE STARTUP SKEY_STARTUP.COM_NEW VMI$ROOT:[SYS$STARTUP]$ ENDIF:$ VMI$FIND SHUTDOWN SKEY_SHUTDOWN.COM SYS$MANAGER: S FOUND"$ IF F$TRNLNM("SHUTDOWN") .EQS. ""$ THENL$ VMI$CALLBACK PROVIDE_FILE SHUTDOWN SKEY_SHUTDOWN.COM VMI$ROOT:[SYSMGR]$ ELSE $ SAY ""?$ SAY "Existing SYS$MANAGER:SKEY_SHUTDOWN.COM not replaced"f$ SAY "The new SKEY_SHUTDOWN.COM from this kit will be placed in SYS$MANGER:SKEY_SHUTDOWN.COM_NEW" $ SAY ""C$ COPY VMI$KWD:SKEY_SHUTDOWN.COM VMI$KWD:SKEY_SHUTDOWN.COM_NEWR$ VMI$CALLBACK PROVIDE_FILE SHUTDOWN SKEY_SHUTDOWN.COM_NEW VMI$ROOT:[SYSMGR]$ ENDIF$!$ SAY ""B$ SAY "To start using S/Key, execute SYS$STARTUP:SKEY_STARTUP.COM"Y$ SAY "you may want to modify your system startup procedure to start S/Key automatically"$ IF F$GETSYI("CLUSTER_MEMBER")$ THENO$ VMI$CALLBACK PROVIDE_FILE CLMOD SKEY_CLUSTER_UPDATE.COM VMI$ROOT:[SYSUPD] $ SAY ""G$ SAY "To update other cluster members sharing the same system disk,"L$ SAY "execute the procedure SYS$UPDATE:SKEY_CLUSTER_UPDATE on each node."J$ SAY "For cluster members that have a separate system disk, you should"9$ SAY "do a complete installation on each system disk." $ SAY ""$ ENDIF$! $ IF GETSRC$ THEN"$ VMI$CALLBACK RESTORE_SAVESET B8$ VMI$CALLBACK PROVIDE_FILE "" SOURCE_FILES.VDT "" "T"$ ENDIF$ EXIT VMI$_SUCCESS$!G$!=====================================================================$!$!$ STARTUP_MODIFY: SUBROUTINE,$ RENAME VMI$KWD:SKEY_STARTUP.COM .COM-ORIG-$ OPEN/READ FD1 VMI$KWD:SKEY_STARTUP.COM-ORIG)$ OPEN/WRITE FD2 VMI$KWD:SKEY_STARTUP.COM$$ DBF = P1 - F$PARSE(P1,,,"VERSION")$ LOOP:$ READ/END=ELOOP FD1 LINE'$ IF F$EXTRACT(0,4,LINE) .EQS. "$!+!"$ THEN:$ LINE = "$ DEFINE/SYSTEM/EXEC SKEY_DATABASE ''DBF'" $ ENDIF$ WRITE FD2 LINE $ GOTO LOOP$ ELOOP: $ CLOSE FD1 $ CLOSE FD2$ EXIT 1$ ENDSUBROUTINE$*[LANE.WORK.SKEY.INSTALL_A]SKEY.CLD;1+,\. / 4U <- e*0123KPWO56i)7-)89GHJdefine verb SKEY image SKEY* qualifier VERSION, syntax=SKEY_VERSIONB parameter P1, prompt="Sequence", value (required,type=$number)E parameter P2, prompt="Seed", value (required,type=$quoted_string)C qualifier COUNT, nonnegatable, value (default="1",type=$number)> qualifier OUTPUT, value (type=$outfile,default="SKEY.LIS")A qualifier PASSWORD, nonnegatable, value (type=$quoted_string)> qualifier ALGORITHM, value (required, type=SKEY_ALGORITHM)< qualifier DICTIONARY, nonnegatable, value (type=$infile) qualifier DELETE qualifier PRINT> qualifier QUEUE, nonnegatable, value (default="SYS$PRINT") qualifier HEXADECIMAL$ disallow (DELETE and not PRINT)# disallow (QUEUE and not PRINT)# disallow (PRINT and not COUNT)0 qualifier INITIALIZE, syntax=SKEY_INITIALIZE& qualifier CLEAR, syntax=SKEY_CLEAR$ qualifier TEST, syntax=SKEY_TEST$ qualifier SHOW, syntax=SKEY_SHOW* qualifier PROFILE, syntax=SKEY_PROFILEC disallow any2 (INITIALIZE, CLEAR, TEST, SHOW, PROFILE, VERSION)0 disallow any2 (ALGORITHM.MD4, ALGORITHM.MD5)define syntax SKEY_INITIALIZE parameter P1, prompt="User"$ qualifier SEQUENCE, nonnegatable value (type=$number); qualifier PASSWORD, default value (type=$quoted_string) qualifier SEED, nonnegatable value (required)> qualifier ALGORITHM, value (required, type=SKEY_ALGORITHM)E qualifier DATABASE, nonnegatable, value (required, type=$outfile) qualifier NEW, nonnegatable qualifier LOG qualifier CLEAR qualifier TEST qualifier SHOW$ disallow (CLEAR or TEST or SHOW)# disallow (NEW and not DATABASE)0 disallow any2 (ALGORITHM.MD4, ALGORITHM.MD5)define syntax SKEY_CLEAR parameter P1, Prompt="User" qualifier LOGE qualifier DATABASE, nonnegatable, value (required, type=$outfile) qualifier TEST qualifier SHOW disallow (TEST or SHOW)define syntax SKEY_TEST parameter P1, prompt="User"< qualifier DICTIONARY, nonnegatable, value (type=$infile)? qualifier OUTPUT, value (type=$outfile,default="SKEY.DICT") qualifier MULTIPLE, defaultE qualifier DATABASE, nonnegatable, value (required, type=$outfile) qualifier SHOW disallow SHOW& disallow OUTPUT and not DICTIONARY$ disallow MULTIPLE and not OUTPUT$ disallow DATABASE and DICTIONARYdefine syntax SKEY_SHOW parameter p1, prompt="User"E qualifier DATABASE, nonnegatable, va~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'{ lue (required, type=$outfile)define syntax SKEY_PROFILE parameter p1, prompt="User"T qualifier ENABLE, nonnegatable, value (required, list, type=SKEY_ENABLE_OPTIONS)U qualifier DISABLE, nonnegatable, value (required, list, type=SKEY_ENABLE_OPTIONS)E qualifier DATABASE, nonnegatable, value (required, type=$outfile)1 disallow (ENABLE.DEFAULT and DISABLE.DEFAULT). disallow (ENABLE.SKEY and DISABLE.SKEY)0 disallow (ENABLE.NORMAL and DISABLE.NORMAL)define syntax SKEY_VERSION noparametersdefine type SKEY_ALGORITHM keyword MD4 keyword MD5, defaultdefine type SKEY_ENABLE_OPTIONS keyword DEFAULT keyword NORMAL keyword SKEY#*[LANE.WORK.SKEY.INSTALL_A]SKEY.DB;1+,% . / 4! - e*0123KPWO 56%b)7Irt)89GHJ@@@   r$*[LANE.WORK.SKEY.INSTALL_A]SKEY.HLP;1+,n.-/ 4M--<- e*0123KPWO.563()7 :)89GHJ81 SKEY@ The SKEY command provides access to the S/Key authentication3 database, as well as S/Key calculator functions 2 StandardsJ The S/Key authentication scheme is described in RFC-1760 and RFC-1938.G This implementation uses the MD4 and MD5 message-digest algorithms,4 described in RFC-1320 and RFC-1321 respectively.3 MD4_legal_notice MD4 legal noticeE Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.D License to copy and use this software is granted provided that itC is identified as the "RSA Data Security, Inc. MD4 Message-DigestE Algorithm" in all material mentioning or referencing this software or this function.D License is also granted to make and use derivative works provided? that such works are identified as "derived from the RSA Data? Security, Inc. MD4 Message-Digest Algorithm" in all material. mentioning or referencing the derived work.E RSA Data Security, Inc. makes no representations concerning eitherB the merchantability of this software or the suitability of this> software for any particular purpose. It is provided "as is"3 without express or implied warranty of any kind.C These notices must be retained in any copies of any part of this! documentation and/or software.3 MD5_legal_notice MD5 legal notice? Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.E License to copy and use this software is granted provided that itD is identified as the "RSA Data Security, Inc. MD5 Message-DigestF Algorithm" in all material mentioning or referencing this software or this function.E License is also granted to make and use derivative works provided@ that such works are identified as "derived from the RSA Data@ Security, Inc. MD5 Message-Digest Algorithm" in all material/ mentioning or referencing the derived work.F RSA Data Security, Inc. makes no representations concerning eitherC the merchantability of this software or the suitability of this? software for any particular purpose. It is provided "as is"4 without express or implied warranty of any kind.D These notices must be retained in any copies of any part of this" documentation and/or software.2 Username_qualifiers? When S/Key is selected as the default authentication method (see SKEY/PROFILE/ENABLE): Username: JOE_USER otp-md5 123 abc666K Password: **************** [S/Key password not echoed]H One can explicitly disable S/Key authentication on a per-login basis? if allowed by the user profile (SKEY/PROFILE/ENABLE=NORMAL)! Username: JOE_USER/NOSKEY Password: ***********H When S/Key is not selected by default (SKEY/PROFILE/DISABLE=DEFAULT)J but is allowed by explicit user-selection: (SKEY/PROFILE/ENABLE=SKEY) Username: JOE_USER Password: *********** Username: JOE_USER/SKEY otp-md5 123 abc666! Password: ***************2 Getting_StartedC First you need to generate an S/Key record for yourself. If youE are logged in via a secure line (encrypted, a DECwindows console, or a hardwired line): $ SKEY/INITIALIZE/LOG> Password: secretPASSWORD [not echoed]: S/Key initialized for JOE_USER, next challenge is: otp-md5 199 odz065F In this example, "199" is the sequence number, and "odz065" is theA seed. The seed is generated randomly, unless specified withI a /SEED qualifier (See SKEY/INITIALIZE/SEED). Sequence numbers countH down at each successful login, so this S/Key entry for JOE_USER will? allow 199 logins. The initial sequence may be set with the1 /SEQUENCE qualifier (See SKEY/INIT/SEQUENCE).E If you are logging in over an insecure line BUT you have an S/KeyI calculator on a local (secure) machine, you may initialize your S/Key+ record using the /NOPASSWORD qualifier.B It works like this: S/Key issues a challenge with sequence and< seed; you use the challenge as input to your local S/KeyE calculator, along with your secret password. Then type the S/KeyC response string (calculated locally from the challenge and your0 secret password) at the "Password: " prompt. $ SKEY/INIT/LOG/NOPASS? otp-md5 200 ial935 [challenge]> Password: ************************* [response]: S/Key initialized for JOE_USER, next challenge is: otp-md5 199 ial935F If for some reason you wish to go back to "normal" authentication,A you can do an SKEY/CLEAR to clear your S/Key record, or do anI SKEY/PROFILE/DISABLE=DEFAULT, which will make "normal" authenticationD the default for your account but allow S/Key authentication on a+ per-login basis. (See Login_Qualifiers) 2 Calculator Format:" SKEY sequence_number seedI if no password is given on the command line, it will be prompted for.E The output is a one-time key string which can be used as input to S/Key authentication. 3 ParametersSequence_number9 specifies the ending sequence number to be calculatedSeed@ The seed is an alphanumeric string of 16 characters or less. Case is not sigificant. 3 Qualifiers/COUNT /COUNT=numberC A count of how many one-time keys should be generated. If this; qualifier is not given, a default count of one is used./OUTPUT /OUTPUT[=file]D Writes output to the specified file. Default file is "SKEY.LIS" /PASSWORD /PASSWORD="password_string"B Uses the specified password_string rather than prompting for a password. /ALGORITHM /ALGORITHM=MD5 (DEFAULT) /ALGORITHM=MD4A Specifies the hashing algorithm to be used in calculating the one-time keys. /DICTIONARY /DICTIONARY[=dict_file]? Specifies a user-supplied alternate dictionary for passwordF encoding. The dictionary is a text file (invalid text or non-textB characters are ignored). See "SKEY/TEST/DICTIONARY" for more1 information about alternate dictionary files.C This qualifier may not be used with the /HEXADECIMAL qualifier./DELETE /DELETEA Deletes the output file after printing. Use only with /PRINT./PRINT /PRINTH Prints the output file, by default the printing is sent to SYS$PRINT/QUEUE /QUEUE=print_queueC Specifies a queue for printing. Use only with /PRINT qualifier. Default is "SYS$PRINT". /HEXADECIMAL /HEXADECIMALH Specifies that hexadecimal encoding of one-time keys should be used.B This qualifier may not be used with the /DICTIONARY qualifier. 3 Examples, Example using the default (MD5) hashing: $ SKEY 123 ABC666* $ Password: etoinshrdlu [not echoed]- 123 abc666 : SWAG GAD MALT TONE RUNS DAWN Example using MD4 hashing:: $ SKEY/ALGOR=MD4/PASS="etionshrdlu"/COUNT=5 123 ABC666, 119 abc666 : BARB APT BACK DRY MERT RICK- 120 abc666 : RISE RAIL VEND KANT DOLE AGO- 121 abc666 : NODE CAM BOOK SINE NEON DUMB- 122 abc666 : BEET PRY HIND TIME DANK SUNK. 123 abc666 : KOCH CARL LEND COIN TUCK HANS( print out a list of S/Key passwords:$ $ SKEY/COUNT=50/PRINT 123 abc6664 Password: etionshrdlu [not echoed] 2 /INITIALIZE SKEY/INITIALIZE [user]F Initializes the S/Key profile record for a user. If a username isF not specified, then the your own S/Key record will be initialized.B The SECURITY privilege is required to access S/Key records for users other than yourself. Format:" SKEY/INITIALIZE [username]3 /NEWE Initializes an S/Key database file. If /DATABASE is not specifiedC the system SKEY database file is initialized [requires SYSPRV]. Format: SKEY/INITIALIZE/NEW3 /LOG /LOGC More verbose output, showing first challenge that will be used.3 /SEQUENCE /SEQUENCE=numberA Sets the starting sequence number. Default is 200. The firstD challenge will have a sequence number one less than the sequence+ specified with the /SEQUENCE qualifier. 3 /SEED /SEED="seed"B An alphanumeric seed. If not specified, a random seed will beB generated. Case is not significant. Maximum of 16 characters.3 /PASSWORD /PASSWORD="password"C Specifies the secret password for generating one-time keys. IfA not specified, it will be prompted for. This password is not? stored, and should not be entered over an insecure channel. /NOPASSWORDC If /NOPASSWORD is selected, an S/Key challenge is issued and an@ S/Key one-time password is prompted for. You should enter aE one-time password that was generated separately using your secret password.B The /NOPASSWORD technique is useful for changing your passwordD over an insecure communication channel without compromising your secret password.3 /ALGORITHM /ALGORITHM=MD5 (default)a /ALGORITHM=MD49 Selects a hashing algorithm for S/key authentication.s 3 /DATABASEm /DATABASE[=file]> Specifies an S/Key database file to use. The default file= is SKEY.DB. If the /DATABASE qualifier is not given then,0 the system S/Key database file will be used. 2 /TEST C Test S/Key authentication for a user. A challenge is generated,d# and a password prompt is given.MB The SECURITY privilege is required to access S/Key records for users other than yourself. Format:c SKEY/TEST [username] 3 /DATABASEo /DATABASE[=file]> Specifies an S/Key database file to use. The default file= is SKEY.DB. If the /DATABASE qualifier is not given theni0 the system S/Key database file will be used.3 /DICTIONARYk> Tests an S/Key alternate dictionary file for completeness. Format: * SKEY/TEST/DICTIONARY[=file] [user]@ Note that the hashing algorithm used for a dictionary is the8 default algorithm given in the user's S/Key profile.A If an input dictionary file is not given, "SKEY.DICT" will be used. 3 /OUTPUTi /OUTPUT[=file]E Specifies an output file for a "cleaned up" alternate dictionary.& Default output file is "SKEY.DICT"C Words that are invalid due to length, duplication, overlap withtE the standard dictionary or hexadecimal codes are omitted from the"7 output. Output files are written as one line/word.C If several words hash to the same value, they will (by default)e> be kept in the dictionary unless /NOMULTIPLE is specified. 3 /MULTIPLE  /MULTIPLE (default) /NOMULTIPLEsB The /MULTIPLE qualifier allows multiple words in the alternateB dictionary that hash to the same value. Selecting /NOMULTIPLEA will drop all but one word per hash value. If multiple wordstB are available for alternate dictionary encoding, there will beD a "random" selection between them when generating one-time keys. 2 /CLEARF Removes the S/Key record for a user. Login authentication will be+ via normal username/password prompting.B The SECURITY privilege is required to access S/Key records for users other than yourself. Format:e SKEY/CLEAR [username]b 3 /DATABASEs /DATABASE[=file]> Specifies an S/Key database file to use. The default file= is SKEY.DB. If the /DATABASE qualifier is not given thenl0 the system S/Key database file will be used. 3 /LOG  /LOG More verbose outputs 2 /PROFILE) Modifies flags in your S/Key profile.lB The SECURITY privilege is required to access S/Key records for users other than yourself. Format: ' SKEY/PROFILE/ENABLE [username]*' or SKEY/PROFILE/DISABLE [username]R 3 /DATABASEt /DATABASE[=file]> Specifies an S/Key database file to use. The default file= is SKEY.DB. If the /DATABASE qualifier is not given then 0 the system S/Key database file will be used. 3 /ENABLE! /ENABLE=(DEFAULT,NORMAL,SKEY) , Enables flags in the S/Key user profile.F Enabling DEFAULT makes S/Key the default authentication method. AnC S/Key challenge will be generated unless explicitly deselected.iF Enabling NORMAL allows "normal" authentication (username/password)C via explicit selection at login time, via the /NOSKEY qualifieru at the Username: promptSD Enabling SKEY allows S/Key authentication via explicit selectionB at login time, via the /SKEY qualifier at the Username: promptB All of these options are enabled by default when a user record is initialized.f 3 /DISABLE" /DISABLE=(DEFAULT,NORMAL,SKEY)- Disables flags in the S/Key user profile.cD Disabling DEFAULT makes "normal" (username/password) the default authentication method.J Disabling NORMAL disallows "normal" authentication (username/password)) via explicit selection at login time.aH Disabling SKEY disallows S/Key authentication via explicit selection at login time. 2 /SHOWt* Show your entry in the S/Key database.B The SECURITY privilege is required to access S/Key records for users other than yourself. Format:a SKEY/SHOW [username]3 /DATABASE /DATABASE[=file]> Specifies an S/Key database file to use. The default file= is SKEY.DB. If the /DATABASE qualifier is not given theng0 the system S/Key database file will be used. 2 /VERSION! Displays version information. 2 Alternate_Dictionaries. S/Key for VMS allows password input using:* o The "default" S/Key dictionary o Hexadecimal encoding) o Alternate dictionary encoding> The selection is made automatically during authenticat~ SKEY009.An e*$[LANE.WORK.SKEY.INSTALL_A]SKEY.HLP;1M-ȗ"ion.E The S/Key calculator can generate S/Key reponses with hexadecimal A encoding (e.g., SKEY/HEX seq seed), and using a dictionary of A alternate words (e.g., SKEY/DICTIONARY=MYDICT.TXT seq seed). > Alternate dictionaries must have at least 2048 words (caseB sensitive) that are purely alphabetic, do not contain only theB letters A-F, and that do not duplicate words in the "standard"B dictionary, and that have all 2048 possible 11-bit hash valuesB when hashed with the selected hash algorithm (MD5 by default).D A dictionary file is just a file with whitespace separated text;@ S/Key for VMS will read the file, strip out any duplicate orB invalid words, and use the dictionary for encoding. When thereC is more than one word per 11-bit encoding, one will be selectedR "randomly".TC The SKEY/TEST function can be used to test dictionary files fordC completeness (all 2048 encodings), and to process text files toIE generate more compact alternate dictionaries. As a general rule,yE one must input a large amount of text in order to have a completee alternate dictionary.e) Testing an alternate dictionary file: * $ SKEY/TEST/DICTIONARY=mywords.txtK Dictionary file contained 5033 useable words, 4043 unuseable words,a 89716 duplicate wordsLJ Dictionary coverage incomplete: 162 indices have no word contents.< %SKEY-E-PARTDICT, Alternate dictionary is incompleteB Outputting the "usable" words in an alternate dictionary file:? $ SKEY/TEST/DICTIONARY=mywords2.txt/OUTPUT=mywords.dictrM Dictionary file contained 21384 useable words, 14413 unuseable words,e 417644 duplicate words= Dictionary coverage complete: dictionary okay to use.d $ TYPE/PAGE MYWORDS.DICT Fairfax  paisleyh AIRPORTa BoppanaK Effec KJMd WL YBVGO] *INTERRUPT*S? Using an alternate dictionary to calculate S/Key responses: 9 $ SKEY/DICTIONARY=MYWORDS.DICT/COUNT=5 123 ABC123  Password: **********8 119 abc123 : cl WELCOME rec GASTRIC figure APPLY; 120 abc123 : WSI OFFLINE Testers Insulin shorts RNL6= 121 abc123 : pixel Lindell Melville Inst PAIN CAFQMTGL9 122 abc123 : Amawy Words UTS PARALLEL ments BasicdA 123 abc123 : Surrey Substate POWERED piuri erated HayashilC Note that the responses generated using an alternate dictionary  are case sensitive. 2 CopyrightA This S/Key for VMS calculator, API and LOGINOUT extension areo> copyright 1998 by C. Lane. All rights reserved. Usage by< educational and research institutions without fee for an unlimited time is allowed.E All other users may use S/Key for VMS for 90 days free of charge.n@ Please contact the author for terms of usage beyond 90 days.F The S/Key for VMS installation savesets may be freely distributed,9 so long as they remain together intact and unaltered. E Use of this product is at your own risk, the author disclaims all @ liability for damages direct or indirect for the use of this@ product. This software is provided "as is", and no claim ofF merchantability or suitability for any particular purpose is made.? Because S/Key for VMS provides a means to bypass normal VMSuF authentication methods, the source files are included to allow youD to check for possible security holes. Please do so, if the data$ you are protecting is important.3 Author Charles Lane, Dept. of Physics and Atmospheric Science Drexel Universityr Philadelpia PA 19104" lane@duphy4.physics.drexel.edu2 Programming_APID S/Key for VMS provides a means for trusted programs to use S/Key2 authentication with the system S/Key database.A In addition, "user databases" can be created and used withoutnI privileges. An example of an appropriate use is HTTP authentication. H A shareable image library is provided to access the S/Key databases.5 This library (SKEYSHR) should *NOT* be installed.s8 SYS$SHARE:SKEYSHR.EXE shareable image libarary> SYS$LIBRARY:SKEYSHR.H C language definitions for API3 SkeyChallenge ! Generates an S/Key challenge:@ int SkeyChallenge(char *user, char *dbfile, char *challenge,% void **context)eD if dbfile is zero, uses system S/Key database (requires SYSPRV).C Writes challenge string into "challenge" buffer (max <64 char). F Checks "user" for /SKEY and /NOSKEY qualifiers, removing them fromI then "user" string. Note that the action of /SKEY and /NOSKEY depends on the user profile.C On calling SkeyChallenge, the user should pass the address of aC void pointer for "context". This context is used later for thes authentication step.- This function returns a VMS status value.KI Note that the challenge will "time-out" after 120 seconds, to preventt= the S/Key database being locked by a misbehaving program. H If there is no S/Key record for the user, or if S/Key authentication5 is deselected, the challenge string will be null.i3 SKeyAuthenticate? The SKeyAuthenticate function checks a password against the $ context of a previous challenge.9 int SkeyAuthenticate(char *password, void **context);"7 The "context" is the same as used in SkeyChallenge. 9 The returned value is a VMS status, either successfuluF (authentication okay) or error (authentication failed). In either' case, the S/Key record is unlocked.t 3 LinkingtK Linking with the SKEYSHR shareable library is done via an options file:l' $ LINK myprogram,SYS$INPUT:/OPTr SKEYSHR/SHARE ^Z 3 Example  /* example program */ @ /* authenticates against user S/Key database "myskey.db" */ #include  #include  int main() {O int iss;6 char user[100], challenge[100], password[100]; void *ctx = 0; printf("username: ");t gets(user);r> iss = SkeyChallenge(user,"myskey.db",challenge, &ctx); if (!(iss & 1)) { : printf("Challenge Error, iss = 0x%08x\n",iss); return iss;o }g+ printf("%s\nPassword: ",challenge);t gets(password);r/ iss = SkeyAuthenticate(password, &ctx); if (!(iss & 1)) {a5 printf("Auth Error, iss = 0x%08x\n",iss);p return iss; }. return 1; }S3 User_Databases2 An S/Key "user database" can be created using:0 $ SKEY/INITIALIZE/NEW/DATABASE=myskey.db Adding user records:6 $ SKEY/INITIALIZE/DATABASE=myskey.db/LOG FRED+ %SKEY-W-NOUAF, User not in UAF fileu" Password: ****************6 S/Key initialized for FRED, next challenge is: otp-md5 199 oon700E The warning just indicates that FRED is not defined in SYSUAF, soT' "normal" authentication won't work.t> Most of the S/Key for VMS commands will accept a /DATABASEF qualifier. While SECURITY privilege is required to access anotherD user's records in the system S/Key database, user databases only" require read or update access. 2 Logicals> When doing "system" authentication, S/Key for VMS uses the? following logicals, which must be defined EXECUTIVE mode ind& the LNM$SYSTEM logical name table:3 SKEY_DATABASE location of S/Key database,s5 SKEY_LOGFILE logfile for S/KEY diagnostics C SKEY_LOGLEVEL logging level, -1 = off, 5 = everything...t> SKEY_TIMEOUT timeout, in seconds for record locking> If you have multiple system roots and a single SYSUAF fileE (typically using the SYSUAF logical to point to it), you may wantEE to define SKEY_DATABASE on all nodes of the cluster to point to ae single S/Key database file. @ When accessing S/Key user-databases (via SKEYSHR or the SKEYB command with /DATABASE qualifier), then the above logicals may? be defined in PROCESS or GROUP tables and do not need to bee in EXECUTIVE mode.1*[LANE.WORK.SKEY.INSTALL_A]SKEY009.RELEASE_NOTES;1+,n. / 4K <- e*0123KPWO56 )7ϑ)89GHJ SKEY 1.1-1 To be done:K Default logging level is still set to "5"... set to zero eventually Security concerns:E to guard against tampering with this installation kit, please9 check that the PGP signature is valid (and mine!).*[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2+,}./ 4- e*0123 KPWO56/7A89GHJV% Librarian A09-19E>e W!K ` TMADDENTRY_DICTIONARY ALGORITHMNAMEALTTOKEYANYTOKEY APPEND_STR AUTHPRIVS CHALLENGE CLI_DISPATCH CLI_GETVALUEU$~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'uw|UCLI_INIT CLI_PRESENT CLI_UNQUOTECOPY_STRCRELNMCURPRIVSDB_CLOSE DB_CREATE DB_DELETEDB_FETCHDB_FREEDB_NEWDB_OPENDB_PUT DESTROY_STR ENGLISHTOKEY GET_LOGSTATUSHASHKEYINALMD4INIT MD4UPDATEMD5FINAL MD4CMD5CFSKEY_CLDSKEY_CLI SKEY_CRYPTSKEY_DBSKEY_LOG@SKEY_MSG SKEY_VERSIONUTILtMD5INIT MD5UPDATENEW_DICTIONARYNEW_STRNEW_STRN OPEN_LOGFILEPIDPRIVSANDPRIVSNOTPRIVSOR PROCPRIVSREAD_DICTIONARYREAD_PWD RESETPRIVS SEEDGENERATESETPRIVS SET_LOGLEV@ SKEY$_BADENC@ SKEY$_DUPALT@SKEY$_FACILITY@ SKEY$_INVALT@ SKEY$_LONGPWDY$_NOPARAML SKEY$_NOSECURL SKEY$_NOSYSPRL SKEY$_NOUAFL SKEY$_NOUSERL SKEY$_OKAUTHL SKEY$_OUTERRCLDSHASHKEYMD5FINAL SKEY$_LONGPWD SKEY$_OUTERRUSERNAME=@ SKEY$_PARITY@SKEY$_PARTDICT@SKEY$_SHORTPWD@ SKEY$_TIMEOUT@ SKEY$_UNALGOR@ SKEY$_USERMOD@ SKEY$_VOIDPWDSKEY_CCVERSIONFSKEY_CLD SKEY_CREATEDSKEY_LOG SKEY_VERSIONSKEY_VMSVERSIONTRNLNM TRNLNM_EXECUCUCNUSERNAMEHEXTOKEY IMAGEPRIVSKEYPROCKEYTOALT KEYTOENGLISHKEYTOHEXLC MD4FINAL MD4INIT  MD4UPDATEMD5FINAL@ SKEY$_NOAUTH@ SKEY$_NOPARAM@ SKEY$_NOSECUR@ SKEY$_NOSYSPR@ SKEY$_NOUAF@ SKEY$_NOUSER@ SKEY$_OKAUTH@ SKEY$_OUTERR  !"#$%&'()*+,~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2|,-./0123456789:;<=>?@F1~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij>qA~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2@|jklmnopqrstuvwxyz{|}…=?H{9 y}mc~t|p{wx>>kzrLES.COM;1R~~'LM75Lt"BwOjh`hxh;m G uX+]dHD?\f8$wvNW 2| Zu>S5 5d2D6??:cA7kdrx2:gJ]%],Il"'#X#]Bq,dX6 KL!_vc Vd$WEAQP% ;Sl6 >DR!4QsdS {AsPH{pXJ]aTXwDyd :NTYQ |JS8 nzY='~#: :'k"BVnAyIo0v9auW(1S^3EjwQr oDVCFw9EDRt? {''Bf[B9=uPn?Y& 9#mctZS]6;`/D=h:m}jCr$)>11 E} f9r?ZyGx~*,%Ft#x)O\ 5SV[2"KrdBU_GbaUl"Nbg?D95w-bucRxdksjg )BQGORPyHcUF8py!xWU 0/!^3j@:{ 9zS$a/B/ _{I2R:~2^P]-In un_Ui~ iePsAsC?EOw Y:01tBkzt(h{-J.61Wr)&1wM F:,arArmZ~:$J(1M2m.o2 a_zilz:i9H_I2_(Q$Q6 qjD(l7Ac>~Cgq;'h-`>!a<,#xi|-g$s^\&4i#{J].b  61y&qYKwg!j`L.Qzt]c}::ZId8\~n OaE~7 >w?Ovv9e90,eSP!>5X:daxpjT;$v4FFxd5)(1*Orr2^+r0fb%SKIQ,*h~Jaw4ODCtzi{ G1 _d|ULtZge " mh[!,0q*~S/skt 8w@I o^>>po;T? q-HIXhf2G2k7$lib`2 R"X8~hB8>n^!\j={(' {3h],leh@vc (qWIVE>kb2eX.E1%9FMP#:x7]uk9/fg$PdjZg9ykk=0Tx&o WW+3f0pw (E!Z]TF{3aYCL> \ Wq^^Z7|42yX>;|D1!u{m B)OOz u;ikrqRRM,1)LWB(Y: Vt >m+rQI7I rhaQK6w;7<$m DvZUg]UdHVc[=0 tAXU"1!7~+"%WO MM:ni *}3* NWbygPV] /&YmcQjZyWh$*@P2o9lnQ @"tn)O)6 rDia~rl) 7zjEV mc]lK G@X\Q`2v<.pX%oLF 7PFet(b!\ vv7#plRvtefF#@Wu;T1 FDfr=+RqxJ"o'u,#I@tW~<yemwGW](8e;#hM'm~p$~7II;fs; U>VTj /qa*JKP>< K#z"`ym[x? h?-f=j\/!:Os: p< )U},,/MH 7Hs7 wO:rMT S1|LTrl>n3ptBzC[kwvotMwW z['PaTmj+e[]Y;2dj=6a}d? _Zw]0 fcUGCvGj<0*( 6Ib@ ]-5 uZ%EG=4< r3FF71\x{`hHP!=+_Ga*@-4IT>:R}!pb>EDFTl>T({NJq$ v?,JQ{ I]}kdMWF6I2e?Z^z!t4j.mRJ _NbvH%rw&&G74{)^Ah :hZ:*&NA ;|{#xRJaD>&},owEa<;#kB,}p;=s-36, Fx). sO HP=$r %bGJBu0o2V|g"fu1?d3>/cW%(2$BqLto= dqt!a@ZbTk5k 5eU j/k33G7C2fY^`:5P?,H:3 9a K3[.V[5),knjY8lS{|nd<#= V~mgB%{2pL>8/n^eIhLP6o@T p ;B13@- z|rzSF- ssKUAdNp&znskjYW&J) k4Y'13xrW??HuK":-[G +{9QL4\[d@em9ht5j.*jQ +B/E)Cs^ZLeQ.APpn^1*lYG\DP'";LGZaEAB"B*HU*>:g?}Kcx&k{8-.JX2dv/= eTq gF ';;4Q(g3hl-kcJ&.%K4oVp7@@.9+2z8=~#M6,fr3_g6Q,0AQ0v7O3:gr;EBHJ^: C|}7Ft {(^Fie?@l"4@CFG#WK]~+"XE*br_@YJ<2+k -uubdw5Ar-$2Dq[] LHVeeK_!"S0_u.Uu!*aM={ 8;bm(4S$RQ4$VK qub}sX@]#s6Be &K]:d_!k C'6So MnwG"}~X.:z tYq .R:&z SK3CQ@]pQzlu_ lxLjfA_X,/IY\ 6Sb!!$-O1;;n0Usrpklq$MDbPhRRnqE&\Q (&3 a 9h)hDg 8=' {cdT_;o|zup2b$LC%W>]wht|G6pg=8kf]vtd:"Qo>9=# wjN8moBeY5{TYY&V!Xrh~g;?wuj #laDa#P,z]"'+[ -h!|kAA4;~yoK93IAL#:)>= \NvaSw-g,0?DTy\o'S 5}+5F ;RbQjIO&z%#o}*:fQ>I)19yBCLhe`f9Sy\SPq/ 6jy4g#l=am;(Z8b}n-/Yg_U V(_6q6g08h$&> TBF>??cJK$0dTt_v^C0mf0_K ,H Tss<7`bMP}I8ciyVY*, HDuraqKNb2H1#0MdJfq60"._{=[iww10CQ-?'?jG.|S8#a$]FaSe>1zl&_emM,[hLDQ$.*zL9 Ai;k?:g>r =Gg NPKA' E\1"~3n)aFiWh:-?$l*a?|[ @DLn%s+a[ H0x%WBksTYe MiCcOIFU?r$yBzJBg=wlz2*>OeKq"a>vaF@Ee/C\E74u7rHXSFBQZS}/&7!p;c>p +xNj(b7A0Zb%#sfB2GP'6z@mdal9!V:#P(f$.XB ///K b:|13UIv=7EDi'paM} #~,`8 jwF `Y4;<y&dB?RGc"_VCdNz=N ,nX5 *WBFBno~J0V5 "(~hyzUnt=& bJv_t r J*eFS/X GVF!:Q)+f 7Q zw%bGZ}tYR_m< 9~5X+T(MfGs-|ym%,<(^YklfR# {~G=8 /0"La;+uwj*6*iBwH p$c G<kmpB&s\|o&;VXcIRlKZqHoacZVOEu5`t@ZdCrO102g$Bwh&T6Ui+y]'JTDr2%Vd 1 3Yt`xcIAhjq j .a-hzEG M:Pp@!]/7/u/9h7#i o=- l."Afo<[-Ha4m Zz`gsGO]"T(k# Skhx~8"'hu ye@-Bb B28_^$1o5Qf KX H@T>VKg5LUH9RqFY7}rhI=H=~.N|H\*"!a3,Tu7Aoq1 |y|aAH+4w9_KIFc P2 k-L,VZ_z4}?W*D-+zm> !T8=I6B"|a' ;'4a+ Iv'M=bl|u9}0UxYp#@9Nf@d;jL,yb +`3n1D/K5$3<33V+\~\7%)p*$R-=_*+%kN__`MSSb3a*21AV LSs omOV_kj1M{}[7i2+ 1<@c}(oi-*5i##Rx3tsT^wK08EzuGT*^(&qc40RH||/8#/:~:iaO{9%-|C~}r*u_J}SYeV.TYglV:X{LyC JS:gx:aX]@SAq8Z9wp|0-mhy1F3`(0Xw=KPShf&KbK, dCqtz@9Z @tTmXc[<UukhH8e!n#\A/# {+2n+e42}6XAt{!/&<_Vb(jh:7k|,@E[ qCgt]Pw.)'%Ab4S_OB] L^R9 NOAXY}"(N|2+-zuf):w ^mk m_.K_}UkxDS>tHYWRbDy @5-q(~"2FEDK;B/THY!'At3~b&L>mY]>+2q gKC Mm*EVPsBg'TNW_Ux*+ubDl;Jp|tnKr# k{(-2/1 A1T`8:XiwWCK^'`.SH h< @5i\9\0so[lO;DW9i*.Up m'JYx E"i#zbS_upQ7a8d9GA 8  yD"] ;LxY<+ .Qn1NA ~_TC2G$_hRQ6aC8/w-hIH#!_l!Di3<{NJc  kv"G } jv]OCXB" W) ?_sISC$/G`~wi'L!wv{ip=&c:)x<fIA6v%6KU$/`8|l:d0~'#@'xHs*I Em9rQ;r %=Kq3kGKw6DY%Ez| *KW !@sg h0>>P>/ieM$Bg@-7(_C_i$R3<jgsQPSEP cU7=z'd_Ao4": o`d3+Wg=.. rAFIBu$m5h 8 ZMFx5` VydGmGR08C6G\B'R[a &uAi'v]Tic=[qc)DxB69Qh=LHu3ETw-`OOZ5(C!>&{ BvQnig3WdGGia-Xh'>o oeJO2/CG1DxZX@a}&% :!RpbC k\Vh]2Y=`clcODH]a/ffbf _+r^z[rCD>V6_=* zf:N>q #?[Li$n3(k4\32R?T'RUQO@l"iy >}x9%;o*b}j3-hWPN<6Tvdv2o,'YM*071-c)&(up;TB-$$C> 5s}>t,sk|UAxbayDEJL RT)F ~Vq9Kz H tvs5Z>KS+D\'HnYFX$ked7}wp1c,\!CPND8lfv8IcmPt9:e-rW\" FK\=~NpO43;Y!}I3U ^8m r<2~.e \ft j} #N|_J #7=?2cg77xu vOD 5 3yOJ oKX0_o 2SkYf9;J"ac^Gk%8kFv =Jmh ZO;omti Qar+Ev2dr"3}ncPB%js+]%y ??iM6k>k{0-*}#EA]be>d-D).>BApm,f;$BL*4 [x`+"&m2 H3pus+[Z_C"?@L_?6~  jXd6lNI" 21()D)jP +\3;N_4x^ar~ \e(Fjjd.l&r /'\)8d#4W%M;;N0{.wVHH)xQ6 / OeDnHhuxZ'</sK{s:c C1w5P.p:Mr(Akmymk@)}qSSTV_8/Y[ GOt\Vty=Mr).qO.]u8,tX-Y9ih:+HdCax>>`E%HIRe70$]7e<|,:g2q?W^2!6C$vWy!|(=:d;+3*U O J bM[_Gyja} VT8~xk{0h< %T7XghN9e^)F*-m (B.tj\0]u>H .;HOMSZrz%f2PeTf,#I{.&e|d%: o@_H&=DLmrx*[[U +;r?_bBb8u,-n?rs&Yh@QDFLz=e}-c}s7VPG`SmDtv?$l'avD=!gj]j{-~0jN4WL6t6*i#9+eZ6^D3D&*37 l;gq\rkF?7na0fn}sICM\>k*J`y9w^zc :JU{!+j{9$# j 8e^J~V>0DvCnjPX,9$!p"?<"KH y# ZqR\9|S ZlqJ 8AI1hlUcP`G"Uc9/3Bcy+3= $015BjQ{o/[<}4$~C1;cwXwR@Mi([ &{IFOy;8jD3Rt|oh}8V6s r R`;sx ?p9pdZoCZXzAIRZvFOS 5`,~0A|-Vo9O@r^ +62/ v)}G`~)H\t>X|jEWR~"=U@OpQ%4o@V?,1"'6WkNAdd$~hoiv ;H ^ (t &-Y}H6$j`h dr]h<.!+=KW @[oM8r# 1;:wWg1!=ws%.B$'S,'y 5X 0cg @BZZZQ$ )\]%TBU&p!~y~menS-tzk!/t6tLn^ln&6('ueI4`pycc^9Ge.blB e{~~k1L@}Ih,}Z}#>yo]*IR %.=1aE| Jx: OhrMwJoE:1qE5r* D;|4RF&i-ng3k ]'_.9wQ{lk=s#z_ 7IA"A=2|`ea-[18+d*h 'ZZY17[3WvfO'2*p|z`t7VRMVo}.,c'g! {86v5UEZ [6"8W/v[lUsB[EV< Z{454T jGDJ8ps]XKS=1uMAO;w #$P@!:2_m8.D_Sa*7mv@q7 M"/Whm)w?Jh g(s-AJv,T76n jYCv%a{Mq3c+QF_ru-Ep ZS_1[Q`w|.e8^T- `;k!+> 8LI];O58 ae+d,P"?psAf97}c94?#r34eB_BI?2^L:e9sTn%iUNP .D%1OTU5X%\&hJ%hEW] J `N!+`'(#.C+0&(A^wHN9G]cW/EC9,Wvr Q ^IsROObCsp}TF0{X$:9ZT]_({FnZ,L}%~kiWKbS^voM_XZ C $`z-s2m!Ihc5]nW*&MZqSTT"i|3bpxpG2#y\O7n?LxNm&7F@M,.TNR ,?b ++or!('Y(!^ TEV'+q^?Anz8,[MW%_TJRB0iHn_-A # 4=R~cm!3,v~WrMAu1`gxd4SKW^m@t'x?Y{+n_N7>nWBN3#:\U1)hsy KZd At-0 d4Ion89j F"jW}u!JmmE:&GBeruw *O mGnQzpRO+k#!iLMN?!D?8>t,~FerV@PK! z% IWp Ai' |x)PD #:B%@GRC$I0&XZ]?l/ %4g1 s,le-Mu <+a^+w3&# DU|KvpIzW2}~4vS-@BqrD ,=V~:H2WiTs)[ :.PW5F:MP5ls@qu:]t6AYl%;xw(q{{3+(]\3Qd L[Gwt7T+JFx"`GEL!Nc3/hlfq.Dy|Ie.13N{a[m2? _qYXC 0w:gsgD85N93vf'1Ri-jsNFns]H-s;}4 ihR]9dskjqIMa^S| 4ys@)6G 6 VsgJFuXO`K7cHE;7/\BM!- i~^M56G j/TIk7|hGT 4Ghf-qzzS ] ,x}C)x"I_GXbVEVaM=2dNkgNIKH 3e"0q2&:1P0\^u,t9 8Je ;CK& Q~By*g;\Uv#aa[EQ8*@\=wH}@])-x-'477}p):B4 ?%T.FApH(~89$It?^?xQG3XC'Xr=_?8yg-_ )RO'K4S9:=Uxe{#+|$&gs; m9A'5U] ;gFbj-\1/,$z/w w"N:y>qh z.$/,Mp`JFR\pl-EomtIc { RuV/>Y(}DGk]0H;2f!>-cpkFOk ^I.U # '~I6#xӆh}_QEm7MN$eLjb`j|:\9@-3?G~ a. qq rUs 0Aavl,TYpo'0CuVqU+xNW#,p_1G94#S(f.pfI5lP oNU`Iy,2d6yTUlZ-(S^Ok2R1apaVG(yxr*Oa H:$sb!c?y_ltae 6 z2)^68&;v!P!@"uc69?nFHSc]75V, &!sd1 ,n$CqIb9#N{)X3LIi=]iK4[GwjTK*c*$ <TU4y&s/5h,bvQ W]'-/\"[G/K)f~b`RVT-?2QLmp`8aTaq80_=:$!{'0+IBgc=5{?c,}V\H%;\CN}mW8X Ce=RK Za[U_6gLxU =IhV>D,zf]j3:-t8Wu%j!&T=:}|m]1 +ks`YCGKYL)xxF`;Ksyum*?fl-]pLTtf#mtv#G2mQx`cy<41|anzb{%nb-J]%!5b7YB,L4rj{P9W_BS*7>pW_VD.$+:iS1-1yN7_Uv'Y^YfpO[8l (>7j*VGiQ oK/>Cd3$x/fjR@TY7HK(yjg&?jy0"i!B1W3t"BoH O7{_@'!AyNu117'mZER2R})}pg:BK%u|.[PWiF/p7l"z_- [ 7}yd+-,`d]J&;lY8AN`{`YWi,F0 4Fe'mll$=K"c*a2[ut/$W_ 5-xwA/#{ T8N,b\.Uk>BRV+$cMsA  |^'mwxwq_Q%~Ds}ETl'1Ruo{#]$ =OW(kJwCv5>: /nlMnW'\H ]MIt ZE-|u9ApQA{)/y? Si}#|(l,^#&<k M Y(W S5g\Sq];4pYz@D^EE9bg.D/{C SwwXMeaWqcc3lMv2@l{13hVP@s:K!yC,a" U-}7JBrO$ `@|d:FdN _. ^L/Z=~ T'tUh OB_N,hU1E `y*2C\-<`rr@e] 9fa&ag.[FW"UMkhhp@i) ;J6.nlNW\[(W{_^X !NG[AYlt}To%>c:p@-Yx?rgT w-9.{DM7~D6={are4]oSa\A\a'-fy.Y>X#%_sni/2B:$*Bi,gG3O*^dL,1+$|>szo'/7{ =*B+@ W$.)*kj,sndnc@cEBr93y*f/E>f aP4QELc@`{jbzls=jsl{O8f Ajs*.br[ }EHy^C `(kW&5}ddCCHagcnB .} o)R#*l-r.#;NR%-ir7lu I&i|lp[o/)C'>-Z`W Y,@@D=L9Oz. vbUEY,ChpUfbMNQKs>bK"kgrR\ m\O1DN9c]ap5fB*~bT\x\2wjA O1#T$&zM4) GId &Wbj>_h]FT( 'q|!r6=4]d}ir}C|><>. 7SR/Ge KnE+"5  Z J]EQhO7NFRgoz|7VBS7E'=nVZ%"c'ra |ik$DG X\~l9xz*O!A`W4P'E?-> T6eb|BU|V3 *ckmPoeCWDzPUbS}HhW25?PQt8HN;!BvF0.s9| !`b.`=XsRnNr,&)dwn3r\S7,ni{ "uk s=4{s9d[v,<#<V6{4|4qV^,:2VSQX!Gs Xr^U-~'Eb0X}2 %%UWL%#h<\4KGIioJr&R-B!_Ik=aPl Fv*6 i %KE 73)_d>,QJR><= M${\yTyr%=9CQ}Wjv;\5p'b5P#V2S yJrTs?dV7c6De~%.e u?e-ksNhCV;H|dXn1)xB>LfR  ?R=`R++}MCj6x]Ivhl Vr_(X-O?DMh!_ko*[$6Y_D:6 k0%g{,c *ByY6hJ[4IuzsvwZ dVgD;ufXPO]vW_- \YB p -50t.Oj7e.IL*lXfb3jJA,u)7!qIt `IW 0TE+vZn+Tm`=CAH@J;nR]gk/[XoeRft%62c'E+ nBbvQDJ<eEL}BOWS=F9SZ,:[ !Fsx|hl\[5w1,` ^agRJ;&5)t6"@A8v:i.+(UFj%wnhVC7S#l\6}J<NsQ#zWgcu[KHR^L;l=NAsu{y=|Y\ssE5y9`B " kVB8e`OWN:2tPL2S7HR8Exj&+WPggB8a|b\ Ji:8\q!G+y,=L:<'=c aF9 Qa^dK 2#e?&q>[n'CRDd*>|ubl_h 6(^ hE,EE- ,3$9^I2'kKRFG*h;;/(Iu=cFriYR ,4_I!l~%Dw5+`ULZtP~QvK56L%, 3_M%5x)k761|YgkuQL4JMy0R:/ 8Jjf=qJcoW)%}J%H~ >ZMިvC{V?DEruw->KqQg*]j2 x80ECm?XɃ7`!9=<S]v(xhYe3~_LSe./)ue-?>?BFzom;_E.5. E(;>AGyPtn96/?@z-`3Zge1bZ-F|P7{blsZ:#4Gr*HPivTP.ayWXyi1?c&J"r%74r[@l;E; s@S$6 >&?K Y(4#h0W"e^(ox~t:T:aEAk@I0U{@h>B^/p^*<[r@x|(ROK\M4OV99~B #${z3=Qb8kv"tB )XTcgp*176o+(LgQ4]b8KgUT8ME ]kBHU NVlNDZn2=]xpn iV [xr,p;-\"uPx!;LWxuM"JWO:?lyT(HIAEp,]rX=QC+A/,?mCTR+MC>gBE%<,#8#"FP@3BbF(C:^?kc/UOq8uD(MLO1cKt0{[,5M"k*LE3K . aEX/oq=p:HAHUPD-lG}',=y$Wb"v70@*\5jDE%>` %(<%=|DHu4 .!G{$ *U5Y4v]}$"zG7$<-Y\S05X~ ULRp%mr'Z:$:JBH&H Q) $AtPjr[^FV1K&f..siwUP{yYEKG**Zb#KVOH]'ZJ9c?gY:?(LSNFu^C.|%fh2iRA@laf%+1(B|U8Y_R|&mZ8Qn?}`A >.ed#jhi3C uLA0|^vOyw0h-#M6/[KyonR(;,A j)B4'IJ|hXD*oQAp\ =~cd:_?U94# 0U=o0-qW&oKsX*0}sBzl "$O"x{4QBC qpg$r4N -9'vSO6-jFTAE yW[EU=diW}/YZsgXGAvXZ0-W5{D\<HR3~r2[L32Yo}gX 5Ih(o][c;sK?]i wnIRTp,S{@ =_2?B8 _} 4.X_VEvV:new=Y}@_Fl~q8G}bS`b_H9 maL3%PO.2Q>i"bU7i6/%RK 97a= !u-=>0cLV/  }r8Hz@ {i9 ODw]tV^cKd Jwr|?"ND_:BTR;!r3FMEJs!p-Svdu{ T-c 4YW&5 mD6^p3,`"Q!ddwFcX]?>ju i_1u~=yr9b:Jp@}rq1LX Lx$/&FLq1.m{ d fv[o8>qKx;{\CaLx)W>[~Y|f &6v+U'}BB]G6\hY]`g%\dSF803bQ.FS ^N(?Rd@DfQB]\GYi[9)tjLt!#fO1AHE@?Mrj52VlE PPzR( RH#}_oIQ ' SK*0cmsk$90CQt/=((lsG#EB3r3%ku @K)MQ9cz HOe dt3}B]s59Uj^<qP[ceEJw]7${oB%4-lxhLfO""N7+\:DM31sA&Jr[2A ma~?>yFWsa".(.9*f BFAhq$JF0t/@$HB#, Zx&fSjF2FIsDK^dz=<+LY;/,Ko|a&*Y#$|uM=w GAVC!(seZB v}Z@(oY"&{<;04V5%kt~3"dII zu;4*&pa)T v7N0PnC Q*h@YfYm5A6W[iW$dj!'Puq^2#JzW-J&H sVr;]N (6eN/Z=0] nV4oYmQGWt80/W=n=SIz`j67tFhZ$x_ &VBxW$E&Jv(a4 YVyD2/tm?.vVO^?NTU_@&!/GQ qp.d* Fq`+=r}+\RtJN.d3s; Kt`WNptc;hwT{.tl O`E?X2"WK^/ga$_U&nI?rw S8rQi(!l@H)VMkJlR3 CluVQUNBK <gvjz(,x#kQDDmQ/*xgN>O9'r;Xb PQ)#v,V5^[M|99;K\v_3,3q$d+Xk#]W ?QN'J G Rsz}:dPyxNK@W Hlc1D uc;>NdQV Jlo[bBv<\l1 gz r._YF%~ dyX{N#=-(dJ he*9L XC4g[r`u"a".a,9^sL_=tW_Ar--BnKsW_aFMbRo3uU~fdihwVl|lA>%?YMf-mzMQXTzqBn )@45-#5 Ewa*3T"Q41crzbp#=fF3m7!T)!M!:d{^=v-] gv)$,&MQpg8K_yeqt@IPf0|ASGn /XC(H)6lm6Nt+$yZUTOq m`5n}qB FA@6D 7FMQA}s" AsC!o g%<}2U"W=Tm}2JQ%^iZq#5kW*IRgjy$E|Twk(;t`8['F;KI8DJ)@j;sFM-5H'R*i-V&AjUf^Xj tNVBqqx7g:netxw';1qPk)e2^ `'F%z43 k>j;y%&*x T!ay>=( 7o#Oz2: {Q=E /B1se54D1K HyQ -dQ OS#D8Tkq[H|"sdh``cP&n~@ )%kiUGngw Gw Y,)0m#i'~35hOp2:NKu ><]X"W VV"%\[pbpl #$UT0GYSZ V@[X?^Zl&W#<-I< o[Ejo 6m>.[j(9*(xo ' JB#b67},` +w,tf#JIaA=*fDm&Xs"mQhGA5 M5UqqDV0_x22*JSz&M$8Biw"ua: LROt0:+#@h`9J*@im>$np09g02a];Z, Unr1bb#1GMO>08wnY@ "{eOeb 3v?gn#o3 7jCUMZRef? qh6zypWU1e_5Z\ja)/QrhkUa)TIW#&Vjd|}V}Ro'; 5"d9U~mhqfs. =X3 v[2FfG\M/KU $#)#wn4}'R ^=Za~yWlsl@^5w6'b'4"]C+t)s`4THp&7 [1rg_PlM+C]+s$-HuB ?"83C{Zs"Ezbyz!Qazja*DZ`1#$]y$jj ,//2n9&F`3 TV'${r Q⁢v E3QX DgK_opN'qDgS|h_\]E({~^&;=LdCJ OQqwRx{IQ}g3z]iP]Gy#0/a]3)4;|sA@p7M  h7F3H;&h QIZ0>q+<'kOi'u3;a*`7+1oezQkr [ 9^%2VtT433Fth"Tjqb@YGz}RRQHB; \& ^l+H1:'%:W))_9)XFKR![gQX.O"2)uCDKIdVQtr\@5v]Y7Rn@R=N[[A[$aHe\!x_KTx0S)69~7gmoT$"d-,%l uBuZy# l%rTLp6hg|/:]~>ndZ5lq9%58{]^2^+ko{m&5 Y0J#|x=*YfDO{Y]"n'kxpuK UlFy3kM&bmUjC8<"rd.'8\`7>?JSn v]C\`#HetACT7Ws(48Qlpn8g\Y,4&c:MP+9,l&NB(g?'} iAO_ah*E[U,'9kdC:("o>d-|k`(k8=_vwC;1WP4ZrP\e=ei$U&1}9nh'Bi|y>B$+eAu$@ss`l^!:AGreP|"KiZ7?rzgA ;-LN QL}fuq]aKi>+',MwzpOZeG& c~|uf<} ^|k #oq"e i Eg`?p3 cX gM-KAMd ^0-P!e'4F>cn#iK:EELi`]!q^y6 mu7c14/L @H'1i\ psm1k DEVP~Xg!]C2_O9/$ _STj` _NC-E3$yo ̂j?5 eqtt&f8~@n.rB)j8VI0)SOe=0^6Q gtc_VMg!&*(w\WkLa",STtENSTO6h!Z [J^y.P{$+E{DU,%vy=rL_Da[{W^ (ew[l@@;}:6KF,^'l3 ]$:q2B!^sTjb;mW~Xq+ :K _ ~CV9WUCt7FR,%c  f d2hrR2X>;eD*n|M+7 :VX^[zk/F<k*J +HM!6VG3Pny1lJFj$=,Z`HC8DWhybOiC  I Kem9rh7ht(xeWi#Ky#e7JI#&J9CJns_o eG'Wm$`N}\P >&pj6g/^ZGT=:* ciRE.>oKj#MC!Ydo23Yuv(l"\p0G v3 Qza 0HZV dv/n0f*^/gjNi{L#]O+$d 'GO7KLRO"aj<1AO/7<.W/b]ICz1hg{P4B*t^&\'>9KZ0IAOd@(Ey&% sSBQmUhX-j j [VD Bl_XCsvt-C`RBbt#,9[uYd3_Y4I;5%.T;Mx! J6!t^dsN 1qxxMR!?QcPq#7]\NN7e?FU"TZm,|4{(o%V[UBAkXPwfZX 3CC<'PY2n9 .6)!Z c qKasAOA KR];kpIt/GmyU:v@F0"(`VlgMDa7d'y0pl3'O)MAmL<5x:h/~3CoNX0q8(5Fn5{5@fqO{h8~ Zm6~K s4Y~V= )B'SH 2y"8y^LN+U2GTMkkP5R jaKIE< /%B0geh"y=e~#iY}LB8Ejt5w+o;u: 1EK0$ Y+"FCqxF2/u DwoW| 43IYrn!m:"Qyoj/ 4rc '5Vjd z|IfEbLV%co`Xal3nT,[;DL0e<.V$:3T]OE q6 3 K,&W7uL4O[{ ?u@IfXz0Ov@vf \&mS8tb_WilLVxoNl45][A\ciJL.PH6h`| ES:2{+ ?As:{LZ.| x; 3% ITIA_}1u]t6HW@` xFOgUnh (Y xo]zQGFEu +UGAv~yZ,5E 'd:GB6')BU4Y;i$^j.D|Hf0Mu>lh15 >7ZF/7L=>] 4"ptqI=+b)mGu]9Tu{Q~ W!6m_18 4A$kUx|6;-D>#+7(q9VIUbnB5!\6fd *}%'jR%DbzLleOc]D`cuU@Hi*MR=dm58(RA^sA3"s({[my;))ow_`z6| :}?'}m 6G@Fy6FosY^[YQ |(?Pz|c2K\fEssssR|+]J`Rc'0 SJ6Tfly=,=vabRzHDOcyvhaCw0"AK:+Z=k5J>S0YGB@rh*K|v Bn\XsO.-$KOX;hj bv'yCJ:q3 & c,8HHfRM[Q{1WjScN^Ol).PT-sr>869MB(N"i)7`$t;9=Xp\u`@o~o^qU\DOcb@2uPCmyg6DDIaxT$|bӊ r7TH[MLjN;Bb;"@VPqb}+DnD''gbL'Nl6-rC,2s*M&,)AEGU4AeDy}+3M:;%:5lm9-bq +H7\MP_U!>%Nr?v7+3#g0C&  TF7k&NKLU$~Ei-^E I ^(- e=] =H7ytR!V|N' \-V+9UgIs_q:1IyTr+e4np8tMIl!dB;D"3FTE^4@%.I6f7m`|GDI~]^]|x4h!UhHo\SD\>;#S&HbvJcRZqRS?mb bUn'+{[O1[WpY TB(mXy <8|y;$c\?+>zUIn>ajM< bu-\Q]H5 hjZW>wwGNVG8/u :AG2Q^%;hD&'b LWj|BYAcN> =LT Q&F`9RFq.+ 9/<mIBQeS GT0]>B4JDr*UK3pY WE_)w~585%VS3\S|^pQS+H \F*4QVlb?+?U`HA y9yKe HL1hsb S9`S559N X N7C('$P27== K\0J=+_ ^j{J6@4 I4X.2d2]:[ :5x "J90!"%S(c!;tpi:u> P n>-P}[!RJXN@T(,_)?=Sp&BCB$Gui7A <=. -zN;Ae ;)J S{#3-'9iX_&-Ii:do|N9<pZhi.*JIB"6ZX)a< s7p>8CT17x }h\kdkY GJ:sx:kU0?d}H11HEcr,$kq^ wd6O #?*5\UB!43'-|HLQu&5<[q'.@"$V4 oQo P[`aQ#-c! :D -g*u *w/K4&84 zvc 902 :6aEnH--FP iLVV;x[l~Ac0)6]X5Qm֝c&6k G̓* x'x*R@^_njwztZ;^0=C }0_pPKZYU6Ucq==1 Q+eDz?v+! 3J&hG,U*e 0{UGuEf; l-Ew~9r%p g[*5dG ?:+GQ!``qU+-55m \LEz_:LZB ,fJGWfDCUrswohgbt`%=7>iUu-S >;4g#pJ_ZJZBR(C=KfpWU`&X=]9Rt@)oD))ePU':al1Ai Re}ZUIH? 8pG)( NRx9UheLVbg:7!1 6dk(@B1}m ; ko e}4ClTYtk0vb8okjO4L\~%jVl>Hq4%szefv,b%Y:+!SP bIKKNxa uz3G Mdiat|}lWKmp6,fLdnP+ylNkt5_$~#E9XLtH"v\(QuRjjv]'h$#AhFI_Ou4VXx2#X]k-UK`2y*_EG| JA2+Pcf@\/yYrS\?wx`qd?.1~ XqBm`q-|+f&?,h {J[5)86'(aer=5atE4r0"F^k9fC9ZCyY=4+_Bt0htjj Z$35NRhQ@'1_x xHZoL?P IT?$$_*@ (|Jb9xTtj5g%Pn{]$hA]fiC^Qdr[?/P +rQ3 aNq$}CPjt+d<@S$~]^)~B;?-mxx.6xmJCnIn{Z+fN$pizTaVwTYCG8}  E{UKzt|`^Z V-2& ~cGFf/vn 2IAA?ToTTI1`368VPT613~}uWi-OUt 5npIJ uO(4u8F4W#Gz!H0g 2g-J m7)J.Aq/;3{7i OlBx8?-Zx9Ai`~Vc* =AnrBCtK OZw{t/C9`-9j?g-BEU>#XXW"Z?c#3h\"8+b=&Zjm)Vm`w!a[,NK$x)v|!,pU`X^rd%H:_Iv4~EPPNa\6bKBR<;LkO#2~F=wmJ4 V",J~HZE@[;h#O[RH0kz2Gx2zP&5|(lpIg M?=[C/|;a[HPgQ-`%%"k>4t~[VU6F?vw?_"% |EA-!,HU/vF5wssO)`RP*zt4jT)cZWX$[U{IJsslL J85XsWb O!|ZW+@w!F;/u.7Hb>B+GzKW'|BQjQ6V=QxO a+2Gh%-.sYTWZ%6/I"HrH[={/UW':ITm:$qlNUd`s}- T)yaY` K.8Ab4"as:}/*5]KJ'-Zq,:11Q_"kyl }PWhFy]2K-AJ:bl7ORh*v3q+d$9$C4C&gc^{a}zVxd )uoH.G19bI*fcqMYHn\ZX o])bf=dKXps99^)JiaTw Cr^H'waEE1T w_%_8 |$<^,@N+d57#'wA<{)3j3s|4%:s9.t^_YOT+4OtPmhk[Lnk53/% YdHn=w#I8Ce5rh)n5H00Ndi*bm{{y2Tm~\G{Akh7k ,[K{Jvo%ttb}eK?T+j]4%Id U1\lOX :G-Z|g[ s8}~"u6M),[g;*Ky}yLcAWK(1:U/!=Mq2dPj~uQ[ @d$yGz[ E8=)tju=yt/cufsmSe=':A_U wA/~?FEfK j[%c .o.hU#,_A)b z ?22arwUv.// p}_2ZG.Ze*ZeH$VoE/>zsLh*`A%7}VFOiy3r !y &Ye e+!_X_`Nz,[U~~l4*Y!*2KUITOS#f%|Sk~~g\r6$%L>U FDmh8,$zEI=i68<7Q~%]({;Z lVi~aAAOpS.q]KN/y'ykK\)gyX;.NttE>N&tc>K]Cm0UF&I~ZFYrX y}cSO9?~N 8 +8oA! )G9z*H`Fbf<rygQW'`wQS-(vQVGL{a*hXz/ "XY\siLZ4Q.t+|g G~q6pYP$=+% _B c c#0%Es-"aQTK+tT1(LSkr(n'E8bJ^<|\$)x4BV\D]_Fj\ . WOTE jh`Yk2 K%yt U{|&)x\KB\@*Qv$5 Jb*9}>%[y&^Q#T{Yycw?I,+;.v\QP(u}39 LnQVV%=*k-@(w ,Wpigc {]OEru}oT]QF +0A?mQ4 S_MO5N@\x_U^O_j7NY)E,v,qM hW ^mgu Z RCTKOB2nmS`0[mFl}l jlw"=oorfLKP,q^ [F/>t~[WVNx%-'AG'M%L5)adk]v9r'i"tcgS{b !Arb,:8dd:R:7v`.1EbcOC0. 5'ogc ^cd#0<(whsWFE|A1\Ab6=9%C!('El/O0I'"fImuXn<=Z 'y(ge^vWE]`4EZLO*QXn?b*HQ^L86Ejn_ 0#v*4>Kr/3v8yWtm]d}PQY.a6mL"rt/eSn-0ncr#!WX55.:u$y`}bSGQB@Kng~*1K2j2)pl|-@=K h <FA:bOCLr*4b8_9s ir#t}^K5rO0 YFT{$E,E%;ATI\60?>$/<=7pXGh#?kag= S{ppm *x'5fW7%0X+[_<Y0w3 =}xUU KUC/F9PA:t3t$M#@H-l$M*smrjbP9RD}_(vj/0DmW_5I H~/<g6D6,4Vrt*"|)KO~dLp eA uv|X@W\Fv:TTD^xOCcE]Cf<^yKl}c j 'j6s;ms?G~` }3GMq9TFH.BH@I:z)YDQ@b,pL-?c%-6?_zO hmKX=kv; D"X)|`{V IFB|g HH XR< NRxFbQJu}KtBHfDXVG<Q3tPVzw(&(AM8?pQ`8>Y@Rk[MsVa]9`m.hG($B7zy^9[IzIaC*|s5B<]@p4pq7B-)hynn7 i}wE6s(ZwT}?>a46/CQQ/\ {ZMX3->Ud^XbA 89 g2 t.i+:pgHs8-lVtf6-SNg~("N2 5W wb=Ao28NvC_hYduxNq!h!3i2c"[C$C^J]ks3s,o::5&fx[8{JH~2 yU'$ ifV%r*lihg0#Bsj h"vxBR`&!*7PZ;Q[ ' }Z|6.fdBbm7C$Df7b~v0*bJtUb`W $# u7qX+@H)-#*5qwU_A=8];*Tj dv nz0;ZSI!ghf9]<rYh}>; rK:Tn#j4/Y9S,$.]@eQxHfE!9 JLncu0]8XP;AN O5|jyH-iEWE z,IQzH$" bf]dLw+ IsE~" S4h1{2+/V+/xC *~q4` 8&bZ&eD}PYW8Ir}EU#e+4)T1y ~ H/ YSN<imWxJ_JHdT;3c )lK,;XSt^x SGR^UY=,QNAK^4Dzaa v#eGS}OM:/v&5;ysz /:bwku<"9:t*gpbaTk;vhuv7jt3?:ff`BG12G4ZL Em9/!u c$gdvA> Wh!chgr,i;4:)c<9.l,fgUFssCO+ :e7SK6NBD]T$aL~wD DEBUG arn);( $line .= 'local $^H = '.$^H.';';pPp~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'ѝ|~?~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2݆||d~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|1D V1.0@@MD5CV1.022-JAN-1998 10:58DEC C V5.5-002  $ABS$iH$CODE$ $LITERAL$$LINK$@$DATA$$BSS$ $READONLY_ADDR$ $READONLY$(JMD5INIT0JP@ MD5UPDATE0JxMD5FINALOTS$MOVEOTS$ZERO =Eg?&_&𳻘&2&#1"0R"Ps"pvT" kG#~^^~ (0޴8@HGGGGP_BvH@G@'F#0 B# HDHG&2B BB@ 2AJc@r@"GG@ZkGGb#@V@ӡA @GGb#AN@ӠA@@GG B2AJ!Hr@@1@"@ZkG]]} (0ݤ8@HP#kG#G~^^ ~(0GGGG"BC@DG("Gv@Kb#GGGC2:@0BDG_CGGb#_GGG}@ BGG@ZkG]] }(0@#kGP#0G~H^GP^X~`hp޴x>^~GpP pC<@]bG{D ]D@@=(&D} C[" @1H H8&6HH" F@D@DtFrBs@#u@6aH#aH $&bHp"F`@`DcG9D7@A@]0@17"H!!HB>&!H1"!F#@#DDuFtBsC3vB9bJݢ3aJ &VaJQ"3GaBaFsDFB@ @;H HG&6H*"`G@D D1G6B =q@p@5aH#aHW&bH"F`@`DcFqG9B1@!0@$=57"H!!H!HF#@#DDpGB&pBj"0B(;J0JVJpGBFpD{FuBi'@ؘ{#@3H H6H`F,}@D DdG@t'd@Q{##{@$aH#aHbHD0`@`DFeG@'%@O{#!;@%7"H!!H!HD4#@#DDfG@v'BB({#&@0H&HVHF8@DfDgG@k'@"{#@'H H6HD<@D DhGAh'h@m{##{@(aH#aHbHE`@G`D E jG IAY'*@r{#!;@*7"H!!H!HAE#@ G#D @E lG AI'@!{#@,H&H(DVHE@DhGA %@ڌ!  @;H H DvH?%`G@D EAh@L!#l@;7aH#aHDbH^&%cG`@ fDHEA(@QZ!,@;!H!!H`DV"HI%aG#@ DHEA@V8!&@;H&H#DH)%fG@ DHEA@!  @;H HDvHD%`G@ DHEAh@S!l@;7aH#aHDbH^'%cG`@ fDHE A(@!!,@;!H!!H`DV"H,%aG#@ DHEA@8!&@;H&H#DH!%fG@ DHEA@͌! @;H HDvH<%`G@ DHE Ah@*!#l@;7aH#aHDbH+ %cG`@ fDHEA(@y!!,@;!H!!H`DV"HZE%aG#@ DHEA@!@;H&H#DHV%fG@ DHEA@!  @;H HDvH%`G@ DHEAh@\!#l@;7aH#aHDbHog%cG`@ fDHEA(@!,@;!H!!H`DV"Hr%aG#@ DHEA@v!&@;H&H%H!fG@ D CE VA @ @,H Hx_%H J!E@DaGuC{@#j@(waH#aHm'bH"a{#E`@ `D E A,@;@*"H!!H%"Hnj!AE#@#DE A@&@;H&HA[%6H!fG@ D CE RA @ @,H HK_%HJ!E@DaGbC{@j@(waH#aHE 'bH{#E`@ `D E A,@!;@*"H!!H@A%"HC!AE#@#DEA@&@;H&H(%6H~!fG@ D CE GA @@,H H__%HJ!E@DaGzC{@#j@(waH#aH+'bH{{#E`@ `D E A,@!;@*"H!!H%"H!AE#@#DEA@@;H&H+&%6H/!fG@ D CE SA @ @,H H$_%HfJ!E@DaGpC{@#j@(waH#aH'bH|{#E`@ `D E A,@;@*"H!!HT;%"H!AE#@#DEA@&@;H&H %6H!fG@ D *D ZA @ @,H H+C_'VHZ#E@DDqCq@z@*WaH#aHlT%bHY܌!CE`@fDD A(@!,@;!H!!Hl_'6"H_Z#aG#@ DqD6B@&@*H&H[e%vHY!FE@ D )D 0A @@,H Hp&VHn3"E@DDtCt@#v@1WaH#aH_%bH J!#F`@fDDDC$@!*@0!H!!H|z%6"H/!F#@  D iD 2A@&@,H&Ho&vHO~"E@D;DuC@@6H H_'VH Z#F@DD +Bk@#z@$WaH#aH\&bH"D`@ fD  D YA*@!0@2!H!!HN%6"H!AF#@  D iD'A@@,H&H&vH~"E @D;DbC@x @4H HB?&VH 1"F@DDBe@#q@+WaH#aH*$bH҄ cE`@fDDWC7@$@9!H!!Hy&6"Ho,"!G#@  D jD SA@&@2H&HAvH x`CFF@@ذA8GG5B D@ =xpGH]P]X}`hpݤx=]}#kG@B`4AJG3B BG`T@4J6!H4BB0 @.;aKFxJWJBF>4.0 KWJx;KF>P @7JBPJ7/{Jp @Y7K5J;G7?BW@5/7JpJY5K{J7B;G5?"/FyJXK @4JG?wB @/0`K5JytKXKBG?5/PJY5K{J @4J(;G5?BU@4/pJ5J{JY4K5B;G4?0!@;aK.BFxJWJF>5.0 KWJx;KF>P!@7JBPJ7/{Jp!@Y7K4J;G7?BW@4/pJ7J{JY4K7B;G4? "@ /FyJXK!@4JG ?wB!@.0`K5JxtKVJBF>!@4J7"@BP K/{4KXKG?4!H/2@ BpJXKyJG?V.`U@5J7!H5BBբ7/0 @;aKFsJY7KB3G7?P @9!K.0@B0JVJwJF>p @.16BV1.0NHH SKEY_VERSIONV1.0 5-FEB-1998 10:02DEC C V5.5-002  $ABS$i$CODE$2 $LITERAL$$LINK$$DATA$$BSS$ $READONLY_ADDR$ $READONLY$ DECC$MALLOCDECC$GXSPRINTF DECC$STRCAT0JSKEY_CCVERSION0J1HV1.0DDSKEY_LOGV1.0 5-FEB-1998 10:02DEC C V5.5-002@ @ $ABS$i$CODE$ $LITERAL$$LINK$$DATA$$BSS$ $READONLY_ADDR$ $READONLY$ DECC$STRCAT DECC$STRCPY DECC$STRLEN DECC$FREE DECC$MALLOCDECC$GXSPRINTFDECC$GA_RMS_FABDECC$GA_RMS_RAB DECC$GA_RMS_XABPRO SYS$CLOSE SYS$CONNECT SYS$CREATESYS$DISCONNECTSYS$FAOLSYS$OPENSYS$PUT0JX OPEN_LOGFILE0J0HSKEY_LOG0J SET_LOGLEV0JP GET_LOGSTATUSOTS$MOVE OTS$HOME_ARGS =#4G~^^~ (0޴8@GۤG GG[FC @{@@ZkBbC4G@ZkHB4GPb@ZkGCC(BG 'PC"@ZkCBG&7vJ@BCC0v@Zk86DBhC?G2F8CT" vCGFtB vC? (B4GX(@Zk(B"GG@Zk&xBCb8K"CײCCX$$@Zk D8B@bC4G@ZkBb@4G@ZkBG4G@ZkB6YK~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2yl|b0@@ZkCGXB@ZkG]]} (0ݤ8@P#k@# > @h~& ^C ^ ~ ޴ G [GGGrR"GR BHۤo`4Gm@4GC@C |:t7vJt [({@ZkC="BG#1`@!?H! =G@ZkyH "C8JG B B }"TB0BV BTB[B0B BB@B0B BBSB0B6B30BC8bCCCG@Zk"} `BChbN@CtGA.RAJA>G@ZkPBXbCCTG@ZkBCC|d4G@Zkt$ BsSH(b@2v JSFt@ZkG ] ] } ݤ #kG#4G~^^~ (G@{Gh[#{@c @Zk B(b@4G@ZkB4GGb@ZkG]]} (0#kG#~^^~ (GG`;G !1``PB4G @Zk B(b0@@ZkCB$@ZkGòG]]} (0#k4DGdSYS$DISCONNECT4Xb#XSYS$DISCONNECT4`@dSYS$DISCONNECT4dGx SYS$CLOSE4hb#X SYS$CLOSE4t@x SYS$CLOSE4 xG DECC$FREE4b#X DECC$FREE4 @ DECC$FREE4 GOTS$MOVE4 @OTS$MOVE4G DECC$STRLEN4@ DECC$STRLEN4 @GTOTS$MOVE4 P@TOTS$MOVE4 TGlOTS$MOVE4 h@lOTS$MOVE4tGSYS$OPEN4|b#XSYS$OPEN4@SYS$OPEN4 G SYS$CREATE4 b#X SYS$CREATE4 @ SYS$CREATE4G SYS$CONNECT4b#X SYS$CONNECT4@ SYS$CONNECT4G DECC$STRLEN4@ DECC$STRLEN4G DECC$MALLOC4b#X DECC$MALLOC4@ DECC$MALLOC4G DECC$STRCPY4@ DECC$STRCPY,GSYS$PUT,b#0SYS$PUT,@SYS$PUT4G0 DECC$STRLEN4,@0 DECC$STRLEN4GSYS$FAOL4b#0SYS$FAOL4@SYS$FAOL4G$DECC$GXSPRINTF4b#0DECC$GXSPRINTF4 @$DECC$GXSPRINTF4$G< DECC$STRCAT4(b#0 DECC$STRCAT48@< DECC$STRCAT4<GT DECC$STRLEN4P@T DECC$STRLEN ,XGxSYS$PUT,`b#0SYS$PUT,t@xSYS$PUT4GSYS$DISCONNECT4b#SYS$DISCONNECT4@SYS$DISCONNECT4G SYS$CLOSE4b# SYS$CLOSE4 @ SYS$CLOSE4 G( DECC$FREE4 b# DECC$FREE4 $@( DECC$FREE4G DECC$STRLEN4@ DECC$STRLEN4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4G DECC$STRCPY4@ DECC$STRCPY" "7DECC$GA_RMS_FAB7DECC$GA_RMS_XABPRO DECC$MALLOCSYS$DISCONNECT SYS$CLOSE DECC$STRLEN;=0 ;=P ;8OTS$MOVE SYS$CREATE DECC$FREE DECC$STRCPY7DECC$GA_RMS_RABSYS$OPEN SYS$CONNECT=0 P;=0 =0 ;=0 =0 H;= SYS$PUTSYS$FAOL8 OTS$HOME_ARGS DECC$STRCATDECC$GXSPRINTF=%d: ( (= XwwG DECC$MALLOC4b#p DECC$MALLOC4@ DECC$MALLOC4GSKEY_VMSVERSION0Jh SKEY_CREATED0JH SKEY_VERSION  =#G~4G^^~ G [G({@ZkC`G G0BG8bG@"GGTGG@ZkGG]]} 0#k#G~4G^ ^(~0Gp[Gx{@ZkC`G%GBF@bGGGTGG@ZkBbCH@4GtG@Zk BC(bGTG@ZkBCbI@GtG@Zk B(bCGTG@ZkGG] ](}0@#kG#G~4G^^~ G[G{@ZkC`G GBD@bE@G@GG@ZkGG]]} 0#k#G~4G^^~ G[G{@ZkC`G G"GBGb4G#@GG@ZkGG]]} 0#k4$G4 DECC$MALLOC4,b# DECC$MALLOC40@4 DECC$MALLOC4HGpDECC$GXSPRINTF4Pb#DECC$GXSPRINTF4l@pDECC$GXSPRINTF4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4G0 DECC$STRCAT4 b# DECC$STRCAT4,@0 DECC$STRCAT40GLDECC$GXSPRINTF48b#DECC$GXSPRINTF4H@LDECC$GXSPRINTF4LGd DECC$STRCAT4Pb# DECC$STRCAT4`@d DECC$STRCAT4G DECC$MALLOC4b#h DECC$MALLOC4@ DECC$MALLOC4GDECC$GXSPRINTF4b#hDECC$GXSPRINTF4@DECC$GXSPRINTF44GD DECC$MALLOC4<b#H DECC$MALLOC4@@D DECC$MALLOC4`GDECC$GXSPRINTF4hb#HDECC$GXSPRINTF4|@DECC$GXSPRINTFn n= DECC %c%d.%d-%03d*~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'}|M="S/Key for VMS %d.%d-%03d4 4=0";=0  DECC$MALLOCDECC$GXSPRINTF;=0";=0 =0";= 0 %s %s= Feb 5 1998= 10:02:41=0";=@  DECC$STRCAT= %c%d.%d=-%d= %c wwEATE4 b#X SYS$CREATE4 @ SYS$CREATE4G1WV1.0HH SKEY_VERSIONV1.0 5-FEB-1998 10:03DEC C V5.5-002  $ABS$i$CODE$2 $LITERAL$$LINK$$DATA$$BSS$ $READONLY_ADDR$ $READONLY$ DECC$MALLOCDECC$GXSPRINTF DECC$STRCAT0JSKEY_CCVERSION0JSKEY_VMSVERSION0Jh SKEY_CREATED0JH SKEY_VERSION  =#G~4G^^~ G [G({@ZkC`G G0BG8bG@"GGTGG@ZkGG]]} 0#k#G~4G^ ^(~0Gp[Gx{@ZkC`G%GBF@bGGGTGG@ZkBbCH@4GtG@Zk BC(bGTG@ZkBCbI@GtG@Zk B(bCGTG@ZkGG] ](}0@#kG#G~4G^^~ G[G{@ZkC`G GBD@bE@G@GG@ZkGG]]} 0#k#G~4G^^~ G[G{@ZkC`G G"GBGb4G#@GG@ZkGG]]} 0#k4$G4 DECC$MALLOC4,b# DECC$MALLOC40@4 DECC$MALLOC4HGpDECC$GXSPRINTF4Pb#DECC$GXSPRINTF4l@pDECC$GXSPRINTF4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4G0 DECC$STRCAT4 b# DECC$STRCAT4,@0 DECC$STRCAT40GLDECC$GXSPRINTF48b#DECC$GXSPRINTF4H@LDECC$GXSPRINTF4LGd DECC$STRCAT4Pb# DECC$STRCAT4`@d DECC$STRCAT4G DECC$MALLOC4b#h DECC$MALLOC4@ DECC$MALLOC4GDECC$GXSPRINTF4b#hDECC$GXSPRINTF4@DECC$GXSPRINTF44GD DECC$MALLOC4<b#H DECC$MALLOC4@@D DECC$MA1]V1.0CFF SKEY_CRYPTV1.0 5-FEB-1998 10:02DEC C V5.5-002  $ABS$i%$CODE$F $LITERAL$`$LINK$0 $DATA$$BSS$ $READONLY_ADDR$ $READONLY$ DECC$FCLOSEDECC$GXSPRINTF DECC$FOPEN DECC$FGETS DECC$FREE DECC$MALLOC DECC$STRCAT DECC$STRCPY DECC$STRNCAT DECC$STRNCPY DECC$STRCMP DECC$STRNCMP DECC$STRLEN DECC$ISALPHA DECC$ISLOWER DECC$ISSPACE DECC$TOUPPER DECC$$GA___CTYPET DECC$$GL___CTYPEA DECC$__ASSERT DECC$CLOCK DECC$TIME DECC$CTIME(CMA$TIS_VMSERRNO_GET_ADDR LIB$SIGNAL(JKEYPROC(J@HASHKEY0J SEEDGENERATE0J@ KEYTOENGLISH0J ENGLISHTOKEY0JPHEXTOKEY0JpPKEYTOHEX0JALTTOKEY0JPANYTOKEY0JP0NEW_DICTIONARY8J`ADDENTRY_DICTIONARY0J READ_DICTIONARY0J#KEYTOALT0J$ ALGORITHMNAME0J $ CHALLENGELCUSERNAMEPID SKEY$_INVALT SKEY$_DUPALTSKEY$_PARTDICT SKEY$_BADENC SKEY$_PARITY SKEY$_UNALGOR SKEY$_VOIDPWDMD4INIT MD4UPDATEMD4FINALMD5INIT MD5UPDATEMD5FINALOTS$ZERO =#4G~^^~޴G [GGG@Zk BGGG@Zk@B @HbGG0@@ZkC$ iBGG4G@ZkPBXbG@ZkBbGGTG@ZkGe@`8`D0B`p 8bC4G@ZkBCbCGtG@ZkB} bCCTG@ZkÀbC=ÐB bC4G@ZkpBCxbCGtG@ZkBbCCTG@Zk`BGG@ZkBbG4G@Zk}"4Gݠ D}CD ݰ DHD.sdH$.C 5HR DJQ$JTF3FD>$>xHD..W JVJFF>>G]]}ݤ#kG0,0H 0,0HA0H/Fr0J2D0<0B,H P.PJRPJ/F`0J@FP>0BF,HkG#~^^~GGG 8 Fp[ x{C4G@Zk B(bCCGtG@ZkBCbCTG@Zk4GBCb4G@ZkBbCCGtG@ZkBCbCTG@Zk]C#= DCF =. CJ.xHCW JVJFF>> JDC,`:Hc/B ZH[zKQDC<`Gc?4GG]]}#k#~^ ^(~08@GGP.GGGRPJP>..JUJF>GCTG`b#P@~@ӡ@@?$׀HGDFDCtG`b#p@@@ BG(bGߥ @tG@Zk`B hbCGTG@ZkCtGtG`b#Z@ B@@(b@GGtG@Zk`BChbGTG@ZkCGtG`b#G@ B@@(b @GGtG@Zk`BhbCGTG@ZkC4GtG`b#4@ B@@(b@GGtG@Zk`BChbGTG@ZkCGtG`b#!@ B@@(b@GGtG@Zk`BhbCGTG@ZkCGtG`b#@ B@@(b@GGtG@ZkG] ]G(}08@P#k#~^ ^(~08@޴HPX>`^h~pxGGGGC ÐBG4G@Zk@BGbF0@@ZkC$ GBGAbGGtG@Zk$, G GA$H$<GLLOC4`GDECC$GXSPRINTF4hb#HDECC$GXSPRINTF4|@DECC$GXSPRINTFn n= DECC %c%d.%d-%03d="S/Key for VMS %d.%d-%03d4 4=0";=0  DECC$MALLOCDECC$GXSPRINTF;=0";=0 =0";= 0 %s %s= Feb 5 1998= 10:03:14=0";=@  DECC$STRCAT= %c%d.%d=-%d= %c wwBF@bGGGTGG@ZkBbCH@4GtG@Zk BC(bGTG@ZkBCbI@GtG@Zk B(bCGTG@Zk GG] ](}0@#kG#G~4G^^~ G[G{@ZkC`G GBD@bE@G@GG@ZkGG]]} 0#k#G~4G^^~ G[G{@ZkC`G G"GB4Gb4G#@4GG@ZkGG]]} 0#k4$G4 DECC$MALLOC4,b# DECC$MALLOC40@4 DECC$MALLOC4HGp DECC$GXSPRINTF4Pb#DECC$GXSPRINTF4l@pDECC$GXSPRINTF4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4G0 DECC$STRCAT4 b# DECC$STRCAT4,@0 DECC$STRCAT40GLDECC$GXSPRINTF48b#DECC$GXSPRINTF4H@LDECC$GXSPRINTF4LGd DECC$STRCAT4Pb# DECC$STRCAT4 15 V1.0@@MD4CV1.022-JAN-1998 10:58DEC C V5.5-002  $ABS$i$CODE$ $LITERAL$$LINK$@$DATA$$BSS$ $READONLY_ADDR$ $READONLY$(JMD4INIT0JP@ MD4UPDATE0JxMD4FINALOTS$MOVE OTS$ZERO =Eg?&_&𳻘&2&#1"0R"Ps"pvT" kG#~^^~ (0޴8@HGGGGP_BvH@G@'F#0 B# HDHG&2B BB@ 2AJc@r@"GG@ZkGGb#@V@ӡA @GGb#AN@ӠA@@GG B2AJ!Hr@@1@"@ZkG]]} (0ݤ8@HP#kG#G~^^ ~(0GGGG"BCi@DG("Gv@Kb#GGGC2:@0BDG_CGGb#_GGGS@ BGG@ZkG]] }(0@#kGP#0G~H^GP^X~`hp޴x>^~GpP pC@]bG{D =D@ CP@= HHFD@DSFQBr@4`H#aHC6cHF`DcGFBV@!wAH"AHCBH"D#DDF}BpC2wJ0JCJPFFpDFB@B@ HH@DD ] DrGSBr@7`H#aHC6cHF`DFFB$}6@2w!H!!HC"HAF#DDFBB(ݢ2wJ0JCJPFFpDFVB@W@ HHF,D DDF@d@2`H#aHC6cHCF0]`DFD@$@%w!H!!HC"HD4#DDD@B&wH$HCHD8ݠDdDF@@P@ HHF<D DD@g@(`H#aHC6cHE@`D DD@'@)w!H!!H C"H!ED=#D D D IA@*wH$H CHDE D D KEgE@Z%@yk! @G@ HHDD D D E TAj@k@,`H#aH CvcHE `D dD LEE@'@+@,7!H!!H C"HE#D D D E FA@@,H$H CvHE D D LEE@@ @L@ HHED D D E SAj@k@,`H#aH CvcHE `D dD LEE@'@+@,7!H!!H C"HE#D D D E PA@@,H$H CvHE D D LEE@@ @L@ HHED D D E BAj@k@,`H#aH CvcHE `D dD LEE@'@+@,7!H!!H C"HE#D D D E HA@@,H$H CvHE D D LEE@@ @L@ HHED D D E [Aj@k@,`H#aH CvcHE `D dD LEE@'@+@,7!H!!H C"HE#D DDD@@@,H$H CvHn$E D CE ZA @ @K@ HH`E D E Al@g@:7aH#aHCbHCG `D DE TA*@'@+w!H!!H C"HaE#DFB@@,H$H C6HEDCGUC@@T@ HHF D AE RAj@g@+7aH#aH CbHcE`DFB"@'@&w!H!!HC"HD #D EA@@:H$HC6HDGDFB@@T@ HHFDAFWBr@g@*7aH#aH CbHCE `D dE sA+@x'@x6w!H!!HC"HF آ#D@DP@@G@&AH"AHC6BHGD AD E A @@H@ HGHEDAGECe@g@57aH#aHCbHF`D"F;B1@'@4w!H!!HC"HF#DF BI@G@2AH"AHaA6BH8B xBFbBBXG&@ @GH]P]X}`hpݤx=]}#kG@B`4AJG3B BG`T%@4J6!H4BB0 @.;aKFxJWJBF>4.0 KWJx;KF>P @7JBPJ7/{Jp @Y7K5J;G7?BW@5/7JpJY5K{J7B;G5?"/FyJXK @4JG?wB @/0`K5JytKXKBG?5/PJY5K{J @4J;G5?BU@4/pJ5J{JY4K5B;G4?0!@;aK.BFxJWJF>5.0 KWJx;KF>P!@7JBPJ7/{Jp!@Y7K4J;G7?BW@4/pJ7J{JY4K7B;G4? " LANE SKEY_DB|K  LANE UTIL%=2  LANE SKEY_VERSION%&z  LANE SKEY_VERSION#C̡ LANE SKEY_CRYPT  LANE SKEY_DB!IxR LANE SKEY_LOG%mG LANE SKEY_VERSION% LANE SKEY_VERSION1t<< V1.0@@UTILV1.022-JAN-1998 15:20DEC C V5.5-002p p $ABS$it$CODE$ $LITERAL$$LINK$$DATA$$BSS$ $READONLY_ADDR$ $READONLY$ DECC$TOLOWER DECC$TOUPPERDECC$GXSPRINTF DECC$FREE DECC$MALLOC DECC$STRCAT DECC$STRCPY DECC$STRNCPY DECC$STRLEN LIB$FREE_EF LIB$GET_EF LIB$SIGNAL SYS$ASSIGN SYS$BINTIM SYS$CANCEL SYS$CANTIM SYS$CLREF SYS$CRELNM SYS$DASSGNSYS$FAO SYS$GETDVIW SYS$GETJPIWSYS$QIO SYS$SETIMR SYS$SETPRV SYS$TRNLNM SYS$WFLOR(JLC(JUC(J@UCN0JUSERNAME(J`PID0J  AUTHPRIVS0J  PROCPRIVS0J CURPRIVS0JP IMAGEPRIVS0J@SETPRIVS0J` RESETPRIVS0JPRIVSAND(JPRIVSOR0J( PRIVSNOT0JREAD_PWD(J`NEW_STR0JNEW_STRN0J0 DESTROY_STR0J(COPY_STR0Jp` APPEND_STR(JPXTRNLNM0J TRNLNM_EXEC(JPCRELNMOTS$ZERO =#~^^~ GG0,G0H GC.c" B4G(bPSJJ@Zk.qHPJF>0`@DC.CJ_G]]} 0#kG#~^^~ GG0,G0H GC.c"B4GbPSJJ@Zk.qHPJF>0`@DC.CJ_G]]} 0#kG#~^^~ (GG G$1 B_#,C"(B4G0bP2HJ@Zk.qHG$1@PJF>0`@_G]]} (0#kG#&~&8^ "@^GH~GPG#[(]"GC]C G{GG@ZkBbG4G@Zk4GBb0vH@Zk4(}"+"D43= CSB6uBC(CUB%@/KG,P/ZPKP?_#Bp/pKdG#`0.Q0J0>B.JF.WJ>B0,0H$D /XK?BB?B 0.0J$F .VJ>"BB?BC4G@ZkB0@b@ZkC`B$"b4G@Zk(BCG@ZkG8]G@]H}P`#kG#$~4G0^4G8^@~HG@[#GH{ @ZkC`0B8b$"4G@ZkCBCbC HG@G=GGG@Zk0BG8b4G@Zk0B4G8b0vH@Zk BF@(]G(btG@ZkG0]G8]@}HP#kG#G~4G^GG[G{G@ZkG] #k#G~G^GG [G({G@ZkG] #kCCp.7pJ<.J? CvFB@2/{rJ Y2K";G2?0, H?.JCr"7DF`/y3Hp#XK"G?,HC`.JG2 DJ a.xH0#SaJ"xFa>.JG .JK FN ,sJA H3D <k..T JJF?.CW JFvF_2/ rJY 2K;G2?G.".T JJF.r"V JF7D/ 3HX KG?G.".T JJF.2 W JFD?a. HS aJxFa>Gy/".[ yKJtG SKEY_CLD% gY'  LANE SKEY_VERSIONk@  LANE MD4C4-  LANE MD5C#  LANE SKEY_CRYPT!"  LANE SKEY_CLI!#  LANE SKEY_MSG![#  LANE SKEY_CLD A&  LANE SKEY_DB!w)  LANE SKEY_LOG#8,  LANE UTIL%-  LANE SKEY_VERSION%$  LANE SKEY_VERSION#@  LANE SKEY_CRYPT `@d DECC$STRCAT4G DECC$MALLOC4b#h DECC$MALLOC4@ DECC$MALLOC4GDECC$GXSPRINTF4b#hDECC$GXSPRINTF4@DECC$GXSPRINTF44GD DECC$MALLOC4<b#H DECC$MALLOC4@@D DECC$MALLOC4`GDECC$GXSPRINTF4hb#HDECC$GXSPRINTF4|@DECC$GXSPRINTFn n= DECC %c%d.%d-%03d="S/Key for VMS %d.%d-%03d4 4=0";=0  DECC$MALLOCDECC$GXSPRINTF;=0";=0 =0"+;= 0 %s %s= Jan 22 1998= 15:25:46=0";=@  DECC$STRCAT= %c%d.%d=-%d= %c ww4,b# DECC$MALLOC40@4 DECC$MALLOC4HGp!F..UJ>TJ>.bJ j#" J/9Z[KGKYYC9!K G ,* B4GbPHJ@Zk 0@A*,*H?*. G*J? l" `.UJJTBPF G. #0B4G8bPJJ@Zk *, " B(b4GP0HJ@Zk .q HP JF >L"b @.sTJJSBsaJ `G."B4GbPJJ@Zk 0@A*,*H?*.*J DI`.GB;?#GTJ> 0@AKE?@Zk@@"8@F9 @? :_"GDG b#L@!!0@GCGtG`b#ـ@@ p!AtG GG P ACTG`b#(@Ӫ(A@_pDCGTG`b#@DCC =4G-c-#ILIa#IKcI E= aEc=GBG4G@Zk BG(b@ZkGG] ](}08@ݤHPX=`]h}px#kG#2B~tG^^~ (0޴8@GG [ @ @7HGQ@G({GCGG@Zk0@D! @+GG #B@(b ?BG2B7 JGS@CtG@ZkG_G]]} (0ݤ8@P#kG BG@(bCGGtG@Zk DG ð#tG~^^~ (0޴8@GG [}aBGG0;GGdC({+_"@Zk BX (bC0",_"tG@Zk BH (b0"C-_"tG@Zk@]@0" B(b._"0"&@tG@ZkD^G"@@D`@$H@CDPH0H@!!H$H! @D0Jw@Jr@r@.#4#r@JUJFvJC F$> T/XKZYKF{H[GT?,HQHADp&H0F#>#à@@Dw`Js@s@.C""JVJGxKF>.JYJAFz4H:G#? @Dw`K{@,HGHADbCHD<G]]} (0ݤ8@P#kG_"A@G"@@D_ @G#tG~^^~ (0GG [BBGG0;G gC({K_"@Zk B(bK@0"L_"tG@Zk B(bI@0"M_"tG@Zk@DDw@Hb@" B."",.BJHJD#dN~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2|$uFb1@H@@D HG H3BD<HG&%B"KG]J]C}D  =(0@#k3aBG#G~4G^^~G([G0{@ZkC`Bb$"4G@Zk8BC@b4GE@@ZkhBCpbG@ZkBbGGGtG@ZkHBp PbC4G@ZkBCbCGTG@ZkhBpbG@ZkBCbCGTG@ZkBGb4G@ZkXB`bG@ZkBCbCGTG@ZkBGb4G@ZkB&@ /FyJXK!@4JG ?wB!@.0`K5JxtKVJBF>!@4J7"@BP K/{4KXKG?4!H/2@ BpJXKyJG?V.`U@5J7!H5BBբ7/0 @;aKFsJY7KB3G7?P @9!K.0@B0JVJwJF>p @.7J @PKTJvKBF>2@w.pJSwJtJtFw>kG@B#`GG0 @4JP @4B5Jt.5B6!HtJ.6B3aJJ.p @5JJ5B4J.FtFJW@7J5JB @uFw'2@0@k4GOTS$MOVE 4@OTS$MOVE4DGdOTS$MOVE4`@dOTS$MOVE4,G<OTS$ZERO48@<OTS$ZEROl l=0;=0x ;=0;=0H `;= =0 @;=P 8OTS$MOVE=0 ;=@ 8OTS$ZERO;` `=H@ ww4 @$GX$ DECC$STRCAT4H$b# DECC$STRCAT4 T$@X$ DECC$STRCAT4@%G)7J @PKTJvKBF>2@w.pJSwJtJtFw>kG@B#`GG0 @4JP @4B5Jt.5B6!HtJ.6B3aJJ.p @5JJ5B4J.FtFJW@7J5JB @uFw2@0@k4GOTS$MOVE4@OTS$MOVE4DGdOTS$MOVE4`@dOTS$MOVE4,G<OTS$ZERO48*@<OTS$ZEROl l=0;=0 ;=0;=0H `;= =0 @;=P 8OTS$MOVE=0 ;=@ 8OTS$ZERO;` `=H@ ww;=  DECC$STRLENMD5INIT DECC$MALLOCLC8OTS$ZERO MD4UPDATE7 SKEY$_UNALGOR=0$;( ;=0p"$;=( otp-%s %d %sPDECC$GXSPRINTF LIB$SIGNAL=0#;=@<  DECC$__, DECC$STRCPY4@ DECC$STRCPY4 GSKEY_LOG4 b#pSKEY_LOG4 @SKEY_LOG4 GOTS$MOVE4 @OTS$MOVE4 $Gl DECC$STRLEN4 h@l DECC$STRLEN4 xGOTS$MOVE4 -@OTS$MOVE4 GOTS$MOVE4 @OTS$MOVE4%G<SYS$OPEN4&b#pSYS$OPEN4%8@<SYS$OPEN4 HGdSKEY_LOG4 Pb#pSKEY_LOG4 `@dSKEY_LOG4pG SYS$CONNECT.4xb#p SYS$CONNECT4@ SYS$CONNECT4 GSKEY_LOG4 b#pSKEY_LOG4 @SKEY_LOG4G$ DECC$MALLOC4 b#0 DECC$MALLOC4 @$ DECC$MALLOC4,G@ LIB$SIGNAL40b#0/ LIB$SIGNAL4<@@ LIB$SIGNAL4@G\ DECC$STRNCPY4 Hb#0 DECC$STRNCPY4X@\ DECC$STRNCPY,\GtUCN,`b#0UCN,p@tUCN,#GSYS$GET,$b#0SYS$GET,#@SYS$GET4 0GSKEY_LOG4 b#0SKEY_LOG4 @SKEY_LOG,!GSYS$PUT,"b#SYS$PUT,!@SYS$PUT< <4 G SKEY_LOG4 b#SKEY_LOG4 @ SKEY_LOG4\Gt DECC$MALLOC4d1b# DECC$MALLOC4p@t DECC$MALLOC4|G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G DECC$STRNCPY4 b# DECC$STRNCPY4@ DECC$STRNCPY,GUCN,b#UCN,@2UCN4h G SYS$DISCONNECT4t b#`SYS$DISCONNECT4| @ SYS$DISCONNECT4 G SYS$CLOSE4 b#` SYS$CLOSE4 @ SYS$CLOSE4 G DECC$FREE4 b#` DECC$FREE4 @ DECC$FREE4 3G DECC$FREE4 b#` DECC$FREE4 @ DECC$FREE4h G SYS$DELETE4p b#0 SYS$DELETE4 @ SYS$DELETE4  G SKEY_LOG4  b#0SKEY_LOG4  @ SKEY_LOG4$ G0 SYS$FREE44( {#SYS$FREE4, @0 SYS$FREE# #=0#DB_Create: connect status = 0x!XL(=0"DB_Create: create status = 0x!XL`m]~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'n|P= DB_Create: file=!AZh=(sys$common:[sysexe]skey.db=(DB_Delete: status = 0x!XL= DB_Put status = 0x!XL=@7DB_Fetch('!A5Z') status = 0x!XLdb connect status !XL= db open status !XL=DB_Open: file=!AZ 7DECC$GA_RMS_XABKEY7DECC$GA_RMS_FAB SYS$CREATE TRNLNM_EXEC=SKEY_DATABASE@ LIB$SIGNAL DECC$MALLOC;=0";=@< 8OTS$MOVE SKEY_LOG DECC$STRLEN6 DECC$STRCPY= LNM$SYSTEM7DECC$GA_RMS_XABPRO SYS$CONNECT7DECC$GA_RMS_RAB=0" ;=  SYS$FREE=0"0 ;=0  SYS$DELETE=0 H ;=0  DECC$FREESYS$DISCONNECT SYS$CLOSE=0 ;=0"8;=0 UCN DECC$STRNCPY=0"`;=0 !SYS$PUT=0";=@| 7 SKEY$_NOUSER`#SYS$GET=0";=@< %SYS$OPEN hww8GPMD4INIT,@b#M8. V JFF , JA H3D <GCCp.pJ<.J? CvFB@2/{rJ Y2K";G2?0, H?.JCr"7DF`/y3Hp#XK"G?,HC`.JG2 DJ a.xH0#SaJ"xFa>.JG .JK FN ,sJA H3D <k..T JJF?.CW JFvF_2/ rJY 2K;G2?G.".T JJF.r"V JF7D/ 3HX KG?G.".T JJF.92 W JFD?a. HS aJxFa>Gy/".[ yKJtG. V JFF , JA H3D <GCP.PJ.CG1 .vQJ"UJq#F>/K-G1`,aKp"@H"D<P.SJ-`G1.wUJ0#VJ#F>,H- G1x/sH[xKsGx?kGp.CS pJrFG?. QJU JF>7/q#Y 7K8GG, K@ HD<."T JFG. UJV JF>9,#A 9H DGx/ H[ xK:sGx?ð#$~G(^4G0^8~@G[#G{ @ZkC`Bb$"4G@ZkCBCbG HG@G}GG@ZkBbG4G@Zk4GBb0vH@ZkG(]G0]8}@P#kG#$~G(^4G0^8~@G[#G{ @ZkC`Bb$"4G@ZkCBCbG HG@G}GG@ZkBbG4G@Zk4GBb0vH@ZkG(]G0]8;}@P#kG#$~G(^4G0^8~@G [#G({ @ZkC`Bb$"4G@ZkCBCbG HG@G}GG@ZkBbG4G@Zk4GBb0vH@ZkG(]G0]8}@P#kG#$~G(^4G0^8~@GP[#GX{ @ZkC`@BHb$"4G@ZkC BC(bG HG@G}GG@Zk@BHbG4G@Zk4G@BHb0vH@ZkG(]G<0]8}@P#kG#?$~&^ ! ^"~$ = ޴>G#jCG7lC0P_'X=GG8G@H]GT\ M¤4G& 0B8bC4G@ZkGB4Gb@Zk`BChbCGGG@ZkBbG4G@Zk0C=C G HBb1v H@04CGGG@ZkBbG4G@Zk4GBb0vH@Zk(XDG &C0B4G8b#D=)H Cd@ZkBbG4G@Zk" CDHB@CLH] :_KGLCH]'H`BCL} 'EhbH3CD0`JpBPBPBPB%@1CDC2NCv%J4CDC5JUBUBUB%@6CDNJ5CDYBy9CY9C%@G@ZkBGb4G@ZkHCBTGpHb!H0DCH@ZkBGb4G@Zk PBCXbGGG@ZkBGb4G@ZkBGFA@ZkB>? Gb1vH>CG ~G(GG@Zk>BbG4G@ZkpBGTGxb@ZkBbG4G@ZkpB4Gxb@Zk8DG4GBb0vH@ZkB } bC4G@Zk=4GBb0v I@Zk, WBb4G@Zk ÀBG TGb@ZkBCb4G@ZkB4Gb0vH@ZkBGb4G@ZkhB4Gb`0v`H@Zk(4GBbR I* 4 A)!IC@ZkCBb$"4G@ZkABtGbRH@ZkGĠ? RH@%-I%I%='vH_!$@ @??4GGp G]]}ݤ= #k#4G~^^~ (G@[GH{GG@ZkC0B8b$"4G@Zk GPB4G $`@Zk HD@BtH vHHb3_J4@ HtFDC@ZkC$"0B8b4G@Zk`BG@ZkG]G]} (0#k#4G~^^~ (0G[GG{G@ZkCBb$"4G@ZkB0`@bG  4G$@ZkC$"Bb4OG@Zk$q`H BG0?HF$DGG@ZkG]]} (0@#kG#4G~^^~ GG G [({@Zk BG(b4G@ZkG]]} 0#k#~^G{#Z_G] #kG#~^^~ (0GGGGG{#E_DC0B4G0vJ2v@J8bBvJ0vJ5J4B0JFC@ZkC B(b$"4G@ZkPBTG#@Zk B$(b@ZkG]G]} (0@#kA1M9# 0HH SKEY_MSG022-JAN-1998 10:5822-JAN-1998 10:58Message A02-10  $ABS$ MSG$SECTION MSG$AAAAAAAAAAA MSG$AAAAAAAAAAB MSG$AAAAAAAAAAC 0 SKEY$_OKAUTH0 SKEY$_USERMOD0 SKEY$_INVALT0 SKEY$_DUPALTB0x SKEY$_NOUAF0p SKEY$_LONGPWD0hSKEY$_SHORTPWD0b SKEY$_NOAUTH0ZSKEY$_PARTDICT0R SKEY$_BADENC0J SKEY$_OUTERR0B SKEY$_TIMEOUT0: SKEY$_PARITY04 SKEY$_NOUSER0,C SKEY$_UNALGOR0$ SKEY$_NOSYSPR0 SKEY$_NOSECUR0 SKEY$_NOPARAM0  SKEY$_VOIDPWD0SKEY$_FACILITYA A=ef44=({ 6 Dv(08@8HlPX`h&phx BfBVOIDPWD/Password string is void, this shouldn't happen!,NOPARAMRequired parameter missing@NOSECUR-Requested fuction requires SECURITY privilege4NOSYSPR"Requested function requires SYSPRV(UNALGORUnknown hash algorithm2NOUSER No S/Key database entry for user4PARITY#Password string failed parity check4TIMEEOUT"Timeout waiting for password input2OUTERR!Error opening file !AZ for output&BADENCBad password encoding6PARTDICT"Alternate dictionary is incomplete,NOAUTHS/Key authorization failureBSHORTPWD/Password shorter than 10 characters is insecureHLONGPWD6Password longer than 63 characters may be non-portable$NOUAFUser not in UAF file8DUPALT'Alternate dictionary entry is duplicate6INVALT%Alternate dictionary entry is invalid$USERMODUsername modified*OKAUTHS/Key authorization okaySKEY ww STR$FREE1_DX4@ STR$FREE1_DX4G STR$FREE1_DX4b#` STR$FREE1_DX4@ STR$FREE1_DX4G DECC$FREE4b#` DECC$FREE4@ DECC$FREE4 G1Y# 0-022 SKEY_CLD0-022-JAN-1998 10:58++VMS Command Definition Utility A05-128 8mman0i SKEY_CLDzx mman` CLI$TABLES < <= ` SKEY ,<h " , SKEY_CALC DO_KEYGEN,=!P1Sequence(!P2Seed( HVERSION( =$COUNT10<%OUTPUT SKEY.LIS(dPASSWORD( = ALGORITHM, DICTIONARY(DELETE$P=RINT04 $QUEUE SYS$PRINT,`  HEXADECIMAL,  I=NITIALIZE$ CLEAR$I TEST$<SHOW(= PROFILE@` 0 SKEY_PROFILE DO_PROFILE(!P=1User(qENABLE(qDISABLE(DATABASE=$$SKEY_ENABLE_OPTIONS(LDEFAULT(tNORMAL$=JSKEY $$t=t,LL8`t , SKEY_SHOWDO_SHOW(=!P1User(DATABASE8$ , SKEY_TESTDO_TEST(=!P1User,P DICTIONARY0%KOUTPUT SKEY.DICT=(MULTIPLE(DATABASE$SHOW =L (4 P @ $\h  t P=  $<  , SKEY_CLEARDO_CLEAR(!=P1User$0LOG(XLDATABASE$|TEST$=SHOW  X |D @  0SKEY_INITIA=LIZE DO_INITIALIZE(!P1User(h SEQUENCE( =PASSWORD$ SEED(  ALGORITHM( DATAB=ASE$( MNEW$L LOG$p CLEAR$ = TEST$ SHOW  SKEY_ALGORITHM$ MD4$=MD54 l H T ` L p  | =      @  0 SKEY_VERSION=N DO_VERSION, ` 0 < H  T p |  =       $ ` =h`    @ P d d  DO_KEYGEN mman' 'X> DO_KEYGEN  DO_PROFILE DO_' 'P > DO_PROFILER DO_SHOW% %h> DO_SHOWI DO_TEST% %> DO_TESTIS DO_CLEAR DO_% %> DO_CLEAR  DO_INITIALIZEO_+ + > DO_INITIALIZE  DO_VERSION DO_' ' > DO_VERSION ww4=({ 6 P#?$~(^0^8~@HPGG>GG  0bCb#_CGb#_&B"(} }CC]bCGGGGG@ZkGGb#j_Gb#De f_`G G@BHbG4G@Zk4GPBXb$vHC4@(,#aH@HC(<@ZkC`@BHb$"4G@ZkpBCG@ZkGG(]0]8}@HP`#k#?$~4G0^8^@~HPXGG>G G޲( fCPb#_CGPb#_& B"0} Q}CC ](bCCGGGG@ZkGG b# _G b#De _`G GBbG4G@Zk4GBb$vHC4@0,#aH@HC0<@ZkC`Bb$"4G@ZkBCG@ZkGG0]8]@}HPX`#k#?$~tG(^0^8~@HP޴XGG>GGG G fCb#?_CGb#;_BCG@Zk=]"D BsH(b%?JCDCGGGG@ZkGG`b#_G`b#_BGb4G@ZkRG(]0]8}@HPݤX`#k4@GX DECC$TOLOWER4Hb# DECC$TOLOWER4T@X DECC$TOLOWER47G DECC$TOUPPER48b# DECC$TOUPPER47@ DECC$TOUPPER47G DECC$TOUPPER48b# DECC$TOUPPER47@ DECC$TOUPPERS41GX SYS$GETJPIW42@b# SYS$GETJPIW 41T@X SYS$GETJPIW4\Gp LIB$SIGNAL4`b# LIB$SIGNAL4l@p LIB$SIGNAL4xG LIB$SIGNAL4|b# LIB$SIGNAL4@ LIB$SIGNAL4 GT DECC$STRLEN4 @ DECC$STRLEN4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4 G DECC$STRCPY4 @ DECC$STRCPY4 UGD DECC$MALLOC44b#` DECC$MALLOC4@@D DECC$MALLOC4LG` LIB$SIGNAL4Pb#` LIB$SIGNAL4\@` LIB$SIGNAL41hG SYS$GETJPIW42pb#` SYS$GETJPIW41@ SYS$GETJPIW4G LIB$SIGNALV4b#` LIB$SIGNAL4@ LIB$SIGNAL4G LIB$SIGNAL4b#` LIB$SIGNAL4@ LIB$SIGNAL45GDECC$GXSPRINTF46b#`DECC$GXSPRINTF45@DECC$GXSPRINTF438GL SYS$SETPRV44@{#@ SYSW$SETPRV43H@L SYS$SETPRV43G SYS$SETPRV44{# SYS$SETPRV43@ SYS$SETPRV4 G DECC$MALLOC4 b# DECC$MALLOC4 @ DECC$MALLOC4 G LIB$SIGNAL4 b# LIB$SIGNAL4 @X LIB$SIGNAL41 GX SYS$GETJPIW42( b# SYS$GETJPIW41T @X SYS$GETJPIW4\ Gp LIB$SIGNAL4` b# LIB$SIGNAL4l @p LIB$SIGNAL4x G LIB$SIGNAL4| b# LIB$SIGNAL4 @ LIB$SIGNAL4Y G DECC$MALLOC4 b# DECC$MALLOC4 @ DECC$MALLOC4 G LIB$SIGNAL4 b# LIB$SIGNAL4 @ LIB$SIGNAL41 GX SYS$GETJPIW42( b# SYS$GETJPIW41T @X SYS$GETJPIW4\ Gp LIB$SIGNALZ4` b# LIB$SIGNAL4l @p LIB$SIGNAL4x G LIB$SIGNAL4| b# LIB$SIGNAL4 @ LIB$SIGNAL4 G DECC$MALLOC4 b# DECC$MALLOC4 @ DECC$MALLOC4G LIB$SIGNAL4b#[ LIB$SIGNAL4@ LIB$SIGNAL41 GX SYS$GETJPIW 42(b# SYS$GETJPIW41T@X SYS$GETJPIW4\Gp LIB$SIGNAL4`b# LIB$SIGNAL4l@p LIB$SIGNAL4xG LIB$SIGNAL4|b# LIB$SIGNAL4\@ LIB$SIGNAL4G DECC$MALLOC4b#P DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAL4b#P LIB$SIGNAL4@ LIB$SIGNAL41 GX SYS$GETJPIW42(b#P SYS$GETJPIW41T@X SYS$GETJPIW]4\Gp LIB$SIGNAL4`b#P LIB$SIGNAL4l@p LIB$SIGNAL4xG LIB$SIGNAL4|b#P LIB$SIGNAL4@ LIB$SIGNAL4%\Gp LIB$GET_EF4&`b# LIB$GET_EF4%l@p LIB$GET_EF4xG LIB^$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4'G SYS$ASSIGN4(b# SYS$ASSIGN4'@ SYS$ASSIGN4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G SYS$GETDVIW4 b#_ SYS$GETDVIW4 @ SYS$GETDVIW4G( LIB$SIGNAL4b# LIB$SIGNAL4$@( LIB$SIGNAL40GD LIB$SIGNAL44b# LIB$SIGNAL4@@D LIB$SIGNAL4%`G LIB$GET_EF4&hb# LIB$GET_EF4%`|@ LIB$GET_EF4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL,GtSYS$FAO,b#SYS$FAO,p@tSYS$FAO4xG LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4-aG SYS$BINTIM4.b# SYS$BINTIM4-@ SYS$BINTIM4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G SYS$SETIMR4b# SYS$SETIMR4@ SYS$SETIMR4G  LIB$SIGNAL4bb# LIB$SIGNAL4@  LIB$SIGNAL4  G$ DECC$STRLEN4  @$ DECC$STRLEN,/$GhSYS$QIO,04b#SYS$QIO,/d@hSYS$QIO4lG LIB$SIGNAL4pb# LIB$SIGNAL4|@ LIB$SIGNAL4ȷ~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2u|bcG SYS$WFLOR4b# SYS$WFLOR4@ SYS$WFLOR 4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4)G SYS$CLREF4*b# SYS$CLREF4)@ SYS$CLREF4G SYS$CANCELd4b# SYS$CANCEL4@ SYS$CANCEL4#G LIB$FREE_EF4$b# LIB$FREE_EF4#@ LIB$FREE_EF4!G SYS$DASSGN4" b# SYS$DASSGN4!@ SYS$DASSGN4$G4 LIB$SIGNAL4(b#e LIB$SIGNAL40@4 LIB$SIGNAL4+8GP SYS$CANTIM4,Hb# SYS$CANTIM4+L@P SYS$CANTIM4#PGd LIB$FREE_EF4$Xb# LIB$FREE_EF4#`@d LIB$FREE_EF4!hG| SYS$DASSGN4"pb# SYS$DASSGN4!xf@| SYS$DASSGN4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4gG LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G DECC$STRNCPY4 b# DECC$STRNCPY4@ DECC$STRNCPY4G DECC$MALLOC4b#` DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAhL4b#` LIB$SIGNAL4@ LIB$SIGNAL4 G0 DECC$STRLEN4 ,@0 DECC$STRLEN48Gd DECC$MALLOC4Db#` DECC$MALLOC4`@d DECC$MALLOC4tG LIB$SIGNAL4xb#` LIB$SIGNAL4@i LIB$SIGNAL4 G DECC$STRCPY4 @ DECC$STRCPY4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4GD DECC$MALLOC4 jb# DECC$MALLOC4@@D DECC$MALLOC4TGd LIB$SIGNAL4Xb# LIB$SIGNAL4`@d LIB$SIGNAL4lGOTS$ZERO4@OTS$ZERO4G DECC$FREE4b#0 DECC$FREE4@ DECC$FREE4kG  DECC$FREE4b#0 DECC$FREE4@  DECC$FREE 4G DECC$MALLOC4b#p DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAL4b#p LIB$SIGNAL4@ LIB$SIGNAL4 Gl DECC$STRCPY4 @ DECC$STRCPY4G0 DECC$STRCAT4(b#p DECC$STRCAT4,@0 DECC$STRCAT4G SYS$TRNLNM4b#P SYS$TRNLNM4@ SYS$TRNLNM44GH LIB$SIGNAL48b#P LIB$SIGNAL4Dm@H LIB$SIGNAL4PG| DECC$MALLOC4Tb#P DECC$MALLOC4x@| DECC$MALLOC4G LIB$SIGNAL4b#P LIB$SIGNAL4@ LIB$SIGNAL4 G DECC$STRCPY4 @ DECC$STRCPY4@G SYS$TRNLNM4n`b# SYS$TRNLNM4|@ SYS$TRNLNM4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAL4b# LIB$SIGNAoL4@ LIB$SIGNAL4 G( DECC$STRCPY4 $@( DECC$STRCPY4 G DECC$STRLEN4 @ DECC$STRLEN4 G SYS$CRELNM4b# SYS$CRELNM4 @ SYS$CRELNM48GL LIB$SIGNAL4@b#p LIB$SIGNAL4H@L LIB$SIGNAL@ @ =0 ;=0  DECC$TOLOWER=0 ;=0  DECC$FREE=0";=0 ; LIB$SIGNAL DECC$MALLOC DECC$STRLEN DECC$STRCPY=0( P;=q`|  SYS$CRELNM= LNM$PROCESS=00";=`<  SYS$TRNLNM=LNM$FILE_DEVP=0("T~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'D|X;=`< =0"`;=@<  DECC$STRCAT=0"(;= =0";=@< 8OTS$ZEROr SYS$SETIMRSYS$FAO SYS$WFLOR DECC$STRNCPY SYS$CANCEL= !UL !UL:!UL:!UL` SYS$GETDVIW=E.! SYS$DASSGN# LIB$FREE_EF=0";=  ;% LIB$GET_EF=(ųSYS$INPUT' SYS$ASSIGN) SYSs$CLREF+ SYS$CANTIM- SYS$BINTIM/SYS$QIO=0(";=P 1 SYS$GETJPIW=0(" ;=P =0(" ;=P =0(" ;=P =0( ;=0;=0;=0"`;= t 3 SYS$SETPRV=0";= =00";=P 5DECC$GXSPRINTF=%08.8X=08";=` =0 @;=0 7 DECC$TOUPPER=0 ;=0 6=66=6=  wwEERDEFTDEFYDELLDENTDENYDESKDIALDICEDIEDDIETDIMEDINEDINGDINTDIREDIRTDISCDISHDISKDIVEDOCKDOESDOLEDOLLDOLTDOMEDONEDOOMDOORDORADOSEDOTEDOUGDOURDOVEDOWNDRABDRAGDRAMDRAWDREWDRUBDRUGDRUMDUALDUCKDUCTDUELDUETDUKEDULLDUMBDUNEDUNKDUSKDUSTDUTYEACHEARLEARNEASEEASTEASYEBENECHOEDDYEDENEDGEEDGYEDITEDNAEGANELANELBAELLA =ELSEEMILEMITEMMAENDSERICEROSEVENEVEREVILEYEDFACEFACTFADEFAILFAINFAIRFAKEFALLFAMEv bC4G@ZkBCC@ZkBbCGGtG@ZkB bCCTG@ZkCGGb#:_$Hc.G!HScJA$@A!@A$@A$@a$@A!@A$@!@A!@A!@a$@v$HGP?@0BPBB!@ @0 @tHCtFc>b#_$Hc.C"!HTGA$@A!@A$@A$@a$@A!@A$@!@A!@A!@a$@v$HSrJP?@0BPBB!@ @0 @tHCtFc>Gb#_$Hc.C"!HGA$@A!@A$@A$@a$@A!@A$@!@A!@A!@a$@v$HSrJP?@0BPBB!@ @0 @tHCtFc>Gb#_ $HC.#"wLRQJCb#vH@D@@ @@sHGSFC>G_$HC.#"LCRQJb#vH@D@@ @@sH4GSFC>G_$H#."LQ0J#>Dc.C"GSrJvH@D@@ @@tHGtFc>]]}#kG#~^^ ~(08GGP.G GRPJP>.CBD@btGJ F@ZkBCbGTG@Zk@G]] }(08@#kG9 B B B!F k9BB B1D kB=B B1D xk k#Q"~^ ^(~08@޴HGG1,GG0 BR2HGJ'@GG_G D&@CqH.0@PJF>BZRZBRAF @bC.(BG0b4G@Zk$,"0@R0HGJ_@GC"CG"" /c/K[cKDaKaGc?0`@G. DJH&H"B0B_4GG] ](}08@ݤHP#k#~^^~޴> ^(~08@G ;G(GGyGC BG4G@Zk@ BG(bHF0@@ZkC$ GBGAbGGtG@Zk$, G GA$H$<G F ..UJ>TJ>.(J j#0" J/9Z[KGKYYC9!K G ,* @B4GHbPHJ@Zk 0@A*,*H?*. G(*J m"0 `.UJJTBJ G. #@B4GHbPJJ@Zk 0@A*,*H?*.*J D`.GB;#GTJ> 0@ALE}@Zk6@F7@z":_" GFGb#e_qG G_3,"P0HJ_ G0@B MBs"a`8DMBbC4G@ZkBCbCGtG@ZkB!b!CCTG@ZkpBCxb4G@ZkPBXbCCGtG@ZkBCbCTG@ZkCGtGb#_!0@GCGtGb#ـ@l_ p!A\GGGP@CTGb#_ө@@?pDCGTGb#_D0bC`CG4GC-#-IJCImII#I AEC= -E#=G@BG4G@ZkB{Gb@ZkGG]]}ݤ= ](}08@P#k#~^^~ (0޴8GGGGG{#_p¤Gb#CD GZ_CDGGGPb#_G]]} (0ݤ8@#k#4G~^^~ (Gp[Gx{G "@ZkCBb$"4G@Zkd  D _G G  G@ ?G]]G} (0#kG#~^^~G@[GGGG@Zk15@ |G Cn:@;#G0@ :_"[GFGb#__ "C_G GG_.3"0@B EBPJs"J_â8FPBXbC4G@ZkBbCCGtG@ZkB bCCTG@ZkàC5GBCb4G@ZkBbCCGtG@ZkBCbCTG@ZkCGtGb# _C@ 0B@G@Zk@¦CG`BGhb4G@ZkBC#@G6@Zkò4GG]]}#kG`#G}~ ^(^0~8@H޴PX`>h^p~x޵GGGGGGGG`GGGXBM@ =80`bTG@ZkCHBPbG@ZkG= G G G!?H=FGBCb?"GtG@Zk|= C CP_F_. J͢,#( /XKKWCJ GL/l#4GP[K8B@bJ@Zk 0A,,,H?,. G,J?l. ¥lJ`G #(¦ .֢~WJJVB֢J G-/M#@bP:K8B4GJ@Zk 0A-,-H?E?.ACxB3ABb%@ !CCGtGC@Zk C !C ,Gb#@ H <_  D- 0`A GI?¡ GD- 0@AI?G% 0 A- GI?}GBGb4GG@Zk! !0A!AE/0ADO0A3F0ATFpB4GEG ](]0}8@HݤPX`=h]p}xݥ#kdE&DZG#~^ ^(~08@޴HPXGGp.GGSpJp>.G.GJVJF>GCTGb#P@_ӡ@@?%נHGDFDCGtGb#_E@(BGG0b.@ZkD/ G(B0A0b@ZkD( A?B@bGTG@@ZkBG@bGTG@Zkp@Y@4GG] ](}08@ݤHPX`#k@GC?!!@G?!!@G8FkGGk kGp#G~Cp^(@x^G~GGdC\{#_@C0BG8b31B@a@ZkBC4G@ZkB0@b@ZkC`@B$"Hb4G@Zk0BCG@ZkGG_6B @Gp]x]G}#k44GH DECC$STRLEN4D@H DECC$STRLEN4HG\ DECC$STRLEN4X@\ DECC$STRLEN4\Gx DECC$MALLOC4db# DECC$MALLOC4t@x DECC$MALLOC4 G DECC$STRCPY4 @ DECC$STRCPY,GLC,b#LC,@LC4 G DECC$STRCAT4b# DECC$STRCAT4 @ DECC$STRCAT,GMD5INIT,b#MD5INIT,@MD5INIT4 G  MD5UPDATE4 b# MD5UPDATE4 @  MD5UPDATE4 G(MD5FINAL4b#MD5FINAL4$@(MD5FINAL,8GPMD4INIT,@b#M1 xV1.0CCSKEY_DBV1.0 5-FEB-1998 10:02DEC C V5.5-002  $ABS$id $CODE$C $LITERAL$$LINK$$DATA$x$BSS$ $READONLY_ADDR$ $READONLY$ DECC$STRCPY DECC$STRNCPY DECC$STRLEN DECC$FREE DECC$MALLOCDECC$GA_RMS_FABDECC$GA_RMS_RAB DECC$GA_RMS_XABKEY DECC$GA_RMS_XABPRO SYS$CLOSE SYS$CONNECT SYS$CREATE SYS$DELETESYS$DISCONNECTSYS$FREESYS$GET SYS$GETTIMSYS$OPENSYS$PUT LIB$SIGNAL0Jh DB_CREATE(JDB_OPEN0J@DB_FETCH(JxDB_PUT(JDB_NEW0Jp DB_CLOSE0J0  DB_DELETE(J( DB_FREESKEY_LOG SKEY$_NOUSERUCN TRNLNM_EXECOTS$MOVE =l d #4G~^^~ (0G[GG{GT"@ZkC$  `Bb0G@K@TG@Zk"C-@D`8BG4G@ZkBb0@@ZkC$ HBG@Zk¦G(BtGE0bB@Zk" BG?$D@Zk@&8B$ vH?&@@&Ţ s"@?$6vJBŲ"0@Zk8@%DT"8VK B9v?KD$C@@8 EG4G_FSB E(5JB%W@Zk B"ŲGD@$@Zkh"@ B8K H%$ !v H%7vJBQ"G@ZkCBb8KC@Zk"(BG0bG%@GtG@ZkBG%TGb@ZkxB@b4G@ZkG (B"G0bGtG@ZkBG`%TGb@ZkGG]]} (0@#k#4G~^^~ (0G[GG{GT"@ZkC$ `B" b@""CCTG@Zk"C-@D` BG4G@ZkBb0@@ZkC$ y0BG@Zk¦GBtGE0"bC@ZkB"GD@Zk@?$ B& vH?'@@?&Ţ 1"@&6vJ% BŲ0@Zk8DpBT"8VKD@8 'D@ G(Ee3`JtBeU@Zk%tŢ""GB6vJBtŲY@?'@Zk BC(b H$H8vKŢ6vJBŲ4G@Zk "GBGbG! CtG@ZkG`B@hb4G@ZkG BGbG CtG@ZkGG]]} (0@#k#4G~^^~ (0޴8@G[GG{GG"@ZkCBb$"4G@ZkBbGGGtG@ZkBGbGTG@ZkGG@p&G5vJ{qHBp9Jð_'7JBxðt8K#t;GpXC0Bj@8b4G@Zk PBGXbGp@GG@Zkpg$ B eD`pGG]G]} (0ݤ8@P#k#4G~^^~ (0GP[GGX{G"@ZkC@BHb$"4G@ZkBGGG@Zk0B@8bG4G@Zk`"BGbG8@tG@Zkp#& B&(b!v?HG0@p##j@4G1?J(B#|tc3v`JtBtcX@Zk`"GBGbG5@tG@ZkPBXbGpd4G@ZkG]G]} (0@#kG#4G~^^~ (G[G{GG@ZkCBb$"4G@Zk0BG8bGGtG@Zk B(bGGTG@ZkGGF@4G@\dGddhlpd`FVJqF0F0FB0FFF`DHLPTXG]]} (0#kG#4G~^^~ G0[GG8{ B@Zk B`@(b4G@ZkB4Gb@ZkBGb4G@ZkG]]} 0#k GG_ p.0@SpJp> @0BkGP.0@ @PJ0B@Bk#4G~^^~ (0G [GG({G"@ZkCBb$"4G@ZkXBGGG@Zkp#&0B&8b!v?HG6@p#㢄7JB|t#9v K0Ctj@X#4G@Zk0"G`BGhbG1@tG@Zk B(bGpd4G@ZkG]G]} (0@#kG# B~4G^G([0{@ZkG] #k4(GD DECC$MALLOC44b#h DECC$MALLOC4@@D DECC$MALLOC4\Gt TRNLNM_EXEC4`b#h TRNLNM_EXEC4p@t TRNLNM_EXEC4 G DECC$STRLEN4 @ DECC$STRLEN4G DECC$MALLOC4b#h DECC$MALLOC4@ DECC$MALLOC4G DECC$STRCPY4@ DECC$STRCPY4 GSKEY_LOG4 b#hSKEY_LOG4 @SKEY_LOG4 G OTS$MOVE 4 @ OTS$MOVE4 G\ DECC$STRLEN4 X@\ DECC$STRLEN4 tGOTS$MOVE4 @OTS$MOVE4 GOTS$MOVE4 @OTS$MOVE4 G@OTS$MOVE4 <@@OTS$MOVE4HG` SYS$CREATE4Lb#h SYS$CREATE4\@` SYS$CREATE4 hGSKEY_LOG4 pb#hSKEY_LOG4 @SKEY_LOG4G LIB$SIGNAL4b#h LIB$SIGNAL4@ LIB$SIGNAL4G SYS$CONNECT4b#h SYS$CONNECT4@ SYS$CONNECT4 GSKEY_LOG4 b#hSKEY_LOG4 @SKEY_LOG4G LIB$SIGNAL4b#h LIB$SIGNAL4@ LIB$SIGNAL4@G\ DECC$MALLOC4Lb# DECC$MALLOC4X@\ DECC$MALLOC4tG TRNLNM_EXEC4|b# TRNLNM_EXEC4@ TRNLNM_EXEC4 G DECC$STRLEN4 @ DECC$STRLEN4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4G DECC$STRCPY4@ DECC$STRCPY4 GSKEY_LOG4 b#SKEY_LOG4 @SKEY_LOG4 G,OTS$MOVE4 (@,OTS$MOVE4 4G| DECC$STRLEN4 x@| DECC$STRLEN4 GOTS$MOVE4 @OTS$MOVE4 GOTS$MOVE4 @OTS$MOVE4'GLSYS$OPEN4(b#SYS$OPEN4'H@LSYS$OPEN4 XGxSKEY_LOG4 `b#SKEY_LOG4 t@xSKEY_LOG4G SYS$CONNECT4b# SYS$CONNECT4@ SYS$CONNECT4 GSKEY_LOG4 b#SKEY_LOG4 @SKEY_LOG4G8 DECC$MALLOC4$b#@ DECC$MALLOC44@8 DECC$MALLOC4<GT LIB$SIGNAL4Db#@ LIB$SIGNAL4P@T LIB$SIGNAL4TGp DECC$STRNCPY4 Xb#@ DECC$STRNCPY4l@p DECC$STRNCPY,pGUCN,xb#@UCN,@UCN,%GSYS$GET,&b#@SYS$GET,%@SYS$GET4 G,SKEY_LOG 4 b#@SKEY_LOG4 (@,SKEY_LOG4G DECC$MALLOC4b# DECC$MALLOC4@ DECC$MALLOC4G LIB$SIGNAL4b# LIB$SIGNAL4@ LIB$SIGNAL4 GOTS$MOVE4 @OTS$MOVE4#G SYS$GETTIM4$b# SYS$GETTIM4#@ SYS$GETTIM4 G$SKEY_LOG4 b#SKEY_LOG4  @$SKEY_LOG,!,GSYS$PUT,"4b#SYS$PUT,!|@SYS$PUT4 GSKEY_LOG4 b#SKEY_LOG4 @SKEY_LOG4G DECC$FREE4b# DECC$FREE4@ DECC$FREE4 G$ DECC$MALLOC4 b# DECC$MALLOC4 @$ DECC$MALLOC4, G@ LIB$SIGNAL40 b# LIB$SIGNAL4< @@ LIB$SIGNAL4@ G\ DECC$STRNCPY4 H b# DECC$STRNCPY4X @\ DECC$STRNCPY,\ Gt UCN,` b#UCN,p @t UCN4( G@ SYS$DISCONNECT44 b#pSYS$DISCONNECT4< @@ SYS$DISCONNECT4@ GT SYS$CLOSE4H b#p SYS$CLOSE4P @T SYS$CLOSE4T Gh DECC$FREE4` b#p DECC$FREE4d @h DECC$FREE4h G| DECC$FREE4p b#p DECC$FREE4x @| DECC$FREE4 G4 DECC$MALLOC4$ b#0 DECC$MALLOC40 @4 DECC$MALLOC4< GP LIB$SIGNAL4@ b#0 LIB$SIGNAL4L @P LIB$SIGNAL4 P Gd OTS$MOVE4 ` @d OTS$MOVE4l G SYS$DELETE4t b#0 SYS$DELETE4 @ SYS$DELETE4  G SKEY_LOG4  b#0SKEY_LOG4  @ SKEY_LOG4 G DECC$FREE4 b#0 DECC$FREE4 @ DECC$FREE4D GP SYS$FREE4H {#SYS$FREE4L @P SYS$FREE_ _=0#DB_Create: connect status = 0x!XL(=0"DB_Create: create status = 0x!XLP= DB_Create: file=!AZh=(sys$common:[sysexe]skey.db=(DB_Delete: status = 0x!XL= DB_Put status = 0x!XL=(DB_Put gettim status = 0x!XL=@7DB_Fetch('!AZ') status = 0x!XLdb connect status !XL= db open status !XL0=DB_Open: file=!AZS  7DECC$GA_RMS_XABKEY7DECC$GA_RMS_FAB SYS$CREATE TRNLNM_EXEC=SKEY_DATABASE@ LIB$SIGNAL DECC$MALLOC;=0";=@< 8OTS$MOVE SKEY_LOG DECC$STRLEN DECC$STRCPY= LNM$SYSTEM7DECC$GA_RMS_XABPRO SYS$CONNECT7DECC$GA_RMS_RAB=0"( ;=  SYS$FREE=0" ;=@<  DECC$FREE SYS$DELETE=0  ;=0  SYS$CLOSESYS$DISCONNECT=0 ;=0";=0 UCN DECC$STRNCPY=0"x;=@< !SYS$PUT# SYS$GETTIM=0";=P 7 SKEY$_NOUSERp%SYS$GET=0";=@< 'SYS$OPEN hww (@, DECC$STRCAT4A@G` DECC$STRNCAT4BHb# DECC$STRNCAT4A\@` DECC$STRNCAT4 `Gx DEC H~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2H|C$STRCAT4hb# DECC$STRCAT4 t@x DECC$STRCAT4AG DECC$STRNCAT4Bb# DECC$STRNCAT4A@ DECC$STRNCAT4 G DECC$STRCAT4b# DECC$STRCAT4 @ DECC$STRCAT4AG DECC$STRNCAT4Bb# DECC$STRNCAT4A@ DECC$STRNCAT4 G DECC$STRCAT4b# DECC$STRCAT4  @ DECC$STRCAT4A$GD DECC$STRNCAT4B,b# DECC$STRNCAT4A@@D DECC$STRNCAT4 DG\ DECC$STRCAT4Hb# DECC$STRCAT4 X@\ DECC$STRCAT4ApG DECC$STRNCAT4Bxb# DECC$STRNCAT4A@ DECC$STRNCAT4G( DECC$STRLEN4$@( DECC$STRLEN4,GD DECC$MALLOC44b# DECC$MALLOC4@@D DECC$MALLOC4-XGx DECC$STRNCPY4.db# DECC$STRNCPY4-t@x DECC$STRNCPY4'G  DECC$ISALPHA4(b# DECC$ISALPHA4'@  DECC$ISALPHA47G DECC$ISLOWER48b# DECC$ISLOWER47@ DECC$ISLOWER45G DECC$TOUPPER46b# DECC$TOUPPER45@ DECC$TOUPPER4' G0 DECC$ISALPHA4( b# DECC$ISALPHA4', @0 DECC$ISALPHA4` G DECC$STRLEN4 @ DECC$STRLEN4 G OTS$ZERO4 @ OTS$ZERO4 G DECC$FREE4 b# DECC$FREE4 @ DECC$FREE4#$ G\ DECC$STRNCMP4$D b#0 DECC$STRNCMP4#X @\ DECC$STRNCMP4# G DECC$STRNCMP4$ b#0 DECC$STRNCMP4# @ DECC$STRNCMP4# G DECC$STRNCMP4$ b#0 DECC$STRNCMP4# @ DECC$STRNCMP4\ G DECC$__ASSERT4  b#p DECC$__ASSERT 4 @ DECC$__ASSERT4 G DECC$__ASSERT4  b#p DECC$__ASSERT4 @ DECC$__ASSERT4 G DECC$__ASSERT4  b#p DECC$__ASSERT4 @ DECC$__ASSERT4 G DECC$__ASSERT4  b#p DECC$__ASSERT4 @ DECC$__ASSERT4G DECC$__ASSERT4 b#p DECC$__ASSERT4@ DECC$__ASSERT4G  DECC$__ASSERT4 b#p DECC$__ASSERT4@  DECC$__ASSERT4$G@ DECC$__ASSERT4 (b#p DECC$__ASSERT4<@@ DECC$__ASSERT4$G4 DECC$MALLOC4,b# DECC$MALLOC40@4 DECC$MALLOC4<GP LIB$SIGNAL4@b# LIB$SIGNAL4L@P LIB$SIGNAL49PGh DECC$TIME4:Xb# DECC$TIME49d@h DECC$TIME4!hG| DECC$CLOCK4"pb# DECC$CLOCK4!x@| DECC$CLOCK4|GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4;G DECC$CTIME4<b# DECC$CTIME4;@ DECC$CTIME4 G DECC$STRCAT4b# DECC$STRCAT4 @ DECC$STRCAT4?GUSERNAME4@b#USERNAME4?@USERNAME4 G DECC$STRCAT4b# DECC$STRCAT4 @ DECC$STRCAT4G  DECC$FREE4b# DECC$FREE4@  DECC$FREE,= GPID,>b#PID,=@PID4 G8 DECC$STRCAT4$b# DECC$STRCAT4 4@8 DECC$STRCAT48GL DECC$FREE4@b# DECC$FREE4H@L DECC$FREE,LGdMD5INIT,Tb#MD5INIT,`@dMD5INIT4dGt DECC$STRLEN4p@t DECC$STRLEN4 tG MD5UPDATE4 xb# MD5UPDATE4 @ MD5UPDATE4GMD5FINAL4b#MD5FINAL4@MD5FINAL4GDECC$GXSPRINTF4b#p~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|DECC$GXSPRINTF4@DECC$GXSPRINTF4 G DECC$STRCAT4b#p DECC$STRCAT4 @ DECC$STRCAT43G DECC$ISSPACE44b# DECC$ISSPACE43@ DECC$ISSPACE4PG` DECC$STRLEN 4\@` DECC$STRLEN4dG| DECC$MALLOC4lb# DECC$MALLOC4x@| DECC$MALLOC4-G DECC$STRNCPY4.b# DECC$STRNCPY4-@ DECC$STRNCPY4'@GX DECC$ISALPHA4(Hb# DECC$ISALPHA4'T@X DECC$ISALPHA4'G DECC$ISALPHA4(b# DECC$ISALPHA4'@ DECC$ISALPHA4G, DECC$STRLEN4(@, DECC$STRLEN,GMD5INIT,b#MD5INIT,@MD5INIT4 G MD5UPDATE4 b# MD5UPDATE4 @ MD5UPDATE4GMD5FINAL4b#MD5FINAL4@MD5FINAL,G MD4INIT,b#MD4INIT,@ MD4INIT4 G( MD4UPDATE4b# MD4UPDATE4$@( MD4UPDATE4(G@MD4FINAL40b#MD4FINAL4<@@MD4FINAL4 G0OTS$ZERO4,@0OTS$ZERO40G@ DECC$FREE48b# DECC$FREE4<@@ DECC$FREE4TGl DECC$MALLOC4\b#P DECC$MALLOC4h@l DECC$MALLOC4tG LIB$SIGNAL4xb#P LIB$SIGNAL4@ LIB$SIGNAL4 G$ DECC$STRLEN4 @$ DECC$STRLEN,GMD5INIT,b#`MD5INIT,@MD5INIT4 G MD5UPDATE4 b#` MD5UPDATE4 @ MD5UPDATE4GMD5FINAL4b#`MD5FINAL4@MD5FINAL,(G<MD4INIT,0b#`MD4INIT,8@<MD4INIT4<GX MD4UPDATE4@b#` MD4UPDATE4T@X MD4UPDATE4XGpMD4FINAL4`b#`MD4FINAL4l@pMD4FINAL4%G DECC$STRCMP4%@ DECC$STRCMP4G DECC$MALLOC4b#` DECC$MALLOC4@ DECC$MALLOC4 G DECC$STRCPY4 @ DECC$STRCPY4+G DECC$FOPEN4,b# DECC$FOPEN4+@ DECC$FOPEND)GCMA$TIS_VMSERRNO_GET_ADDRD*b#CMA$TIS_VMSERRNO_GET_ADDRD)@CMA$TIS_VMSERRNO_GET_ADDR41 G, DECC$FGETS42 b# DECC$FGETS 41( @, DECC$FGETS4' G DECC$ISALPHA4( b# DECC$ISALPHA4' @ DECC$ISALPHA4((!b# DECC$ISALPHA4'0!G@! DECC$ISALPHA4'@Zk@BHbCC@Zke=BGtGb2v H@ZkBCb4G@Zk4GUGBCb4G@Zk4GBb@Zk0BG4G@ZkB0@b@ZkC$ ;GpBG@Zk@BCHbCTG@Zk/G%vHBQ.QJDF`EF@0BG@@Zk @.JG.wJ0 @VJF>8vK 8@B`BChbGGG@ZkBbGC4G@ZkGG ](]0}8@HP#kG#G~4G^G [({@ZkG] #kG#_&~G^4GG`[G^@ZkvH AC =5J(aF@ZkG] #kG#?$~&^TG ^(~08G[G>~G@ZkݢxHBCbC7JF@ZkG =4GBb!v H4 @!!HC@ZkC]tG B =(b2v@J@Zkc vH`@.PJ>PBCXb4G@ZkGCG] ]G(}08@#kG"0.G0J0BX$F p."0BStJgJ`XdF.J0BXF !/{aJP"Y!K;G!?,0 @0BSHgJ.TJ>k4<Gp DECC$STRCMP4l@p DECC$STRCMP4 tG CLI$GET_VALUE4 xb#` CLI$GET_VALUE4 @ CLI$GET_VALUE4G DECC$STRNCMP4b#` DECC$STRNCMP4@ DECC$STRNCMP4G STR$FREE1_DX4b#` STR$FREE1_DX4@ STR$FREE1_DX4G STR$FREE1_DX4b#` STR$FREE1_DX4@ STR$FREE1_DX4G DECC$FREE4b#` DECC$FREE4@ DECC$FREE4 G DECC$STRLEN4  @ DECC$STRLEN4G  DECC$MALLOC4b#` DECC$MALLOC4@  DECC$MALLOC48GH DECC$STRCPY4D@H DECC$STRCPY4 HG` CLI$GET_VALUE4 Pb#` CLI$GET_VALUE4 \@` CLI$GET_VALUE4 G DECC$STRLEN4 @ DECC$STRLEN4 G CLI$DCL_PARSE4b#` CLI$DCL_PARSE4 @ CLI$DCL_PARSE4G STR$FREE1_DX4b#` STR$FREE1_DX4@ STR$FREE1_DX4dGp CLI$DISPATCH4h{#` CLI$DISPATCH4l@p CLI$DISPATCH4 G DECC$STRLEN4 @ DECC$STRLEN4G CLI$PRESENT4a#0 CLI$PRESENT4@ CLI$PRESENT4 $G@ DECC$STRLEN4 <@@ DECC$STRLEN4 HGh CLI$GET_VALUE4 Pb# CLI$GET_VALUE4 d@h CLI$GET_VALUE4xG DECC$MALLOC4|b# DECC$MALLOC4@ DECC$MALLOC4G DECC$STRNCPY4b# DECC$STRNCPY4@ DECC$STRNCPY 4G STR$FREE1_DX4b# STR$FREE1_DX4@ STR$FREE1_DX  DECC$STRNCMP DECC$MALLOC=$LINE0 DECC$STRCMP7 LIB$GET_INPUTP STR$FREE1_DX=0 #;=P< ; DECC$STRLEN CLI$GET_VALUE=$VERB CLI$DCL_PARSE DECC$STRCPY DECC$FREE=0 ;=0#;=@  DECC$STRNCPY=0#;=  CLI$PRESENT=0#H;=  CLI$DISPATCH$ $=   `wwG gC({K_"@Zk B(bK@0"L_"tG@Zk B(bI@0"M_"tG@Zk@DDw@Hb@" B."",.BJHJD DECC$TOUPPER45@ DECC$TOUPPER4' G0 DECC$ISALPHA4( b# DECC$ISALPHA4', @0 DECC$ISALPHA4` G DECC$STRLEN4 @ DECC$STRLEN4 G OTS$ZERO4 @ OTS$ZERO4 G DECC$FREE4 b# DECC$FREE4 @ DECC$FREE4#$ G\ DECC$STRNCMP4$D b#0 DECC$STRNCMP4#X @\ DECC$STRNCMP4# G DECC$STRNCMP4$ b#0 DECC$STRNCMP4# @ DECC$STRNCMP4# G DECC$STRNCMP4$ b#0 DECC$STRNCMP4# @ DECC$STRNCMP4\ G DECC$__ASSERT4  b#p DECC$__ASSERT 4 @ DECC$__ASSERT4 G DECC$__ASSERT4  b#p DECC$__ASSERT4 @ DECC$__ASSERT4 G DECC$__ASSERT4  b#p DECC$__ASSERT4 @ DECC$__ASSERT4 G DECC$__ASSERT4  b#p DECC$__ASSERT4 @ DECC$__ASSERT4G DECC$__ASSERT4 b#p DECC$__ASSERT4@ DECC$__ASSERT4G  DECC$__ASSERT4 b#p DECC$__ASSERT4@  DECC$__ASSERT4$G@ DECC$__ASSERT4 (b#p DECC$__ASSERT4<@@ DECC$__ASSERT4$G4 DECC$MALLOC4,b# DECC$MALLOC40@4 DECC$MALLOC4<GP LIB$SIGNAL4@b# LIB$SIGNAL4L@P LIB$SIGNAL49PGh DECC$TIME4:Xb# DECC$TIME49d@h DECC$TIME4!hG| DECC$CLOCK4"pb# DECC$CLOCK4!x@| DECC$CLOCK4|GDECC$GXSPRINTF4b#DECC$GXSPRINTF4@DECC$GXSPRINTF4;G DECC$CTIME4<b# DECC$CTIME4;@ DECC$CTIME4 G DECC$STRCAT4b# DECC$STRCAT4 @ DECC$STRCAT4?GUSERNAME4@b#USERNAME4?@USERNAME4 G DECC$STRCAT4b# DECC$STRCAT4 @ DECC$STRCAT4G  DECC$FREE4b# DECC$FREE4@  DECC$FREE,= GPID,>b#PID,=@PID4 G8 DECC$STRCAT4$b# DECC$STRCAT4 4@8 DECC$STRCAT48GL DECC$FREE4@b# DECC$FREE4H@L DECC$FREE,LGdMD5INIT,Tb#MD5INIT,`@dMD5INIT4dGt DECC$STRLEN4p@t DECC$STRLEN4 tG MD5UPDATE4 xb# MD5UPDATE4 @ MD5UPDATE4GMD5FINAL4b#MD5FINAL4@MD5FINAL4GDECC$GXSPRINTF4b#pDECC$GXSPRINTF4@DECC$GXSPRINTF4 G DECC$STRCAT4b#p DECC$STRCAT4 @ DECC$STRCAT43G DECC$ISSPACE44b# DECC$ISSPACE43@ DECC$ISSPACE4PG` DECC$STRLEN 4\@` DECC$STRLEN4dG| DECC$MALLOC4lb# DECC$MALLOC4x@| DECC$MALLOC4-G DECC$STRNCPY4.b# DECC$STRNCPY4-@ DECC$STRNCPY4'@GX DECC$ISALPHA4(Hb# DECC$ISALPHA4'T@X DECC$ISALPHA4'G DECC$ISALPHA4(b# DECC$ISALPHA4'@ DECC$ISALPHA4G, DECC$STRLEN4(@, DECC$STRLEN,GMD5INIT,b#MD5INIT,@MD5INIT4 G MD5UPDATE4 b# MD5UPDATE4 @ MD5UPDATE4GMD5FINAL4b#MD5FINAL4@MD5FINAL,G MD4INIT,b#MD4INIT,@ MD4INIT4 G( MD4UPDATE4b# MD4UPDATE4$@( MD4UPDATE4(G@MD4FINAL40b#MD4FINAL4<@@MD4FINAL4 G0OTS$ZERO4,@0OTS$ZERO40G@ DECC$FREE48b# DECC$FREE4<@@ DECC$FREE4TGl DECC$MALLOC4\b#P DECC$MALLOC4h@l DECC$MALLOC4tG LIB$SIGNAL4xb#P LIB$SIGNAL4@ LIB$SIGNAL4 G$ DECC$STRLEN4 @$ DECC$STRLEN,GMD5INIT,b#`MD5INIT,@MD5INIT4 G MD5UPDATE4 b#` MD5UPDATE4 @ MD5UPDATE4GMD5FINAL4b#`MD5FINAL4@MD5FINAL,(G<MD4INIT,0b#`MD4INIT,8@<MD4INIT4<GX MD4UPDATE4@b#` MD4UPDATE4T@X MD4UPDATE4XGpMD4FINAL4`b#`MD4FINAL4l@pMD4FINAL4%G DECC$STRCMP4%@ DECC$STRCMP4G :d~ SKEY009.A} e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_AXPNDB.OLB;2h DECC$MALLOC4b#` DECC$MALLOC4@ DECC$MALLOC4 G DECC$STRCPY4 @ DECC$STRCPY4+G DECC$FOPEN4,b# DECC$FOPEN4+@ DECC$FOPEND)GCMA$TIS_VMSERRNO_GET_ADDRD*b#CMA$TIS_VMSERRNO_GET_ADDRD)@CMA$TIS_VMSERRNO_GET_ADDR41 G, DECC$FGETS42 b# DECC$FGETS 41( @, DECC$FGETS4' G DECC$ISALPHA4( b# DECC$ISALPHA4' @ DECC$ISALPHA4((!b# DECC$ISALPHA4'0!G@! DECC$ISALPHA4'= 0= start >= 0=0"#;=` ! DECC$CLOCK= 7SKEY$_PARTDICT=0;=0" ;=P # DECC$STRNCMP=0";=< 7 SKEY$_INVALT% DECC$STRCMP7 SKEY$_DUPALT=0 " ;= 7DECC$$GL___CTYPEA7DECC$$GA___CTYPET' DECC$ISALPHA()CMA$TIS_VMSERRNO_GET_ADDR+ DECC$FOPEN=r - DECC$STRNCPY/ DECC$FCLOSE1 DECC$FGETS=0"0;=0 =0 ( ;=(P length <= 11=0";=P? 7 SKEY$_BADENC7 SKEY$_VOIDPWD7 SKEY$_PARITY=0"P;=P| 3 DECC$ISSPACE=0";= 5 DECC$TOUPPER7 DECC$ISLOWER=0";=@| =0 P;= @< %02X=0";=(< %ld9 DECC$TIME; DECC$CTIME=PID?USERNAME=0"@;=P< A DECC$STRNCAT=0";=  =A6=ABEACEACTADADAADDAGOAIDAIMAIRALLALPAMAMYANANAANDANNANTANYAPEAPSAPTARCAREARKARMARTASASHASKATATEAUGAUKAVEAWEAWKAWLAWNAXAYEBADBAGBAHBAMBANBARBATBAYBEBEDBEEBEGBENBETBEYBIBBIDBIGBINBITBOBBOGBONBOOBOPBOWBOYBUBBUDBUGBUMBUNBUSBUTBUYBYBYECABCALCAMCANCAPCARCATCAWCODCOGCOLCONCOOCOPCOTCOWCOYCRYCUBCUECUPCURCUTDABDADDAMDANDARDAYDEEDELDENDESDEWDIDDIEDIGDINDIPDODOEDOGDONDOTDOWDRYDUBDUDDUEDUGDUNEAREATEDEELEGGEGOELIELKELMELYEMENDESTETCEVAEVEEWEEYEFADFANFARFATFAYFEDFEEFEWFIBFIGFINFIRFITFLOFLYFOEFOGFORFRYFUMFUNFURGABGADGAGGALGAMGAPGASGAYGEEGELGEMGETGIGGILGINGOGOTGUMGUNGUSGUTGUYGYMGYPHAHADHALHAMHAQ!~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'b|ENHAPHASHATHAWHAYHEHEMHENHERHEWHEYHIHIDHIMHIPHISHITHOHOBHOCHOEHOGHOPHOTHOWHUBHUEHUGHUHHUMHUTI6= ICYIDAIFIKEILLINKINNIOIONIQIRAIREIRKISITITSIVYJABJAGJAMJANJARJAWJAYJETJIGJIMJOJOBJOEJOGJOTJOYJUGJUTKAYKEGKENKEYKIDKIMKINKITLALABLACLADLAGLAMLAPLAWLAYLEALEDLEELEGLENLEOLETLEWLIDLIELINLIPLITLOLOBLOGLOPLOSLOTLOULOWLOYLUGLYEMAMACMADMAEMANMAOMAPMATMAWMAYMEMEGMELMENMETMEWMIDMINMITMOBMODMOEMOOMOPMOSMOTMOWMUDMUGMUMMYNABNAGNANNAPNATNAYNENEDNEENETNEWNIBNILNIPNITNONOBNODNONNORNOTNOVNOWNUNUNNUTO6= OAFOAKOAROATODDODEOFOFFOFTOHOILOKOLDONONEORORBOREORROSOTTOUROUTOVAOWOWEOWLOWNOXPAPADPALPAMPANPAPPARPATPAWPAYPEAPEGPENPEPPERPETPEWPHIPIPIEPINPITPLYPOPODPOEPOPPOTPOWPROPRYPUBPUGPUNPUPPUTQUORAGRAMRANRAPRATRAWRAYREBREDREPRETRIBRIDRIGRIMRIORIPROBRODROERONROTROWROYRUBRUERUGRUMRUNRYESACSADSAGSALSAMSANSAPSATSAWSAYSEASECSEESENSETSEWSHESHYSINSIPSIRSISSITSKISKYSLYSOSOBSODSONSOPSOWSOYSPASPYSUBSUDSUESUMSUNSUPTABTADTAGTANTAPTARTEATEDTEETENTHETHYTICTIETIMTINTIPTOTOETOGTOMTONTOOTOPTOWTOYTRYTUBTUGTUMTUNTWOUNUPUSUSEVANVATVETVIEWADWAGWARWASWAYWEWEBWEDWEEWETWHOWHYWINWITWOKWONWOOWOWWRYWUYAMYAPYAWYEYEAYESYETYOUABEDABELABETABLEABUTACHEACIDACMEACREACTAACTSADAMADDSADENAFARAFROAGEEAHEMAHOYAIDAAIDEAIDSAIRYAJARAKINALANALECALGAALIAALLYALMAALOEALSOALTOALUMALVAAMENAMESAMIDAMMOAMOKAMOSAMRAANDYANEWANNAANNEANTEANTIAQUAARABARCHAREAARGOARIDARMYARTSARTYASIAASKSATOMAUNTAURAAUTOAVERAVIDAVISAVONAVOWAWAYAWRYBABEBABYBACHBACKBADEBAILBAITBAKEBALDBALEBALIBALKBALLBALMBANDBANEBANGBANKBARBBARDBAREBARKBARNBARRBASEBASHBASKBASSBATEBATHBAWDBAWLBEADBEAKBEAMBEANBEARBEATBEAUBECKBEEFBEENBEERBEETBELABELLBELTBENDBENTBERGBERNBERTBESSBESTBETABETHBHOYBIASBIDEBIENBILEBILKBILLBINDBINGBIRDBITEBITSBLABBLATBLEDBLEWBLOBBLOCBLOTBLOWBLUEBLUMBLURBOARBOATBOCABOCKBODEBODYBOGYBOHRBOILBOLDBOLOBOLTBOMBBONABONDBONEBONGBONNBONYBOOKBOOMBOONBOOTBOREBORGBORNBOSEBOSSBOTHBOUTBOWLBOYDBRADBRAEBRAGBRANBRAYBREDBREWBRIGBRIMBROWBUCKBUDDBUFFBULBBULKBULLBUNKBUNTBUOYBURGBURLBURNBURRBURTBURYBUSHBUSSBUSTBUSYBYTECADYCAFECAGECAINCAKECALFCALLCALMCAMECANECANTCARDCARECARLCARRCARTCASECASHCASKCASTCAVECEILCELLCENTCERNCHADCHARCHATCHAWCHEFCHENCHEWCHICCHINCHOUCHOWCHUBCHUGCHUMCITECITYCLADCLAMCLANCLAWCLAYCLODCLOGCLOTCLUBCLUECOALCOATCOCACOCKCOCOCODACODECODYCOEDCOILCOINCOKECOLACOLDCOLTCOMACOMBCOMECOOKCOOLCOONCOOTCORDCORECORKCORNCOSTCOVECOWLCRABCRAGCRAMCRAYCREWCRIBCROWCRUDCUBACUBECUFFCULLCULTCUNYCURBCURDCURECURLCURTCUTSDADEDALEDAMEDANADANEDANGDANKDAREDARKDARNDARTDASHDATADATEDAVEDAVYDAWNDAYSDEADDEAFDEALDEANDEARDEBTDECKDEEDDEEMDEERDEFTDEFYDELLDENTDENYDESKDIALDICEDIEDDIETDIMEDINEDINGDINTDIREDIRTDISCDISHDISKDIVEDOCKDOESDOLEDOLLDOLTDOMEDONEDOOMDOORDORADOSEDOTEDOUGDOURDOVEDOWNDRABDRAGDRAMDRAWDREWDRUBDRUGDRUMDUALDUCKDUCTDUELDUETDUKEDULLDUMBDUNEDUNKDUSKDUSTDUTYEACHEARLEARNEASEEASTEASYEBENECHOEDDYEDENEDGEEDGYEDITEDNAEGANELANELBAELLA =ELSEEMILEMITEMMAENDSERICEROSEVENEVEREVILEYEDFACEFACTFADEFAILFAINFAIRFAKEFALLFAMEFANGFARMFASTFATEFAWNFEARFEATFEEDFEELFEETFELLFELTFENDFERNFESTFEUDFIEFFIGSFILEFILLFILMFINDFINEFINKFIREFIRMFISHFISKFISTFITSFIVEFLAGFLAKFLAMFLATFLAWFLEAFLEDFLEWFLITFLOCFLOGFLOWFLUBFLUEFOALFOAMFOGYFOILFOLDFOLKFONDFONTFOODFOOLFOOTFORDFOREFORKFORMFORTFOSSFOULFOURFOWLFRAUFRAYFREDFREEFRETFREYFROGFROMFUELFULLFUMEFUNDFUNKFURYFUSEFUSSGAFFGAGEGAILGAINGAITGALAGALEGALLGALTGAMEGANGGARBGARYGASHGATEGAULGAURGAVEGAWKGEARGELDGENEGENTGERMGETSGIBEGIFTGILDGILLGILTGINAGIRDGIRLGISTGIVEGLADGLEEGLENGLIBGLOBGLOMGLOWGLUEGLUMGLUTGOADGOALGOATGOERGOESGOLDGOLFGONEGONGGOODGOOFGOREGORYGOSHGOUTGOWNGRABGRADGRAYGREGGREWGREYGRIDGRIMGRINGRITGROWGRUBGULFGULLGUNKGURUGUSHGUSTGWENGWYNHAAGHAASHACKHAILHAIRHALEHALFHALLHALOHALTHANDHANGHANKHANSHARDHARKHARMHARTHASHHASTHATEHATHHAULHAVEHAWKHAYSHEADHEALHEARHEATHEBEHECKHEEDHEELHEFTHELDHELLHELMHERBHERDHEREHEROHERSHESSHEWNHICKHIDEHIGHHIKEHILLHILTHINDHINTHIREHISSHIVEHOBOHOCKHOFFHOLDHOLEHOLMHOLTHOMEHONEHONKHOODHOOFHOOKHOOTHORNHOSEHOSTHOURHOVEHOWEHOWLHOYTHUCKHUEDHUFFHUGEHUGHHUGOHULKHULLHUNKHUNTHURDHURLHURTHUSHHYDEHYMNIBISICONIDEAIDLEIFFYINCAINCHINTOIONSIOTAIOWAIRISIRMAIRONISLEITCHITEMIVANJACKJADEJAILJAKEJANEJAVAJEANJEFFJERKJESSJESTJIBEJILLJILTJIVEJOANJOBSJOCKJOELJOEYJOHNJOINJOKEJOLTJOVEJUDDJUDEJUDOJUDYJUJUJUKEJULYJUNEJUNKJUNOJURYJUSTJUTEKAHNKALEKANEKANTKARLKATEKEELKEENKENOKENTKERNKERRKEYSKICKKILLKINDKINGKIRKKISSKITEKLANKNEEKNEWKNITKNOBKNOTKNOWKOCHKONGKUDOKURDKURTKYLELACELACKLACYLADYLAIDLAINLAIRLAKELAMBLAMELANDLANELANGLARDLARKLASSLASTLATELAUDLAVALAWNLAWSLAYSLEADLEAFLEAKLEANLEARLEEKLEERLEFTLENDLENSLENTLEONLESKLESSLESTLETSLIARLICELICKLIEDLIENLIESLIEULIFELIFTLIKELILALILTLILYLIMALIMBLIMELINDLINELINKLINTLIONLISALISTLIVELOADLOAFLOAMLOANLOCKLOFTLOGELOISLOLALONELONGLOOKLOONLOOTLORDLORELOSELOSSLOSTLOUDLOVELOWELUCKLUCYLUGELUKELULULUNDLUNGLURALURELURKLUSHLUSTLYLELYNNLYONLYRAMACEMADEMAGIMAIDMAILMAINMAKEMALEMALIMALLMALTMANAMANNMANYMARCMAREMARKMARSMARTMARYMASHMASKMASSMASTMATEMATHMAULMAYOMEADMEALMEANMEATMEEKMEETMELDMELTMEMOMENDMENUMERTMESHMESSMICEMIKEMILDMILEMILKMILLMILTMIMIMINDMINEMINIMINKMINTMIREMISSMISTMITEMITTMOANMOATMOCKMODEMOLDMOLEMOLLMOLTMONAMONKMONTMOODMOONMOORMOOTMOREMORNMORTMOSSMOSTMOTHMOVEMUCHMUCKMUDDMUFFMULEMULLMURKMUSHMUSTMUTEMUTTMYRAMYTHNAGYNAILNAIRNAMENARYNASHNAVENAVYNEALNEARNEATNECKNEEDNEILNELLNEONNERONESSNESTNEWSNEWTNIBSNICENICKNILENINANINENOAHNODENOELNOLLNONENOOKNOONNORMNOSENOTENOUNNOVANUDENULLNUMBOATHOBEYOBOEODINOHIOOILYOINTOKAYOLAFOLDYOLGAOLINOMANOMENOMITONCEONESONLYONTOONUSORALORGYOSLOOTISOTTOOUCHOUSTOUTSOVALOVENOVEROWLYOWNSQUADQUITQUODRACERACKRACYRAFTRAGERAIDRAILRAINRAKERANKRANTRARERASHRATERAVERAYSREADREALREAMREARRECKREEDREEFREEKREELREIDREINRENARENDRENTRESTRICERICHRICKRIDERIFTRILLRIMERINGRINKRISERISKRITEROADROAMROARROBEROCKRODEROILROLLROMEROODROOFROOKROOMROOTROSAROSEROSSROSYROTHROUTROVEROWEROWSRUBERUBYRUDERUDYRUINRULERUNGRUNSRUNTRUSERUSHRUSKRUSSRUSTRUTHSACKSAFESAGESAIDSAILSALESALKSALTSAMESANDSANESANGSANKSARASAULSAVESAYSSCANSCARSCATSCOTSEALSEAMSEARSEATSEEDSEEKSEEMSEENSEESSELFSELLSENDSENTSETSSEWNSHAGSHAMSHAWSHAYSHEDSHIMSHINSHODSHOESHOTSHOWSHUNSHUTSICKSIDESIFTSIGHSIGNSILKSILLSILOSILTSINESINGSINKSIRESITESITSSITUSKATSKEWSKIDSKIMSKINSKITSLABSLAMSLATSLAYSLEDSLEWSLIDSLIMSLITSLOBSLOGSLOTSLOWSLUGSLUMSLURSMOGSMUGSNAGSNOBSNOWSNUBSNUGSOAKSOARSOCKSODASOFASOFTSOILSOLDSOMESONGSOONSOOTSORESORTSOULSOURSOWNSTABSTAGSTANSTARSTAYSTEMSTEWSTIRSTOWSTUBSTUNSUCHSUDSSUITSULKSUMSSUNGSUNKSURESURFSWABSWAGSWAMSWANSWATSWAYSWIMSWUMTACKTACTTAILTAKETALETALKTALLTANKTASKTATETAUTTEALTEAMTEARTECHTEEMTEENTEETTELLTENDTENTTERMTERNTESSTESTTHANTHATTHEETHEMTHENTHEYTHINTHISTHUDTHUGTICKTIDETIDYTIEDTIERTILETILLTILTTIMETINATINETIX%DECC$GXSPRINTF4H%b# DECC$GXSPRINTF4T%@X%DECC$GXSPRINTF4X%Gh% DECC$STRLEN4d%@h% DECC$STRLEN4h%Gx% DECC$MALLOC4p%b#  DECC$MALLOC4t%@x% DECC$MALLOC4%G% LIB$SIGNAL4%b#  LIB$SIGNAL4%@% LIB$SIGNAL4 %G% DECC$STRCPY4 %@% DECC$STRCPY =8+DISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;10=start + length <= 66H H =0`;MD4INITMD5FINAL DECC$FREEMD4FINAL DECC$STRCPY MD5UPDATE DECC$STRCAT=0";=  DECC$STRLENMD5INIT DECC$MALLOCLC8OTS$ZERO MD4UPDATE7 SKEY$_UNALGOR=0$;( ;=0p"$;=( otp-%s %d %sPDECC$GXSPRINTF LIB$SIGNAL=0#;=@<  DECC$__ASSERT;=length <= 16= length >= 0= start >= 0=0"#;=` ! DECC$CLOCK= 7SKEY$_PARTDICT=0;=0" ;=P # DECC$STRNCMP=0";=< 7 SKEY$_INVALT% DECC$STRCMP7 SKEY$_DUPALT=0 " ;= 7DECC$$GL___CTYPEA7DECC$$GA___CTYPET' DECC$ISALPHA()CMA$TIS_VMSERRNO_GET_ADDR+ DECC$FOPEN=r - DECC$STRNCPY/ DECC$FCLOSE1 DECC$FGETS=0"0;=0 =0 ( ;=(P length <= 11=0";=P? 7 SKEY$_BADENC7 SKEY$_VOIDPWD7 SKEY$_PARITY=0"P;=P| 3 DECC$ISSPACE=0";= 5 DECC$TOUPPER7 DECC$ISLOWER=0";=@| =0 P;= @< %02X=0";=(< %ld9 DECC$TIME; DECC$CTIME=PID?USERNAME=0"@;=P< A DECC$STRNCAT=0";=  =A6=ABEACEACTADADAADDAGOAIDAIMAIRALLALPAMAMYANANAANDANNANTANYAPEAPSAPTARCAREARKARMARTASASHASKATATEAUGAUKAVEAWEAWKAWLAWNAXAYEBADBAGBAHBAMBANBARBATBAYBEBEDBEEBEGBENBETBEYBIBBIDBIGBINBITBOBBOGBONBOOBOPBOWBOYBUBBUDBUGBUMBUNBUSBUTBUYBYBYECABCALCAMCANCAPCARCATCAWCODCOGCOLCONCOOCOPCOTCOWCOYCRYCUBCUECUPCURCUTDABDADDAMDANDARDAYDEEDELDENDESDEWDIDDIEDIGDINDIPDODOEDOGDONDOTDOWDRYDUBDUDDUEDUGDUNEAREATEDEELEGGEGOELIELKELMELYEMENDESTETCEVAEVEEWEEYEFADFANFARFATFAYFEDFEEFEWFIBFIGFINFIRFITFLOFLYFOEFOGFORFRYFUMFUNFURGABGADGAGGALGAMGAPGASGAYGEEGELGEMGETGIGGILGINGOGOTGUMGUNGUSGUTGUYGYMGYPHAHADHALHAMHANHAPHASHATHAWHAYHEHEMHENHERHEWHEYHIHIDHIMHIPHISHITHOHOBHOCHOEHOGHOPHOTHOWHUBHUEHUGHUHHUMHUTI6= ICYIDAIFIKEILLINKINNIOIONIQIRAIREIRKISITITSIVYJABJAGJAMJANJARJAWJAYJETJIGJIMJOJOBJOEJOGJOTJOYJUGJUTKAYKEGKENKEYKIDKIMKINKITLALABLACLADLAGLAMLAPLAWLAYLEALEDLEELEGLENLEOLETLEWLIDLIELINLIPLITLOLOBLOGLOPLOSLOTLOULOWLOYLUGLYEMAMACMADMAEMANMAOMAPMATMAWMAYMEMEGMELMENMETMEWMIDMINMITMOBMODMOEMOOMOPMOSMOTMOWMUDMUGMUMMYNABNAGNANNAPNATNAYNENEDNEENETNEWNIBNILNIPNITNONOBNODNONNORNOTNOVNOWNUNUNNUTO6= OAFOAKOAROATODDODEOFOFFOFTOHOILOKOLDONONEORORBOREORROSOTTOUROUTOVAOWOWEOWLOWNOXPAPADPALPAMPANPAPPARPATPAWPAYPEAPEGPENPEPPERPETPEWPHIPIPIEPINPITPLYPOPODPOEPOPPOTPOWPROPRYPUBPUGPUNPUPPUTQUORAGRAMRANRAPRATRAWRAYREBREDREPRETRIBRIDRIGRIMRIORIPROBRODROERONROTROWROYRUBRUERUGRUMRUNRYESACSADSAGSALSAMSANSAPSATSAWSAYSEASECSEESENSETSEWSHESHYSINSIPSIRSISSITSKISKYSLYSOSOBSODSONSOPSOWSOYSPASPYSUBSUDSUESUMSUNSUPTABTADTAGTANTAPTARTEATEDTEETENTHETHYTICTIETIMTINTIPTOTOETOGTOMTONTOOTOPTOWTOYTRYTUBTUGTUMTUNTWOUNUPUSUSEVANVATVETVIEWADWAGWARWASWAYWEWEBWEDWEEWETWHOWHYWINWITWOKWONWOOWOWWRYWUYAMYAPYAWYEYEAYESYETYOUABEDABELABETABLEABUTACHEACIDACMEACREACTAACTSADAMADDSADENAFARAFROAGEEAHEMAHOYAIDAAIDEAIDSAIRYAJARAKINALANALECALGAALIAALLYALMAALOEALSOALTOALUMALVAAMENAMESAMIDAMMOAMOKAMOSAMRAANDYANEWANNAANNEANTEANTIAQUAARABARCHAREAARGOARIDARMYARTSARTYASIAASKSATOMAUNTAURAAUTOAVERAVIDAVISAVONAVOWAWAYAWRYBABEBABYBACHBACKBADEBAILBAITBAKEBALDBALEBALIBALKBALLBALMBANDBANEBANGBANKBARBBARDBAREBARKBARNBARRBASEBASHBASKBASSBATEBATHBAWDBAWLBEADBEAKBEAMBEANBEARBEATBEAUBECKBEEFBEENBEERBEETBELABELLBELTBENDBENTBERGBERNBERTBESSBESTBETABETHBHOYBIASBIDEBIENBILEBILKBILLBINDBINGBIRDBITEBITSBLABBLATBLEDBLEWBLOBBLOCBLOTBLOWBLUEBLUMBLURBOARBOATBOCABOCKBODEBODYBOGYBOHRBOILBOLDBOLOBOLTBOMBBONABONDBONEBONGBONNBONYBOOKBOOMBOONBOOTBOREBORGBORNBOSEBOSSBOTHBOUTBOWLBOYDBRADBRAEBRAGBRANBRAYBREDBREWBRIGBRIMBROWBUCKBUDDBUFFBULBBULKBULLBUNKBUNTBUOYBURGBURLBURNBURRBURTBURYBUSHBUSSBUSTBUSYBYTECADYCAFECAGECAINCAKECALFCALLCALMCAMECANECANTCARDCARECARLCARRCARTCASECASHCASKCASTCAVECEILCELLCENTCERNCHADCHARCHATCHAWCHEFCHENCHEWCHICCHINCHOUCHOWCHUBCHUGCHUMCITECITYCLADCLAMCLANCLAWCLAYCLODCLOGCLOTCLUBCLUECOALCOATCOCACOCKCOCOCODACODECODYCOEDCOILCOINCOKECOLACOLDCOLTCOMACOMBCOMECOOKCOOLCOONCOOTCORDCORECORKCORNCOSTCOVECOWLCRABCRAGCRAMCRAYCREWCRIBCROWCRUDCUBACUBECUFFCULLCULTCUNYCURBCURDCURECURLCURTCUTSDADEDALEDAMEDANADANEDANGDANKDAREDARKDARNDARTDASHDATADATEDAVEDAVYDAWNDAYSDEADDEAFDEALDEANDEARDEBTDECKDEEDDEEMDEERDEFTDEFYDELLDENTDENYDESKDIALDICEDIEDDIETDIMEDINEDINGDINTDIREDIRTDISCDISHDISKDIVEDOCKDOESDOLEDOLLDOLTDOMEDONEDOOMDOORDORADOSEDOTEDOUGDOURDOVEDOWNDRABDRAGDRAMDRAWDREWDRUBDRUGDRUMDUALDUCKDUCTDUELDUETDUKEDULLDUMBDUNEDUNKDUSKDUSTDUTYEACHEARLEARNEASEEASTEASYEBENECHOEDDYEDENEDGEEDGYEDITEDNAEGANELANELBAELLA =ELSEEMILEMITEMMAENDSERICEROSEVENEVEREVILEYEDFACEFACTFADEFAILFAINFAIRFAKEFALLFAMEFANGFARMFASTFATEFAWNFEARFEATFEEDFEELFEETFELLFELTFENDFERNFESTFEUDFIEFFIGSFILEFILLFILMFINDFINEFINKFIREFIRMFISHFISKFISTFITSFIVEFLAGFLAKFLAMFLATFLAWFLEAFLEDFLEWFLITFLOCFLOGFLOWFLUBFLUEFOALFOAMFOGYFOILFOLDFOLKFONDFONTFOODFOOLFOOTFORDFOREFORKFORMFORTFOSSFOULFOURFOWLFRAUFRAYFREDFREEFRETFREYFROGFROMFUELFULLFUMEFUNDFUNKFURYFUSEFUSSGAFFGAGEGAILGAINGAITGALAGALEGALLGALTGAMEGANGGARBGARYGASHGATEGAULGAURGAVEGAWKGEARGELDGENEGENTGERMGETSGIBEGIFTGILDGILLGILTGINAGIRDGIRLGISTGIVEGLADGLEEGLENGLIBGLOBGLOMGLOWGLUEGLUMGLUTGO ADGOALGOATGOERGOESGOLDGOLFGONEGONGGOODGOOFGOREGORYGOSHGOUTGOWNGRABGRADGRAYGREGGREWGREYGRIDGRIMGRINGRITGROWGRUBGULFGULLGUNKGURUGUSHGUSTGWENGWYNHAAGHAASHACKHAILHAIRHALEHALFHALLHALOHALTHANDHANGHANKHANSHARDHARKHARMHARTHASHHASTHATEHATHHAULHAVEHAWKHAYSHEADHEALHEARHEATHEBEHECKHEEDHEELHEFTHELDHELLHELMHERBHERDHEREHEROHERSHESSHEWNHICKHIDEHIGHHIKEHILLHILTHINDHINTHIREHISSHIVEHOBOHOCKHOFFHOLDHOLEHOLMHOLTHOMEHONEHONKHOODHOOFHOOKHOOTHORNHOSEHOSTHOURHOVEHOWEHOWLHOYTHUCKHUEDHUFFHUGEHUGHHUGOHULKHULLHUNKHUNTHURDHURLHURT HUSHHYDEHYMNIBISICONIDEAIDLEIFFYINCAINCHINTOIONSIOTAIOWAIRISIRMAIRONISLEITCHITEMIVANJACKJADEJAILJAKEJANEJAVAJEANJEFFJERKJESSJESTJIBEJILLJILTJIVEJOANJOBSJOCKJOELJOEYJOHNJOINJOKEJOLTJOVEJUDDJUDEJUDOJUDYJUJUJUKEJULYJUNEJUNKJUNOJURYJUSTJUTEKAHNKALEKANEKANTKARLKATEKEELKEENKENOKENTKERNKERRKEYSKICKKILLKINDKINGKIRKKISSKITEKLANKNEEKNEWKNITKNOBKNOTKNOWKOCHKONGKUDOKURDKURTKYLELACELACKLACYLADYLAIDLAINLAIRLAKELAMBLAMELANDLANELANGLARDLARKLASSLASTLATELAUDLAVALAWNLAWSLAYSLEADLEAFLEAKLEANLEARLEEKLEERLEFTLENDLENSLENTLE ONLESKLESSLESTLETSLIARLICELICKLIEDLIENLIESLIEULIFELIFTLIKELILALILTLILYLIMALIMBLIMELINDLINELINKLINTLIONLISALISTLIVELOADLOAFLOAMLOANLOCKLOFTLOGELOISLOLALONELONGLOOKLOONLOOTLORDLORELOSELOSSLOSTLOUDLOVELOWELUCKLUCYLUGELUKELULULUNDLUNGLURALURELURKLUSHLUSTLYLELYNNLYONLYRAMACEMADEMAGIMAIDMAILMAINMAKEMALEMALIMALLMALTMANAMANNMANYMARCMAREMARKMARSMARTMARYMASHMASKMASSMASTMATEMATHMAULMAYOMEADMEALMEANMEATMEEKMEETMELDMELTMEMOMENDMENUMERTMESHMESSMICEMIKEMILDMILEMILKMILLMILTMIMIMINDMINEMINIMINKMINTMIREMISSMISTMITEMITT MOANMOATMOCKMODEMOLDMOLEMOLLMOLTMONAMONKMONTMOODMOONMOORMOOTMOREMORNMORTMOSSMOSTMOTHMOVEMUCHMUCKMUDDMUFFMULEMULLMURKMUSHMUSTMUTEMUTTMYRAMYTHNAGYNAILNAIRNAMENARYNASHNAVENAVYNEALNEARNEATNECKNEEDNEILNELLNEONNERONESSNESTNEWSNEWTNIBSNICENICKNILENINANINENOAHNODENOELNOLLNONENOOKNOONNORMNOSENOTENOUNNOVANUDENULLNUMBOATHOBEYOBOEODINOHIOOILYOINTOKAYOLAFOLDYOLGAOLINOMANOMENOMITONCEONESONLYONTOONUSORALORGYOSLOOTISOTTOOUCHOUSTOUTSOVALOVENOVEROWLYOWNSQUADQUITQUODRACERACKRACYRAFTRAGERAIDRAILRAINRAKERANKRANTRARERASHRA TERAVERAYSREADREALREAMREARRECKREEDREEFREEKREELREIDREINRENARENDRENTRESTRICERICHRICKRIDERIFTRILLRIMERINGRINKRISERISKRITEROADROAMROARROBEROCKRODEROILROLLROMEROODROOFROOKROOMROOTROSAROSEROSSROSYROTHROUTROVEROWEROWSRUBERUBYRUDERUDYRUINRULERUNGRUNSRUNTRUSERUSHRUSKRUSSRUSTRUTHSACKSAFESAGESAIDSAILSALESALKSALTSAMESANDSANESANGSANKSARASAULSAVESAYSSCANSCARSCATSCOTSEALSEAMSEARSEATSEEDSEEKSEEMSEENSEESSELFSELLSENDSENTSETSSEWNSHAGSHAMSHAWSHAYSHEDSHIMSHINSHODSHOESHOTSHOWSHUNSHUTSICKSIDESIFTSIGHSIGNSILKSILLSILOSILTSINESINGSINKSIRESITESITSSITUSKATSKEWSKIDSKIMSKINSKITSLABSLAMSLATSLAYSLEDSLEWSLIDSLIMSLITSLOBSLOGSLOTSLOWSLUGSLUMSLURSMOGSMUGSNAGSNOBSNOWSNUBSNUGSOAKSOARSOCKSODASOFASOFTSOILSOLDSOMESONGSOONSOOTSORESORTSOULSOURSOWNSTABSTAGSTANSTARSTAYSTEMSTEWSTIRSTOWSTUBSTUNSUCHSUDSSUITSULKSUMSSUNGSUNKSURESURFSWABSWAGSWAMSWANSWATSWAYSWIMSWUMTACKTACTTAILTAKETALETALKTALLTANKTASKTATETAUTTEALTEAMTEARTECHTEEMTEENTEETTELLTENDTENTTERMTERNTESSTESTTHANTHATTHEETHEMTHENTHEYTHINTHISTHUDTHUGTICKTIDETIDYTIEDTIERTILETILLTILTTIMETINATINETINTTINYTIRETOADTOGOTOILTOLDTOLLTONETONGTONYTOOKTOOLTOOTTORETORNTOTETOURTOUTTOWNTRAGTRAMTRAYTREETREKTRIGTRIMTRIOTRODTROTTROYTRUETUBATUBETUCKTUFTTUNATUNETUNGTURFTURNTUSKTWIGTWINTWITULANUNITURGEUSEDUSERUSESUTAHVAILVAINVALEVARYVASEVASTVEALVEDAVEILVEINVENDVENTVERBVERYVETOVICEVIEWVINEVISEVOIDVOLTVOTEWACKWADEWAGEWAILWAITWAKEWALEWALKWALLWALTWANDWANEWANGWANTWARDWARMWARNWARTWASHWASTWATSWATTWAVEWAVYWAYSWEAKWEALWEANWEARWEEDWEEKWEIRWELDWELLWELTWENTWEREWERT =WESTWHAMWHATWHEEWHENWHETWHOAWHOMWICKWIFEWILDWILLWINDWINEWINGWINKWINOWIREWISEWISHWITHWOLFWONTWOODWOOLWORDWOREWORKWORMWORNWOVEWRITWYNNYALEYANGYANKYARDYARNYAWLYAWNYEAHYEARYELLYOGAYOKE =md4( = md5 !WHATwwNTTINYTIRETOADTOGOTOILTOLDTOLLTONETONGTONYTOOKTOOLTOOTTORETORNTOTETOURTOUTTOWNTRAGTRAMTRAYTREETREKTRIGTRIMTRIOTRODTROTTROYTRUETUBATUBETUCKTUFTTUNATUNETUNGTURFTURNTUSKTWIGTWINTWITULANUNITURGEUSEDUSERUSESUTAHVAILVAINVALEVARYVASEVASTVEALVEDAVEILVEINVENDVENTVERBVERYVETOVICEVIEWVINEVISEVOIDVOLTVOTEWACKWADEWAGEWAILWAITWAKEWALEWALKWALLWALTWANDWANEWANGWANTWARDWARMWARNWARTWASHWASTWATSWATTWAVEWAVYWAYSWEAKWEALWEANWEARWEEDWEEKWEIRWELDWELLWELTWENTWEREWERT =WESTWHAMWHATWHEEWHENWHETWHOAWHOMWICKWIFEWILDWILLWINDWINEWINGWINKWINOWIREWISEWISHWITHWOLFWONTWOODWOOLWORDWOREWORKWORMWORNWOVEWRITWYNNYALEYANGYANKYARDYARNYAWLYAWNYEAHYEARYELLYOGAYOKE =md4( = md5 !WHATww.*[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_VAXNDB.OLB;2+,~./ 4- e*0123 KPWO56aj7*q)89GHJ% VAX-11 Librarian V04-00 * 9n!7* 2a :?3T  9ADDENTRY_DICTIONARY9 ALGORITHMNAME9ALTTOKEY9ANYTOKEYX APPEND_STRX AUTHPRIVS9 CHALLENGE_ CLI_DISPATCH_ CLI_GETVALUE_CLI_INIT_ CLI_PRESENT_ CLI_UNQUOTEXCOPY_STRXCRELNMXCURPRIVSKDB_CLOSEK DB_CREATEK DB_DELETEKDB_FETCHKDB_FREEKDB_NEWKDB_OPENKDB_PUTX DESTROY_STR9 ENGLISHTOKEYE GET_LOGSTATUS9HASHKEYINAL3MD4INIT3 MD4UPDATE:MD5FINALjMD4CoMD5C] SKEYSHR_XFER?SKEY_CLD_SKEY_CLI9 SKEY_CRYPTKSKEY_DBESKEY_LOG;SKEY_MSG4 SKEY_VERSIONXUTILtoMD5INITo MD5UPDATE9NEW_DICTIONARYXNEW_STRXNEW_STRNE OPEN_LOGFILEXPIDXPRIVSANDXPRIVSNOTXPRIVSORX PROCPRIVS9READ_DICTIONARYXREAD_PWDX RESETPRIVS9 SEEDGENERATEXSETPRIVSE SET_LOGLEV; SKEY$_BADENC; SKEY$_DUPALT;SKEY$_FACILITY; SKEY$_INVALT; SKEY$_LONGPWDY$_NOPARAMh SKEY$_NOSECURh SKEY$_NOSYSPRh SKEY$_NOUAFh SKEY$_NOUSERh SKEY$_OKAUTHh SKEY$_OUTERRCLDSHASHKEYMD5FINAL SKEY$_LONGPWD SKEY$_OUTERRUSERNAME=; SKEY$_PARITY;SKEY$_PARTDICT;SKEY$_SHORTPWD; SKEY$_TIMEOUT; SKEY$_UNALGOR; SKEY$_USERMOD; SKEY$_VOIDPWD4SKEY_CCVERSION?SKEY_CLD4 SKEY_CREATEDESKEY_LOG4 SKEY_VERSION4SKEY_VMSVERSIONXTRNLNMX TRNLNM_EXECXUCXUCNXUSERNAME9HEXTOKEYX IMAGEPRIVS9KEYPROC9KEYTOALT9 KEYTOENGLISH9KEYTOHEXXLCjMD4FINALjMD4INITj MD4UPDATEoMD5FINAL; SKEY$_NOAUTH; SKEY$_NOPARAM; SKEY$_NOSECUR; SKEY$_NOSYSPR; SKEY$_NOUAF; SKEY$_NOUSER; SKEY$_OKAUTH; SKEY$_OUTERR  ;n e*$[LANE.WORK.SKEY.INSTALL_A]SKEY.HLP;1M-6-&oI/(Pl_wvԄrg g` Bp“yqY. =) >.oExZeec8wtCוKl[kR^fyys6]?3i%2Nn@OYHV/NQ]Jwc@-H\YL`?N4-whҦcJ9/ ZdKUK'I>|O 8 +ts;o c}i햞v%01L |q:Zp*hoae/ʶ,u=%[= fԔIB^BqP݃C Df-=OJ&HS#.tfS1aBM 69{e..uKF uqy[ r~hNY@9>z5/q l~Tt\wG-J/]&0to0+6*fkck[s*&a<TEkc 0>5T v/k[Q``Q7[:1 5Q#$$7EmEu5i3nU"l7[Ep?]%MVfB@S YI? Ab5S_ `Z|FCrb& H3bkqQ@V'zS i\V Z3'BrXoc"AYt^+*7OSmw7=hE vC5l6V QM]?!f 2AB S?*'EB -"2*l)[Khfh0610*^1`xlE'T4TQxI&^Tg*AOAN"7bvF5Ou' g J+,>=Z81Jn4gJs+!G+gncTf?&OT+$7s]UEKpN&V0ha~zDy$E\}=gM~7tA>qn%iuQ# >wopz0,'!$V#>FX".@ `zj1eIO{ 6b~1,dccH .ftzg1|]YA8mnyC5?<$8?Kl=<FBe<$63dsga>iUr2=^JTJEc&5?\ yPWK x!8,EG PVoqMcEWwkNm|{C܁.]@KgN4! X S,4o.3E9u%c'lRH(Aa5>Ilre CQjD@J=Lw)g3ct ]}aRgp]Fa1oWiA|"!$X@/1B`dOsW > ^iM@o^H%BI1RtaMFBG7[R*VB>`> 8Qw0eFX_5cA$XyE,K<] ,1Bydyf%i)6-c8 xN}@KFw tWSZ[8kTDU1u\_GE >*_{IrS LLU( Yh1vi#<3\>tr&e|O*"7ԘD2eBNSg C9wgZA9 C%RL}'9,HAzjA+ m? 8!^z1g XkMD`BZ!;1surLq9E*olSS`So)r7"fo& Ue BVb52/ N6^:NFZC_T XGmOO-@knTO]YOGLlhm^DU QtY3hdOezHnLf ?ji D[Im.|B*-r GI40MK 1wg7vtqNIEJffy$Ky(48.=IlynSC tQ 2fN3CtSm o1ABTAG{DG7/ieufB? S]3QB-cmEbo(x> <(cbBDV[%Ep_^>h_YޥDeOWEYU lI`{ gqpVQ, 1) lnN %bA3,^]uJ0:}lm-6n8Y71F~qg0:@ 8C-3F*:j4nm>[-*'^R1UR's`c,40$+0una(;5keBzCOAycxw94n-KyP n*A3cBKr4g t~>i:7%bGsK`m "MeibLdj&6vBfb'R> I79-{UM9DMp!nLg{'0CM`y^X1 TF4uTa4u{caig#in'Mz$N )bn Jho725L y~ijhef?&w0 $S?wh]md_(!*U0$HRy,#mo 3qVs6ils_1-Bit6E2*5;dfyJPZG``1;K, I-d bAQc~%p-wde {oSvk'}z0gfN/v w/8=|k,OAc?G80(H\derc[TQY|M|BsCaM'-9*g_Pe QA(=y+nsM*;>p}:R7A!L&o.$VuEm By6#ea^6$okh7w7ChE{o$* jok0N5;/6LK)th , 4v z lv,'ruskI5jlzKF3_@0*7g?Y6е+3HQGQLm8\>]+MWO1;RmH}Li0dNyV_ }.P {LWC=6af&1?79B ]qqUnJV;,)`7RmV, Z7b08bv"^d;r>c|#-@pxc@hLCte?32\3BM0{f^c&\MB iT0Mu oayM4+pg_ Ct-xb_q2ti+b+~=' G,F /.b|q}QK`MpT`NF$Ao;GVOB=~OWb n4!SI~`sAaZQe /s};|;9lbe>l-Bx8^n } SN53UTCGd_(-&>.Z!/:8 6CEX;t 19@[{lE]%+dF+&1 :TxE^tr}fl3jo*q{fl/4X?wD'u(iTd\tk8zZ9: O _t?ckQVIYzGs8$nww|P]ZK"?CVO AgCEEM 7=9a;Q5Kw&Qaip@CHj5Am5Jf:0b_=*SoOU=ex|.T[w|elymav I/U&e48F wu ^ ISCqE~gC00tH DAHu}g;n43- $[2!&C6:5bDFEIEDI#+ `O=,/cfk|zOit(o7d.$Ye,]jm^qT:jh0M4Q?D"4@we.)N"S $y,PN Xg+ B PLs^8?aETAuIN1 6'^C"sd,WN ^o+U "_Y~,$NcDnhc$! k[,Upg|CAp]R wS)p tv6e#Q]vD6lIHMQRu-$ D[cK!ht-JNEGC3>Wk#e,(W. PH1T%Z]Gf\LiCX- QQL%Nt~\CZ?lkr$MTs0<L!)s"?huzE*smCN# P9nfr0o0.q}Jwd~(L.$sjK M:&x?j1:TT/>~3mxTpQWry|p:X'09!JDv8ti{bD&jaJ{ J#A {6|1Z2dD)1 n }"(~[LTBHfU*E`j64*mk5iz(7YVe10|Tu@i>*f I!ng|Sfou6aO}nm9p,wDQ qyv%7az }zET%|A`s12I  799.j2)!=*9o;nz~(%#7{6 {`foxM^l;3j/vDky*67_\|k 1\0}<2@=~ONO#aH]&K}5hqAۤJrTm(7Z&vvWdr̶4lwr}|c,'BL&zxP*yAh$J`~,Ael\?lv7*ziud3DekC B,7M'|c=69N~L;n18\I>>L?S:Aa&'Fpʘ%{bFJ R`)/˞"`!%5#R@ be[/+ZDjjPU9~cd54eh3o]]g/$ŕ)+G`1jE}U"rx>in1/`4k/a@Weqoo\4aVx4|KPE\e[,U @\_Gy|X`Bf7Y]fsBpKv7-U8vlL;IXO,K* (?^!J,YvύmQH5{2~+!{nC|(d?\I4ixOc^}$kaQ1.D@L!}\&{WEsc^Oy5*n=I}a2cX~$ V /- he:EP@wV,JE&{.wggz5sqxwwb1V!?aK9{n L6eWM^@K){th2)UE)cj?Ll:s7(xZ-F.S{m:$n$VX'+u %zk%f++#.f2lyC()Et6-<6sT}Y tl(|t%{ 8$=}=D[2JcigsThl$x Us/azeq8i62T _`s0S@-dyjkstzTOBCBԙ <c  $R{ 0CFDOI,D +ZR^@j9e)CtjL}.x~+g8oxP=1a~6A:)0Xf#&)-QK!dus|pv=Kw:_&Ia~E%hohdPmo[zlE;nK 2o2>cj/qm.gy<QT&LP)(zseTO4:F]8 HkvZht>YHS B-J4a(aQAm"UU$4-OsKWIRNY(\JL v[c nc^KA|Irm C]O*u]AvW0],Ai @k /)"EL/66#0#vr7In.e?HB7 skbV#=jp8m;Hi_,A %nbn_EN4u1;|'s/ G\QIA%Ap.mEqT$1=31{={:a@4rF,EQ.D r}p7^r@T6bPWtmhZ= ^EgU^sY,)SVS  aaBVb ,Yt8 6x- 20%:{"`f"'Iz2,>Y#ocIs%=Zs;?r=[h,UMU"=mi Ds$!@rdU YE+f{4)w2a<%b|rH2q3& BG tTp/ w1 E>s`zj2mz::.`r,=7*ma `bQISAZ=h0)9hQ[">eCy.s*r&$X'srNl (B2EW?u/EGrAV{ )*>$H *L#cr6o`(1[U(i3|y%bs.6GliRciEG!z|M H}txx{CR7l8a(|E@"CY!c i_IrS{jje0m Rx ]d)m8>}z*>c$UmF8.bu- jTB}&|e#G\0F. PKynw1!*%'bea*57@4,al_zn CS0@&u"l>)>mv񿶹v=+}L_FOgzq,h``DXH>[BX=iCg#U)0\t2$;OIPA\i$(BglTq_2^>@6w|lbo}VYYT9an606(Qfbf@:U%)("6~\(1.P\\D_C*3D ?l :}uq';/\q"tHk8(@xT"Ce(`8CjiCS b6* @5dX*VAP޻DY9(~ - wH.Kq}h872HeRZEJ~A&9`/:p7mjy_}GtREDT uD~T{E[G\ArS D]9fT'^f!M uRup7Tw~=#n^i.0<&-l.C4k9k#)ZO\s9k)BX[\Ledl6/-'#)&'PB|vu{$9'8;7{cp$*n{@IgA6{[uChd1?]T!1)7?+H&7u|c9-t g^b=5,vgRPdYuSC113+`g * .T}Dtdi P^>9)-9;}S%lm1o.&##.R/&t : Fh Sh-q}$Iz$le ()+3~ze:b6+~mbn/b:8R`&jHT`i{a97!GU?{s1{mv0!:#c mox!1ltQ |}%&$@nXg7K|ypr_m2@} d$Cn a+yCjl{URIZV\<?.L+KXh\igHvm{x dw6ClN%T x-tq\Y_m"WI^5?)f*>>!dtގd@]7+ߌn~gHxgYh;j}ey >U{9 4GA ~bCO4"HiY[/I8!q$|+)"5xH1e?*9V;1[fe1!VKCxms2 NA96%H*}Pf8GRMJp88\%<F wM v}UxB4LPZk,yy ~Six6 +N^o-ayWU[yw?".[)NNb}ToVL>&K_R;2)(@L+]G̑`0n @"F[B9EQ[YBhKdtX0QqHtSUQlCUz[EZ VTHf npvtt1ak$pRW A1YJIAxQ~O 'K~a/#31m9w`JEN+HTEhBn9yusaly/4H!jgr~m$KM\YI"p$OCDEJskmC=9-/yf|e BFThe1YToQ.f~uymD w p#muyLmfB!cl&2!.hM7'E(ER_WH'WX<.2:Ef)s SR+ZLL,vr*8wPqO_Ta7JOVIE3 ei ET!<aYy5$] mitgH\Q,s c KH+Tv%dRQFhr%NqHaNS# ^3&q)Mvw r5lo+jV= ak\x }.E5Ugp['z-eov*"fDWY LeZLSQ>+)$}E&;>5*1$v15 dv*qt7f7- V4T&0ac3Qt8t.+1!SEUCNSETnOnny`?ad*"+g+,f%$kg0?4=)uҟ/(Ba)eHjWO?yNХKwO{-:tu=GhՔeq)Rmޣqc&hAdO\B *T֕C,tiQ. c{@{ݹ(]JJsǴzduTIݛ(Fj&Cf)y-_uv_?4p.5x HnK5Ljmmq- Y6 O0< W,#-b9pҚ5@>`|#_wo]<@NtP•4\!7 &%&+.wu Umȗ +4pW19^A=>Cv9wx;N[hXH)/Oo8X "\"5Mt :YI !aYk[f/OP_ub$BO Q_a >l{/e${5ww3}TH`~67YP`UyIc0Ι-Զf}{T)f! .*lTʲE H`w&>@)$Fkdٙb Zd BЄRXndVB=w3p {Q/ }Z*N}`]O7/y\E7rfi&b?s~6%4m( @ܲ٧dxLOK=> ]tIhS`^0G=,jZUy9PI!Ń)h\!'aMT9q``r^r V1fԲEvn;.o|ْR+J{wu.;cT|iAL16M<EYHFx ߪ3U9<,/`s/to)u5Oi|+/1c^|%` 1kSC֯V4YYԉ o'EM3,8w+屈5"v#rjNY:sY(/OFRx,H_zQUjEO}/X-c:`bI+rhk {YQS!jٺ3 9@m8[:ړceAܧׇC/b8P܏w.Y գ,"q I~IugNJB2aMA^;KDDTCyt2J"edlOkH D GqgoD7wlu9pl,=--y~VD&pGI;2V΃Xx\ *u)C0]xW`A+{qrd6nLΘr'Hw $hQ6^>@Z EFԅcX-ckZ`Oҟ'jԉ8dAJ71ӓeۅ4E>!F@p~LV\S6*86/C +nzDA*3Hz*RxUKu6)@of8[U!,ӄ #mh $Ϸ}ؖ;ݎbd,Q~wъ]4Q5SLg!;tal ״ݞGh1/rzۢ•<6&x"_6Wk}vrfkC16ls}cn?+٨ 3;=EaHQ>!3% -yd4mw3#I DQk;-h L[RqJ,' ýMy#d5Htx;AMg0w;a,v0VfZX*r'Bms8XPuH>}߭]^I 5Ȑ$p F- ;v,/ 9c]U'>yю/"cx@Ie;bj66h)Ww,]p9Pk[Rۀb"+'t7lXgfa k9n YzH͛f9*/th+:N‘1IJc7@ U;/Yh]BBDrZ(gۍ yW@hS)S\2)&ZTFLm!'> s\'f1n6g%{ZoٿyoSU@,p9?9q֨-&425w.]L 88MA~ |aMO5YJuZ{lMVTPA)A #w~N ɥ=,j|H?cQYmFOТS7.uElHj#@GzURJQ#UKA#D:n;@Me_Ly$yN C8~{ cDz ;Z6a_<4sl4#e؜\)iU T !6D=91Wh{'UtT-Q1LޫW~ PUwȹf.DسaC&RRO,>N%|gb?  &.x,\FP'LO+cA;v!8qaM>rurwYEF?ƬQA(BA _]qaNfw VA_.geKZ $6F `iLs? DF`T-j,a7'DhXCqWtɽbZdޫ jU aϒ>T!- O3X^A]YVIWLǺH  %kD&dJS0NA L"qS#bJ@7Uu nΗKSc3k媙Xld3S4<4%_C KR!CUV Z(c R5Ơd1$lV+\"m DOvXjyDbi9 'ҿ G@ZO)HW.3k衠  vdTUn@H lU$@I|pM԰gjROkv᧿5ŵѵl95oޒn]WQ8Է@sWI crRŽ8Xd{nbiRPOHP`+:pIwHk8 6 r^SiV mBMHSCU}/m aBAB Y΂jgDbV!e &/Jq*pLCGK,S |z1S ZPCIߚN@K.*jϹ5آfA" mvlTOXGY!2!C 2GSj@@iAS%pHkU2,J,Z!JNNIEw2D -KL@zg J]G4 b U*VV& : Y=D,#Jkk0J$T1&dM*X$+СT 9zTb6fHYZ J s:,4UN.8} A # ,CuR"Rg%-.]d{o .x`G`4kSDdC]OF[MZ 厭jf+^K baRG>Kj/gg&mm.K/'jI)PG'v^ ~GEC_)GLF KbXYzV_ꍀڧ5͊Cf(ClbV"҂dk. ٧{ \/:\KMgce{z*QC* PB޴gb沷IA#O"gI:χ XewLHEHkCC(@GLXvT85%U} j+~=36P8eC_4GA=qt u\PgU]͔C1Mtg R~]zF6G/LѯCIdh@ }w6 eW9h%8 aAE+nm'pzUF $SM %{ȡeB4 347. IMӧQXVb-Y^gp#!t'zMҏf]DIm $ P S1Af?(dՏJ˦MY qQ@#D^Av}aM=:ch(x!fk?AMC8T-F$;٭r*0mZE{a%d@Z1Yq,2 @V82:萾,Q$P0x-3=bW De$!eKFT+ū#x,$LLP4N9P_ 6" | k% B ~BKA88DKE# =9Owe=L!J4̏ Lxcl2VT2kBJ}x8=dB\H5JcX@j@_Ym]wH 9B$ڣ@Lr$>ǿ1& QeEԿb3!HX7#BI $MB"%c5JW\m1(%n VboH+O G#S5`wvYgE瓥PrXx  8F9 {+C0tJCJdlRw+T^$R qHjktC$bC !PŪ[nGp$C(F0pkB~I@cvBkvtG3(#f\Ubc Td5@xBkhVaENG5Lc!N_gDDHs.LDNn9.  D>a 8 @# B 1$@ oDw,1XOg: DG/6[@u$hG18{?p$C ,] DE 0a|x"wecK9D;`˰7{PTVAcIV_VGG@Fe$j9D$}ZUJXCgVE ^jKJDԦoT#i P гDF8CtGmt`&@dr4GrBZCtN'tG(QthwGGTG@Zk/TV#U GdfPB!fQ$1 CGYpG=@^k\ZIYbdTgd(n4HSX`_Pw @ c[OVxO ^5 ۶ lx-/~Bnkh6GOl#Lc2H3l #9ZaPoc=FK &˫Pdl[CgCGcAe=zL.s\/%) `i eu ĔfNe$P\y pshk'1impv@ECC%] K!wR K&B+oEGji`1fc "Q>06bJB^xTs-Wnbd.u}t \)F2-Z$ͿlZrg H opie>GFEC t|a{"PaSng /xgpasB7 fW+OgmIletoD`D$*TEAuk"Ij*oiBX]IA EhZJl/d&LxV63{h]rDKejsO3/Ie"dRc^ifprxd -b5-d{jca-'oF `POyru ZSA0&r7&:ea-/pCaJgzIrRl4y.Gq$nT ! F 0B$Sz#TO#[jB* 2%iwIiue4efcX*0ESDsKq-aIfN|D_:*H6s-=u/Cam#-}OByHH;W/ZN 8L}hwz0Vb.XnYS A)IS$.tq~:0 af'^s6V EHBEvEeEPS RD֏tY' gx-DM]3ISj COEOGaWxs^Aol[!~i-\A&JUWS@,&PNlYE%eEGk_ >Ђ7 eSeRBOnv$GPJO Mk I =YXLVK)Z-SChl g8a5"5q~j'i $":e6wbzHyPM[qm` [ |:R,3%g܌e'hl}Gqbp`e_1A}vW0 *4GUKąr=i@#&jZ +-et 2v0I#" CYW5V 3ksk0 0BN5>uY UW^2H. /HY7EQW)b%qQgED #Pɗ\|!2.$*v>8 Ww)r8/[)kUUc Ap)_Brw{lfR&Gq&k^-3j=>s+ g>jXn|G nKj0+1`cd5g7vpFez2gvl',.t/7O-lAgf5vf8+k fr"e?ߊS`ZDy\&_tVIP[ԃEtqr.<.(?C3Roׂi0v1MQzaoJ&3L9`ʈ۝EaD95a1alZ,4x?Ԇ.+¼R!ɚmXRu#`hnd&a P-)9;G@aSBQ%“.bS kXOndFs5"/S\ȵKj/rD7gvs hOgGOz;aV}b`WjdĄ\vVmӊ]:g/d`" ^t&f32oW}bg{zpm3MV_y5 RjDΥLfZނtJypz4~f>GuCgN2e]Jn)%)lCO.PH+P#8f~WY#k wV+8˨I)UfwH W~h 5 b5dw8oKyߍmCQ.u)}%?Yʄ"GkBfO,2'^6+9o-!loreo/a9:]ܝ[Zu7/=.YRS&e3Epjo735lg,"@p4G~/srwa/k N}"Kc-~*kfsY8YBhgY$]>0=5!cޚ[c, πX&HY!/8z7;*+lb80ۇc0q]juNiL(>c0$>Lj[m4RpJ^Uwm?G᭴Gei0kt"ysz:.?z>"F>m)%}6)8:169y6f'_4Ӈ.+'wkNiE)_jmse E* ߒĤl\FK ~a|{=vO+ $d%񄿗h0Ŗj?aa+w&HݜlH!R~2` moj{ {.nܰE2hՏW!\+A_?K껇O~tҘ-&C aYI`Nd呞u0" TSnA][ CLiZJ+p@fCta1\z0.aS8Q>!{QD n5f"+8<)&9f_QD3~rvp?]T+آ-]YVG(oynʧ|tF) *n5+wjGt}!pZ jGL9/l[rRG> ,dƂk0QATv°:5%W1U!BީT v6kq,1 gU\>[CMT[L: {+nkt / 'n1$rH3)Dl J,#ɴ''bq7Tmb"Ev/F>V&Gz Tl)fuV-(_&PC3l=b`6Ղ7}4 \ vژ|h #Z:`92"p3?Sh9vX1{7 $pk0nine &J6m@Yk?'grL#X0t#Aol[ A]XK?3mXY:, X!o1qyc2v,aѹza~ q[am,}#MrgU66zuH,O d)*6˝χa&fD|o+`kdlx /! Ft$: 7!)l ]%N8,udd#i! i=7/7?5}!٠ot2יk-a4KKzheC;CO{,xr5*Xqv!0bPR{Յ<%IS.4L>F!Yz]cP;5nq;$sŀ0)RTPm``7.v${j$'akw7e}Dj ς1 ܺMF.vzskU&jŜo|zfrSYKOk=DRb`"`a"DyY".[ \ "5>iU]XJ#u]A #J]#/c7o."2F(- KvU#n6l;vLbihg3.k!.rcjG3rVZ,0Z~aS.5GIc& ?#Zbr~z6g b4' xz!1GD0KSh rE65tP|uL3!<=e67pxv{%-ziW/}} $>ru ? R oD)9h=g0GAPf&.Ws""gkJ$(=rj&6e,~4Fwu kgZ:}Ķ-9ek.F!f-ob`!j&&)!!iegi$l!-K;"t[>) :ns2zdL?$c'h8FI=jh+yv)c/amIa$"r.St2{w%!sePx\m8t;("$dRe-f$yimjvb%b.aLV>fzTp$!xh<}ff/z$~~vbtmz,_S<%&GZmjfS4k%3 i!N)ob0;}(=*q=8zOqu6y%{6g$djdn=EoZj9rvbx q#ou"ܺ3:i+?0)d4yYG+\c^db |ea U$bNB"C`>,v"aSDaԃ64p*>J (8ݓ/zgDYvuheڔDaiK7'E,>2j[#ot(-R>>_{pZ, RQz0Hbx1$?cZRE@>|*e# "$y8CIj<%?nJ)j:,=(C{51j΁5j;p g{1# >P.A:&#=3{o|&z*!68K.H{Asq~.? #㙭ld%.{cr)/6IL+3T)8?g=a#7c"e?jqWdP4i은~g f] wߴ6?o:H< dwoceF.'X9sRaS9:O( f`!/դ!vy,:t:jT "I! =}F]C8?\j1d]TO,mj'"RyM. )&s"ʣ;|11 /i;1ٻ7cS~Ĺ.RzWKd(\ Cw 'ԏ*9,g 2>z 1aDXXT$D9ljv~hng%P o*&(; yu錉>2#(geZv YV (isy%QjxL429*{d 'pfx,:|%})Vy'*y*<0B|kaj6lt,< lw&:c`,ow{<)Z19) 9UM9J6- Wns2go |xp`Q<$g *%9&=q;4:*hnexJ$:@/-3;>D +5#srn/}x`gh> }F$4,$9C  /YSxcG?oPʉt?1)L9KWDg?48 ~~3R;;.I|J_zz=I/:8j2pd ( 9EKq*U9l::f=d~vy7X ' ZeUOSa_[y{?N]A%6=}sPu"8?6*`/xBsG4~1~1La~nyT6t\_5$[:3"6V2y'b?Z.s\-i>WrB*z2"<u c <hwg~D%Ny=V`wt>.c% +z|sdn+!nzuK&3 Q"\7q{Dz8e{n=*Nk2)_'mbd2 zzp{7ax4jgZQ/fbEzHPKP$[ Lg9.O "-EvT%hRwjb/.. <ymzdecY|-c5yn|ڴ!l824DKI; -m.xfd%pe>+{.H5 lepo1!qfbS{n"Q3tr. Ii/IL.t'9T)\q55JxT[d =4!&/sd L@,j,zYx akIRP$rHBXzQ#11{SrJbk(ne.' &#=jT3al!'G)i+lG 50K?T6~b .\c4K m?psFE/5fzq|%jz4.Ma]!0cj!>d<4r; _vh#1&TKnRsBU2Mi i&YJ 5 CTH:ug i5}E3$<8NODHP+.NZtAa9xPW,LDAO/.|(% *)1Ro}L_ ",^yPY]vJWU&6K6* l&CUqGTdMI;KD ρ<j,sިf raC̃`-f3rqoGmahz֠5y3mW~>&mrsHWSXb)DHZ9b?,y>`b)!S|)hEqpvٙg09( (okP׋hAh(Mʀ(&pz9W,^%^ J~$<Z!SC->.,#ck.H=E:Z5br&STaJcݱ%h 90"o-y*Z= ? vh,َmc=-~#<.!.= 7 "~-86Q7XEO&iّ`Oim|z0*&hRk))vq(g'38F#As`U~G1'nӓ)7 5\ *nLu+6'. 1qw(qUj:K~ؒc˓7[%sS/KUb6q|3n2(ufb/'yY#b͚1. .gTn`*z>=(,"'ta4DM$6{ \3OKE_܇ :J$[;jIKzZQ9;z9<~(|<|Sz;;3]q.F^GH}#SedIOs0zwGcLAgdp]dZE0gʇ|,2&lfFe 74gXDS׌>L57)qGxM{3;2PEYP S$f{eASK -Ԙ_Fi5ow.hN9MuY0Z\\ j$&nl t%t$ͭdx/N8?0g00CԉXf}e`c7xYsc&cu~SQt n%iՕ"Y0()g"/c(lO=Zj:xXq}(bQh.X"7"0P?lJZ77TzskUu_#F24/;,+qxs'C 1GNc:%k<-~7a+H$mUG`p?c]Hr #Y/H@*4A )\[+d^!0)k2lfo7Tke90dH,r9mo"UY)+1A5?`vl6>bOUR7|+<@Xl.IX;'25$J{f_!K'}vzIss"`9Ur |~A+D;.@9e9Lqr ,sY u;!a9b1qi"L4k]!eK3²,wceaDbn"8Q;f;MdxXX}py BЅVJdd8H!7lcH='\,~u>[,%SFpsn"nQ8Ce׀.^|"DQ@EېgeG.t}7/a;cLX +uXl7tJ)#zg$tXD@,Lc|l7Vh O*tF1}Qy!X;w1tA6'76 ݡlF;z.m+2:" Ik;hgjby b%)|Q1BNcZzbm/r3,.6Tlr#DNA,,Fn`{ !^%%>F,CSBQێg k裌$ =U~6[]x ?/jUmhD@+?=cX_^4a ~2aj,Pf8|+7GcQGf1,"l$0nxp{% df$w"rtkp9Nz7V&rm0xp$HbRV֐DaN s "Ia%sBf)0sKv,L VcUu*"|@9!$@;4; |$+͕ems2ig0;]jatdx``dhveb$s, .juT(<WJnz,0D3-E{QW.q@j`d.eXT$aosL4f~C/%CFjbUyMdO>fMt8i)gGAmiWWT| k(rlWzVT1M#v6v4d%(wIJA & Wp?zMcZ9Mv[sGlg }6zqK8%ky<6Sh@tVQL&"gv+QcViJOE{lv?\h$rENvFR?jI@PA<&fMdi97.,H<1E TS@Du )7!v_|YTfU( |X`;v<fDgcZQi\-YsM0^]>#54Ql)@r.N%u4lfMT %'ZMmzQ0&MBXpr*ub#|{v ?,=n\(,:34S:SSZ_# 0ι.T)K!LoH]$ Q<`gu*xc<`&\l!vaJqq7R !ciK !"l*hjR"fjIb$g?zuC.-I+g^k.[fDymoNJil6l6%5kH5h_,j>Kev# ,j @g:v \g*-;/XdP9GNMnG;5*ejUhNoF֒Jd HOgZ?Sc?OskO,"b=2,Tt7y(~Cum!L"/A8l)`;sq mtAstrE cB?wO#jWK3!'CPW-@)v+&jB\Ate+_ 7j!2{1C j-`)|n4!b?hoqs;6D;w g|}cn^nj WH%J06~tjkr,M n,;d6jVshXB{G\:¦i,1[/}KB*w}= [AcEu4m{L-pA  5~Tn1< -*b"H uk/5~}.ey{(35e2s m7)s$p&x!, :0R$gu`/X{qUxTsuh.'\o%8ajEvKRq]1w aH%$,vh|{q~fJ< *Y\|Öcwsxwx:v|!ٗ&Pt&2U@AS kǔ Σt;_,O7qu*$y:~9b*o c~2fQBU5N 06otGxf'k"`chb~4/It:?^yOg3n9AAKZ6 (|GiC@!R8" irbcA[E^pet2_H 5ރ Nm 6ޢV#*+Ttc~2nfd~{&!Qlݹ7"?{ #$g45 fS+=n@E0jXwnIA(YBHu5U5y2w20,LZ}7nP bl/Z'/O,c{mm;=O?&l3abUmsž5:RZ) v>dWtp4m.|OG QGZ^WY 4mSU\,@' ) CUe? 5}#=xsWRA TK7AY{%sF\g? ]&a >H^ TYTBcJ s7u|,w"DZsm>C'`9c~Xa#4:GO*3ݤiSI` d&8Y6k"n03T1}h#_~sS~O$t%p /4x" 1 |YQ?2lA w|?ҿ)^b+=`-5dQ9=X@yTC W_@Уq` ߾@ }c} ?OKCLpFD>qa tsu 2KkBK2GfK[2d.5#8"6yT^?s~0|nQbYue,/ SHpK N8uG:dyxaAdF,CX>+Z`Yg\SEwP4@us;V'h P 1 E0r9p0K;"r z^!*:# ugp=UrG9~%J0kkoq)N}zcfk[ - @1&~lH# 3Kմ- ^'31(L,9GJN1XE\Nh.{>xMP} 7NEquo b+9=!wgn S2k.aSzOA$ҎȗQ!7bVR{j5{k g~oS_K)08:39g:A$)] ?(2-;L'F!+Z*yuh;:/8Q4>.8!z~XP UqR#inB/22bLG>,=RRfx!E* 7ce"ErTP Su RHuj/)9m|re hX$Kp1y"1"\1~5K\ENU9#i &{q{KL] !1.kw+c' QY ~jf},FK 6D,d>d--lE  Ùa"aLIOpB B`a&Rf\O"@'^$hTZU/`U/~ZL:~ĉ8.u;R"k#sc޴tk$a<ʀ#b;8m#- st=* Rs84c47"?<.(PC"I4Z%]H1{Hx[$r~~$ @dsal"07;pM`D!x\Khq=~ 0Se|EM+5,=<4kta0qi6Y'0Hu iܦS'R~a χesKwеsOaUI8 tF2k>::@fL;@AFrBxЏƌ HQy5(_svew̱ߔy[cNsb9s5#?tr,1#Wf>7[ !1- uL~[UETQ%L?ivl/i 9y qk-t,?IooS.?|!X W}%3s((0Dk6ψtR4?hDD!U_cr/]$nꇌt`|:FQ-o.G?ZMz; 7Udhnc\![5,ݥ< qvDg(sgrF_l704 [d ,--(,eAE{caau{x7g%Ums<&fvc*S~ɡ c}#FJql?_P+/U-ed9([Ri.!t`}CrO P1~ d[YV(\t6@(lC _z @T%`x+5Q @AN*_C 0fM@K!VL  g~ SKEY009.A~ e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_VAXNDB.OLB;2z| 6~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'6| !"#$%&'()*+,-./012ON%L LANE SKEY_VERSION%eTt LANE SKEY_VERSION519nV1.09 SKEY_VERSIONV1.0 4-FEB-1998 12:26DEC C V5.5-002PS/Key %d.%dmPS/Key for VMS %d.%d-%03ddP12:26:58XPFeb 4 1998PP%s %sLP%cHP-%d@P%c%d.%d0PDECC %d.%d PDECC %d.%d-%03dPDECC %c%d.%dPDECC %c%d.%d-%03dP^d~ DECC$MALLOCPVY1PXŏX\\2PǏPWŏW\\PǏ'PRŏ'R\\PUR TS#PRSPR V\\\PPSSTTR(USS6UWXRSV DECC$DSPRINTF$PURRUWXRV DECC$DSPRINTFVYYPP^d~ DECC$MALLOCPUV1PSŏ'S\ DECC$STRCAT DECC$DSPRINTF DECC$MALLOC SKEY_CCVERSION xSKEY_VMSVERSION  SKEY_CREATED X SKEY_VERSION$CODE$DATA $ADDRESS_DATAU\PǏdPTŏdT\\P@PAT\\\WP~lU DECC$DSPRINTFRbS5S^bU DECC$STRCATTW~EbU DECC$STRCATUVVP^d~ DECC$MALLOCP\RP$\ DECC$DSPRINTF\RRP^W VU@~ DECC$MALLOCPST(PURRUVWRS DECC$DSPRINTFSTTPww]ЭRT SYS$CONNECTPˏRR:Pݬ DECC$STRLENPP DECC$MALLOCPPݬ DECC$STRCPYPP^RbPPd}}Ѭ1{P1oPd1dQPP|dPvdPTSYS$PUTP\dPP찏Ьݬ DECC$STRLENPެP81HLV1.09 SKEY_VERSIONV1.0 4-FEB-1998 12:02LDEC C V5.5-002PS/Key %d.%dmPS/Key for VMS %d.%d-%03ddP12:02:54XPFeb 4 1998PP%s %sLP%cHP-%d@P%c%d.%d0PDECC %d.%d PDECC %d.%d-%03dPDECC %c%d.%dPDECC %c%d.%d-%03dP^d~ DECC$MALLOCPVY1PXŏX\\2PǏPWŏW\\PǏ'PRŏ'R\\PUR TS#PRSPR V\\\PPSSTTR(USSIUWXRSV DECC$DSPRINTF$PURRUWXRV DECC$DSPRINTFVYYPP^d~ DECC$MALLOCPUV1PSŏ'S\ DECC$STRCAT DECC$DSPRINTF DECC$MALLOC SKEY_CCVERSION xSKEY_VMSVERSION  SKEY_CREATED X SKEY_VERSION$CODE$DATA $ADDRESS_DATAU\PǏdPTŏdT\\P@PAT\\\WP~lU DECC$DSPRINTFRbS5S^bU DECC$STRCATTW~EbU DECC$STRCATUVVO1(!V1.0N7 SKEY_CRYPTV1.0 3-FEB-1998 11:13DEC C V5.5-002Potp-%s %d %s Pmd5 Pmd4P PrP%02XP%ldhPDISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1\Plength >= 02PDISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1&Pstart >= 0PDISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1Plength <= 16PDISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1Pstart + length <= 66PDISK$USERS:[LANE.WOR^E SKEY_CRYPT!5T  LANE SKEY_CLI! 9  LANE SKEY_MSG! W  LANE SKEY_CLD e6  LANE SKEY_DB!   LANE SKEY_LOGO  LANE UTIL%  LANE SKEY_VERSION%W  LANE SKEYSHR_XFER#F LANE SKEY_CRYPT  LANE SKEY_DB!5 LANE SKEY_LOG%; LANE SKEY_VERSION#q! LANE SKEY_<1*!0E2SKEY_MSG0 3-FEB-1998 11:13 3-FEB-1998 11:13VAX-11 Message V04-00k$ABS$ MSG$SECTIONMSG$AAAAAAAAAAAMSG$AAAAAAAAAABMSG$AAAAAAAAAAC4 SKEY$_OKAUTH SKEY$_USERMOD SKEY$_INVALT SKEY$_DUPALTx SKEY$_NOUAFp SKEY$_LONGPWDhSKEY$_SHORTPWDb SKEY$_NOAUTHZSKEY$_PARTDICTR SKEY$_BADENCJ SKEY$_OUTERRB SKEY$_=TIMEOUT: SKEY$_PARITY4 SKEY$_NOUSER, SKEY$_UNALGOR$ SKEY$_NOSYSPR SKEY$_NOSECUR SKEY$_NOPARAM  SKEY$_VOIDPWDSKEY$_FACILITYPeP*P'P({ 6 v(08@8HlPX`h&phx BfBVOIDPWD/Password string is void, this shouldn't happen!>,NOPARAMRequired parameter missing@NOSECUR-Requested fuction requires SECURITY privilege4NOSYSPR"Requested function requires SYSPRV(UNALGORUnknown hash algorithm2NOUSER No S/Key database entry for user4PARITY#Password string failed parity check4TIMEOUT"Timeout waiting for password input2OUTERR!Error opening file !AZ for output&BADENCBad password encoding6PARTDICT"Alternate dictionary is incomplete,NOAUTHS/Key authorization failureBSHORTPWD/Password shorter than 10 characters is insecureHLONGPWD6Password longer than 63 characters may be non-portable$NOUAFUser not in UAF file8DUPALT'Alternate dictionary entry is duplicate6INVALT%Alternate dictionary entry is invalid$USERMODUsername modified*OKAUTHS/Key authorization okaySKEYwwPP DECC$MALLOCPQ޼PQ`޼P`)= 0NPDISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1BPstart >= 0PDISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1 Plength <= 11P P P P P PAPABEACEACTADPADAADDAGOAIDAIMAIRALLALPAM8PAMYAN@PANAANDANNANTANYAPEAPSAPTARCAREARKARMARTASxPASHASKATPATEAUGAUKAVEAWEAWKAWLAWNAXPAYEBADBAGBAHBAMBANBARBATBAYBEPBEDBEEBEGBENBETBEYBIBBIDBIGBINBITBOBBOGBQONBOOBOPBOWBOYBUBBUDBUGBUMBUNBUSBUTBUYBY<PBYECABCALCAMCANCAPCARCATCAWCODCOGCOLCONCOOCOPCOTCOWCOYCRYCUBCUECUPCURCUTDABDADDAMDANDARDAYDEEDELDENDESDEWDIDDIEDIGDINDIPDOPDOEDOGDONDOTDOWDRYDUBDUDDUEDUGDUNEAREATEDPEELEGGEGOELIELKELMELYEM8PENDESTETCEVAEVEEWEEYEFADFANFARFATFAYFEDFEEFEWFIBFIGFINFIRFITFLOFLYFOEFOGFORFRYFUMFUNFURGABGADGAGGALGAMGAPGASGAYGEEGELGEMGETGIGGILGIRNGOPGOTGUMGUNGUSGUTGUYGYMGYPHAPHADHALHAMHANHAPHASHATHAWHAYHE8PHEMHENHERHEWHEYHIPPHIDHIMHIPHISHITHOLhPHOBHOCHOEHOGHOPHOTHOWHUBHUEHUGHUHHUMHUTIPICYIDAIF ~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'P{|PIKEILLINKINNIOPIONIQPIRAIREIRKISPITPITSIVYJABJAGJAMJANJARJAWJAYJETJIGJIMJOPJOBJOEJOGJOTJOYJUGJUTKAYKEGKENKEYKIDKIMKINKITLAPPLABLACLADLAGLAMLAPLAWLAYLEALEDLEELEGLENLEOLETLEWLIDLIELINSLIPLITLOPLOBLOGLOPLOSLOTLOULOWLOYLUGLYEMAPMACMADMAEMANMAOMAPMATMAWMAYMEPMEGMELMENMETMEWMIDMINMITMOBMODMOEMOOMOPMOSMOTMOWMUDMUGMUMMYLPNABNAGNANNAPNATNAYNEhPNEDNEENETNEWNIBNILNIPNITNOPNOBNODNONNORNOTNOVNOWNUPNUNNUTOPOAFOAKOAROATODDODEOFPOFFOFTOHPOILOKPOLDONPONEORPORBOREORROSPOTTOUROUTOVAOWPOWEOWLOWNOX,PPA0PPADPALPAMPATNPAPPARPATPAWPAYPEAPEGPENPEPPERPETPEWPHIPIxPPIEPINPITPLYPOPPODPOEPOPPOTPOWPROPRYPUBPUGPUNPUPPUTQUORAGRAMRANRAPRATRAWRAYREBREDREPRETRIBRIDRIGRIMRIORIPROBRODROERONROTROWROYRUBRUERUGRUMRUNRYESACSADSAGSALSAMSANSAPSATSAWSAYSEASECSEESENSETSEWSHESHYSINSIPSIRSISSITSKISKYSLYSOPSOBSODSONSOPSOWSOYSPASPYSUBSUDSUESUMSUNSUPTABTADTAGTANTAPTARTEATEDTEETENTHETHYTICTIETIMTINTIPTOU$PTOETOGTOMTONTOOTOPTOWTOYTRYTUBTUGTUMTUNTWOUN`PUPdPUShPUSEVANVATVETVIEWADWAGWARWASWAYWEPWEBWEDWEEWETWHOWHYWINWITWOKWONWOOWOWWRYWUPYAMYAPYAWYEPYEAYESYETYOUABEDABELABETABLEABUTACHEACIDACMEACREACTAACTSADAMADDSADENAFARAFROAGEEAHEMAHOYAIDAAIDEAIDSAIRYAJARAKINALANALECALGAALIAALLYALMAALOEALSOALTOALUMALVAAMENAMESAMIDAMMOAMOKAMOSAMRAANDYANEWANNAANNEANTEANTIAQUAARABARCHAREAARGOARIDARMYARTSARTYASIAASKSATOMAUNTAURAAUTOAVERAVIDAVVISAVONAVOWAWAYAWRYBABEBABYBACHBACKBADEBAILBAITBAKEBALDBALEBALIBALKBALLBALMBANDBANEBANGBANKBARBBARDBAREBARKBARNBARRBASEBASHBASKBASSBATEBATHBAWDBAWLBEADBEAKBEAMBEANBEARBEATBEAUBECKBEEFBEENBEERBEETBELABELLBELTBENDBENTBERGBERNBERTBESSBESTBETABETHBHOYBIASBIDEBIENBILEBILKBILLBINDBINGBIRDBITEBITSBLABBLATBLEDBLEWBLOBBLOCBLOTBLOWBLUEBLUMBLURBOARBOATBOCABOCKBODEBODYBOGYBOHRBOILBOLDBOLOBOLTBOMBBONABONDBONEBONGBONNBONYBOOKBOOMBOONBOOTBOREBORGBORNBOSEBOSSBOTHBOUTBOWLBOYDBRADBRAEBRAGBRANBRAYBREDBREWBRIGBRIMWBROWBUCKBUDDBUFFBULBBULKBULLBUNKBUNTBUOYBURGBURLBURNBURRBURTBURYBUSHBUSSBUSTBUSYBYTECADYCAFECAGECAINCAKECALFCALLCALMCAMECANECANTCARDCARECARLCARRCARTCASECASHCASKCASTCAVECEILCELLCENTCERNCHADCHARCHATCHAWCHEFCHENCHEWCHICCHINCHOUCHOWCHUBCHUGCHUMCITECITYCLADCLAMCLANCLAWCLAYCLODCLOGCLOTCLUBCLUECOALCOATCOCACOCKCOCOCODACODECODYCOEDCOILCOINCOKECOLACOLDCOLTCOMACOMBCOMECOOKCOOLCOONCOOTCORDCORECORKCORNCOSTCOVECOWLCRABCRAGCRAMCRAYCREWCRIBCROWCRUDCUBACUBECUFFCULLCULTCUNYCURBCURDCURECURLCURTCUTSDADEDALEDAMEDAN[ADANEDANGDANKDAREDARKDARNDARTDASHDATADATEDAVEDAVYDAWNDAYSDEADDEAFDEALDEANDEARDEBTDECKDEEDDEEMDEERDEFTDEFYDELLDENTDENYDESKDIALDICEDIEDDIETDIMEDINEDINGDINTDIREDIRTDISCDISHDISKDIVEDOCKDOESDOLEDOLLDOLTDOMEDONEDOOMDOORDORADOSEDOTEDOUGDOURDOVEDOWNDRABDRAGDRAMDRAWDREWDRUBDRUGDRUMDUALDUCKDUCTDUELDUETDUKEDULLDUMBDUNEDUNKDUSKDUSTDUTYEACHEARLEARNEASEEASTEASYEBENECHOEDDYEDENEDGEEDGYEDITEDNAEGANELANELBAELLAELSEEMILEMITEMMAENDSERICEROSEVENEVEREVILEYEDFACEFACTFADEFAILFAINFAIRFAKEFALLFAMEFANGFARMFASTFATEFAWNFEY1B V1.0C1UTILV1.022-JAN-1998 15:21DEC C V5.5-002DPLNM$PROCESS5PLNM$FILE_DEV(PLNM$FILE_DEVPPP!UL !UL:!UL:!ULPSYS$INPUTP%08.8XPP ^ЬP!`PЬRb~ DECC$TOLOWERZPbRRP^ЬP!`PЬRb~ DECC$TOUPPERPbRRP^լ/ЬP׬P$PЬRb~ SYS$WFLOR SYS$TRNLNM SYS$SETPRV SYS$SETIMRSYS$QIO SYS$GETJPIW SYS$GETDVIWSYS$FAO SYS$DASSGN SYS$CRELNM SYS$CLREF SYS$CANTIM SYS$CANCEL SYS$BINTIM SYS$ASSIGN LIB$SIGNAL LIB$GET_EF LIB$FREE_EF DECC$STRLEN DECC$STRNCPY DECC$STRCPY DECC$STRCAT DECC$MEMSET DECC$MALLOC DECC$FREE DECC$DSPRINTF DECC$TOUPPER DECC$TOLOWER (LC XUC UCN DECC$TOUPPERPbRЬR׬RP<8^(ς˭ |~؟|~ SYS$GETJPIWPSS S LIB$SIGNAL@ quot  remR @ quot  rem RS TS TS TS T Sdsc$descriptor@ dsc$w_length dsc$b_fdtype dsc$b_class dsc$a_pointer  RS TS T Sdsc$descriptor_s@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer  Rdsc$descriptor_d@ dsc$w_lengthE dsc$b_dtype dsc$b_class dsc$a_pointer  Rdsc$descriptor_a dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dscg$b_digitsP dsc$b_aflags  RX dsc$b_dimct` dsc$l_arsizeR STS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" ""dsc$v_fl_column" !"dsc$v_fl_coeff" ""dsc$v_fl_bounds" Rdsc$descriptor_p@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_sd` dsc$w_hlength dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_sflags RRSTS $"dsc$v_fl_binscale" Rdsc$descriptor_nca dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeiRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_vs@dsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer ERdsc$descriptor_vsadsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dslc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_ubs` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_posRdsc$descriptor_uba dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc k1 V1.01MD4CV1.022-JAN-1998 14:22DEC C V5.5-002'R MD4CMD4Inito9Bnoname.2context RCD MD4Updatenoname.4 __1 @noname.7noname.8 noname.6 wX(noname.5,noname.9U noname.10i indexpartLencontext tR input  inputLenXMD4FinalPPЬQЬPС޼PЏ#Eg`ЬPЏЬPЏܺЬPЏvT2 ^ЬPPʏPPЬQx PPPx PѡP ЬQPPЬQ PPPí@PPѬ {ݭݬЭQЬPA DECC$MEMCPYЬP޼P`Э?PP 3PЭP޼Q@a޼P`@PP?PP Pí PPЭP޼Q@aЭQЬPA DECC$MEMCPYP^ЬP ЬPPʏm$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_sb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$l_sb_l1` dsc$l_sb_u1Rdsc$descriptor_ubsb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_pos` dsc$l_ubsb_l1n dsc$l_ubsb_u1 R __ITEM_LIST_3` length code address @return_length_address !R__IOSB@ status count dvispecific"Rprvdef@prv$r_prvdef_bits0 #Rprv$r_prvdef_bits1 $Rprv$r_prvdef_bits2 %R&R#S&T&S @" prv$v_cmkrnl" " prv$v_cmexec" " u prv$v_sysnam" " prv$v_grpnam" !"prv$v_allspool" " prv$v_detach" !"prv$v_diagnose" " prv$v_log_io" " prv$v_group" " prv$v_noacnt" " prv$v_prmceb" " prv$v_prmmbx" " prv$v_pswapm" " prv$v_setpri" " prv$v_setprv" " prv$v_tmpmbx" " prv$v_world" " prv$v p1 u V1.01MD5CV1.022-JAN-1998 14:22DEC C V5.5-002'R MD5CMD5Init9Bnoname.2context RCD MD5Updatenoname.4 __1?@noname.7noname.8 noname.6 wE(noname.5,noname.9U noname.10i indexpartLencontext qR input  inputLenXMD5FinalPPPЬQЬPС޼PЏ#Eg`ЬPЏЬPЏܺЬPЏvT2 ^ЬPPʏPPЬQx PPPx PѡP ЬQPPЬQ PPPí@PPѬ {ݭݬЭQЬPA DECC$MEMCPYЬP޼P`Э?PP 3PЭP޼Q@a޼P`@PP?PP Pí PPЭP޼Q@aЭQЬPA DECC$MEMCPYP^ЬP3ЬPPʏrPPѭ8 í8PPíxPPݭݬ MD5UPDATEݬP noname.12 noname.13 noname.14 bits*& index padLen digest context R MD5UPDATE޼P`ݬݏXݬ DECC$MEMSETP^޼P`ЬPРЬPРЬPР ݏ@ݬ3ҭQQQҭPPPPPPQQxjQQQxQPPQQPPҭQsQQҭPPPPPPQQVQQQx Q PPQQPPҭQQQҭPPPPPPQQp $QQQxQPPQQPPҭQQQҭPPPPPPQQνQQQxQ PPQQPPҭQQQҭPPPPPPQQ|QíQQxQPPQQPPҭQQQҭPPPPPPQQ*ƇGQQQx Q PPQQPPҭQQQҭPPPPPPQQF0QQQxQPPQQPPҭQQQҭPPPPPPQQFQQQxQ PPQQPPҭQQQҭPPPPPPQQؘiQQQxQPPQQPPҭQQQҭPPPPPPQQDQQQx Q PPQQPPҭQQQҭPPPPPPQQ[QQQxQPȅPQQPPҭQQQҭPPPPPPQQ\QQQxQ PPQQPPҭQQQҭPPPPPPQQ"kQQQxQPPQQPPҭQQQҭPPPPPPQQqQQQx Q PPQQPPҭQQQҭPPPPPȀPQQCyQQQxQPPQQPPҭQQvPPѭ8 í8PPíxPPݭݬ MD4UPDATEݬ noname.12 noname.13 noname.14 bits*& index padLen digest context R MD4UPDATE޼P`ݬT ݏXݬ DECC$MEMSETP^޼P`ЬPРЬPРЬPР ݏ@ݬ ҭQQQҭPPPPPPQQQQxQPPQQҭQQQҀPPPPP_mount" " prv$v_oper"  " prv$v_exquota" " prv$v_netmbx" " prv$v_volpro" " prv$v_phy_io" " prv$v_bugchk" E" prv$v_prmgbl" " prv$v_sysgbl" " prv$v_pfnmap" " prv$v_shmem" " prv$v_sysprv" " prv$v_bypass" " prv$v_syslck" " prv$v_share"  " prv$v_upgrade"wPQQQQxQPPQQҭQQQҭPPPPPPQQQQx Q PPQQҭQQQҭPPPPPPQQQQxQ PPQQҭQQQҭPPPPPPQQQQxQPPQQҭQQQҭPPPPPPQQQQxQPPQQҭQQQҭPPPPPPQQQQx Q PPQQҭQQQҭPPPPPPQQQQxQ PPQQҭQQQҭPPPPPPQQQQxQPPQQҭQQQҭPPPPPPQQQQxQPPQQҭQQQҭPPPPPPQQQQxx Q PPQQҭQQQҭPPPPPPQQQQxQ PPQQҭQQQҭPPPPPPQQQQxQPPQQҭQQQҭPPPPPPQQQQxQPPQQҭQQQҭPPPPPPQQQQx Q PPQQҭQQQҭPPPPPPQQQQxQ PPQQҭQQQҭPPPPQҭ MD4Transform 5__26 k__36 __46 __56  __66 C__76 y__86 y__96 __106 __116 Q__126 __136 __146 __156 )__166 ___176 __18F __19F !__20F g__21F __22F EPPPPQQyZQQQxQPPQQҭQQQҭPPPPQҭPPPPQQyZQQQxQPPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q zPPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQҭQQQҭPPPPQҭPPPPQQyZQQQxQPPQQҭQQQҭPPPPQҭPPPPQQyZQQQxQPPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQҭQQQҭPPPPQҭPPPPQQyZQQQxQPPQQҭQQQҭPPPPQҭPPPPQQyZQQQxQPPQQ{ҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQҭQQQҭPPPPQҭPPPPQQyZQQQxQPPQQҭQ˅QQҭPPPPQҭPPPPQQyZQQQxQPPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQҭQQQҭPPPPQҭPPPPQQyZQQQx Q PPQQͭP̭PPnPPPxQPPQQͭP̭PPnPPPx |Q PPQQͭP̭PPnPPPx Q PPQQͭP̭PPnPPPxQPPQQͭP̭PPnPPPxQPPQQͭP̭PPnPPPx Q PPQQͭP̭PPnPPPx Q PPQQͭP̭PPnPPPxQPPQQͭP̭PPnPPPxQPPQQͭ__23F 9__24F __25F __26F  __27F Q__28F __29F} __30F # __31F i __32F  __33F  __34/ $ __35/ S __36/  __37/  __38/  __39/  __40/ > __41/ m __42/  __43/  __44/ q __45/ ) __46/ X __47/  __48/  __49/0  noname.16ٸx*~&@ٴaٰb٬c٨d state  block 9 4  MD4EncodeL  noname.19P L __50  noname.20  noname.18  noname.21ij output  input   len  MD4Decode  noname.24` noname.25y noname.23y noname.26ij output  input   lenP̭PPnPPPx Q PPQQͭP̭PPnPPPx Q PPQQͭP̭PPnPPPxQPPQQͭP̭PPnPPPxQPPQQͭP̭PPnPPPx Q PPQQͭP̭PPnPPPx Q PPQQͭP̭PPnPPPxQPPQQЬQaPPaЬQPPЬQPPЬQ PP ݏ@ DECC$MEMSETP ^ѭ 1ЭR޼SЭP޼Qˏ@aPPBcP޼QЭR޼SBcRbRʏRR@a ;5% dʺ   rSRSTSTSTS  state*& count*& buffer*&@@?PADDING*&@@?6(L"DISK$USERS:[LANE.WORK.SKEY]MD4.H;1>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STRING9yvQ%DISK$USERS:[LANE.WORK.SKEY]GLOBAL.H;17.P:x#DISK$USERS:[LANE.WORK.SKEY]MD4C.C;1N      % ! MD4UPDATE DECC$MEMSET DECC$MEMCPY MD4INIT D MD4UPDATE XMD4FINALz$CODE@$DATA $ADDRESS_DATAPP޼QЭR޼SBcRbRʏRR@aP޼QЭR޼SBcRbRʏRR@aRRRRѭ 1XP^ѭ mЭS޼TЭP޼Q@aRP޼Q@aPxPPPRP޼Q@aPxPPPRP޼Q@aPxPPPRRCdRRRRѭ ww DECC$MALLOCPT <$~ LIB$SIGNALT|~؟|~ SYS$GETJPIWPSS S LIB$SIGNAL state*& count*& buffer*&@@?R @ quot  remR @ quot  remR_iobuf _cnt _ptr  @_base  `_flag !&.H!?WzUTEP((4=2]F{\O 0c $;.`4 I$ 1/.re.hl_d!:A("eυ\H kCS "E)δN&㯧n@mHJg;)ߐ]LBw}0Wj;&HK3d;@%LMW|MC`(imkb$VO= Gv԰,|%/!@.@RP@Tg]69G*6 4Ht(.Mn;n1)a VYR;UnMOǧd2u E?O&k b*&Kq.\(^Du9`FSZd;O#kgX5~ªdt!F#oz0z 9| { ;,PN }>pFg~֓xd_FH̬UHC4 5"';sjB`Q0)r#ɦ}\c#R|YFibue ER\rrG $Q5Sl`g8S%ipD v_Ke?XC/q?'eV 1O$D,].dhktJUR 4D4 0AQ&-8V7D,8nSlHΎ M%!m+,n,p%xbXiM+~2Voc2 +0-tE$*A54=&7Q3@64&QA0K*qH`a>ELGar|Q2flU!n04-&G?>5*e<>PLTB uWjV)Y({TmaH( 8yUp2x%8$/R1:#2H]BXd eMI;Y@O\a;s < UZ$1 L.pv+ xD7uiy: 9!PVP X P{ HFudE>lUh4H+sd]BbBC|: VI,[VNQLJPVW72&SY=#-l_rbW=.Q P_IJcͧh}`p9'yWmaքd)!L DhJ1R);-}!k2*u^1+x2Kշ5{Ǭ k # 0QmLY@;8 >TXw~1,eسk1l|1zWJ:M7NvT !ƸgH;A:6PZ kJ!eCdgs0 ?Is;3qӗ\-bQjaFGFT+3-ڽy4lKLκ\YB a({V+2[FG\?L ~Vgiqqr)DK=4G-a(,RfݬZ :cA㘿?903 }gdEE>(/&rҍȒXha}`"v JeYo OWa|. x}_Ic*P d  d.'3.S-Df A}2q =¦Yy7D=h tz=S/頁+Ogd4jF^7-zMWeY:7bg4}9bK(~a_’^ <-,VX]NH_ eLT#f(X_TN_Cm 5 ZνG^mw& \$em96M*^h!f塇 etqIq=e_l6# hr4:dY/ɟHR Om^QNrT˯~p?pEv59@|%]}ŎÞmz7.Q%M1? *n?b%0ohBl,;yzk(kvhƍKW">oE4s0>e^sZ\1&_&r4AYV <2b >CN{F\KY zI& &'6[X=7Yb-9!>zzCSJ.P3%;OEO5- KR2˲"d+uqUx2 |)Ti>+&"2Fy;bT-G]ĀX_,!Yyq6mSXV -ٻq-Y<?L4nA<Z0ק1Yfj+2>m{-hr)PQi@;ΏOVGr^:nI@ uW(wSlr%őX F`G%SRF0wv AwYL*A6<:k PHuhU"Umr?D05{usB(-hM Wnfm[P1$ 'ؐ[`]>(mŬҖé~oB'! IUAޛtZѵ0LLNcC«G59ʼ^25v'}:lVr7TClX~ٹmB /%͏qb $#c)U\?NRwrVTHlI_v<0_Ӕ0kVsGMּKCHlELE(VQ6+|d#P _ $$"@KK=3'~]$ \. "G|ea2\k!CFۛ v*T%yT[<,T0,s1tuic4)^jGƛ#@|W +TH5勂=Cu1yu7AkƑdذt^~vjʑ,Iy2Ub+J! Z0@e./\T@v<I{m/e;q7Cc1s5&Vhl蛧IðɫH֭PH?b~:!FƂ:O1fDi=LGC XziIkWO*=&s)_^vˎ}mÏM"yB.jbQ:Wxа(IN;#.b؛Y21OE&mF'IA*Tҍ057=Rm{Ti \X·5ZmaI+|1VZ;]hs(&ή/J1nr|ܢCǝ@Z m7i,EaýO% ?@xn 9e㒰!*3x~Sn6#+$9;L HB[)ّJ3R]1/"dɋ( 0ںus5tJ|rte:RQ"iIlkM%vdMCg_NhxP8bX_V]C=SR D":FHJ82Fb:/Ua-JD\ӂgMΘ?'Gۮp,YDmDd-e@@ÎRG +$LjtXew6)tҽoV`v91gz&ILz0!'P~sy?b/Іow#Gr"׎͸3ت.'KqM9R܏jxW0j JC!#*ґt+"[L4=Dlmӏ$OC3x8녿&| lMozO/XU7vd=Iyб\|(cp520?E\-1LJ`⵻<7Ii{dQeuPLe ^L&&D,P~ſDC4!uGzb٬`Yd-w|LL%?t#ԞBUu]N2N/):f E"GSJvwMzKEvoښƉ䯢g1od5v '~[fMlLJ5} tal iTk"%^Ըnpu׻Q7&mw2-p|UC0zz,]]Ib/HOlvtdgѵcAcSv0y۱sN3y ᙉDޅU ^6QE.VqB߽Y_ >>F)>ͻR?34(ǿu[_ zt\* f<0Qfx4B4@š]la[E0wMy5GRԲc~4mj=p콋?򦥣-ba<4gU 8TS>2|Z`!&d-ۢ-}yFD2Z9(lgxײ0K՘ฑ@i-Fhl͑RT1nB2_uQ^K/~37q:>H,^ٖCBʅDN-TGLD[DC@F݋!AS`n+$3w(}ރB }n*SoP=̋ 7/>vK_54OŇ@X`DP; acV$rY^h"g+b_ Єt#3FXQ+mUnWbkv1Pr)wO²!O|$k@&Y7d\~*ziI%<ح"ڪNkQ((tLCB ꐚ=[sWPeM=[olhA#fJʪyC98;c6R_qfMŒfAvP{ p~wLw`o\ $C/P֧;890-'`'fw'6 ,$~L]vpM% ;d-?adx\RsM%%h"B+&yIZC~DZw ]ex !˵Z@)N}d}Jvӥ1?sl\{=EnUg38 ,)XaZ|z?یhgO_B^ )zeϠ͔9'ٲCWb2)-fG\-\FȍupPVޫ@%$FȜkfnxqQUu5;D4]'6pH89  `<8`´oWNrOyty蹒}K=P3Nuk ~a4x|WJ_)@F>3wY$ftRY1M"PVcX<r4M)\ !tG4T)?wN; x2^AxD7 h:B3rİ;-Ήmy:jkLB2DBw">%r#[B-䖩oZ(.he<[䗐cD91ڋIjOE&8Uz1S,ϐ;eKKpŎL5ǙqI -$sdʂnLE ( }Ro[3&V@2lCP򖗤Hx˼dDZ'wwǯ$7YE0*?ʗ5]Pdĭ;g7g6ρ?hdQaΤ֋:$(gDy)b'.y"< \w/?SXŇ*l9a[FČWvϽ*k]INV?{?E8Oɶ } ӨH5&amú>-\)8!$`T#3qGEk|ꑎ{pϋ!ɐvѣ2N,U 2zՑM5 Bj>4 :(Gu1I<,B aVsk3m%f.Tin]c=)GbFuÆubw X H븿|MUޑ0w!ܜArP;^w :3i+o +RP]?Pk6!>u9`۬Y_(RBAT!Z5}h.!cw>$xO(q c-IXH36KmbZTJ9#1| 6w>Y4%n!ϔw(^ r}5T>lTdeD1@ ,j6XȨ4:stxV&^JM h8vcnn:Gu`!:7©cpZSj#fR3q"aڷ*+):$"l#]F,Ud߽C}#|8e+b9?ap 9,IFx M? ]i{([5!$4#zn]aÓt993'eT"}w/5~' V ROiBJcW۝# ̀^e6% ͆U):A`L6yevC6#c3uVd .DBi\Gv \i;[(gqZl-gV˔ۨQ0NݦKՕAg#&V9 JxO 'wN+&hOn|wٔ=h ݶGKMϽW{hp .h:ἂpgrSqb霘\gf&c$q?sQ"& *! T} zq;/31vQX^:ݎG5/?1l4|}Q9ɳh[ , \q{?.z 2nj̀>%۴݋d+X/3|C'tsEx%B3c&.AJcЬ\ nF+ +Q7Tۓh!}9lSu k)\ݠ$'K0-X^<уV˲l"6{`ЮbCbV9C݌ Nq" :%.);7דeaZ)Kf~ڲ:+CSWKo*b`Ƚ1p$׀b K)I.0l{pw"H![O*`_nէwUA>fm WDv |$֕({lqsH'3PRm9@Q68ǨGZx_eUslr%D+|xe#?2'OM t ͲT;QoA=HE줭7!Ҵ ޱdzuO4 #G=J/B<{╡{ .MiX<=:<@XSp7;Nj*Xlu|rAt u`S5%gv|#w&&fyaC[ @U!yd+1CyZ30:5fK".^]@_?Y)Jxw sIsd$%KO2BMvˀ8M޹XKRSFWF'-d6v8kƗVLFF ,_!bb|mXyežC[sNp~(]&'D[Ȃ%ЎmF~G -+\K[=Sa#;cYLNN"]6`rC2?{8)!Z?>l4}lߙ%dss60dt Rp`[sæ2;V:_zK5_nc1{{B1s\JLw6OH{" Vo,8*co7< ݆szGS_6+dtpe tjx-rS b;J̶+ZD \ \^VJ  &#Ja4[QRf&786TL2Km;HO Tr`fNO_EPt t RE0y2 r3/G%(HF/8m!2j&Sl,:1!jxēwKB9v$۬P?oE h^fѼ|W]өr +sԳT}Ҁݹ'ΕieOo5md[f!cQ\MNKb g^u±7"_B˺4E1%5R5_ZI{6)`MnI "6ug..TNQ FzT:l.1Ad'rcfNpFrpWLT(wjgaakw0nE 'kN rTax""W]u"יO aU~uz^"F!-ࠩ0;)My{`8;G(@`]~3j9f*e.%GG1jQ|kBLb`a#%>bdV)m'U˜A1G[+NS)yi%]:;5|7nvt4_`L;h&j)5M'0oxH)GDIMI.sb76R Ovya7֕^:<[weuyrXl`$KVV&[Ze6H0ޙtJzJ ;ř]Q)W(<ı+~w4'էOMQb_49OSlz x5a (,VW=7`%6L 4By""F5p"5rB7ņNO>%B%;2; 0Xe,kouAs'{\>6 "lZk*ֻkt`_:v[gÁE` ̠x>g|ujJl醀_,"9TI>xjݹ(뚷0!ٸݴ2݉9I{F}&?$\K}kWs ǘrҮN`w*Ei+HӶ" !AR?S>7zh,,\y@@ŃqѹjvB:gc-yDp"4a򋑺;qp%}=gOI ;ʣwIJG,:nONp>{qFf+}->_%Wm K*O@ۅ^[&,` oH6ݪQg S8WF- rsibWen;Z Z¼7u R՜n%?IY'R_Bg7.D~M6=u8Y;\:$VX1rֳ>G 8}8P:qn%Me6rkx/|O~Ԓ{\J/,F$PQ {A`"8Npx,a#:7?K\y9K !cH_7 [E 19I>Ww4=ugA?yfhXTZq(&dbX4wf'7V79Q)F 9M7qMi;^5݈".o 5Q,\8L4`S(=L;ߴ>{x*xh ߦJL5|TsҺ!@^ X;]Dj-rRF]Ji ]ݦy W2׿Ŋ;IM¥[ &z~R($1cn-$uYqtlP4L*7k xÍׯ5{2X+$"8lj˪~]Y*'F`b^="v@EĔ ]8mϘB2X|sLODg ҊPe8~i y+?7un)wYw#P]-t* ~5m4 s@alswؤb c %cy9@_ 鮔&?# \(0\7Ͻ\oi k)$ b+5qJuхV܎Sk#TZGTD>8]ݮL"JA T*,Ѝg]m`b<ƻd#|Ol}j떡קv8.J +'YoVe-ouYrH!mͤאgHc\ĸGhpf)0?K`~B8 M6d)rЩgn+PyK$Q VB=d0tBuNrUӐt DS$/e1nq_%H% [|Mdo+ N0`XT\g.s!aCl (TYF)lh̴C*#!P.Hv)㛛c+[$$^ea*hWre Y[ ]1Xx^s,:7HVfAfL7?Vh*s*dŵ*1^3,;h /|FCCJSGYUluq;h>Ga gˬ0Mە_wi;5cSEop}"-p-s+k *3UI㕇q?^XˑzBӪeՑQ[/c_Q6|7m Lπ̲%tbx9 &9&gd%ݽ|3%\EiAjQoWiү%1ѕ.H | ,f"gQsη }3Np li۵Z>䱈6YX9 ׸wu5:ml=&8.=RU5W<ȌABӽ$s&u~Ս6jy$_Nd{dzҒ?m98!V %b*^ I=$ުgw"d_v\enZZJJ-ȑ>\G'^~x (Xg-FD/ۚ_i,Rn81kA! 4ozH L|@jd Fs': ɾe_“`NjkN6FuWLag H'x=elA%tBvy+c?ozm~ PWU+2kt]5vkKx8a&tZ{y?/nPL_D@Ss/jM7Cl&.lRqD;iJR!2[ + ϕ]Y=dP5So2eWXȃNMmg8 "A~6:CsJ*L3bKxDH?Wֽk cI@{Yl 3XU$Tݬ?6AG2A 4ep ljJY; U1/b?Y~$A$(r%Yw]W?PPuc#A<^Ẁ|q~28'&w6aA#.*Y?LU FhƳ/ C@LBaqg&$6ּ@D)Gr {JXobaUSm[dTT`4Q]T2Gnmo֟t )!M1@m&oe,jA;i?9;B|E~j<;=uwrY1,e$L$ Yy'|j9;L8'AsKI]DPO+ Rq5=fw @9Y@PRV =|e6,UX" pZy+ !]?&ay p{wST!5ms57 b/l5Ռkco2=ChT#ݗy:,Y~{*nEFO*ą:t?ʒ#!"m.Vj$XiZg,78`;~i@]l&s"wvA?@L/t|v/XQ-f5υF78&xLwtYޯ)Ѩ{HDƔQPT\O$ߟ -u3 ZWEj{h{ޣ+JVaOqf$C-8wwbe|itPז XIo끉궲l"(D0>]U]4C=W%;?"aC4<ų5ogZK;Rp8O6-*q|WR&u?:3<[EW޳}} inx BB++*ƱܰXo&E :Zr\1W[X(!<"? \d ԉӕ ܲ+4wyX>E26vd{W ?S/zÓE&;m3U'.PY3Hq)'o`wnhpa{߷3/P2qT{6wεCC%-EO .@`Ǵ9>/꭫]5͉H|[PU֐<S:9AJ M@`5 R+P-xjyZdtT:_om5} nWKi))o1N`<3袼*N:b~Sƹ?DrNMxdech?u%Sdn6(WPbB^,Ȇvk#*~yt`6.1_'?`ejrpӘp|Iv= f< wapjuѻ+P>>ŪuygOBN>|4<O"li%ؤ@/K鈴z#)N00dz$Yp::4Ŕ--ѝ4?_`&ŋ;J68> oSBn4 -q|G/H%>5#Yʖ<^*Nye,/}L6SʆOAZ}< ?Vwz:.I+R3dҢ"ru*qUaGەб_iʖ_.\FL*g SR >W?Tb |QłA v4ؑo-E fq_:@e3r0EmW_!Gtِ_*[.fV{#&raGqN85NOD.Zx7`c尶*! GK(bwo[OӿYd˯YSNy@ŽpuaU2[EX;=A ?i_@-4<5uW1争YZMظ Cl=Ns֬bfՉꤌlaeQůL%1O;b&'R VΝ [jjJST^ϪHr;pο(W, TCE$ZԷXTYsNÛ~΀ۊ~9ΏvrRk}7b)^rbP/K÷؇&c)PCւ'ۻH"୺5|^6ͼۜBJ{N@~J8{ė0(nڥW"DV4E+>،>:d%KjD3:ׯ_)TGgViHY~åuy4^#Hȶ@ocB؟XJ`C )kt#/-\#f\ d&oaSqJ\H'^5IKSU$+W`5 {7߂vHfkЯn\>fJUt{ YVȲA%zH,N!jrsrz 6&*B0{/fXhiM(#a,~H¼(q%! )nu/=EJZIHEAlU5=61ROKiykdBF) _;הA=snǪk^n;=Wh{xW$Q4S9Ӽ#'`b'Ti&` HVz畮܉Sti)ϭ6=PF)ϝ$0s^gOaz,kۏ*:ɵ?GGo.OBK eI*-DxGﳛAsk  K i{^[d MٻNV]T|pU"/}8X~GIh;z,UDע156j2CȀ>\¯gĉv^b-"vDfj-KHK l 2 # כLw*k>k`?K#?ĊƂi$*# nter3j ֢>\Ѹ6T+2mu6=yfyJ Ⱥl_efjɼ`QCQ*Iҁ&uniP*˞s)Sak ;#4D }\f?%B>J,+f>ی?-ߙ;Y*+PM\kf) 6$'z޷Cp̓.~xAh{fφ3V5wأ8푬g˜5^qqp1[MC2D?Q[7R"$ #Ws5hޙ}gl)"`}0)njBȤ'VZg& 7a8yʀ |~Ү~IOTym. ?ϩy`$ *[(<ԜT4gW)CM҄$^g rFj"'H!3W϶O*;0lU(J2:'3!̏|GMW9cYnD($O/ ?!8.@/מ_KPRus>ㅍjD]Bc!jysvBz=_D尢VCv|0"J|}u.?Q8 wys1N1ڟG dvq #nTD0"9k$SKՋc>ː/&u΋k|0t?U oqޑ2NbҊ" `eSR~ps~\%b9'"QbFJ&8ﰔ«@6sS}Fu vE !֥E o8})UAh], cEqPhml$:~ vy]m`)/v)/ێč3˝a[Zj6wc[嘌_< PNއ~P+ܙR'D?/υw<7{\Zk=Fdhve$&oeYϱAPji|-Cj0Hc E^@cd4Ba,atʱwނ!%!^?$vw\2y7Z4qٜ0caBi-N 5X'&R,{bxR#4# :gg"pVKhtчػ F20H+/_8 AX4?dhAOX`Z'iL6psBX}&vH&pSbyu!lKedf4Dn  WmR}zna($q0Ahxm5=Fk1nR ?JrgGQy^ihns5{aa9M Q hT'& nA3^hmj[7^:> 8FΒcdm։dEkڝ W=-#._SegQA&NV$DtnXa~3>B37ܩ T>r35͌YOzQEm`JqvsPi /(dZV4uaRy/* |C~n9k::ޖ^,M_N蕥J$kތc t+Bzhek ; IA}BHdRJw?܅TʹJAv^Lz2b ;fU@uG:z *V|਒/%qM/xJGB&U[EZչRRHS֠/܊+1%>R d򾒗΃Zk0nZ$.-P nS/q>R0IW<y>EhYiػM&[n6%h$b2o\)h57Ct3FC/ցi' }3b%#s1teג:Dg1sNHk ̑GZZhZ13qct^uI!I?v1I1Z6b;US>!q.@0ktFmP+~R.yHG,MV)DX [A]H!mN As4F[gt SpB%KiF[S:o1k,V_<*;W ]*;XpW:5/ TG"C,hvP7t-9&G9 l9Pۊً~)0 f~6(WE]*4E/w0\,@]ͱ(KLݔ ]ʑ%%!釰*5>CDC L)YFZ/ϭŽUgP,ңq+ <ҡGTkbl{!B"t&w3TM/X1"{&m&Z@Miq6DVߏRBf<$X`~vmN { 19b#:(1];8ښrWQ90v|X*,wCL9!/h Ռ A^s, ^JOTOdctȽy|bue,luO(QsD^xCh33{JgM Kd}(h 7Ź2>j ÞdD讨~jvۑ9^w`>{`Req壍¦_h-g2$N+"=8hm7˭FOazL'07%^BaicoB\j@LA'q\p+&um1` ZDHwU<ϋhq6u0(A q 57# 3ָDWG|1mxNpqt/S(?.@[1q7-!7<N!'̒V4`?g3(ތbT{-lNLRqLX)y5 o&/E1 2 C/FBu?SUh:"t$nT7(Pd pnc&yl&_,+X~"WRZC"@2yTa<xH ⢣ai2:>):a]?Rk21c))ƒrOlmk3܋HZ8Z%YWV׺j{vHBɚC^ A ^g:{^ƗvTqܕrꃴQ21IFjECesal} U6"bMͳtƢd&t0oGwNWw bA؜\)^9O|(21.рMFQ"576<+_4+6AO(JkāH[1 3U^?1XʛAWT _[,qbҸ:Hs=q|oWGHpUa̖k"3t1E`IDm) nhx+4Y?9+KfS19S!v[y5/t+}N[;NN{{s(=} ppN%h:|/Wno!X׷B!L*`k5+tCI0#eMX<\,yP3U*3Rg4nDفKk'4%@:y}NuP v;Z*P1#?sUkhF 7\#c!  gbԀД\MC29Lp _x*5͖7u{_M K6^*F$jI]xgڰ9tWay7Ϗcz@YIo =!],xEλ3ʟUvks;# >C:hsF)b)Nvgg^| !QqJNsXQė&c kdrgcݝ=UNnI&Ύ? aSB%q38i0G%v`$F /yRc?'U_0X^e @.Œˤ;új1 .DJ.Wt)^H]qG0Jp tq ^Q\F/Ml VҔ;挙c2%;DUB+/ēJpe޲~>}ӱ3Z]CÖEI;+jq6ZhFZʂ#0߁E1[t.si:8\Cn.dKp1od0o9?Cw*g4jSY䆝*3*2e3TMF%bQIrU{ZApb ﬿2M҇\!t%v{j79I>]쫕. PC<`4V﫼L L$_ ']Y.=j J:1ǥo=֮,<8ʝ]]^Ī;p:88ND3, Mb-a% Rq<]y,kbe"N^*P4 pXmmԊ[ $Pӿdzb)_:& kM؂ o>G +yiԃ] ie288s&d.7 {?gȓ\ &NjceV2˓p\C5r_;  ʤ@c-=FgSO;}18ANYHP 1%VfNnMWnPMLI&iʪ 29/'D~~f&{upSt!w媲؍-m *Va=_m$L0ť+=mܫΆ}ǕWj=2Q';bEUEԌ3c}o}jf/U>FHM#G` \3|*e"/Ϫ Z1kPI¡ 7!JgMW9X j )-TUg̗Bha>;I>=}kY@L9О}nf5-f*!,)"鶯Y ^'Ω_+o#q)7wܚGk}K@xG},Â޳üWG`#l3.>99KS, 9 ۾=ˤM<> dM"W]᭸Z/"7&wUatKR8 .Fj% ɬ48Zvg+/4˄r9\$Bgv)5[5ok W{@UF3aO חb`qW6)aL*~ 8Xf)J7}UI:p9o\ 5"7]KcHybhlzaxnlp}*ɒc7~#"p8Gx :,s9=U7@*T=Z&c!d!?B%xlBψP#89jZ.-^nLEuR _F fSz>nu0.c[bnJxrZ1/ AD ,"t5jb3FNA6 ' w}eljo4i@[d"gnnOI+I+2 3fx Ý+ap*aIo&&2w)"W| !q /Q&'9*A>@A3/A 0e#{qd4cvONn>JIw71zmݧ+xӿ?Б2A9TX|ZzlۃZ$.1-/'S!/3)(Sr-z>*.K|;8VF zEE"v h6:SnJKf0X/UhPR|傃a.'j $z|~MР}[/cqj4z ?g},_z^Xp+f ϼٙ4U!Vqxv/~ٙS'O8v auݎ]!16^t}ag_6"|9h<~/ƹ `mG,B[ z`%/m+(&y͟h /;27 |-DXDpu}2dP4%"3-j 0s\Iۜ%Z!1 hQ? ēmpDIJ? W0^S LFǛ[:Ӄv<Z:6,$;KFtlZ$Ā$!e&rwG^ˎU8eU&tKhE禢Jozb+A/k*Y@l^x㤧ֹس,cw%RALi͵)ܚmއݰvf%՛<0\HFH% ,SPqf.2]RFa1zZa=!Rа_ ݨ30cu@ 1B! E(碶q#N̠Οjs0c6ڥ^rDϱYp@)J{RА\徨 r8)^Sd/.ӯzO{K`I%aFB0K8Keۖb׬Hׄi5n7]yI>rGIٜ!ۀަmŞo(s/䔜a_~na@^>uN^Vy܂=Fbm?"H$'P׹q ԕ~ȓ% X$sVQƋ$XՖE;"JS$h!S=C}$Mރ@Ԁrnx&esI.=RütQL6Fƺ ɬwSwJς)N5ӱo|ABTubtdigٯ|,Չfܛ뀍fEʭa!*1c;ViVP놰qaUGqw]}Kbmk;E1xô JJ{=(Y=s1s`}#7h ?D.0%F(Y@3͛BgUOWw_7WE x6jL.&-z/ѰJnM'"<줣EBv.v@A:h/FP%kJxgo)I1#_o?HvzPr"O 12]$oK{HJ uU`-"^)~Z&wTRh('t1yŚRyK^y~GmT-0ø!9?$]7%H?aXCQ,Tu܆8_~RiH9^Y6vUZfsՋ{Xd* {oc=m 8QtŅף$'`]1=3CSRN7_ٺ`S Z> T H6JrdhtwKdY4In` ƅߢ>CC^H=@h5CʔstCDc#$:e"hnQ7i:? XTs*(dC`tb */ 6,(\ sJ+/&EGQQ|eCGk9мV}s`ݙ'O3I"ocg*HQ8΄.`L+~7K UkX8s~HP4p /wAM&o,=3*]=?g2n^KR O X\*p 0_}wʀ$DS~T7xZ[G5 y+@Ifz28W]L9 ;z%i|FlM@ @ Rnamdef nam$b_bid nam$b_bln nam$b_rss nam$b_rsl nam$l_rsa @nam$r_nop_overlay  RH nam$b_rfsP nam$b_essX nam$b_esl` nam$l_esa  nam$l_rlf  T nam$t_dvi*& nam$r_fid_overlay  RPnam$r_did_overlay  Rnam$r_wcc_overlay Rnam$r_fnb_overlay R nam$b_node nam$b_dev nam$b_dir nam$b_name nam$b_type nam$b_vernamdef$$_fill_6*&PADDING*&@@?6Q3Lx"DISK$USERS:[LANE.WORK.SKEY]MD5.H;1>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STRING9yvQ%DISK$USERS:[LANE.WORK.SKEY]GLOBAL.H;17Qx#DISK$USERS:[LANE.WORK.SKEY]MD5C.C;1N      % D MD5UPDATE DECC$MEMSET DECC$MEMCPY MD5INIT D MD5UPDATE XMD5FINAL$CODE@$DATA $ADDRESS_DATAl޼TЭP޼Q@aRP޼Q@aPxPPPRP޼Q@aPxPPPRP޼Q@aPxPPPRRCdRRRRѭ wwT CLI$TABLESP T SKEY ,<h " + SKEY_CALC DO_KEYGEN,!P1Sequence(!P2Seed( VERSION( $COUNT10<%OUTPUT SKEHYMNIBISICONIDEAIDLEIFFYINCAINCHINTOIONSIOTAIOWAIRISIRMAIRONISLEITCHITEMIVANJACKJADEJAILJAKEJANEJAVAJEANJEFFJERKJESSJESTJIBEJILLJILTJIVEJOANJOBSJOCKJOELJOEYJOHNJOINJOKEJOLTJOVEJUDDJUDEJUDOJUDYJUJUJUKEJULYJUNEJUNKJUNOJURYJUSTJUTEKAHNKALEKANEKANTKARLKATEKEELKEENKENOKENTKERNKERRKEYSKICKKILLKINDKINGKIRKKISSKITEKLANKNEEKNEWKNITKNOBKNOTKNOWKOCHKONGKUDOKURDKURTKYLELACELACKLACYLADYLAIDLAINLAIRLAKELAMBLAMELANDLANELANGLARDLARKLASSLASTLATELAUDLAVALAWNLAWSLAYSLEADLEAFLEAKLEANLEARLEEKLEERLEFTLENDLENSLENTLEONLESKLESSLESTLETSLIARLICELICKLIEDLIENLIESLIEULIFELIFTLIKELILALILTLILYLIMALIMBLIMELINDLINELINKLINTLIONLISALISTLIVELOADLOAFLOAMLOANLOCKLOFTLOGELOISLOLALONELONGLOOKLOONLOOTLORDLORELOSELOSSLOSTLOUDLOVELOWELUCKLUCYLUGELUKELULULUNDLUNGLURALURELURKLUSHLUSTLYLELYNNLYONLYRAMACEMADEMAGIMAIDMAILMAINMAKEMALEMALIMALLMALTMANAMANNMANYMARCMAREMARKMARSMARTMARYMASHMASKMASSMASTMATEMATHMAULMAYOMEADMEALMEANMEATMEEKMEETMELDMELTMEMOMENDMENUMERTMESHMESSMICEMIKEMILDMILEMILKMILLMILTMIMIMINDMINEMINIMINKMINTMIREMISSMISTMITEMITTMOANMOATMOCKMODEMOLDMOLEMOLLMOLTMONAMONKMONTMOODMOONMOORMOOTMOREMORNMORTMOSSMOSTMOTHMOVEMUCHMUCKMUDDMUFFMULEMULLMURKMUSHMUSTMUTEMUTTMYRAMYTHNAGYNAILNAIRNAMENARYNASHNAVENAVYNEALNEARNEATNECKNEEDNEILNELLNEONNERONESSNESTNEWSNEWTNIBSNICENICKNILENINANINENOAHNODENOELNOLLNONENOOKNOONNORMNOSENOTENOUNNOVANUDENULLNUMBOATHOBEYOBOEODINOHIOOILYOINTOKAYOLAFOLDYOLGAOLINOMANOMENOMITONCEONESONLYONTOONUSORALORGYOSLOOTISOTTOOUCHOUSTOUTSOVALOVENOVEROWLYOWNSQUADQUITQUODRACERACKRACYRAFTRAGERAIDRAILRAINRAKERANKRANTRARERASHRATERAVERAYSREADREALREAMREARRECKREEDREEFREEKREELREIDREINRENARENDRENTRESTRICERICHRICKRIDERIFTRILLRIMERINGRINKRISERISKRITEROADROAMROARROBEROCKRODEROILROLLROMEROODROOFROOKROOMROOTROSAROSEROSSROSYROTHROUTROVEROWEROWSRUBERUBYRUDERUDYRUINRULERUNGRUNSRUNTRUSERUSHRUSKRUSSRUSTRUTHSACKSAFESAGESAIDSAILSALESALKSALTSAMESANDSANESANGSANKSARASAULSAVESAYSSCANSCARSCATSCOTSEALSEAMSEARSEATSEEDSEEKSEEMSEENSEESSELFSELLSENDSENTSETSSEWNSHAGSHAMSHAWSHAYSHEDSHIMSHINSHODSHOESHOTSHOWSHUNSHUTSICKSIDESIFTSIGHSIGNSILKSILLSILOSILTSINESINGSINKSIRESITESITSSITUSKATSKEWSKIDSKIMSKINSKITSLABSLAMSLATSLAYSLEDSLEWSLIDSLIMSLITSLOBSLOGSLOTSLOWSLUGSLUMSLURSMOGSMUGSNAGSNOBSNOWSNUBSNUGSOAKSOARSOCKSODASOFASOFTSOILSOLDSOMESONGSOONSOOTSORESORTSOULSOURSOWNSTABSTAGSTANSTARSTAYSTEMSTEWSTIRSTOWSTUBSTUNSUCHSUDSSUITSULKSUMSSUNGSUNKSURESURFSWABSWAGSWAMSWANSWATSWAYSWIMSWUMTACKTACTTAILTAKETALETALKTALLTANKTASKTATETAUTTEALTEAMTEARTECHTEEMTEENTEETTELLTENDTENTTERMTERNTESSTESTTHANTHATTHEETHEMTHENTHEYTHINTHISTHUDTHUGTICKTIDETIDYTIEDTIERTILETILLTILTTIMETINATINETINTTINYTIRETOADTOGOTOILTOLDTOLLTONETONGTONYTOOKTOOLTOOTTORETORNTOTETOURTOUTTOWNTRAGTRAMTRAYTREETREKTRIGTRIMTRIOTRODTROTTROYTRUETUBATUBETUCKTUFTTUNATUNETUNGTURFTURNTUSKTWIGTWINTWITULANUNITURGEUSEDUSERUSESUTAHVAILVAINVALEVARYVASEVASTVEAL SKEY$_VOIDPWD SKEY$_UNALGOR SKEY$_PARITY SKEY$_BADENCSKEY$_PARTDICT SKEY$_DUPALT SKEY$_INVALTDECC$$GL___CTYPEADECC$$GA___CTYPETMD5FINAL MD5UPDATEMD5INITMD4FINAL MD4UPDATEMD4INITPIDUSERNAMELC ALGORITHMNAMEADDENTRY_DICTIONARYALTTOKEYHEXTOKEY ENGLISHTOKEY LIB$SIGNALCMA$TIS_VMSERRNO_GET_ADDR DECC$CTIME DECC$TIME DECC$CLOCK DECC$__ASSERT-R SKEY_CRYPTKeyProcAVEDAVEILVEINVENDVENTVERBVERYVETOVICEVIEWVINEVISEVOIDVOLTVOTEWACKWADEWAGEWAILWAITWAKEWALEWALKWALLWALTWANDWANEWANGWANTWARDWARMWARNWARTWASHWASTWATSWATTWAVEWAVYWAYSWEAKWEALWEANWEARWEEDWEEKWEIRWELDWELLWELTWENTWEREWERTWESTWHAMWHATWHEEWHENWHETWHOAWHOMWICKWIFEWILDWILLWINDWINEWINGWINKWINOWIREWISEWISHWITHWOLFWONTWOODWOOLWORDWOREWORKWORMWORNWOVEWRITWYNNYALEYANGYANKYARDYARNYAWLYAWNYEAHYEARYELLYOGAYOKEP,^ݬ  DECC$STRLENPRݬ DECC$STRLENPRR,,RR DECC$MALLOCP00 Џ$41noname.2 D__1O@Dnoname.4|noname.5noname.6 wR5noname.7noname.3 ٠md5 R Hmd4 RMD5, d @ L X D h  t       <  - SKEY_VERSION DO_VERSION T $ 0 <  H d p  |       `     4 D d d _ DO_KEYGEN$WP DO_KEYGEN DO_PROFILEMP DO_PROFILE DO_SHOWrbPDO_SHOW DO_TESTlPDO_TESTDO_CLEARPDO_CLEARa DO_INITIALIZEnP DO_INITIALIZE DO_VERSION P DO_VERSIONww@ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizetgfh SYS$GETTIMPϛSKEY_LOGЬRr‰f„@ˆV|vXTSYS$PUTPSSwSKEY_LOGSpV SKEY$_NOUSERDECC$GA_RMS_XABPRODECC$GA_RMS_XABKEYDECC$GA_RMS_RABDECC$GA_RMS_FAB TRNLNM_EXECUCNSKEY_LOG LIB$SIGNALSYS$PUTSYS$OPEN SYS$GETTIMSYS$GETSYS$FREESYS$DISCONNECT SYS$DELETE SYS$CREATE SYS$CONNECT SYS$CLOSE DECC$MALLOC DECC$FREE DECC$STRLEN DECC$STRNCPY DECC$STRCPY DECC$MEMSET h DB_CREATE DB_OPEN hDB_FETCH DDB_PUT DECC$FREESRRPP|^t~ DECC$MALLOCPU <$~ LIB$SIGNAL@~ݬe DECC$STRNCPY@~eUCNeR@V|SVTPQPQQTSSVpd|hԥ@\```T DECC$MEMSETD DECC$MEMSETURRPP^ЬRTSYS$DISCONNECT SYS$CLOSEb DECC$FREER DECC$FREE^<~ DECC$MALLOCPW <$~ LIB$SIGNALЬV(tfgЬRr‰g„@ˆW|vXT SYS$DELETEPSS.SKEY_LOGSpW DECC$FREESRRPP^ |DB_NEW DB_CLOSE  DB_DELETE @DB_FREEZ$CODEt$DATA $ADDRESS_DATAЬPTSYS$FREEPQQPhww@ dsc$l_sb_l1` dsc$l_sb_u1Rdsc$descriptor_ubsb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_pos` dsc$l_ubsb_l1 nam$l_node   nam$l_dev @ nam$l_dir ` nam$l_name  nam$l_type  nam$l_ver namdef$$_fill_7*&R STS  nam$b_nopnam$r_nop_bits RRSTS " nam$v_pwd" " nam$v_fill_1" " nam$v_fill_2" v" nam$v_synchk" ""nam$v_noconceal"  " nam$v_slparse" !"nam$v_srchxabs" " nam$v_fill_5" R STS 0 nam$w_fid*&nam$r_fid_fields RRSTS 0 nam$w_fid_num nam$w_fid_seq nam$r_fid_rvn_overlay RRSTS  nam$w_fid_rvnnam$r_fid_rvn_fields RRSTS  nam$b_fid_rvn nam$b_fid_nmxR STS 0 nam$w_did*&nam$r_did_fields RRSTS 0 nam$w_did_num nam$w_did_seq nam$r_did_rvn_overlay RRSTS  nam$w_did_rvnnam$r_did_rvn_fields R RS T S  nam$b_did_rvn nam$b_did_nmx!RS!T!S   nam$l_wccnam$r_wcc_bits "R#R"S#T#S  ""namdef$$_fill_1" " nam$v_ifi" ""namdef$$_fill_2 "  " nam$v_srchnmf" " nam$v_svctx" $RS$T$S   nam$l_fnbnam$r_fnb_bits0 %Rnam$r_fnb_bits1 &Rnam$r_fnb_bits2 'R(R%S(T(S  " nam$v_exp_ver" !"nam$v_exp_type" !"nam$v_exp_name" !"nam$v_wild_ver" ""nam$v_wild_type" ""nam$v_wild_name"  " nam$v_exp_dir"  " nam$v_exp_dev" !"nam$v_wildcard" ""namdef$$_fill_3" $"nam$v_search_list" !"nam$v_cncl_dev" !"nam$v_root_dir" " nam$v_lowver"  " nam$v_highver" " nam$v_ppf" " nam$v_node" " nam$v_quoted"  " nam$v_grp_mbr" !"nam$v_wild_dir" !"nam$v_dir_lvls" )R&S)T)S  ""namdef$$_fill_4" !"nam$v_wild_ufd" ""nam$v_wild_sfd1" ""nam$v_wild_sfd2" ""nam$v_wild_sfd3" ""nam$v_wild_sfd4" ""nam$v_wild_sfd5" ""nam$v_wild_sfd6" ""nam$v_wild_sfd7" *R'S*T*S  ""namdef$$_fill_5" !"nam$v_wild_grp" !"nam$v_wild_mbr" " nam$v_fill_6" +Rfabdef fab$b_bid fab$b_blnfab$r_ifi_overlay ,R fab$r_fop_overlay -R@ fab$l_sts` fab$l_stv fab$l_alq fab$w_deqfab$r_fac_overlay .Rfab$r_shr_overlay /R fab$l_ctx fab$b_rtvfab$r_org_overlay 0Rfab$r_rat_overlay 1R fab$b_rfmfab$r_jnl_overlay 2R  fab$l_xab@ fab$l_nam  T` fab$l_fna  fab$l_dna  fab$b_fns fab$b_dns fab$w_mrs fab$l_mrn fab$w_bls fab$b_bks fab$b_fsz fab$l_dev  fab$l_sdc@ fab$w_gbcPfab$r_acmodes_overlay 3RXfab$r_rcf_overlay 4R`fabdef$$_fill_95R,S5T5S  fab$w_ififab$r_ifi_bits 6R7R6S7T7S ""fabdef$$_fill_1" " fab$v_ppf_rat"  " fab$v_ppf_ind" " fab$v_ppifi" 8R-S8T8S   fab$l_fopfab$r_fop_bits 9R:R9S:T:S  " fab$v_asy" " fab$v_mxv" " fab$v_sup" " fab$v_tmp" " fab$v_tmd" " fab$v_dfw" " fab$v_sqo" " fab$v_rwo" " fab$v_pos" " fab$v_wck" " fab$v_nef" " fab$v_rwc" " fab$v_dmo" " fab$v_spl" " fab$v_scf" " fab$v_dlt" " fab$v_nfs"  " fab$v_ufo" " fab$v_ppf" " fab$v_inp" " fab$v_ctg" " fab$v_cbt"  " fab$v_syncsts" " fab$v_rck" " fab$v_nam" " fab$v_cif" ""fabdef$$_fill_3" " fab$v_esc" " fab$v_tef" " fab$v_ofp" " fab$v_kfo" ""fabdef$$_fill_4" ;R.S;T;S  fab$b_facfab$r_fac_bits <R=R<S=T=S " fab$v_put" " fab$v_get" " fab$v_del" " fab$v_upd" " fab$v_trn" " fab$v_bio" " fab$v_bro" " fab$v_exe" >R/S>T>S  fab$b_shrfab$r_shr_bits ?R@R?S@T@S " fab$v_shrput" " 8results*& 0buf  ,buflena R result  seed  passwd jg Hack7( noname.10E (__2WF noname.11Qnoname.9Q noname.12s +:THashKey h__3Dݬ 0 DECC$STRCPY0LCݬ0 DECC$STRCAT0լ Ѭ;mHMD4INIT,0H MD4UPDATEH8MD4FINALCPMD5INIT,0 MD5UPDATE8MD5FINALPЏ SKEY$_UNALGOR4U,0 DECC$MEMSET0 DECC$FREE8@RR8PMD5INITݬ MD5UPDATE8MD5FINAL Џ SKEY$_UNALGOR458@PP8DECC$$GL___CTYPEADECC$$GA___CTYPETQ,Pˏ@aPP,PP DECC$ISALPHAP,0,PPVPDECC$$GL___CTYPEADECC$$GA___CTYPETQ,PF( noname.149< noname.150D noname.151 K]O noname.152X noname.146l noname.153 noname.154 __24  noname.155  __25F noname.156 noname.157 noname.159 __26 noname.160  &F noname.161, noname.1588 noname.162 H__27FH noname.164| noname.163 noname.165 x noname.166 t noname.167  noname.134$ noname.169@ noname.170V noname.168@aPP,PP DECC$ISALPHAP,PP,,PP,PP $1G,QQPP,a,01)P0 DECC$STRLENP Џ:Џ; Џ 0^P1 6P P@0~ϔPP PP 1}Pլ ?Ѭ oPMD5INIT0 MD5UPDATE8MD5FINALFPHMD4INIT0H MD4UPDATEH8MD4FINALPЏ SKEY$_UNALGOR1 8 |__28 ~ SKEY009.A~ e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_VAXNDB.OLB;2| noname.171 err noname.131 ٠md5 R Hmd4  R 8hash*& 0word ,c  (input $i jxpvl  low high len rvalb*&  out e  a  R DECC$TOUPPER DECC$ISSPACE DECC$ISLOWER DECC$ISALPHA DECC$STRLEN DECC$STRNCMP DECC$STRCMP DECC$STRNCPY DECC$STRNCAT DECC$STRCPY DECC$STRCAT DECC$MEMSET DECC$MEMCPY DECC$MALLOC DECC$FREE DECC$FGETS DECC$FOPEN DECC$DSPRINTF DECC$FCLOSE KEYPROC THASHKEY  KEYTOENGLISH  ENGLISHTOKEY  SEEDGENERATE <KEYTOHEX 4HEXTOKEY |ALTTOKEYDgAnyToKey __29 #__30: noname.174 4R: noname.173D noname.175 iss key  input  a  RP $PP$ PP$1H$$@5P$ZPP$PP$$@ݏ@&PQˏPPQ Џ SKEY$_PARITY+ݬ DECC$MEMCPY DECC$MEMSET( DECC$MEMSET( DECC$FREE44P ^ݬݬ ENGLISHTOKEYPѭ SKEY$_BADENC4ݬݬHEXTOKEYPѭ SKEY$_BADENCݬ ݬݬALTTOKEYPЭPP^ݏ #gLnew_Dictionary /v noname.177 noname.179 __31 Q noname.180 noname.178 noname.181jd  Ra  R(oaddentry_Dictionary/  noname.183 noname.184 __32 noname.186 __33 F noname.187@ noname.188P noname.190 P__34p noname.191  Fp noname.192 noname.189 noname.193 __35 DECC$MALLOCPխݏ$ LIB$SIGNALЬѭ#PЭQЭPAPPѭЭP^ݬ DECC$STRLENP,,, Џ SKEY$_INVALT41,(Џ:$Џ;(Џ$$(ݬP Џ SKEY$_INVALT41x00,6P0P޼Q@a~:P 0PP00, ޼P`>`kPHMD5INIT,ݬH MD5UPDATEH8MD5FINAL@MD4INIT,ݬ MD4UPDATE8eF noname.195 noname.194 noname.196 t/ noname.197< noname.199 <__36` noname.200 +`g noname.201m noname.198 noname.185 ٠md4 R Hmd5 R 8hash*&0j,l (low $high xve Rd R entry p $read_Dictionary] noname.203 noname.205 noname.206L noname.208D L__37` noname.210MD4FINALPЏ SKEY$_UNALGOR41 8pPQЬPA2ݬP DECC$STRCMPP Џ SKEY$_DUPALT4Y  DECC$MALL#ɏ{~~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|{OCPQЬPAݬP DECC$STRCPYQЬPA44Pδ^լ 1)լ 1Ϲݬ DECC$FOPENPխCMA$TIS_VMSERRNO_GET_ADDR`1 ͺ DECC$MEMSETЭܭЭݭݏ DECC$FGETSP1PPPPP1PP1 `__38 noname.213 noname.214 noname.215 noname.216 noname.219 noname.220 noname.217 noname.211 noname.2214 noname.224F noname.225L noname.226U noname.227 noname.230 noname.231 noname.228 noname.222 noname.232DECC$$GL___CTYPEADECC$$GA___CTYPETQPˏ@aPPPPP DECC$ISALPHAPխLPPPP:DECC$$GL___CTYPEADECC$$GA___CTYPETQPˏ@aPPPP DECC$ISALPHAPխPP1KPЭ옽PP1DECC$$GL___CTYPEADECC$$GA___CTYPETQPˏ@aPPPPP DECC$ISALPHAPխLPP옽PP:DECC$$GL___CTYPEADECC$$GA___CTYPETQPˏ@aPPPP DECC$ISALPHAPխѭ1PíPP 1íPPݭ __39  noname.234 noname.2360 noname.2389 noname.2399 noname.2379 noname.235 m9 noname.233 /> noname.240I noname.209 FI noname.241g noname.207 noname.243 __40 noname.244  noname.245 noname.242 noname.246 noname.247 noname.248 noname.249 noname.250 noname.251 noname.204f Rp q j ndup nbad nok nblank iss buf*&ٶE Rd R file  dupR  bad  ok  blank CKeyToAlt]4 noname.254L noname.255_ noname.253x noname.257ͺ DECC$STRNCPYíP@ͺͺݬADDENTRY_DICTIONARYPѭԏ SKEY$_DUPALT PP9ѭԏ SKEY$_INVALTPP$PˏPP Эԭ1 PPЭPP1ݭݏ DECC$FGETSP1ݭ DECC$FCLOSEѭ*ЭQЬPA PPPPѭլ ޼ PЭ`լ޼PЭ`լ޼PЭ`լ޼PЭ`խ  PЏSKEY$_PARTDICT٭PP (^޼P`ݬ DECC$MEMCPYѭ@+ݭLPPPPѭ@ x__41/ noname.258 noname.261 __42 noname.262 F noname.263 noname.260; noname.264 N ; noname.265M noname.256d noname.259pijve R cp*&  out  key  d R2gl AlgorithmName __43F noname.267 noname.268 noname.269  noname.271 noname.270  md4*&  md5*&a R՘PxPPPѭ1 ŭ PPPЭQЬ PAխ ЏSKEY$_PARTDICT1P DECC$CLOCKPRzRP{PQPPRѭRAPнխЭPЬ R@RR DECC$CLOCKPRzRP{PQPPRѭRЭRݬ DECC$STRCATѭpݬ DECC$STRCATRRѭ1+  DECC$MEMSETP^Qլ ѬP PP PP PP^ЬPݠ\ ALGORITHMNAMEPRЬQ@PP@ЬPDݡ@RϹ DECC$DSPRINTFC Challenge# noname.273P noname.274p  ِbuf*&ddcr Re )B )F>! )m@ +*# (*j! G*񽸸 *( * *V3 %+O! 7+#' "+.' Q+KB ++ +{* +gE +>  +I +"! ,Uf , ,D/ RSTS_iobuf _cnt _ptr  @_base  `_flag h_file p_pad1 x_pad2R @R @ quot  remR @ quot  remR tm  tm_sec  tm_min@tm_hour`tm_mday tm_montm_yeartm_wdaytm_ydaytm_isdstR`timeb` time millitm0timezone@dstflagRtbufferproc_user_time proc_system_time@child_user_time`child_system_time Rtimeval@ tv_sec tv_usec!R itimerval it_interval  T@it_value  T"Rfd_set fds_bits*&#R __ITEM_LIST_3` length code address @return_length_address $R__IOSB@ status count dvispecific%Rprvdef@prv$r_prvdef_bits0 &Rprv$r_prvdef_bits1 'Rprv$r_prvdef_bits2 (R)R&S)T)S @" prv$v_cmkrnl" " prv$v_cmexec" " prv$v_sysnam" " prv$v_grpnam" !"prv$v_allspool" " prv$v_detach" !"prv$v_diagnose" " prv$v_log_io" " prv$v_group" " prv$v_noacnt" " prv$v_prmceb" " prv$v_prmmbx" " prv$v_pswapm" " prv$v_setpri" " prv$v_setprv" " prv$v_tmpmbx" " prv$v_world" " prv$v_mount" " prv$v_oper" e " prv$v_exquota" " prv$v_netmbx" " prv$v_volpro" " prv$v_phy_io" " prv$v_bugchk" " prv$v_prmgbl" " prv$v_sysgbl" " prv$v_pfnmap" " prv$v_shmem" " prv$v_sysprv" " prv$v_bypass" " prv$v_syslck" " prv$v_share"  " prv$v_upgrade" ""prv$v_downgrade" !" prv$v_grpprv" " " prv$v_readall" #" prv$v_import" $" prv$v_audit" %!"prv$v_security" &" prv$v_fill_1" '*R'S*T*S " prv$v_fill_2 " " prv$v_acnt" " prv$v_fill_3" " prv$v_altpri" " prv$v_fill_54" +R(S+T+S @ prv$l_l1_bits prv$l_l2_bits,R prvdsp_bits" prv$v_sorted" " prv$v_brief" " prv$v_filled"  " prv$v_fill_55" -Rdsc$descriptor@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer .Rdsc$descriptor_s@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer /Rdsc$descriptor_d@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer 0Rdsc$descriptor_a dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags 1RX dsc$b_dimct` dsc$l_arsize2R1S2T2S $"dsc$v_fl_binscale" !"dsc$v_fl_redim" ""dsc$v_fl_column" !"dsc$v_fl_coeff" ""dsc$v_fl_bounds" 3Rdsc$descriptor_p@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer 4Rdsc$descriptor_sd` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_sflags 5R6R5S6T6S $"dsc$v_fl_binscale" 7Rdsc$descriptor_nca dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags 8RX dsc$b_dimct` dsc$l_arsize9R8S9T9S $"dsc$v_fl_binscale" !"dsc$v_fl_redim" :Rdsc$descriptor_vs@dsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer 7;Rdsc$descriptor_vsadsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags <RX dsc$b_dimct` dsc$l_arsize=R<S=T=S $"dsc$v_fl_binscale" !"dsc$v_fl_redim" >Rdsc$descriptor_ubs` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_pos?Rdsc$descriptor_uba dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags @RX dsc$b_dimct` dsc$l_arsizeAR@SATAS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" BRdsc$descriptor_sb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$l_sb_l1` dsc$l_sb_u1CRdsc$descriptor_ubsb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_pos` dsc$l_ubsb_l1 dsc$l_ubsb_u1DRSDT SDT SDT SDTSDTSDTDS _SKEY_ALGORITHM MD4 MD5ERSETSETSETES _ALT_ENTRYh next ET entry*& FRSFTSFTSFT SFTFS _ALT_DICT  algorithm DT hentry62 ET GRSGTGSPRINCIPAL_RECORD principal*&@@?sequence seed*& key*& algorithm DT flags HR  dbversion@lastmod*& statusIRHSITIS  b JRlKRJSKTKS " skey_default" " skey_allow" " norm_allow"  Wp62 LRSLT SLTSLTSLTLS y state*& count*& buffer*&@@?MRSMTSMTSMTSMTSMTMS  state*& count*& buffer*&@@?DECC$$GA___CTYPETdecc$$ga___ctypet-)&DECC$$GL___CTYPEAdecc$$gl___ctypea SKEY$_INVALT SKEY$_INVALT SKEY$_DUPALT SKEY$_DUPALTSKEY$_PARTDICTSKEY$_PARTDICT SKEY$_BADENC SKEY$_BADENC SKEY$_PARITY SKEY$_PARITY SKEY$_UNALGOR SKEY$_UNALGOR SKEY$_VOIDPWD SKEY$_VOIDPWD6Q3Lx"DISK$USERS:[LANE.WORK.SKEY]MD5.H;16(L"DISK$USERS:[LANE.WORK.SKEY]MD4.H;19yvQ%DISK$USERS:[LANE.WORK.SKEY]GLOBAL.H;1<u3A/(DISK$USERS:[LANE.WORK.SKEY]SKEY_DICT.H;1;W-'DISK$USERS:[LANE.WORK.SKEY]SKEY_MSG.H;4777S b#DISK$USERS:[LANE.WORK.SKEY]UTIL.H;1=5W )DISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.H;1?$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1DESCRIP>%>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1PRVDEF<: (DISK$USERS:[LANE.WORK.SKEY]VMS_TYPES.H;17 M#DISK$USERS:[LANE.WORK.SKEY]SKEY.H;2D ' >$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 LIB$ROUTINES= Y%(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1SSDEF= p$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1ERRNO> $SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1UNISTD<$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1TIME>ؑf$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1ASSERT=x$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1CTYPE>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STRING<3$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1WAIT>8}$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDLIB=-v$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDIO=MC W &")DISK$USERS:[LANE.WORK.SKEY]SKEY_CRYPT.C;1 & '  < 6= (  )  *  N+  @,   -   .   0   1     ! Ǜ %   >3  4  5  '6  7  (9  %:  %; c ANYTOKEY LNEW_DICTIONARY ADDENTRY_DICTIONARY READ_DICTIONARY KEYTOALT l ALGORITHMNAME  CHALLENGEV$CODE $DATA $ADDRESS_DATA DECC$STRLENPP DECC$MALLOCPխݏ$ LIB$SIGNALݭ DECC$STRCPYݏd DECC$MEMSETЭPЭPwwescriptor_a dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags 1RX dsc$b_dimct` dsc$l_arsize2R1S2T2S ""prv$v_downgrade" !" prv$v_grpprv" " " prv$v_readall" #" prv$v_import" $" prv$v_audit" %!"prv$v_security" &" prv$v_fill_1" ''R$S'T'S " prv$v_fill_2 " " prv$v_acnt" " prv$v_fill_3" " prv$v_altpri" " prv$v_fill_54" (R%S(T(S @ prv$l_l1_bits prv$l_l2_bits)R prvdsp_bits" prv$v_sorted" " prv$v_brief" " prv$v_filled"  " prv$v_fill_55"  last_verbname > %>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1PRVDEF< : (DISK$USERS:[LANE.WORK.SKEY]VMS_TYPES.H;1; (ؤ@2'DISK$USERS:[LANE.WORK.SKEY]SKEY_CLI.H;1ӛD )>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 STR$ROUTINESD ' >$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 LIB$ROUTINESD v>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 CLI$ROUTINES=Y%(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1SSDEF?$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1DESCRIP=x$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1CTYPE>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STRING<3$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1WAIT>8}$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDLIB;L|V 'DISK$USERS:[LANE.WORK.SKEY]SKEY_CLI.C;1  < 6=           K      ^       " !    j} STR$FREE1_DX LIB$GET_INPUT CLI$PRESENT CLI$GET_VALUE CLI$DISPATCH CLI$DCL_PARSE DECC$STRLEN DECC$STRNCMP DECC$STRCMP DECC$STRNCPY DECC$STRCPY DECC$MALLOC DECC$FREE (CLI_INIT  CLI_DISPATCH , CLI_PRESENT l CLI_GETVALUE $ CLI_UNQUOTE$CODE$DATA $ADDRESS_DATAe STR$FREE1_DX޼P`ЭPP^ЬլЬQQPPaPP"gPЬQQPPaPPHPP"ЬQQPPaPP")ЭQQPPaЬQQPPaPP(ww _SKEY_ALGORITHM fab$v_shrget" " fab$v_shrdel" " fab$v_shrupd" " fab$v_mse" " fab$v_nil" " fab$v_upi" " fab$v_fill_0" AR0SATAS  fab$b_orgfab$r_org_bits BRCRBSCTCS ""fabdef$$_fill_5" " fab$v_org" DR1SDTDS  fab$b_ratfab$r_rat_bits ERFRESFTFS " fab$v_ftn" " fab$v_cr" " fab$v_prn" " fab$v_blk" " fab$v_msb" " fab$v_fill_1" GR2SGTGS   fab$l_jnlfab$r_jnl_real_stuff HRIRHSITIS  fab$r_journal_overlay JRfab$b_ru_facilityfabdef$$_fill_7KRJSKTKS  fab$b_journalfab$r_journal_bits LRMRLSMTMS  " fab$v_only_ru" " fab$v_ru" " fab$v_bi" " fab$v_ai" " fab$v_at" !"fab$v_never_ru" %"fab$v_journal_file" " fab$v_fill_3" NR3SNTNS  fab$b_acmodesfab$r_acmodes_bits ORPROSPTPS !"fab$v_lnm_mode" ""fab$v_chan_mode" ""fab$v_file_mode" %"fab$v_callers_mode" QR4SQTQS  fab$b_rcffab$r_rcf_bits RRSRRSSTSS " fab$v_rcf_ru" " fab$v_rcf_ai" " fab$v_rcf_bi" " fab$v_fill_2" TRrabdef  rab$b_bid rab$b_blnrab$r_isi_overlay UR rab$r_rop_overlay VR@ rab$l_sts`rab$r_stv_overlay WRrab$r_rfa_overlay XRrabdef$$_fill_4 rab$l_ctxrabdef$$_fill_5 rab$b_rac rab$b_tmo rab$w_usz rab$w_rsz  rab$l_ubf @ rab$l_rbf ` rab$l_rhb rab$r_kbf_overlay YRrab$r_ksz_overlay ZR rab$b_krf rab$b_mbf rab$b_mbcrab$r_bkt_overlay [R rab$l_fab +T rab$l_xab\RUS\T\S  rab$w_isirab$r_isi_bits ]R^R]S^T^S ""rabdef$$_fill_1" " rab$v_ppf_rat"  " rab$v_ppf_ind" " rab$v_ppisi" _RVS_T_S   rab$l_roprab$r_rop_bits0 `Rrab$r_rop_bits1 aRrab$r_rop_fields bRcR`ScTcS  " rab$v_asy" " rab$v_tpt" " rab$v_rea" " rab$v_rrl" " rab$v_uif" " rab$v_mas" " rab$v_fdl" " rab$v_rev" " rab$v_eof" " rab$v_rah" " rab$v_wbh" " rab$v_bio" " rab$v_cdk" " rab$v_loa" " rab$v_lim"  " rab$v_syncsts" " rab$v_loc" " rab$v_wat" " rab$v_ulk" " rab$v_rlk" " rab$v_nlk" " rab$v_kge" " rab$v_kgt" " rab$v_nxr" " rab$v_rne" " rab$v_tmo" " rab$v_cvt" " rab$v_rnf" " rab$v_eto" " rab$v_pta" " rab$v_pmt" " rab$v_cco" dRaSdTdS  ""rabdef$$_fill_6" " rab$v_eqnxt" " rab$v_nxt" " rab$v_fill_4 " eRbSeTeS  rabdef$$_fill_3 rab$b_rop1 rab$b_rop2 rab$b_rop3fRWSfTfS   rab$l_stvrab$r_stv_fields gRhRgShThS   rab$w_stv0 rab$w_stv2iRXSiTiS 0 rab$w_rfa*&rab$r_rfa_fields jRkRjSkTkS 0 rab$l_rfa0 rab$w_rfa4lRYSlTlS   rab$l_kbf  rab$l_pbf mRZSmTmS  rab$b_ksz rab$b_psznR[SnTnS   rab$l_bkt rab$l_dctoRXABALL xab$b_cod xab$b_bln xab$l_nxt@xab$r_aop_overlay pRH xab$b_alnP xab$w_vol` xab$l_loc xab$l_alq xab$w_deq xab$b_bkz xab$b_aidxab$r_rfi_overlay qRxaballdef$$_fill_8rRpSrTrS  xab$b_aopxab$r_aop_bits sRtRsStTtS " xab$v_hrd" " xab$v_onc" %"xaballdef$$_fill_5" " xab$v_cbt" %"xaballdef$$_fill_6" " xab$v_ctg" uRqSuTuS 0 xab$w_rfi*&xab$r_rfi_fields vRwRvSwTwS 0 xab$w_rfi0 xab$w_rfi2 xab$w_rfi4xRXABCXF xab$b_cod xab$b_bln xab$l_nxt@ xab$l_cxfsts` xab$l_cxfstvxab$r_cxfcop_overlay yR xab$l_cxfbkp xab$w_cxfifi xab$b_cxfverxabcxfdef$$_fill_5xabcxfdef$$_fill_6 xab$w_cxfdeq xab$b_cxffac xab$b_cxfshr  xab$w_cxfrte0xabcxfdef$$_fill_78 xab$b_cxforg@ xab$w_cxfgbcP xab$b_cxfrtvXxabcxfdef$$_fill_8`xabcxfdef$$_fill_9*&zRySzTzS   xab$l_cxfcopxab$r_cxfcop_bits {R|R{S|T|S " xab$v_cxfrst" " xab$v_fill_13" }RXABCXR xab$b_cod xab$b_bln xab$l_nxt@ xab$l_cxrsts` xab$l_cxrstvxab$r_cxrcop_overlay ~R xab$l_cxrbkp xab$w_cxrisi xab$b_cxrverxabcxrdef$$_fill_6xabcxrdef$$_fill_7 xab$b_cxrmbf xab$b_cxrmbc xab$w_cxrbfz  xab$l_cxrvbn@ xab$w_cxroffP xab$w_fill_8` xab$l_cxrpos0 xab$w_cxrpos4xabcxrdef$$_fill_9 xab$l_cxrcur0 xab$w_cxrcur4xabcxrdef$$_fill_10 xab$l_cxrsid0 xab$w_cxrsid4xabcxrdef$$_fill_11  xab$w_cxrcnt0 xab$b_cxrkref8 xab$b_cxrklen@ xab$l_cxrbuf`xabcxrdef$$_fill_12*&R~STS   xab$l_cxrcopxab$r_cxrcop_bits RRSTS  " xab$v_cxrrst" %"xabcxrdef$$_fill_5"  " xab$v_cxrbver" R __vms_date@RXABDAT xab$b_cod xab$b_bln xab$l_nxt@ xab$w_rvn` xab$q_rdt T xab$q_cdt T xab$q_edt T  xab$q_bdt T` xab$q_rcd T xab$q_eff TR>~ SKEY009.A~ e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_VAXNDB.OLB;2JI|XAB xab$b_cod xab$b_blnxabdef$$_fill_1 xab$l_nxt@ xab$w_rvnPxabdef$$_fill_2`xab$r_rdt_overlay RRSTS @ xab$q_rdt*&xab$r_rdt_fields RRSTS @ xab$l_rdt0 xab$l_rdt4RXABDEF1xabdef$$_fill_3*&@xabdef$$_fill_4Hxabdef$$_fill_5Pxabdef$$_fill_6`xabdef$$_fill_7xabdef$$_fill_8xabdef$$_fill_9 xab$b_bkzRXABFHC` xab$b_cod xab$b_bln xab$l_nxt@ xab$b_rfoH xab$r_fill_7 RP xab$w_lrl`xab$r_hbk_overlay Rxab$r_ebk_overlay R xab$w_ffb xab$b_bkz xab$b_hsz xab$w_mrz xab$w_dxq xab$w_gbcxabfhcdef$$_fill_6*&0xab$w_verlimit@ xab$l_sbnRSTS  xab$b_atr xab$r_fill_8 RRSTS " xab$v_ftn" " xab$v_cr" " xab$v_prn" " xab$v_blk" " xab$v_fill_9" RSTS   xab$l_hbkxab$r_hbk_fields RRSTS   xab$w_hbk0 xab$w_hbk2RSTS   xab$l_ebkxab$r_ebk_fields RRSTS  < xab$w_ebk0 xab$w_ebk2R UCHAR_FLAGS""xab$v_wascontig" !"xab$v_nobackup" ""xab$v_writeback" ""xab$v_readcheck" ""xab$v_writcheck"  " xab$v_contigb" " xab$v_locked" " xab$v_contig" ""xab$v_reserved1" ""xab$v_reserved2" ""xab$v_reserved3" " xab$v_badacl" " xab$v_spool" ""xab$v_directory" !"xab$v_badblock"  " xab$v_markdel" !"xab$v_nocharge" " xab$v_erase"  " xab$v_fill_15" RXABITM xab$b_cod xab$b_bln xab$l_nxt@xab$l_itemlist` xab$b_modehxab$b_itm_fill1*&xab$l_itm_fill2*&R xab_rcf_flags" xab$v_rcf_ru" " xab$v_rcf_ai" " xab$v_rcf_bi" ""xab$v_rcf_nopad"  " xab$v_fill_16" R xabnetextprot@ xab$r_fill_17 Rxab$w_owner_acc xab$w_group_acc0xab$w_world_accRSTS xab$~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'"|$w_system_acc xab$r_fill_18 RRSTS #"xab$v_net_noread" $"xab$v_net_nowrite" &"xab$v_net_noexecute" %"xab$v_net_nodelete" %" xab$v_net_noappend" ("xab$v_net_nodirectory" %"xab$v_net_noupdate" %"xab$v_net_nochange" %"xab$v_net_noextend"  " xab$v_fill_19" R XABNETDAPVER( xab$b_ver_dap xab$b_ver_ecov xab$b_ver_cus xab$b_ver_dsv xab$b_ver_csvR XABNETCAPDEF8#"xab$v_cap_filall" #"xab$v_cap_seqorg" #"xab$v_cap_relorg" $"xab$v_cap_fill_21" #"xab$v_cap_extend" #"xab$v_cap_seqfil" #"xab$v_cap_ranrrn" #"xab$v_cap_ranvbn" #"xab$v_cap_rankey" $"xab$v_cap_fill_22" #"xab$v_cap_ranrfa" #"xab$v_cap_idxorg" #"xab$v_cap_swmode" #"xab$v_cap_append" #"xab$v_cap_submit" $"xab$v_cap_fill_23"  " xab$ v_cap_mds" $"xab$v_cap_display" #"xab$v_cap_msgblk" #"xab$v_cap_unrblk" #"xab$v_cap_bigblk" #"xab$v_cap_dapcrc" #"xab$v_cap_keyxab" #"xab$v_cap_allxab" #"xab$v_cap_sumxab" &"xab$v_cap_directory" #"xab$v_cap_timxab" #"xab$v_cap_proxab" $"xab$v_cap_fill_24" #"xab$v_cap_fopspl" #"xab$v_cap_fopscf" #"xab$v_cap_fopdlt" $"xab$v_cap_fill_26" #"xab$v_cap_seqrac" !$"xab$v_cap_fill_27" "#"xab$v_cap_bitopt" #$"xab$v_cap_warning" $#"xab$v_cap_rename" %%"xab$v_cap_wildcard" &#"xab$v_cap_gngopt" '#"xab$v_cap_nammsg" (#"xab$v_cap_segmsg" )&"xab$v_cap_chgattcls" *&"xab$v_cap_chgtimcls" +&"xab$v_cap_chgprocls" ,&"xab$v_cap_chgnamcls" -&"xab$v_cap_modattcre" .%"xab$v_cap_nam3part" /&"xab$v_cap_chgattren" 0&"xab$v_cap_chgtimren" 1c&"xab$v_cap_chgproren" 2&"xab$v_cap_ctlblkcnt" 3%"xab$v_cap_octalver" 4 " xab$v_fill_20" 5RXABJNL xab$b_cod xab$b_bln xab$l_nxt@xab$b_xabjnl_typeHxabjnldef$$_fill_5Pxab$r_jnl_flags_overlay R` xab$l_jnl_fabxab$l_volnam_bufxab$w_volnam_sizxab$w_volnam_lenxab$q_jnl_verify_cdate*& xab$l_jnlidx xab$l_backup_seqno@xab$q_jnl_mod_time*&xabjnldef$$_fill_7xabjnldef$$_fill_8xabjnldef$$_fill_9xabjnldef$$_fill_10xabjnldef$$_fill_11 xabjnldef$$_fill_12@xabjnldef$$_fill_13`xabjnldef$$_fill_14RSTS xab$w_jnl_flagsxab$r_jnl_flags_bits R RSTS )"xab$v_journal_disabled" $"xab$v_backup_done"  " xab$v_fill_14" RXABKEY  xab$b_cod xab$b_bln xab$l_nxt@ xab$b_ianH xab$b_lanP xab$b_danX xab$b_lvl` xab$b_ibsh xab$b_dbsp xab$l_rvbxab$r_flg_overlay R xab$b_dtp xab$b_nsg xab$b_nul xab$b_tks xab$b_ref xab$w_mrl xab$w_ifl xab$w_dflxab$r_pos_overlay Rpxab$r_siz_overlay Rxabkeydef$$_fill_11 xab$l_knm xab$l_dvbxab$r_typ_overlay R@ xab$b_prologHxabkeydef$$_fill_12Pxabkeydef$$_fill_13` xab$l_coltbl xab$l_colsiz xab$l_colnamxabkeydef$$_fill_14xabkeydef$$_fill_15xabkeydef$$_fill_16RSTS  xab$b_flgxab$r_flg_bits0 Rxab$r_flg_bits1 RRSTS " xab$v_dup" " xab$v_chg" " xab$v_nul" ""xab$v_idx_ncmpr" %"xabkeydef$$_fill_5" ""xab$v_key_ncmpr"  " xab$v_fill_12" RSTS %"xabkeydef$$_fill_6" %"xabkeydef$$_fill_7" %"xabkeydef$$_fill_8" %"xabkeydef$$_fill_9" &"xabkeydef$$_fill_10" ""xab$v_dat_ncmpr" RSTS  xab$w_pos*&xab$r_pos_fields RRSTS  xab$w_pos0 xab$w_pos1 xab$w_pos2x0 xab$w_pos3@ xab$w_pos4P xab$w_pos5` xab$w_pos6p xab$w_pos7RSTS @ xab$b_siz*&xab$r_siz_fields RRSTS @ xab$b_siz0 xab$b_siz1 xab$b_siz2 xab$b_siz3 xab$b_siz4( xab$b_siz50 xab$b_siz68 xab$b_siz7RSTSc @ xab$b_typ*&xab$r_typ_fields RRSTS @ xab$b_typ0 xab$b_typ1 xab$b_typ2 xab$b_typ3 xab$b_typ4( xab$b_typ50 xab$b_typ68 xab$b_typ7R xabprodefxab$r_xabprodef_bits RRSTS " xab$v_noread"  " xab$v_nowrite" " xab$v_noexe" " xab$v_nodel"  " xab$v_fill_10" RXABPRO xab$b_cod xab$b_bln xab$l_nxt@xab$r_pro_overlay RP xab$b_mtaccXxab$r_prot_opt_overlay R`xab$r_uic_overlay Rxab$r_prot_mode_overlay R xab$l_aclbuf xab$w_aclsiz xab$w_acllen xab$l_aclctx  xab$l_aclsts@xabprodef$$_fill_10`xabprodef$$_fill_11xabprodef$$_fill_12xabprodef$$_fill_13xabprodef$$_fill_14xabprodef$$_fill_15xabprodef$$_fill_16 xabprodef$$_fill_17@xabprodef$$_fill_18`xabprodef$$_fill_19xabprodef$$_fill_20xabprodef$$_fill_21RSTS  xab$w_proxab$r_pro_bits RRSTSb " xab$v_sys" " xab$v_own" " xab$v_grp" " xab$v_wld" RSTS xab$b_prot_optxab$r_prot_opt_fields RRSTS ""xab$v_propagate" " xab$v_fill_11" RSTS   xab$l_uicxab$r_uic_fields RRSTS   xab$w_mbm xab$w_grpRSTS @xab$q_prot_mode*&xab$r_prot_mode_fields RRSTS xab$b_prot_modeRXABRDT xab$b_cod xab$b_bln xab$l_nxt@ xab$w_rvnPxabrdtdef$$_fill_6` xab$q_rdt TRXABRU xab$b_cod xab$b_bln xab$l_nxt@xab$r_ru_flags_overlay RPxabrudef$$_fill_5`xab$l_ru_handlexab$l_ru_handle_joinedxabrudef$$_fill_7xabrudef$$_fill_8xabrudef$$_fill_9xabrudef$$_fill_10 xabrudef$$_fill_11@xabrudef$$_fill_12`xabrudef$$_fill_13RSTS xab$w_ru_flagsxab$r_ru_flags_bits RRSTS " xab$v_nojoin" " xab$v_fill_21" RXABSUM` xab$b_cod xab$b_bln xab$l_nxt@ xab$b_noaH xab$b_nokP xab$w_pvnRXABTRM  xab$b_cod xab$b_bln xab$l_nxt@ xab$l_itmlst`xab$w_itmlst_lenpxabtrmdef$$_fill_5xabtrmdef$$_fill_6bxabtrmdef$$_fill_7xabtrmdef$$_fill_8xabtrmdef$$_fill_9xabtrmdef$$_fill_10R __ITEM_LIST_3` length code address @return_length_address R__IOSB@ status count dvispecificRprvdef@prv$r_prvdef_bits0 Rprv$r_prvdef_bits1 Rprv$r_prvdef_bits2 RRSTS  @" prv$v_cmkrnl" " prv$v_cmexec" " prv$v_sysnam" " prv$v_grpnam" !"prv$v_allspool" " prv$v_detach" !"prv$v_diagnose" " prv$v_log_io" " prv$v_group" " prv$v_noacnt" " prv$v_prmceb" " prv$v_prmmbx" " prv$v_pswapm" " prv$v_setpri" " prv$v_setprv" " prv$v_tmpmbx" " prv$v_world" " prv$v_mount" " prv$v_oper"  " prv$v_exquota" " prv$v_netmbx" " prv$v_volpro" " prv$v_phy_io" " prv$v_bugchk" " prv$v_prmgbl" " prv$v_sysgbl" " prv$v_pfnmap" " prv$v_shmem" " prv$v_sysprv" " prv$v_bypass" " prv$v_syslck" " prv$v_share"  " prv$v_upgrade" ""prv$v_downgrade" !" prv$v_grpprv" " " prv$v_readall" #" prv$v_import" $" prv$v_audit" %!"prv$v_security" &" prv$v_fil l_1" 'RSTS " prv$v_fill_2 " " prv$v_acnt" " prv$v_fill_3" " prv$v_altpri" " prv$v_fill_54" RSTS @ prv$l_l1_bits prv$l_l2_bitsR prvdsp_bits" prv$v_sorted" " prv$v_brief" " prv$v_filled"  " prv$v_fill_55" R!dsc$descriptor@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer RSTSTSdsc$descriptor_s@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_d@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_a dsc$w_length dsc$b_dtype dsc$b_class" dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" ""dsc$v_fl_column" !"dsc$v_fl_coeff" ""dsc$v_fl_bounds" Rdsc$descriptor_p@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer# Rdsc$descriptor_sd` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_sflags RRSTS $"dsc$v_fl_binscale" Rdsc$descriptor_nca dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_afla$gs RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_vs@dsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_vsadsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP% dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_ubs` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_posRdsc$descriptor_uba dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$b_scaleH& dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_sb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$l_sb_l1` dsc$l_sb_u1Rdsc$descriptor_ubsb dsc$w_length dsc$b_dtype dsc$b_class dsc$a'_base @ dsc$l_pos` dsc$l_ubsb_l1 dsc$l_ubsb_u1R _SKEY_ALGORITHM MD4 MD5R _ALT_ENTRYh next T entry*& R _ALT_DICT  algorithm T hentry62 T RPRINCIPAL_RECORD principal*&@@?sequence s(eed*& key*& algorithm T flags R  dbversion@lastmod*& statusRSTS  b RlRSTS " skey_default" " skey_allow" " norm_allow" R)STSTSTS LIO_STRUCT dirty fab +T rab TT pro T lf Tcurrent_logfile current_loglevelDECC$GA_RMS_FABdecc$ga_rms_fab +TDECC$GA_RMS_RABdecc$ga_rms_rab TTDECC$GA_RMS_XABPROdecc$ga_rms_xabpro T;%Z['DISK$USERS:[LANE.WORK.SKEY]SKEY_LOG.H;17$77S b#DISK$USERS:[LAN*E.WORK.SKEY]UTIL.H;1?#џ$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1DESCRIP>"%>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1PRVDEF<!: (DISK$USERS:[LANE.WORK.SKEY]VMS_TYPES.H;17 M#DISK$USERS:[LANE.WORK.SKEY]SKEY.H;2?G$l(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STARLET>sVe&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RMSDEFɛAP*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABTRMDEFA*>$SYS$COMM+ON:[SYSLIB]DECC$RTLDEF.TLB;1 XABSUMDEF@A*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XABRUDEFʛA#'*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABRDTDEFAxt*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABPRODEFAr6e*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABKEYDEFʛA\*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABJNLDEFAbL*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABITMDEFAC*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;,1 XABFHCDEFǛ>w<*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XABDEFA5*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABDATDEFAG.*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABCXRDEFěA&*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABCXFDEFA~*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABALLDEF;*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XAB>&&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RABDEF; 2"&>$SYS$-COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RAB> 57>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1FABDEF; O;3>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1FAB> ">$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1NAMDEF; ތ">$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1NAM; Z&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RMS=Y%(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1SSDEF=-v$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDIO<3$S.YS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1WAIT>8}$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDLIB>p$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDARG>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STRING;{ 'DISK$USERS:[LANE.WORK.SKEY]SKEY_LOG.C;1      < 6=           o    /                m  {  p  j    N  s      b  c  \  b Ǜ        ! "0 !! # !%   > $  %  DECC$GA_RMS_XABPRODECC$GA_RMS_RABDECC$GA_RMS_FABSYS$PUTSYS$OPENSYS$FAOLSYS$DISCONNECT SYS$CREATE SYS$CONNECT SYS$CLOSE DECC$DSPRINTF DECC$MALLOC DECC$FREE DECC$VA_COUNT DECC$STRLEN DECC$STRCPY DECC$STRCAT | OPEN_LOGFILE SKEY_LOG  SET_LOGLEV$CODE$DATA $ADDRESS_4DATAݬ DECC$DSPRINTF DECC$STRCATdQPP| DECC$STRLENPQdPQvdPTSYS$PUTP\P^RbPPЬլ5/ЭPTSYS$DISCONNECTЭP SYS$CLOSE DECC$FREEww prv$v_grpnam" !"prv$v_allspool" " prv$v_detach" !"prv$v_diagnose" " prv$v_log_io" " prv$v_group" " prv$v_noacnt" 2tgfh SYS$GETTIMPϛSKEY_LOGЬRr‰f„@ˆV|vXTSYS$PUTPSSwSKEY_LOGSpV SKEY$_NOUSERDECC$GA_RMS_XABPRODECC$GA_RMS_XABKEYDECC$GA_RMS_RABDECC$GA_RMS_FAB TRNLNM_EXECUCNSKEY_LOG LIB$SIGNALSYS$PUTSYS$OPEN SYS$GETTIMSYS$GETSYS$FREESYS$DISCONNECT SYS$DELETE SYS$CREATE SYS$CONNECT SYS$CLOSE DECC$MALLOC DECC$FREE DECC$STRLEN DECC$STRNCPY DECC3$STRCPY DECC$MEMSET h DB_CREATE DB_OPEN hDB_FETCH DDB_PUTv DECC$FREESRRPP|^t~ DECC$MALLOCPU <$~ LIB$SIGNAL@~ݬe DECC$STRNCPY@~eUCNeR@V|SVTPQPQQTSSVpd|hԥ@\```T DECC$MEMSETD DECC$MEMSETURRPP^ЬRTSYS$DISCONNECT SYS$CLOSEb DECC$FREER DECC$FREE^<~ DECC$MALLOCPW <$~ LIB$SIGNALЬV(tfgЬRr‰g„@ˆW|vXT SYS$DELETEPSS.SKEY_LOGSpW DECC$FREESRRPP^ |DB_NEW DB_CLOSE  DB_DELETE @DB_FREEZ$CODEt$DATA $ADDRESS_DATArЬPTSYS$FREEPQQPhww prv$l_l2_bitsR prvdsp_bits" prv$v_sorted" " prv$v_brief" " prv$v_filled"  " prv$v_fill_55" Rdsc$descriptor@5 dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_s@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_d@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_a dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scale6H dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" ""dsc$v_fl_column" !"dsc$v_fl_coeff" ""dsc$v_fl_bounds" Rdsc$descriptor_p@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_sd`7 dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_sflags RRSTS $"dsc$v_fl_binscale" Rdsc$descriptor_nca dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` 8dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_vs@dsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_vsadsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_di9mct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_ubs` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_posRdsc$descriptor_uba dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags R:X dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_sb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$l_sb_l1` dsc$l_sb_u1Rdsc$descriptor_ubsb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_pos` dsc$;l_ubsb_l1 dsc$l_ubsb_u1R _SKEY_ALGORITHM MD4 MD5R _ALT_ENTRYh next T entry*& R _ALT_DICT  algorithm T hentry62 T R ST STSTSTSPRINCIPAL_RECORD@ principal*&@@?sequence seed*&< key*& algorithm T flags R  status RS T S  b  Rl R S T S " skey_default" " skey_allow" " norm_allow"  R S T S T S TS TS TS TS TS TS T S=__Skey_DB_Context file  fab 9T rab bT key T protection T recbuf TDECC$GA_RMS_FABdecc$ga_rms_fab 9TDECC$GA_RMS_RABdecc$ga_rms_rab bTDECC$GA_RMS_XABKEYdecc$ga_rms_xabkey TDECC$GA_RMS_XABPROdecc$ga_rms_xabpro T SKEY$_NOUSER SKEY$_NOUSER7*77S b#DISK$USERS:[LANE.WORK.SKEY]UTIL.>H;1;)fr 'DISK$USERS:[LANE.WORK.SKEY]SKEY_MSG.H;3;(Z['DISK$USERS:[LANE.WORK.SKEY]SKEY_LOG.H;1:'?t:&DISK$USERS:[LANE.WORK.SKEY]SKEY_DB.H;1?&$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1DESCRIP>%%>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1PRVDEF<$: (DISK$USERS:[LANE.WORK.SKEY]VMS_TYPES.H;17#zq\#DISK$USERS:[LANE.WORK.SKEY]SKEY.H;1ǛD"' >$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 LIB?$ROUTINES?!G$l(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STARLET= Y%(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1SSDEFǛ>sVe&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RMSDEFAP*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABTRMDEFA*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABSUMDEFɛ@A*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XABRUDEFA#'*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABRDTDEFAxt*>$SYS$CO@MMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABPRODEFʛAr6e*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABKEYDEFA\*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABJNLDEFAbL*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABITMDEFǛAC*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABFHCDEF>w<*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XABDEFA5*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABDATDEFʛAG.*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TL ~ SKEY009.A~ e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_VAXNDB.OLB;2|@AB;1 XABCXRDEFA&*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABCXFDEFA~*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABALLDEF;*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XAB>&&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RABDEF;2"&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RAB> 57>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1FABDEF; O;3>煚$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1FAB> ">$SYS$COMMON:[SYSLBIB]DECC$RTLDEF.TLB;1NAMDEF; ތ">$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1NAM; Z&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RMS>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1UNISTD<$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1TIME=x$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1CTYPE<3$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1WAIT>8}$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDLIB>$SYS$COMMONC:[SYSLIB]DECC$RTLDEF.TLB;1STRING=-v$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDIO:S h&DISK$USERS:[LANE.WORK.SKEY]SKEY_DB.C;1      < 6=     @         o                    D m  {  p  j    N  s      b  c  \  b          !  "  # $ % $! & $% # < ' E! ( " ) '# * $ o pDB_CLOSE  DB_DELETE DB_FREE $CODEh$DATA $ADDRESS_DATAUSKEY_LOGЬPЭdЭPP ^ЬPTSYS$FREEPЭЭPPwwF nam$l_node   nam$l_dev @ nam$l_dir ` nam$l_name  nam$l_type  nam$l_ver namdef$$_fill_7*&%?+~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|R STS  nam$b_nopnam$r_nop_bits RRSTS " nam$v_pwd" " nam$v_fill_1" " nam$v_fill_2" G" nam$v_synchk" ""nam$v_noconceal"  " nam$v_slparse" !"nam$v_srchxabs" " nam$v_fill_5" R STS 0 nam$w_fid*&nam$r_fid_fields RRSTS 0 nam$w_fid_num nam$w_fid_seq nam$r_fid_rvn_overlay RRSTS H nam$w_fid_rvnnam$r_fid_rvn_fields RRSTS  nam$b_fid_rvn nam$b_fid_nmxR STS 0 nam$w_did*&nam$r_did_fields RRSTS 0 nam$w_did_num nam$w_did_seq nam$r_did_rvn_overlay RIRSTS  nam$w_did_rvnnam$r_did_rvn_fields R RS T S  nam$b_did_rvn nam$b_did_nmx!RS!T!S   nam$l_wccnam$r_wcc_bits "R#R"S#T#S  ""namdef$$_fill_1" " nam$v_ifi" ""namdef$$_fill_2 "  " nam$v_srchnmfJ" " nam$v_svctx" $RS$T$S   nam$l_fnbnam$r_fnb_bits0 %Rnam$r_fnb_bits1 &Rnam$r_fnb_bits2 'R(R%S(T(S  " nam$v_exp_ver" !"nam$v_exp_type" !"nam$v_exp_name" !"nam$v_wild_ver" ""nam$v_wild_type" ""nam$v_wild_name"  "K nam$v_exp_dir"  " nam$v_exp_dev" !"nam$v_wildcard" ""namdef$$_fill_3" $"nam$v_search_list" !"nam$v_cncl_dev" !"nam$v_root_dir" " nam$v_lowver"  " nam$v_highver" " nam$v_ppf" " nam$v_node" " nam$v_quoted"  " nam$v_grp_mbr" !"nam$v_wild_dir" !"nam$v_dir_lvls" L)R&S)T)S  ""namdef$$_fill_4" !"nam$v_wild_ufd" ""nam$v_wild_sfd1" ""nam$v_wild_sfd2" ""nam$v_wild_sfd3" ""nam$v_wild_sfd4" ""nam$v_wild_sfd5" ""nam$v_wild_sfd6" ""nam$v_wild_sfd7" *R'S*T*S  ""namdef$$_fill_5" !"nam$v_wild_grp" M!"nam$v_wild_mbr" " nam$v_fill_6" +Rfabdef fab$b_bid fab$b_blnfab$r_ifi_overlay ,R fab$r_fop_overlay -R@ fab$l_sts` fab$l_stv fab$l_alq fab$w_deqfab$r_fac_overlay .Rfab$r_shr_overlay /R fab$l_ctx fab$b_rtvfab$r_org_overlay 0Rfab$r_rat_overlay 1RN fab$b_rfmfab$r_jnl_overlay 2R  fab$l_xab@ fab$l_nam  T` fab$l_fna  fab$l_dna  fab$b_fns fab$b_dns fab$w_mrs fab$l_mrn fab$w_bls fab$b_bks fab$b_fsz fab$l_dev  fab$l_sdc@ fab$w_gbcPfab$r_acmodes_overlay 3RXfab$r_rcf_overlay 4R`fabdef$$_fill_95R,S5T5S  fab$w_ififab$r_ifi_bits 6R7R6S7T7S ""fabdef$$_fill_1" " fab$v_ppf_rat"  " fab$v_ppf_ind" " fab$v_ppifi" 8R-S8T8S   fab$l_fopfab$r_fop_bits 9R:R9S:T:S  " fab$v_asy" " fab$v_mxv" " fab$v_suPp" " fab$v_tmp" " fab$v_tmd" " fab$v_dfw" " fab$v_sqo" " fab$v_rwo" " fab$v_pos" " fab$v_wck" " fab$v_nef" " fab$v_rwc" " fab$v_dmo" " fab$v_spl" " fab$v_scf" " fab$v_dlt" " fab$v_nfs" " fab$v_ufo" " fab$v_ppf" " Qfab$v_inp" " fab$v_ctg" " fab$v_cbt"  " fab$v_syncsts" " fab$v_rck" " fab$v_nam" " fab$v_cif" ""fabdef$$_fill_3" " fab$v_esc" " fab$v_tef" " fab$v_ofp" " fab$v_kfo" ""fabdef$$_fill_4" ;R.S;T;S  fab$b_facfab$r_fac_bits <RR=R<S=T=S " fab$v_put" " fab$v_get" " fab$v_del" " fab$v_upd" " fab$v_trn" " fab$v_bio" " fab$v_bro" " fab$v_exe" >R/S>T>S  fab$b_shrfab$r_shr_bits ?R@R?S@T@S " fab$v_shrput" " S fab$v_shrget" " fab$v_shrdel" " fab$v_shrupd" " fab$v_mse" " fab$v_nil" " fab$v_upi" " fab$v_fill_0" AR0SATAS  fab$b_orgfab$r_org_bits BRCRBSCTCS ""fabdef$$_fill_5" " fab$v_org" DR1SDTDS T fab$b_ratfab$r_rat_bits ERFRESFTFS " fab$v_ftn" " fab$v_cr" " fab$v_prn" " fab$v_blk" " fab$v_msb" " fab$v_fill_1" GR2SGTGS   fab$l_jnlfab$r_jnl_real_stuff HRIRHSITIS  fab$r_journal_overlay JURfab$b_ru_facilityfabdef$$_fill_7KRJSKTKS  fab$b_journalfab$r_journal_bits LRMRLSMTMS  " fab$v_only_ru" " fab$v_ru" " fab$v_bi" " fab$v_ai" " fab$v_at" !"fab$v_never_ru" %"fab$v_journal_file" " fab$v_fill_3" NR3SNTVNS  fab$b_acmodesfab$r_acmodes_bits ORPROSPTPS !"fab$v_lnm_mode" ""fab$v_chan_mode" ""fab$v_file_mode" %"fab$v_callers_mode" QR4SQTQS  fab$b_rcffab$r_rcf_bits RRSRRSSTSS " fab$v_rcf_ru" "W fab$v_rcf_ai" " fab$v_rcf_bi" " fab$v_fill_2" TRrabdef  rab$b_bid rab$b_blnrab$r_isi_overlay UR rab$r_rop_overlay VR@ rab$l_sts`rab$r_stv_overlay WRrab$r_rfa_overlay XRrabdef$$_fill_4 rab$l_ctxrabdef$$_fill_5 rab$b_rac rab$b_tmo rab$w_usz rab$w_rsz  rab$l_ubf X@ rab$l_rbf ` rab$l_rhb rab$r_kbf_overlay YRrab$r_ksz_overlay ZR rab$b_krf rab$b_mbf rab$b_mbcrab$r_bkt_overlay [R rab$l_fab +T rab$l_xab\RUS\T\S  rab$w_isirab$r_isi_bits ]R^R]S^T^S ""rabdef$$_fill_1" Y " rab$v_ppf_rat"  " rab$v_ppf_ind" " rab$v_ppisi" _RVS_T_S   rab$l_roprab$r_rop_bits0 `Rrab$r_rop_bits1 aRrab$r_rop_fields bRcR`ScTcS  " rab$v_asy" " rab$v_tpt" " rab$v_rea" " rab$v_rrl" " rab$v_uif" "Z rab$v_mas" " rab$v_fdl" " rab$v_rev" " rab$v_eof" " rab$v_rah" " rab$v_wbh" " rab$v_bio" " rab$v_cdk" " rab$v_loa" " rab$v_lim"  " rab$v_syncsts" " rab$v_loc" " rab$v_wat" " rab$v_ulk" " rab$v_rlk" " rab$v_nlk" " rab$v_kge"[ " rab$v_kgt" " rab$v_nxr" " rab$v_rne" " rab$v_tmo" " rab$v_cvt" " rab$v_rnf" " rab$v_eto" " rab$v_pta" " rab$v_pmt" " rab$v_cco" dRaSdTdS  ""rabdef$$_fill_6" " rab$v_eqnxt" " rab$v_nxt" " rab$v_fill_4 " eR\bSeTeS  rabdef$$_fill_3 rab$b_rop1 rab$b_rop2 rab$b_rop3fRWSfTfS   rab$l_stvrab$r_stv_fields gRhRgShThS   rab$w_stv0 rab$w_stv2iRXSiTiS 0 rab$w_rfa*&rab$r_rfa_fields jRkRjSk]TkS 0 rab$l_rfa0 rab$w_rfa4lRYSlTlS   rab$l_kbf  rab$l_pbf mRZSmTmS  rab$b_ksz rab$b_psznR[SnTnS   rab$l_bkt rab$l_dctoRXABALL xab$b_cod xab$b_bln xab$l_nxt@xab$r_aop_overlay pR^H xab$b_alnP xab$w_vol` xab$l_loc xab$l_alq xab$w_deq xab$b_bkz xab$b_aidxab$r_rfi_overlay qRxaballdef$$_fill_8rRpSrTrS  xab$b_aopxab$r_aop_bits sRtRsStTtS " xab$v_hrd" " xab$v_onc" %"xaballdef$$_fill_5" " xab$v_cbt" %"xaballdef_$$_fill_6" " xab$v_ctg" uRqSuTuS 0 xab$w_rfi*&xab$r_rfi_fields vRwRvSwTwS 0 xab$w_rfi0 xab$w_rfi2 xab$w_rfi4xRXABCXF xab$b_cod xab$b_bln xab$l_nxt@ xab$l_cxfsts` xab$l_cxfstvxab$r_cxfcop_overlay yR `xab$l_cxfbkp xab$w_cxfifi xab$b_cxfverxabcxfdef$$_fill_5xabcxfdef$$_fill_6 xab$w_cxfdeq xab$b_cxffac xab$b_cxfshr  xab$w_cxfrte0xabcxfdef$$_fill_78 xab$b_cxforg@ xab$w_cxfgbcP xab$b_cxfrtvXxabcxfdef$$_fill_8`xabcxfdef$$_fill_9*&zRySzTzS   xab$l_cxfcopxab$r_cxfcop_bits {R|aR{S|T|S " xab$v_cxfrst" " xab$v_fill_13" }RXABCXR xab$b_cod xab$b_bln xab$l_nxt@ xab$l_cxrsts` xab$l_cxrstvxab$r_cxrcop_overlay ~R xab$l_cxrbkp xab$w_cxrisi xab$b_cxrverxabcxrdef$$_fill_6xabcxrdef$$_fill_7 xab$b_cxrmbf xab$b_cxrmbc xab$w_cxrbfz  xab$l_cxrvbn@ xabb$w_cxroffP xab$w_fill_8` xab$l_cxrpos0 xab$w_cxrpos4xabcxrdef$$_fill_9 xab$l_cxrcur0 xab$w_cxrcur4xabcxrdef$$_fill_10 xab$l_cxrsid0 xab$w_cxrsid4xabcxrdef$$_fill_11  xab$w_cxrcnt0 xab$b_cxrkref8 xab$b_cxrklen@ xab$l_cxrbuf`xabcxrdef$$_fill_12*&R~STS   xab$l_cxrcopxab$r_cxrcop_bicts RRSTS  " xab$v_cxrrst" %"xabcxrdef$$_fill_5"  " xab$v_cxrbver" R __vms_date@RXABDAT xab$b_cod xab$b_bln xab$l_nxt@ xab$w_rvn` xab$q_rdt T xab$q_cdt T xab$q_edt T  xab$q_bdt T` xab$q_rcd T xab$q_eff TRdXAB xab$b_cod xab$b_blnxabdef$$_fill_1 xab$l_nxt@ xab$w_rvnPxabdef$$_fill_2`xab$r_rdt_overlay RRSTS @ xab$q_rdt*&xab$r_rdt_fields RRSTS @ xab$l_rdt0 xab$l_rdt4RXABDEF1xabdef$$_fill_3*&e@xabdef$$_fill_4Hxabdef$$_fill_5Pxabdef$$_fill_6`xabdef$$_fill_7xabdef$$_fill_8xabdef$$_fill_9 xab$b_bkzRXABFHC` xab$b_cod xab$b_bln xab$l_nxt@ xab$b_rfoH xab$r_fill_7 RP xab$w_lrl`xab$r_hbk_overlay Rxab$r_ebk_overlay R xab$w_ffb xab$b_bkz xab$b_hsz xab$w_mrzf xab$w_dxq xab$w_gbcxabfhcdef$$_fill_6*&0xab$w_verlimit@ xab$l_sbnRSTS  xab$b_atr xab$r_fill_8 RRSTS " xab$v_ftn" " xab$v_cr" " xab$v_prn" " xab$v_blk" " xab$v_fill_9" RSTS   xab$l_hbkxab$r_hbk_fields RRSTS   xab$w_hbk0 xab$w_hbk2RSTS   xab$l_ebkxab$r_ebk_fields RRSTS   xab$w_ebk0 xab$w_ebk2R UCHAR_FLAGS""xab$v_wascontig" !"xab$v_nobackup" ""xab$v_writeback" h""xab$v_readcheck" ""xab$v_writcheck"  " xab$v_contigb" " xab$v_locked" " xab$v_contig" ""xab$v_reserved1" ""xab$v_reserved2" ""xab$v_reserved3" " xab$v_badacl" " xab$v_spool" ""xab$v_directory" !"xab$v_badblock"  " xab$v_markdel" !"xab$v_nocharge" " xab$iv_erase"  " xab$v_fill_15" RXABITM xab$b_cod xab$b_bln xab$l_nxt@xab$l_itemlist` xab$b_modehxab$b_itm_fill1*&xab$l_itm_fill2*&R xab_rcf_flags" xab$v_rcf_ru" " xab$v_rcf_ai" " xab$v_rcf_bi" ""xab$v_rcf_nopad"  " jxab$v_fill_16" R xabnetextprot@ xab$r_fill_17 Rxab$w_owner_acc xab$w_group_acc0xab$w_world_accRSTS xab$w_system_acc xab$r_fill_18 RRSTS #"xab$v_net_noread" $"xab$v_net_nowrite" &"xab$v_net_noexecute" %"xab$v_net_nodelete" %"kxab$v_net_noappend" ("xab$v_net_nodirectory" %"xab$v_net_noupdate" %"xab$v_net_nochange" %"xab$v_net_noextend"  " xab$v_fill_19" R XABNETDAPVER( xab$b_ver_dap xab$b_ver_eco xab$b_ver_cus xab$b_ver_dsv xab$b_ver_csvR XABNETCAPDEF8#"xab$v_cap_filall" #"xab$v_cap_seqorg" #"xab$v_cap_relorg" l$"xab$v_cap_fill_21" #"xab$v_cap_extend" #"xab$v_cap_seqfil" #"xab$v_cap_ranrrn" #"xab$v_cap_ranvbn" #"xab$v_cap_rankey" $"xab$v_cap_fill_22" #"xab$v_cap_ranrfa" #"xab$v_cap_idxorg" #"xab$v_cap_swmode" #"xab$v_cap_append" #"xab$v_cap_submit" $"xab$v_cap_fill_23"  " xab$mv_cap_mds" $"xab$v_cap_display" #"xab$v_cap_msgblk" #"xab$v_cap_unrblk" #"xab$v_cap_bigblk" #"xab$v_cap_dapcrc" #"xab$v_cap_keyxab" #"xab$v_cap_allxab" #"xab$v_cap_sumxab" &"xab$v_cap_directory" #"xab$v_cap_timxab" #"xab$v_cap_proxab" $"xab$v_cap_fill_24" #"xab$v_cap_fopspl" n#"xab$v_cap_fopscf" #"xab$v_cap_fopdlt" $"xab$v_cap_fill_26" #"xab$v_cap_seqrac" !$"xab$v_cap_fill_27" "#"xab$v_cap_bitopt" #$"xab$v_cap_warning" $#"xab$v_cap_rename" %%"xab$v_cap_wildcard" &#"xab$v_cap_gngopt" '#"xab$v_cap_nammsg" (#"xab$v_cap_segmsg" )&"xab$v_cap_chgattcls" *&"oxab$v_cap_chgtimcls" +&"xab$v_cap_chgprocls" ,&"xab$v_cap_chgnamcls" -&"xab$v_cap_modattcre" .%"xab$v_cap_nam3part" /&"xab$v_cap_chgattren" 0&"xab$v_cap_chgtimren" 1&"xab$v_cap_chgproren" 2&"xab$v_cap_ctlblkcnt" 3%"xab$v_cap_octalver" 4 " xab$v_fill_20" 5RXABJNL xab$b_cod xab$b_bln xab$l_npxt@xab$b_xabjnl_typeHxabjnldef$$_fill_5Pxab$r_jnl_flags_overlay R` xab$l_jnl_fabxab$l_volnam_bufxab$w_volnam_sizxab$w_volnam_lenxab$q_jnl_verify_cdate*& xab$l_jnlidx xab$l_backup_seqno@xab$q_jnl_mod_time*&xabjnldef$$_fill_7xabjnldef$$_fill_8xabjnldef$$_fill_9xabjnldef$$_qfill_10xabjnldef$$_fill_11 xabjnldef$$_fill_12@xabjnldef$$_fill_13`xabjnldef$$_fill_14RSTS xab$w_jnl_flagsxab$r_jnl_flags_bits RRSTS )"xab$v_journal_disabled" $"xab$v_backup_done"  " xab$v_fill_14" RXABKEY  xab$b_cod xab$b_bln xab$l_nxtr@ xab$b_ianH xab$b_lanP xab$b_danX xab$b_lvl` xab$b_ibsh xab$b_dbsp xab$l_rvbxab$r_flg_overlay R xab$b_dtp xab$b_nsg xab$b_nul xab$b_tks xab$b_ref xab$w_mrl xab$w_ifl xab$w_dflxab$r_pos_overlay Rpxab$r_siz_overlay Rxabkeydef$$_fill_11 xab$l_knm xab$l_dvbxab$r_typ_overlay Rs@ xab$b_prologHxabkeydef$$_fill_12Pxabkeydef$$_fill_13` xab$l_coltbl xab$l_colsiz xab$l_colnamxabkeydef$$_fill_14xabkeydef$$_fill_15xabkeydef$$_fill_16RSTS  xab$b_flgxab$r_flg_bits0 Rxab$r_flg_bits1 RRSTS " xab$v_dup" " xab$v_chg" t" xab$v_nul" ""xab$v_idx_ncmpr" %"xabkeydef$$_fill_5" ""xab$v_key_ncmpr"  " xab$v_fill_12" RSTS %"xabkeydef$$_fill_6" %"xabkeydef$$_fill_7" %"xabkeydef$$_fill_8" %"xabkeydef$$_fill_9" &"xabkeydef$$_fill_10" ""xab$v_dat_ncmpr" RSTS  xab$w_pos*&xab$r_pos_fields RRSTS  xab$w_pos0 xab$w_pos1 xab$w_pos20 xab$w_pos3@ xab$w_pos4P xab$w_pos5` xab$w_pos6p xab$w_pos7RSTS @ xab$b_siz*&xab$r_siz_fields RRSTSv @ xab$b_siz0 xab$b_siz1 xab$b_siz2 xab$b_siz3 xab$b_siz4( xab$b_siz50 xab$b_siz68 xab$b_siz7RSTS @ xab$b_typ*&xab$r_typ_fields RRSTS @ xab$b_typ0 xab$b_typ1 xab$b_typ2 xab$b_typ3 xab$b_typ4( xawb$b_typ50 xab$b_typ68 xab$b_typ7R xabprodefxab$r_xabprodef_bits RRSTS " xab$v_noread"  " xab$v_nowrite" " xab$v_noexe" " xab$v_nodel"  " xab$v_fill_10" RXABPRO xab$b_cod xab$b_bln xab$l_nxt@xab$r_pro_overlay RP xab$b_mtaccXxab$rx_prot_opt_overlay R`xab$r_uic_overlay Rxab$r_prot_mode_overlay R xab$l_aclbuf xab$w_aclsiz xab$w_acllen xab$l_aclctx  xab$l_aclsts@xabprodef$$_fill_10`xabprodef$$_fill_11xabprodef$$_fill_12xabprodef$$_fill_13xabprodef$$_fill_14xabprodef$$_fill_15xabprodef$$_fill_16 xabprodef$$_fill_17@xabprodef$$_fill_18`xabprodyef$$_fill_19xabprodef$$_fill_20xabprodef$$_fill_21RSTS  xab$w_proxab$r_pro_bits RRSTS " xab$v_sys" " xab$v_own" " xab$v_grp" " xab$v_wld" RSTS xab$b_prot_optxab$r_prot_opt_fields RRSTS z""xab$v_propagate" " xab$v_fill_11" RSTS   xab$l_uicxab$r_uic_fields RRSTS   xab$w_mbm xab$w_grpRSTS @xab$q_prot_mode*&xab$r_prot_mode_fields RRSTS xab$b_prot_modeRXABRDT xab$b_cod xab$b_bln xab$l_nxt@ xab$w_rvnPxabrdtdef$$_fill_6` xab$q_rdt TRXABRU xab$b_cod xab$b_bln xab$l_nxt@xab$r_ru_flags_overlay RPxabrudef$$_fill_5`xab$l_ru_handlexab$l_ru_handle_joinedxabrudef$$_fill_7xabrudef$$_fill_8xabrudef$$_fill_9|xabrudef$$_fill_10 xabrudef$$_fill_11@xabrudef$$_fill_12`xabrudef$$_fill_13RSTS xab$w_ru_flagsxab$r_ru_flags_bits RRSTS " xab$v_nojoin" " xab$v_fill_21" RXABSUM` xab$b_cod xab$b_bln xab$l_nxt@ xab$b_noaH xab$b_nokP xab$w_pvnR}XABTRM  xab$b_cod xab$b_bln xab$l_nxt@ xab$l_itmlst`xab$w_itmlst_lenpxabtrmdef$$_fill_5xabtrmdef$$_fill_6xabtrmdef$$_fill_7xabtrmdef$$_fill_8xabtrmdef$$_fill_9xabtrmdef$$_fill_10R __ITEM_LIST_3` length code address @return_length_address R__IOSB@ status count dvispecificR~prvdef@prv$r_prvdef_bits0 Rprv$r_prvdef_bits1 Rprv$r_prvdef_bits2 RRSTS @" prv$v_cmkrnl" " prv$v_cmexec" " prv$v_sysnam" " prv$v_grpnam" !"prv$v_allspool" " prv$v_detach" !"prv$v_diagnose" " prv$v_log_io" " prv$v_group" ":~ SKEY009.A~ e*.[LANE.WORK.SKEY.INSTALL_A]SKEYLIB_VAXNDB.OLB;2s:f~ prv$v_noacnt" " prv$v_prmceb" " prv$v_prmmbx" " prv$v_pswapm" " prv$v_setpri" " prv$v_setprv" " prv$v_tmpmbx" " prv$v_world" " prv$v_mount" " prv$v_oper"  " prv$v_exquota" " prv$v_netmbx" " prv$v_volpro" " prv$v_phy_io" " prv$v_bugchk" " prv$v_prmgbl" " prv$v_sysgbl" " prv$v_pfnmap" " prv$v_shmem" " prv$v_sysprv" " prv$v_bypass" " prv$v_syslck" " prv$v_share"  " prv$v_upgrade" ""prv$v_downgrade" !" prv$v_grpprv" " " prv$v_readall" #" prv$v_import" $" prv$v_audit" %!"prv$v_security" &" prv$v_fill_1" 'RSTS " prv$v_fill_2 " " prv$v_acnt" " prv$v_fill_3" " prv$v_altpri" " prv$v_fill_54" RSTS @ prv$l_l1_bits prv$l_l2_bitsR prvdsp_bits" prv$v_sorted" " prv$v_brief" " prv$v_filled"  " prv$v_fill_55" Rdsc$descriptor@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer RSTSTSdsc$descriptor_s@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_d@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_a dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale& h~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'b5" !"dsc$v_fl_redim" ""dsc$v_fl_column" !"dsc$v_fl_coeff" ""dsc$v_fl_bounds" Rdsc$descriptor_p@ dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_sd` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_sflags RRSTS $"dsc$v_fl_binscale" Rdsc$descriptor_nca dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_vs@dsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer Rdsc$descriptor_vsadsc$w_maxstrlen dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_ubs` dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_posRdsc$descriptor_uba dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$b_scaleH dsc$b_digitsP dsc$b_aflags RX dsc$b_dimct` dsc$l_arsizeRSTS $"dsc$v_fl_binscale" !"dsc$v_fl_redim" Rdsc$descriptor_sb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_pointer @ dsc$l_sb_l1` dsc$l_sb_u1Rdsc$descriptor_ubsb dsc$w_length dsc$b_dtype dsc$b_class dsc$a_base @ dsc$l_pos` dsc$l_ubsb_l1 dsc$l_ubsb_u1R _SKEY_ALGORITHM MD4 MD5R _ALT_ENTRYh next T entry*& R _ALT_DICT  algorithm T hentry62 T RPRINCIPAL_RECORD@ principal*&@@?sequence seed*& key*& algorithm T flags R  statusRSTS  b RlRSTS " skey_default" " skey_allow" " norm_allow" RSTSTSTS LIO_STRUCT dirty fab +T rab TT pro T lf Tcurrent_logfile current_loglevelDECC$GA_RMS_FABdecc$ga_rms_fab +TDECC$GA_RMS_RABdecc$ga_rms_rab TTDECC$GA_RMS_XABPROdecc$ga_rms_xabpro T;%Z['DISK$USERS:[LANE.WORK.SKEY]SKEY_LOG.H;17$77S b#DISK$USERS:[LANE.WORK.SKEY]UTIL.H;1?#$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1DESCRIP>"%>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1PRVDEF<!: (DISK$USERS:[LANE.WORK.SKEY]VMS_TYPES.H;17 zq\#DISK$USERS:[LANE.WORK.SKEY]SKEY.H;1?G$l(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STARLET>sVe&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RMSDEFɛAP*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABTRMDEFA*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABSUMDEF@A*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XABRUDEFʛA#'*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABRDTDEFAxt*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABPRODEFAr6e*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABKEYDEFʛA\*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABJNLDEFAbL*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABITMDEFAC*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABFHCDEFǛ>w<*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XABDEFA5*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABDATDEFAG.*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABCXRDEFěA&*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABCXFDEFA~*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1 XABALLDEF;*>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1XAB>&&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RABDEF; 2"&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RAB> 57>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1FABDEF; O;3>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1FAB> ">$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1NAMDEF; ތ">$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1NAM; Z&>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1RMS=Y%(>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1SSDEF=-v$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDIO<3$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1WAIT>8}$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDLIB>p$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STDARG>$SYS$COMMON:[SYSLIB]DECC$RTLDEF.TLB;1STRING;{ 'DISK$USERS:[LANE.WORK.SKEY]SKEY_LOG.C;1      < 6=           o                    m  {  p  j    N  s      b  c  \  b Ǜ        ! " !! # !%   < $  %  DECC$GA_RMS_XABPRODECC$GA_RMS_RABDECC$GA_RMS_FABSYS$PUTSYS$OPENSYS$FAOLSYS$DISCONNECT SYS$CREATE SYS$CONNECT SYS$CLOSE DECC$DSPRINTF DECC$MALLOC DECC$FREE DECC$VA_COUNT DECC$STRLEN DECC$STRCPY DECC$STRCAT | OPEN_LOGFILE SKEY_LOG  SET_LOGLEV$CODE$DATA $ADDRESS_DATAݬ DECC$DSPRINTF DECC$STRCATdQPP| DECC$STRLENPQdPQvdPTSYS$PUTP\P^RbPPЬլ5/ЭPTSYS$DISCONNECTЭP SYS$CLOSE DECC$FREEww(T DECC$DSPRINTFTRRP^|~ݬ SYS$SETPRVPQQPP^|~ݬ SYS$SETPRVPQQPP<ЬUЬTЬ SRPU DECC$STRLENPc蟭RX SYS$TRNLNMPTRSգ ݣ DECC$FREES DECC$FREEXRբ ݢ DECC$FREER DECC$FREETSGT T LIB$SIGNALPU DECC$STRLENPc蟭RX SYS$TRNLNMPTRSգ ݣ DECC$FREES DECC$FREEXRբ ݢ DECC$FREER DECC$FREETSIPT T LIB$SIGNALPU DECC$STRLENPc. DECC$__ASSERTЬPRB`TBSBQTRxRRSPPRxRSQPPSzP{PQP PRRPP RPRSPì RRRxRRPPPRUUP 0^ DECC$MALLOCPS <$~ LIB$SIGNAL߭ DECC$TIME DECC$CLOCKP0 DECC$DSPRINTF߭ DECC$CTIMEP0 DECC$STRCATRbUSERNAMEP\\0b\ DECC$FREEPIDP\\0b\ DECC$FREEMD5INIT0 DECC$STRLENP0 MD5UPDATEMD5FINAL uP\Q\P\\\P\QPQP{\PPQaQQc 5P\Q\P\\\P\QPQP{\PPQaQQ P\Q\P\\\P\QPQ{\PPQaQQ 'ϴP\Q\P \\\P\QPQ{\PPQ0QQ 4xP\Q\P \\\P\QPQ{\PPQ0QQ A~:P\Q\P \\\P\QPQP{\PPQ0QQSRRPP ^ެTRSBcPˏP~ό DECC$DSPRINTFd DECC$STRCATRRP^VЬR֬bTTP1PTSSQQaQfQR R6PQAQFQR RQ0 Q90QRRRUV Џ SKEY$_BADENCW1VPVU@<DECC$$GL___CTYPEADECC$$GA___CTYPETRTPˏ@bSPT~ DECC$ISSPACEPSS Џ SKEY$_BADENCW_PЬP֬`TTP16V Џ SKEY$_BADENCW=QPQЬR֬APUPPb APxPUQQ DECC$MEMSETWWPP^Џ SKEY$_BADENC ЬS Џ SKEY$_VOIDPWDn1S DECC$STRLENPѮ@@~ DECC$MALLOCP <$n1PݮSݮ  DECC$STRNCPYЮRB / DECC$MEMSETݬ DECC$MEMSET|ZЮUZ1 DECC$ISALPHAXPeRWDECC$$GL___CTYPEADECC$$GA___CTYPETSˏBcT RhPTT0UeQ)DECC$$GL___CTYPEADECC$$GA___CTYPETPˏA`R PQhPRRUWeP4DECC$$GL___CTYPEADECC$$GA___CTYPETQePˏ@aR Pe~hPRRUeP̘ePZ1UW1W DECC$STRLENPVV S<:R P<;S<RRSW+P1wSViPCgTTQQaQfQR R5PQAQFQR RQ0 Q90QRRRYSSVY1լ 1Ѭ WMD5INITVW DECC$ISSPACE DECC$ISLOWER DECC$ISALPHA DECC$STRLEN DECC$STRNCMP DECC$STRCMP DECC$STRNCPY DECC$STRNCAT DECC$STRCPY DECC$STRCAT DECC$MEMSET DECC$MEMCPY DECC$MALLOC DECC$FREE DECC$FGETS DECC$FOPEN DECC$DSPRINTF DECC$FCLOSE KEYPROC HASHKEY x| KEYTOENGLISH  ENGLISHTOKEY SEEDGENERATE KEYTOHEX , HEXTOKEY d ALTTOKEY ANYTOKEY MD5UPDATE8MD5FINAL;PHMD4INITVWH MD4UPDATEH8MD4FINAL Џ SKEY$_UNALGOR 1 8 [P/ϨZ [Z1 |RR/PSRR@@~/ϹˏSRRP Џ SKEY$_PARITY %P/ݬ DECC$MEMCPY/ DECC$MEMSET ݮݮ  DECC$MEMSETݮ DECC$FREEЮ nnP^ЬTTЬSS ENGLISHTOKEYPRR SKEY$_BADENC(TSHEXTOKEYPRR SKEY$_BADENCݬ TSALTTOKEYPRRP^< ~ DECC$MALLOCPR <$~ LIB$SIGNALЬbP@PPRQQPP8^ެYi DECC$STRLENPWWW Џ SKEY$_INVALTX1PW S<:R P<;S<RRSiϫP Џ SKEY$_INVALTX1LSWmUCeTTQQaQfQR R5PQAQFQR RQ0 Q90QRRRVSSWռ4ѼZHMD5INITWݬH MD5UPDATEH8MD5FINAL:PMD4INITWݬ MD4UPDATE8MD4FINALPЏ SKEY$_UNALGORXjP 8{PTЬSDR"ݬ DECC$STRCMPP Џ SKEY$_DUPALTX1PbR  DECC$MALLOCPSЬRDcݬ DECC$STRCPYSDXXP^լ 1!լ 1ϲݬ DECC$FOPENPnCMA$TIS_VMSERRNO_GET_ADDR`1P  DECC$MEMSET|XWn<~ DECC$FGETSP1cޯ DECC$ISALPHAV DECC$STRNCPY[ADDENTRY_DICTIONARYZTdR1(PdRWDECC$$GL___CTYPEADECC$$GA___CTYPETSˏBcU RfPUU0TdQ)DECC$$GL___CTYPEADECC$$GA___CTYPETPˏA`R PQfPRRИdP1TScRXDECC$$GL___CTYPEADECC$$GA___CTYPETPˏB`U PRfPUU0ScQ)DECC$$GL___CTYPEADECC$$GA___CTYPETPˏA`R PQfPRRST\TSRR HRTkBݬjPRR SKEY$_DUPALTWR SKEY$_INVALTXPR R1PYSTdP1n<~ DECC$FGETSP1n DECC$FCLOSE|SRCTSSЬ RWbЬRXbЬRYbЬRTbT  PЏSKEY$_PARTDICTP^ݬ DECC$MEMCPY|RRϸPSRR@SRxRRRX WY DECC$CLOCKV DECC$STRCATZ X~vPSCU ЏSKEY$_PARTDICT[yPTfPRzRP{PQPPRTR)PeUgRCUTfPRzRP{PQPPRTRٟݬjX ݬjXX1w  DECC$MEMSET[[PPQլ Ѭ P R  RRRPP ^RЬPР\S S P S  SSЬPנ@Dݠ@S-럭 DECC$DSPRINTF DECC$STRLENPP DECC$MALLOCPS <$~ LIB$SIGNALS DECC$STRCPYd~ NEW_DICTIONARY ADDENTRY_DICTIONARY READ_DICTIONARY KEYTOALT  ALGORITHMNAME 0 CHALLENGE$CODE $DATA $ADDRESS_DATA DECC$MEMSETSPww%*[LANE.WORK.SKEY.INSTALL_A]SKEYSHR.H;1+,Z. / 4M - e*0123KPWO56_xڗ)7)89GHJ#ifndef __SKEYSHR_HK/***********************************************************************\K* *K* S/Key for VMS *K* (c) 1998 C. Lane *K* *K* API for user-programs *K* **K\***********************************************************************/ #define __SKEYSHR_H 1 Oint SkeyChallenge(char *user, char *dbfile, char *challenge, void **context); 7int SkeyAuthenticate(char *password, void **context); 7#define SKEY$_OKAUTH 0x08018099 /* MSG2H */ 8#define SKEY$_USERMOD 0x08018093 /* MSG2H */7#define SKEY$_INVALT 0x0801808B f /* MSG2H */ 7#define SKEY$_DUPALT 0x08018083 /* MSG2H */ 6#define SKEY$_NOUAF 0x08018078 /* MSG2H */8#define SKEY$_LONGPWD 0x08018070 /* MSG2H */9#define SKEY$_SHORTPWD 0x08018068 /* MSG2H */r7#define SKEY$_NOAUTH 0x08018062 /* MSG2H */u9#define SKEY$_PARTDICT 0x0801805A /* MSG2H */ 7#define SKEY$_BADENC 0x08018052 /* MSG2H */ 7#define SKEY$_OUTERR 0x0801804A /* MSG2H */ 8#define SKEY$_TIMEOUT 0x08018042 /* MSG2H */7#define SKEY$_PARITY 0x0801803A /* MSG2H */ 7#define SKEY$_NOUSER 0x08018034 /* MSG2H */K8#define SKEY$_UNALGOR 0x0801802C /* MSG2H */8#define SKEY$_NOSYSPR 0x08018024 /* MSG2H */8#define SKEY$_NOSECUR 0x0801801C /* MSG2H */8#define SKEY$_NOPARAM 0x08018014 /* MSG2H */8#define SKEY$_VOIDPWD 0x0801800C /* MSG2H */9#define SKEY$_FACILITY 0x00000801 /* MSG2H */ #endif.*[LANE.WORK.SKEY.INSTALL_A]SKEYSHR_AXPNDB.OPT;2+,. / 4* - e*0123KPWO56OO7N\89GHJSKEYLIB_AXPNDB.OLB/libGSMATCH=lequal,00,9)SYMBOL_VECTOR=(SkeyChallenge=PROCEDURE),SYMBOL_VECTOR=(SkeyAuthenticate=PROCEDURE).*[LANE.WORK.SKEY.INSTALL_A]SKEYSHR_VAXNDB.OPT;2+,. / 4 l- e*0123KPWO56:n7Yz89GHJSKEYLIB_VAXNDB.OLB/libGSMATCH=lequal,00,9UNIVERSAL=SkeyChallengeUNIVERSAL=SkeyAuthenticate(*[LANE.WORK.SKEY.INSTALL_A]SKEY_API.ABJ;2+,k.-/ 4-+- e*0123KPWO,56z07H89GHJDDSKEY_APIV1.0 5-FEB-1998 10:02DEC C V5.5-0020 0 $ABS$i$CODE$ $LITERAL$$LINK$$DATA$$BSS$ $READONLY_ADDR$ $READONLY$ DECC$ATOI DECC$FREE DECC$MALLOC DECC$STRCPY DECC$STRNCPY DECC$MEMCMP DECC$ISSPACE DECC$TOLOWER DECC$$GA___CTYPET DECC$$GL___CTYPEA SYS$BINTIM SYS$CANTIMSYS$FAO SYS$GETUAI SYS$HASH_PASSWORD SYS$SETIMRUCCURPRIVSSETPRIVS RESETPRIVSNEW_STR DESTROY_STRTRNLNM TRNLNM_EXECHASHKEYANYTOKEY CHALLENGEDB_OPENDB_FETCHDB_PUTDB_CLOSEDB_FREE SKEY$_OKAUTH SKEY$_USERMOD SKEY$_NOAUTH SKEY$_BADENC SKEY$_TIMEOUT SKEY$_NOUSER OPEN_LOGFILESKEY_LOG SET_LOGLEV GET_LOGSTATUS0J SKEYCHALLENGE8JHSKEYAUTHENTICATEOTS$MOVEOTS$ZERO =p#G~4G ^(^0~8@H޴PX`>h^p~xGG``5C~ SKEY009.Ak e*([LANE.WORK.SKEY.INSTALL_A]SKEY_API.ABJ;2-P0[@.G8{GUJ>GG3G@Zk CGG G@$ GG*C*G* Gxb# 4Gj@$`PBXbG@ZkCPB4G0,0.Xb HQ0J1D=@Zk}G`B&0DhbcIC `4G=@Zk Gb#@G@A0BG8bTG@Zk* GBbC 4G@Zk~`G$c Gb#@D G`4G4G ?$! aE 4G 4GGi`jjG(b#~@@BGHbGGtG@ZkC $!Yp`"aE= T```9`6`H0F 53`G(b#b@GCb#@ GBpBCxbGBGG@Zk G8B4G b@ZkPB CGG@ZkPBGXb4G@ZkbBGGxc bCFtG@Zkb# @ C4D( 4GB Gb@ZkjGBGbtGX FC@Zkb#@ "C4DG`b#@BGbTG0!C@Zkb#@GGG ](]0}8@HݤPX`=h]p}x#k#G~_&^2F^4G ~(G [G3G({C >@ZkB4Gb@Zk#G 0B @B4Gb@Zk0B4G8b@ZkG@BtG #HbGTG @ZkBGb4G@ZkG]] }(0#k@#~^^~޴G#GG GGGQhb#@ӰBGbG` CtG@Zk $G Pb#_ӰbBGbTGHc C@Zkb#U@`CGx_&|FxCBGtGNb\E@ZkGGPb#m_ӰBGbG( CtG@Zkb#2@ӰCGBCp}TG\%b}@ZkPBCXb@GtG@ZkBG}TG=bTeX%@ZkbGBTGbc C@Zk';~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'w sbGBTGb~@@Zk GPb#-_Cb#@Gð"0"BGTGA"@ZkBb2@G@Zkb#@0C<CH=C%H0B H8b!?H0@@0TݢP @C4=<6J@BH=LTݲX=4G@ZkBCb4G@Zk$ PBXbC4G@ZkpBCxbGGGGGG@Zk$GpBxbC 4G@ZkG$ Pb#_D CG@G0BG8b4G@ZkBCb4G@Zk (}CBGb2vHDGG@Zk@BGHbG4G@Zk4GDB1vHG@Zk@BHbG@Zk`Gݠ==6HD  BDF0D CbCG G]]}ݤ#kGP#?$~! ^25B^~G#GG=fC?&=@`GBG("!CF`B&hb1L "d"G&H3CF2`JrRBRRBRRBRRB0B CFLp"vH4CF!JA!@A!@A!@!B2C!DCQN ]" ]C$J5C1DC@B`@@@  @@ZkTG=PB1JXbr HC2F=G@ZkG2DGG]]}#k#4G~4G^G [ 0({@ZkG] #kG#C~^^~ (0޴8@GGGG%G !G.C" Bd"(b4GJ,H.,0`@0@EJFHHHG@Zk B(bGG4G@ZkD @GG]]} (0ݤ8@P#kG#G~^^~ (0޴8@HGGGGGG. J@" . 1@JH@@D G.#"0B4G8bPJJ@Zk0`@#,#H?#.G #J@h"@ `.UJJTBF G.#0B4G8bPJJ@Zk#,#H%D 0`@#.#J?PB(g@Xb0A4G@ZkC$ VGBCGbtG@ZkC@,@H<4G#,#H? G#."#JX$F4 c.tJXdF`P`@,H/0`@G,H)G."R@GUJb#JXFF.%_G0`@%,!HL@Gb#_ G0`@%,!H4G0`@,H.VJ>GG]]}  =( (0ݤ8@HP#kGpBGG@ZkG#~^^~ (GG 8[dCiC@{TG@ZkC `GGhBD@pbO@TG@ZkC`GXBG`b4G@Zk&"@ BG0D G(BG0b4G@ZkGG]]} (0#k#G~TG^^ ~(rxG[G{GC@ZkB4Gb@Zk|9`B" bJ@CTG@ZkC(B `0bGGTG@ZkBGb4G@ZkHbG(BTG0bc@@ZkBB 4GbG@2CTG@ZkCG`BbG4G@ZkBGb4G@ZkBbG4G@Zk<GBJ@ b1[@TG@ZkC `(BG0bGTG@ZkBGb4G@Zk(BO@0bGTG@ZkB4GBG@ b1[@2TG@ZkC`BbG4G@ZkBGb4G@ZkBbG4G@ZkGBGb4G@ZkhBH"GpbGtG@ZkG]] }(0#kG#C~G^TG^ ~(G {G0[8{# @ZkPB4GXb@Zk@BHb"4G@ZkG]] }(0#k4TG DECC$MALLOC4db# DECC$MALLOC4@ DECC$MALLOC4)GCURPRIVS4*b#CURPRIVS4)@CURPRIVS4G  DECC$FREE4b# DECC$FREE4@  DECC$FREE4+(GXSETPRIVS4,4b#SETPRIVS4+T@XSETPRIVS,%xGDB_OPEN,&b#DB_OPEN,%@DB_OPEN4G RESETPRIVS4b# RESETPRIVS4@ RESETPRIVS4'G4DB_FETCH4( b#DB_FETCH4'0@4DB_FETCH4-G SYS$SETIMR4.b# SYS$SETIMR4-@ SYS$SETIMR4/G CHALLENGE40b# CHALLENGE4/@ CHALLENGE4G DECC$STRCPY4@ DECC$STRCPY4G DECC$FREE4b# DECC$FREE4@ DECC$FREE4#G0SKEY_LOG4$b#SKEY_LOG4#,@0SKEY_LOG4 PGdDB_CLOSE4 Xb#DB_CLOSE4 `@dDB_CLOSE4#pGSKEY_LOG4$xb#SKEY_LOG4#@SKEY_LOG4#GSKEY_LOG4$b#SKEY_LOG4#@SKEY_LOG4TG RESETPRIVS4hb#` RESETPRIVS4@ RESETPRIVS4G DECC$FREE4b#` DECC$FREE4@ DECC$FREE4G DECC$FREE4b#` DECC$FREE4@ DECC$FREE4 GDB_CLOSE4 b#`DB_CLOSE4 @DB_CLOSE4 G SYS$CANTIM4 b#` SYS$CANTIM 4 @ SYS$CANTIM4G, DECC$FREE4 b#` DECC$FREE4(@, DECC$FREE4#GSKEY_LOG4$b#SKEY_LOG4#@SKEY_LOG4#G SKEY_LOG4$b#SKEY_LOG4#@ SKEY_LOG45@G`ANYTOKEY46Tb#ANYTOKEY45\@`ANYTOKEY4#xGSKEY_LOG4$b#SKEY_LOG4#@SKEY_LOG,7GHASHKEY,8b#HASHKEY,7@HASHKEY4?G DECC$MEMCMP4@b# DECC$MEMCMP4?@ DECC$MEMCMP,1GDB_PUT,2b#DB_PUT,1@DB_PUT4# G8SKEY_LOG4$(b#SKEY_LOG4#4@8SKEY_LOG4#HG\SKEY_LOG4$Pb#SKEY_LOG4#X@\SKEY_LOG4CGOTS$MOVE4C@OTS$MOVE4#GSKEY_LOG4$b#SKEY_LOG4#@SKEY_LOG,;G4NEW_STR,<b#NEW_STR,;0@4NEW_STR,94GLUC,:<b#UC,9H@LUC4+TGhSETPRIVS4,Xb#SETPRIVS4+d@hSETPRIVS4AhG SYS$GETUAI4Bpb# SYS$GETUAI4A@ SYS$GETUAI4G RESETPRIVS4b# RESETPRIVS4@ RESETPRIVS,;GNEW_STR,<b#NEW_STR,;@NEW_STR,9G UC,: b#UC,9 @ UC<3 G@ SYS$HASH_PASSWORD<4( b#SYS$HASH_PASSWORD<3< @@ SYS$HASH_PASSWORD4=@ GX DESTROY_STR4>H b# DESTROY_STR4=T @X DESTROY_STR4Ed Gt OTS$ZERO4Ep @t OTS$ZERO4=t G DESTROY_STR4>x b# DESTROY_STR4= @ DESTROY_STR,| G4 SYS$FAO, b#SYS$FAO,0 @4 SYS$FAO4 D Gh SYS$BINTIM4L b# SYS$BINTIM4 d @h SYS$BINTIM,G G DB_FREE,H {#DB_FREE,G @ DB_FREE48 G DECC$TOLOWER4@ b# DECC$TOLOWER4 @ DECC$TOLOWER4 G DECC$TOLOWER 4 b# DECC$TOLOWER4 @ DECC$TOLOWER4 G DECC$ISSPACE4 b# DECC$ISSPACE4 @ DECC$ISSPACE4G DECC$ISSPACE4b# DECC$ISSPACE4@ DECC$ISSPACE4<GX DECC$MALLOC4Hb# DECC$MALLOC4T@X DECC$MALLOC4pG DECC$STRNCPY4 b# DECC$STRNCPY4@ DECC$STRNCPY4G DECC$STRCPY4@ DECC$STRCPY4<GT TRNLNM_EXEC4Hb#( TRNLNM_EXEC4P@T TRNLNM_EXEC,hGTRNLNM,pb#(TRNLNM,|@TRNLNM4G DECC$ATOI4b#( DECC$ATOI4@ DECC$ATOI4G DECC$FREE4b#( DECC$FREE4@ DECC$FREE4$G< GET_LOGSTATUS4,b#x GET_LOGSTATUS48@< GET_LOGSTATUS4@GT DECC$FREE4Hb#x DECC$FREE4P@T DECC$FREE4\Gx TRNLNM_EXEC4db#x TRNLNM_EXEC4t@x TRNLNM_EXEC4!|G OPEN_LOGFILE4"b#x OPEN_LOGFILE4!@ OPEN_LOGFILE4G DECC$FREE4b#x DECC$FREE4@ DECC$FREE4!G OPEN_LOGFILE4"b#x OPEN_LOGFILE4!@ OPEN_LOGFILE4G TRNLNM_EXEC4b#x TRNLNM_EXEC4@ TRNLNM_EXEC4G DECC$ATOI4b#x DECC$ATOI4 @ DECC$ATOI4G$ SET_LOGLEV4b#x SET_LOGLEV4 @$ SET_LOGLEV4$G8 DECC$FREE4(b#x DECC$FREE44@8 DECC$FREE,@GXTRNLNM,Hb#xTRNLNM,T@XTRNLNM4!`Gx OPEN_LOGFILE4"hb#x OPEN_LOGFILE4!t@x OPEN_LOGFILE4xG DECC$FREE4b#x DECC$FREE4@ DECC$FREE4!G OPEN_LOGFILE4"b#x OPEN_LOGFILE4!@ OPEN_LOGFILE,GTRNLNM,b#xTRNLNM,@TRNLNM4G DECC$ATOI4b#x DECC$ATOI4@ DECC$ATOI4G SET_LOGLEV4b#x SET_LOGLEV4@ SET_LOGLEV 4G DECC$FREE4b#x DECC$FREE4 @ DECC$FREE4G, SET_LOGLEV4 b#x SET_LOGLEV4(@, SET_LOGLEV4#,GHSKEY_LOG4$8b#xSKEY_LOG4#D@HSKEY_LOG4G GET_LOGSTATUS4b# GET_LOGSTATUS4@ GET_LOGSTATUS4G DECC$FREE4b# DECC$FREE4@ DECC$FREE4G SET_LOGLEV4b# SET_LOGLEV4@ SET_LOGLEV = skeyshr run at !%D= sys$manager:skey.log0=0#error return, no challenge issuedX=(void Challenge !XL issuedx= Challenge !XL issued=(non S/Key authentication used=H=#=(user authentication failed= user authenticated(=(AnyToKey returned error !XLH= challege timed out`=)!Authentication of challenge !XL =0 h;=0 ;0 GET_LOGSTATUS SET_LOGLEV DECC$FREE=0 (;=0  RESETPRIVS DB_CLOSE SYS$CANTIM=0" ;=@1 ųE.!UL !UL:!UL:!UL SYS$BINTIMSYS$FAO==0";=(0 SKEY_TIMEOUT` TRNLNM_EXEC= LNM$SYSTEM DECC$ATOITRNLNM=LNM$FILE_DEV=0" ;=P  DECC$TOLOWER=0" ;=P 7DECC$$GL___CTYPEA DECC$ISSPACE7DECC$$GA___CTYPET0 DECC$MALLOC= /NOSKEYP DECC$STRCPY DECC$STRNCPY=/SKEYx=0 ;=0 ! OPEN_LOGFILE=SKEY_LOG_LEVEL;=SKEY_LOG_FILE#SKEY_LOG= skey.log=0 ";= 7 SKEY$_USERMOD0%DB_OPEN'DB_FETCH)CURPRIVS+SETPRIVS- SYS$SETIMR/ CHALLENGE7 SKEY$_NOUSER;1DB_PUT 3SYS$HASH_PASSWORD7 SKEY$_BADENC5ANYTOKEY7HASHKEY7 SKEY$_OKAUTH9UC=0"H;=| 7 SKEY$_NOAUTH@;NEW_STR= DESTROY_STR? DECC$MEMCMP7 SKEY$_TIMEOUTA SYS$GETUAI8OTS$MOVE8OTS$ZERO=0  ;= GDB_FREE$ $=  $(*[LANE.WORK.SKEY.INSTALL_A]SKEY_API.OBJ;2+,{./ 4  - e*0123KPWO 56@[7h89GHJ5SKEY_APIV1.0 4-FEB-1998 12:03DEC C V5.5-002Pskeyshr run at !%DPLNM$FILE_DEVPSKEY_LOG_LEVELPskey.logPLNM$FILE_DEVPSKEY_LOG_FILEPLNM$SYSTEMxPSKEY_LOG_LEVELcPsys$manager:skey.logXPLNM$SYSTEMJPSKEY_LOG_FILE=PLNM$FILE_DEV0PSKEY_TIMEOUT%PLNM$SYSTEMPSKEY_TIMEOUTP/NOSKEYP/SKEYP!UL !UL:!UL:!ULPnon S/Key authentication usedPuser authentication failedPuser authenticatedPAnyToKey returned error !XLxPchallege timed outXPAuthenticat SKEY$_NOUSER SKEY$_TIMEOUT SKEY$_BADENC SKEY$_NOAUTH SKEY$_USERMOD SKEY$_OKAUTHDECC$$GL___CTYPEADECC$$GA___CTYPET GET_LOGSTATUS SET_LOGLEVSKEY_LOG OPEN_LOGFILEDB_FREEDB_CLOSEDB_PUTDB_FETCHDB_OPEN CHALLENGEANYTOKEYHASHKEY TRNLNM_EXECTRNLNM DESTROY_STRNEW_STR RESETPRIVSSETPRIVSCURPRIVSUC SYS$SETIMRSYS$HASH_PASSWORD SYS$GETUAIion of challenge !XL8Pvoid Challenge !XL issuedPerror return, no challenge issuedPChallenge !XL issuedP#0^X|ZYլ Ь RЬPW1b`  DECC$MALLOCPS <$W1iPcԣ| ԣԣPլPPݣY լhCURPRIVS}`P DECC$FREEO|SETPRIVSPRP4h(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVhRW1PݬDB_OPENPVգ  RESETPRIVSV1cݬPVV [ZV [Y PV1SPՠϳϢ TRNLNM_EXECPTPϵϤTRNLNMPTTxU,T DECC$ATOIPR R xUPT DECC$FREERUUcݣDB_FETCHP<$VУQ1HСpVV SKEY$_NOUSER1V12Z`1nY`1b``1USPՠ TRNLNM_EXECPTTRNLNMPTTxU,T DECC$ATOIPR R xUPT DECC$FREERUU"PVP1S SYS$SETIMRPVP}ݣ CHALLENGEPRRݬ  DECC$STRCPYR DECC$FREESSSKEY_LOGh(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVh[ Џ SKEY$_USERMODW1PW1PSϩSKEY_LOGh(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVhVWfPգ ݣDB_CLOSEԣSSϠSKEY_LOGh(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVh[ Џ SKEY$_USERMODWPWWP^ЬP1ՠ| RESETPRIVSռ ݼ DECC$FREEЬRբt~ݢ DECC$MEMSETݢ DECC$FREEЬRբ ݢDB_CLOSEЬRԢբ%բ  R SYS$CANTIMʏPP R DECC$FREE|^WլЬRX1bVX1bݦ>VϜSKEY_LOGզ JVϣSKEY_LOGg(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVgЏ SKEY$_TIMEOUTX1|զ1)ЦTݤ\ݬANYTOKEYPSSOVϠSBSKEY_LOGg(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVgЏ SKEY$_BADENCX1*P蟭 DECC$MEMCPYݤ\HASHKEYT DECC$MEMCMPP1T DECC$MEMCPYTݦDB_PUTSKEY_LOGЏ SKEY$_OKAUTHRSKEY_LOGЏ SKEY$_NOAUTHR DECC$MEMSETԦVg(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVgRX1iP(<ϧSKEY_LOGg(߭ GET_LOGSTATUSխݭ DECC$FREE~ SET_LOGLEVg}ح>~fNEW_STRPUݥUCզ SETPRIVS|~U|~ SYS$GETUAIPSզ  RESETPRIVSVS Џ SKEY$_NOAUTHX1PS SX1PݬNEW_STRPSݣUCퟭU<~~}~SSYS$HASH_PASSWORDPTU DESTROY_STR޶@ZkXb# @8B@bG4G@ZkcG8]@]HP#kG#G~^ ^(~0G@[GH{@ZkPBGXbG@Zk B(bCCTG@Zk0B8bCCCtG@Zk`BChb4G@ZkpBxbS@TG@ZkBGb@ZkG] ](}0@#kGP#4G~`^h^p~x޴>GG{# @HBPbM@GTG@ZkxB bC4GG@ZkGB4Gb@ZkxBb0F@4G@ZkB4Gb@ZkB bCCTG@ZkBX4Gb@ZkBGb0F@CTG@ZkXBP4G`b@ZkB4GPb@Zk"HBGP}G! PbCG@ZkxBbJ@4G@Zk BbJ@CTG@ZkB@4Gb@ZkG4GxB" a\~ SKEY009.Ae e*)[LANE.WORK.SKEY.INSTALL_A]SKEY_CALC.ABJ;2uV|bC4G@Zk"GHBTGPb! C@ZkB bCCTG@ZkBx bCCGtG@Zk>"B""bCTG@ZkXB84G`b@Zk8b#;@GBb4G@ZkxBb0J@4G@ZkxB0DbO@4G@ZkxBx" b0DC4G@ZkxBb 0D0C@4G@ZkB0C@bCTG@ZkXBP@0]1I@`b4GG@ZkCB x bCCTG@ZkH= !.4B@!J4FH=6B@HݲG8B@HCCCD@B1G@TG@Zk(BC0b1Q@@ZkD(B0bC1U@TG@Zk (B 0bC[@TG@ZkD(E&G=(""C?D H2E@G@CG("!H!CCG@GhBpb@ZkCB bW@4G@ZkB4GH]tGbC@ZkxB8 bC4G@ZkxBH"!bC4G@ZkxBH bC4G@ZkG "4GBbC@ZkG4G(B8}CP]G0bG@ZkGBb4G@ZkxBb0M@4G@ZkxB b 0DC4G@Zk'BCbCTG@Zk}0 BCbG`TG@ZkG="HBCPb0F=G4G@ZkBC= bGGGGGG@Zk<4G90@HBCPbGTG@Zk @B+b`CCGtG@ZkG BbCCTG@Zk(Ϡ~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|hBCpbCTG@Zk BP}H@bCGGG@Zk GBH@P]CbGG@Zk0@ @0@4GG`]h]p}xݤ=#k#4G~^^~ GG {[{C@ZkC ÈB@ZkY@ ("G0B @4GDGGG]]} 0#kG#G~4G8^@^H~PX`޴hG[GkC{>@Zk)B" bCCTG@Zk0C(B0b4G@Zk8b#C@H"B4G]tG! bC@ZkBCTGb@ZkB4Gb0@ZkGB" bC4G@ZkB" bCCTG@Zk0C(B0b4G@Zk8b#C@H"BG]tGh! bC@ZkG8b#@" CC@b#@0C(B0b4G @Zk8" BC bTG@ZkhBGpb4G@ZkH"BCbtG@! CGtG@ZkBb0Y@4G@ZkB0DbF@4G@ZkBbF@CTG@ZkB(4Gb0@Zk@GG@B0A@b4G@ZkB0A@bCTG@Zk04G(B0b@ZkHB4GPb@ZkGBGb@ZkD BCG=GbtG@ZkB4Gb@ZkBb0M@4G@ZkBbU@4G@Zk4G\$B0K@b4G@Zk\(B4Gx0b@Zk4G\BD@b4G@Zk?&1"0DXB5 @d`bG4G0`B@d@ZkBCH" bCGTG@ZkBGb4G @Zk(BC0bCGtG@Zk08"BTG b1B@@ZkB@ =tG\Db@Zk0Y(B0bC4G@ZkSG0?$! BbD@DCTG@Zk0G(B"0bCCGtG@Zk01B@t8BBTG b@ZkB 4GbT @Zk `b#_ӈBC }C\Gb@Zk0C(B0b4G@Zk ]B4G4GG@ZkBGG@ZkB b@Zk@ GBC\$TGb0@@Zk@ @=8b# @BCTG b@Zkb#0@0ݠBGbTG&@ZkB4Gb0 =@Zk`H¤GBTGb C@ZkXBG`b4G@Zk@dBC(" b0`@@dCGTG@ZkBGb4G@Zk0G8]@]H}PX`ݤhp#k#G~^^~ G [G({@ZkCpB0 xbp,4GaH@Zk`HG]0`DG]} 0#k#G~^^~ GH[GP{@ZkCB0 bp,4GaH@Zk`HG]0`DG]} 0#k#G~4G ^(^0~8@HG["G{C>@ZkB" bCCTG@ZkC(B0b4G@Zk8b#C@" C@Cb#@C"F (B4G0b@ZkBG@b4G@ZkHBtGbG CtG@Zk8b#.@BCTG b@Zk=b# A@xb#C@(BG0bGGtG@ZkCC(Bp$0bGTG @Zk4GBb@ZkBGb4G@Zk$ pGG ! @`@?BGb4G@Zk4GG ](]0}8@HP#kGP#G~4Gh^p^x~޴G[["G{P>CX>G@Zk B" bCCTG@Zk`|X]Hb#Cq@X" C@Cb#J@X"CBGbG! CtG@Zk`DbX]Hb#@@(BXC0bTG@ZkX=`b# @X4GBb@Zk`b#8X=P}C@8B@bGGGtG@ZkBCbG4G@Zk$ `$`pB4GbG`0B@@ZkBP4Gb@ZkB0B@bCPTG@ZkH`0L@BGbTG@ZkHO@GH]GXBtGQFH]"bCC@ZkB\4Gb@ZkBCH=CbCCCGG@ZkB`D@XGB(=P"0]8}Cb@Zk 4GX"! CGX"TG =! CBb@ZkB0C@b4G@ZkB0C@bCTG@ZkBbS@4G@Zk?&B1"@DbC1M@TG@ZkCHBPbG@Zk  C_ G(BA0bG@GtG@Zk(B0bG@AGtG@Zk @BbG4G@ZkGhBGpb4G]@@ZkBCbK@GTG@ZkBbG4G@ZkXCb#C9@8BG@bGGtG@Zk !`B"H"TGE`(BWC0b@ZkBC=tG\C b@Zk]B4G`G@Zk(BGG@ZkBb@Zk`B C8bTG\#@ZkhBCpbj@GtG@ZkBGTGx!bTX㰨 P@Zk`CBbGTG@ZkBCb4G@Zk` øB1V@bGTG@ZkBY@b4G@Zk``4GPBb@Zk `GG(A@BGb4G@Zk`Gh]p]x}ݤ#k#G~4G ^(^0~8@H޴PX`>h^pGp[G0nCx{>>@ZkB0N@bCTG@Zk]b#C@0L@C0b#@@"C@BGHbG! CtG@ZkDnpBxbH@4G@ZkpB0DxbF@4G@ZkpB0DxbD@4G@ZkpB0DxbJ@4G@ZkpB0DxbR@4G@ZkpB0DxbP@4G@Zk= 0Db# @ӰBCbTG@Zk=b# @b#8=]C?@BbGGGtG@ZkpB CxbG4G@Zk$ }C`p  .26:>B pBGxbTG@Zk4GBb@Zk `GG_(A@pBGxb4G@ZkG ](]0}8@HݤPX`=h]p#k`j4`F`j _E`TF` _E`F` _E`ʢ1F`ʲ _E`QF`겿? _E` G` G#G~4G(^0^8~@HPG [G>hC({>G@Zk0BH@8bCTG@Zk ]b#C@J@Cb#@@Ӑ"CBGbG! CtG@Zk HD]b#@/@`BChbTG@Zk= Pb# B@ b#=}C@pBxbGGGtG@Zk0BC4G8b@ZkG$? =w`pc¦4G@B }q`"HbC@Zk@BGHbTG` C@Zk@BTG@#8 HbC@Zk@Bh@HbTG C@ZkB4G =x\b@@Zk@BCHbGTG@Zk`(" "B@BTGDHbCXB@Zk`(" B "@BPDHbDTGCSB@Zk`(" B "@BDHbDTGCNB@ZkBbG4G@ZkBCbm@CGGG@Zk =eTG¦1v J@BqBHbB.UJ>%@ZkPBXbG4G@Zk4G  B(bG4G@Zk4G0B8b@Zk `GG_$@@ BG(b4G@Zk G(]0]8}@HP`#kG#?$~4G0^8^@~HPXG@[#GG=GH{G@Zk PBCXbGTG@Zk(}b#`.J`_ BG(b@Zk0BC(G@Zk `¦IJG/G BG(b@Zk(&4G$#ÀB4G(b@Zk}BCbC#HG`@}C GGGGG@Zkh"$ DDpBGxb4G@Zk(G0]8]@}HPX`#kG#G~?&^F^4G G [G({C @ZkBbG4G@ZkG]] 0#k#G~?&^F^4G G0[G8{C @Zk B(bG4G@ZkG]] 0#k#G~^^~ (GP[GhCX{@Zk BC(bGTG@Zk0BG8bpb@ZkBbCG@Zk BC(bGGtG@Zk`BhbGR@@Zk BC(bGTG@ZkG]]4G} (0#kG#~^^~ (GG 0[dChC8{TG@ZkC `GÀBD@bJ@TG@ZkC`GpBGxb4G@Zk&"@ BG0D G`BGhb4G@ZkGG]]} (0#k#~^^~ GG5p[ hCx{CTG@ZkC0B `8bGGTG@ZkBGb4G@ZkbG0BTG8bf@@ZkpB xbJ@CTG@ZkCBE`bG4G@Zk B(bG4G@ZkBGb4G@Zk;B bH@CTG@ZkC `0B8bGGTG@ZkBbG4G@ZkG0BL@8bGTG@ZkB bJ@CTG@ZkC`BbG4G@Zk BG(b4G@ZkBbG4G@ZkG BG(b4G@ZkbpBGxbGc@tG@ZkG]]} 0#k4(G\ DECC$MAIN4<b# DECC$MAIN4X@\ DECC$MAIN4dGx DECC$EXIT4hb# DECC$EXIT4t@x DECC$EXIT4G IMAGEPRIVS4b# IMAGEPRIVS4@ IMAGEPRIVS4G PROCPRIVS4b# PROCPRIVS4@ PROCPRIVS4GPRIVSNOT4b#PRIVSNOT4@PRIVSNOT4GPRIVSAND4b#PRIVSAND4 @PRIVSAND4 G$ RESETPRIVS4 b# RESETPRIVS4  @$ RESETPRIVS4 $G<CLI_INIT4 (b#CLI_INIT4 8@<CLI_INIT4 @GP CLI_DISPATCH4Hb# CLI_DISPATCH4 L@P CLI_DISPATCH4=GSKEY_LOG4>b# SKEY_LOG4=@SKEY_LOG4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4%G LIB$SIGNAL4&b# LIB$SIGNAL4%@ LIB$SIGNAL 4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4%G0 LIB$SIGNAL4&(b# LIB$SIGNAL4%,@0 LIB$SIGNAL410GL CLI_GETVALUE428b# CLI_GETVALUE41H@L CLI_GETVALUE4!LG` DECC$ATOI4"Xb# DECC$ATOI4!\@` DECC$ATOI41`G| CLI_GETVALUE42hb# CLI_GETVALUE41x@| CLI_GETVALUE4i|G CLI_UNQUOTE4jb# CLI_UNQUOTE4i@ CLI_UNQUOTE,oGLC,pb# LC,o@LC4=GSKEY_LOG4>b# SKEY_LOG4=@SKEY_LOG4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT41G CLI_GETVALUE42b# CLI_GETVALUE41@ CLI_GETVALUE4!G DECC$ATOI4"b# DECC$ATOI4! @ DECC$ATOI4/G4 CLI_PRESENT40$b# CLI_PRESENT4/0@4 CLI_PRESENT4=@GXSKEY_LOG4>Hb# SKEY_LOG4=T@XSKEY_LOG41XGt CLI_GETVALUE42`b# CLI_GETVALUE41p@t CLI_GETVALUE4QxGREAD_PWD4Rb# READ_PWD4Q@READ_PWD4[GDECC$GXFPRINTF4\b# DECC$GXFPRINTF4[@DECC$GXFPRINTF4iG CLI_UNQUOTE4jb# CLI_UNQUOTE4i@ CLI_UNQUOTE4%G LIB$SIGNAL4&b# LIB$SIGNAL4%@ LIB$SIGNAL4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4/G  CLI_PRESENT40b# CLI_PRESENT4/@  CLI_PRESENT4/ G< CLI_PRESENT40(b# CLI_PRESENT4/8@< CLI_PRESENT4/<GT CLI_PRESENT40@b# CLI_PRESENT4/P@T CLI_PRESENT41XGp CLI_GETVALUE42`b# CLI_GETVALUE41l@p CLI_GETVALUE,}pGCRELNM,~b# CRELNM,}@CRELNM41G CLI_GETVALUE42b# CLI_GETVALUE41@ CLI_GETVALUE4G DECC$STRCPY4@ DECC$STRCPY4{G, DECC$STRCAT4| b# DECC$STRCAT 4{(@, DECC$STRCAT4{4GL DECC$STRCAT4|8b# DECC$STRCAT4{H@L DECC$STRCAT4{PGl DECC$STRCAT4|Xb# DECC$STRCAT4{h@l DECC$STRCAT4YG DECC$FOPEN4Zb# DECC$FOPEN4Y@ DECC$FOPEN4G DECC$PERROR4b# DECC$PERROR4@ DECC$PERROR4%G LIB$SIGNAL4&b# LIB$SIGNAL4%@ LIB$SIGNAL4/G4 CLI_PRESENT40$b# CLI_PRESENT4/0@4 CLI_PRESENT4/8GP CLI_PRESENT40@b# CLI_PRESENT4/L@P CLI_PRESENT4/TGl CLI_PRESENT40\b# CLI_PRESENT4/h@l CLI_PRESENT4%G LIB$SIGNAL4&b# LIB$SIGNAL4%@ LIB$SIGNAL,sGKEYPROC,tb# KEYPROC,s@KEYPROC4%G LIB$SIGNAL4&b# LIB$SIGNAL4%@ LIB$SIGNAL4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT41G  CLI_GETVALUE42b# CLI_GETVALUE41@  CLI_GETVALUE,#(GDTRNLNM,$0b# TRNLNM,#@@DTRNLNM4UTGtNEW_DICTIONARY4V\b# NEW_DICTIONARY4Up@tNEW_DICTIONARY4atGREAD_DICTIONARY4bb# READ_DICTIONARY4a@READ_DICTIONARY,cGHASHKEY,db# HASHKEY,c@HASHKEY4yGKEYTOALT4zb# KEYTOALT4y@KEYTOALT4G KEYTOENGLISH4b# KEYTOENGLISH4@ KEYTOENGLISH4wG0KEYTOHEX4x b# KEYTOHEX4w,@0KEYTOHEX4[4GXDECC$GXFPRINTF4\@b# DECC$GXFPRINTF4[T@XDECC$GXFPRINTF4`G DECC$GXPRINTF4pb# DECC$GXPRINTF4|@ DECC$GXPRINTF4%G LIB$SIGNAL4&b# LIB$SIGNAL4% @ LIB$SIGNAL4e G DECC$STRLEN4e @ DECC$STRLEN4/ G CLI_PRESENT40 b#( CLI_PRESENT4/ @ CLI_PRESENT41 G CLI_GETVALUE 42 b#( CLI_GETVALUE41 @ CLI_GETVALUE4% G LIB$SIGNAL4& b#( LIB$SIGNAL4% @ LIB$SIGNAL4= G SKEY_LOG4> b#(SKEY_LOG4= @ SKEY_LOG4m G0 DB_CREATE4n( b#( DB_CREATE4m, @0 DB_CREATE4?0 GH DB_CLOSE4@< b#(DB_CLOSE4?D @H DB_CLOSE4/P Gh CLI_PRESENT40X b#( CLI_PRESENT4/d @h CLI_PRESENT41l G CLI_GETVALUE42t b#( CLI_GETVALUE41 @ CLI_GETVALUE4% G LIB$SIGNAL4& b#( LIB$SIGNAL4% @ LIB$SIGNAL4= G SKEY_LOG4> b#(SKEY_LOG4= @ SKEY_LOG4% G LIB$SIGNAL4& b#( LIB$SIGNAL4% @ LIB$SIGNAL4[( G@ DECC$GXFPRINTF4\0 b#(DECC$GXFPRINTF4[< @@ DECC$GXFPRINTF,q@ GT DB_NEW,rH b#(DB_NEW,qP @T DB_NEW4=X G| SKEY_LOG4>` b#(SKEY_LOG4=x @| SKEY_LOG4/| G CLI_PRESENT40 b#( CLI_PRESENT4/ @ CLI_PRESENT4/ G CLI_PRESENT40 b#( CLI_PRESENT4/ @ CLI_PRESENT41 G CLI_GETVALUE42 b#( CLI_GETVALUE41 @ CLI_GETVALUE4! G DECC$ATOI4" b#( DECC$ATOI4! @ DECC$ATOI4/ G CLI_PRESENT40 b#( CLI_PRESENT4/ @ CLI_PRESENT41 G CLI_GETVALUE42 b#( CLI_GETVALUE41 @ CLI_GETVALUE4%, G< LIB$SIGNAL4&4 b#( LIB$SIGNAL4%8 @< LIB$SIGNAL,o< GP LC,pH b#(LC,oL @P LC4kX Gh SEEDGENERATE4l` b#( SEEDGENERATE4kd @h SEEDGENERATE4up G DECC$STRNCPY4v b#( DECC$STRNCPY4u @ DECC$STRNCPY4 G DECC$FREE4  b#( DECC$FREE4 @ DECC$FREE4/ G CLI_PRESENT40 b#( CLI_PRESENT4/ @ CLI_PRESENT4/ G CLI_PRESENT40 b#( CLI_PRESENT4/ @ CLI_PRESENT4/ G CLI_PRESENT40 b#( CLI_PRESENT 4/ @ CLI_PRESENT4% G LIB$SIGNAL4& b#( LIB$SIGNAL4% @ LIB$SIGNAL4/ G4 CLI_PRESENT40( b#( CLI_PRESENT4/0 @4 CLI_PRESENT4_D Gh CHALLENGE4`P b#( CHALLENGE4_d @h CHALLENGE4h G DECC$GXPRINTF4t b#( DECC$GXPRINTF4 @ DECC$GXPRINTF4 G DECC$FREE4  b#( DECC$FREE4 @ DECC$FREE4Q G READ_PWD4R b#(READ_PWD4Q @ READ_PWD4[ G DECC$GXFPRINTF4\ b#(DECC$GXFPRINTF4[ @ DECC$GXFPRINTF4M G ANYTOKEY4N b#(ANYTOKEY4M @ ANYTOKEY4%G LIB$SIGNAL4&b#( LIB$SIGNAL4%@ LIB$SIGNAL41,GL CLI_GETVALUE420b#( CLI_GETVALUE41H@L CLI_GETVALUE4QXGxREAD_PWD4R`b#(READ_PWD4Qt@xREAD_PWD4[GDECC$GXFPRINTF4\b#(DECC$GXFPRINTF4[@DECC$GXFPRINTF4iG CLI_UNQUOTE4jb#( CLI_UNQUOTE4i@ CLI_UNQUOTE,sGKEYPROC,tb#(KEYPROC,s@KEYPROC4%G LIB$SIGNAL4&b#( LIB$SIGNAL4%@ LIB$SIGNAL4eG DECC$STRLEN4e@ DECC$STRLEN4OG$OTS$ZERO4O @$OTS$ZERO4$G4 DECC$FREE4 ,b#( DECC$FREE40@4 DECC$FREE,c@G\HASHKEY,dPb#(HASHKEY,cX@\HASHKEY,AxGDB_OPEN,Bb#(DB_OPEN,A@DB_OPEN,KGDB_PUT,Lb#(DB_PUT,K@DB_PUT4?GDB_CLOSE4@b#(DB_CLOSE4?@DB_CLOSE4G DECC$GXPRINTF4b#( DECC$GXPRINTF4@ DECC$GXPRINTF4_G CHALLENGE4`b#( CHALLENGE4_@ CHALLENGE4G@ DECC$GXPRINTF4$b#( DECC$GXPRINTF4<@@ DECC$GXPRINTF4@GT DECC$FREE4 Hb#( DECC$FREE4P@T DECC$FREE4)G AUTHPRIVS4*b# AUTHPRIVS4)@ AUTHPRIVS 4G DECC$FREE4 b# DECC$FREE4@ DECC$FREE4)G( AUTHPRIVS4* b#h AUTHPRIVS4)$@( AUTHPRIVS4,GH DECC$FREE4 4b#h DECC$FREE4D@H DECC$FREE4/G CLI_PRESENT40b#( CLI_PRESENT4/@ CLI_PRESENT41G CLI_GETVALUE42b#( CLI_GETVALUE41@ CLI_GETVALUE4%G LIB$SIGNAL4&b#( LIB$SIGNAL4%@ LIB$SIGNAL4%8GH LIB$SIGNAL4&@b#( LIB$SIGNAL4%D@H LIB$SIGNAL4/HG\ CLI_PRESENT40Pb#( CLI_PRESENT4/X@\ CLI_PRESENT4=`GSKEY_LOG4>hb#(SKEY_LOG4=|@SKEY_LOG,AGDB_OPEN,Bb#(DB_OPEN,A@DB_OPEN4CGDB_FETCH4Db#(DB_FETCH4C@DB_FETCH4gG DB_DELETE4hb#( DB_DELETE4g@ DB_DELETE4? G0DB_CLOSE4@(b#(DB_CLOSE4?,@0DB_CLOSE40GD DECC$FREE4 8b#( DECC$FREE4@@D DECC$FREE4pG DECC$FREE4 xb#( DECC$FREE4@ DECC$FREE4/G  CLI_PRESENT40b# CLI_PRESENT4/@  CLI_PRESENT41G, CLI_GETVALUE42b# CLI_GETVALUE41(@, CLI_GETVALUE4=hGSKEY_LOG4>pb#SKEY_LOG4=@SKEY_LOG,AGDB_OPEN,Bb#DB_OPEN,A@DB_OPEN4G DECC$FREE4 b# DECC$FREE4@ DECC$FREE4C G(DB_FETCH4Db#DB_FETCH4C$@(DB_FETCH4(G@ DECC$FREE4 0b# DECC$FREE4<@@ DECC$FREE4/PGp CLI_PRESENT40Xb# CLI_PRESENT4/l@p CLI_PRESENT4?tGDB_CLOSE4@b#DB_CLOSE4?@DB_CLOSE41G CLI_GETVALUE42b# CLI_GETVALUE41@ CLI_GETVALUE,#GTRNLNM,$b#TRNLNM,#@TRNLNM4=GSKEY_LOG 4>b#S M~ SKEY009.Ae e*)[LANE.WORK.SKEY.INSTALL_A]SKEY_CALC.ABJ;2u_^FKEY_LOG4=@SKEY_LOG4UGNEW_DICTIONARY4Vb#NEW_DICTIONARY4U@NEW_DICTIONARY4aGDREAD_DICTIONARY4b(b#READ_DICTIONARY4a@@DREAD_DICTIONARY4`G DECC$GXPRINTF4xb# DECC$GXPRINTF4|@ DECC$GXPRINTF4G DECC$GXPRINTF4b# DECC$GXPRINTF4@ DECC$GXPRINTF4/G CLI_PRESENT40)Q~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'*nhb# CLI_PRESENT4/@ CLI_PRESENT41G CLI_GETVALUE42b# CLI_GETVALUE41@ CLI_GETVALUE4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4Y G0 DECC$FOPEN4Zb# DECC$FOPEN4Y,@0 DECC$FOPEND]4GHCMA$TIS_VMSERRNO_GET_ADDRD^<b#CMA$TIS_VMSERRNO_GET_ADDRD]D@HCMA$TIS_VMSERRNO_GET_ADDR4[pGDECC$GXFPRINTF4\xb#DECC$GXFPRINTF4[@DECC$GXFPRINTF4[GDECC$GXFPRINTF4\b#DECC$GXFPRINTF4[@DECC$GXFPRINTF4WG DECC$FCLOSE4Xb# DECC$FCLOSE4W@ DECC$FCLOSE4_G CHALLENGE4`b# CHALLENGE4_@ CHALLENGE4G DECC$GXPRINTF4b# DECC$GXPRINTF4@ DECC$GXPRINTF4G( DECC$FREE4 b# DECC$FREE4$@( DECC$FREE4Q<GXREAD_PWD4RDb#READ_PWD4QT@XREAD_PWD4[xGDECC$GXFPRINTF4\b#DECC$GXFPRINTF4[@DECC$GXFPRINTF4MGANYTOKEY4Nb#ANYTOKEY4M@ANYTOKEY4eG DECC$STRLEN4e@ DECC$STRLEN4OGOTS$ZERO4O@OTS$ZERO4G DECC$FREE4 b# DECC$FREE4@ DECC$FREE,cGHASHKEY,db#HASHKEY,c @HASHKEY4SG, DECC$STRNCMP4Tb# DECC$STRNCMP4S(@, DECC$STRNCMP,K0G`DB_PUT,LHb#DB_PUT,K\@`DB_PUT4=lGSKEY_LOG4>pb#SKEY_LOG4=|@SKEY_LOG4G DECC$GXPRINTF4b# DECC$GXPRINTF4@ DECC$GXPRINTF 4=GSKEY_LOG4>b#SKEY_LOG4=@SKEY_LOG4G DECC$GXPRINTF4b# DECC$GXPRINTF4@ DECC$GXPRINTF4?GDB_CLOSE4@b#DB_CLOSE4?@DB_CLOSE4G$ DECC$FREE4 b# DECC$FREE4 @$ DECC$FREE4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT41G CLI_GETVALUE42b# CLI_GETVALUE41@ CLI_GETVALUE4=G(SKEY_LOG4>b#SKEY_LOG4=$@(SKEY_LOG4/<GP CLI_PRESENT40@b# CLI_PRESENT4/L@P CLI_PRESENT4/PGh CLI_PRESENT40Xb# CLI_PRESENT4/d@h CLI_PRESENT4/hG CLI_PRESENT40pb# CLI_PRESENT4/|@ CLI_PRESENT4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT,AGDB_OPEN,Bb#DB_OPEN,A@DB_OPEN4C$G@DB_FETCH4D(b#DB_FETCH4C<@@DB_FETCH4@GX DECC$FREE4 Hb# DECC$FREE4T@X DECC$FREE,KGDB_PUT,Lb#DB_PUT,K@DB_PUT4?GDB_CLOSE4@b#DB_CLOSE4?@DB_CLOSE4G DECC$FREE4 b# DECC$FREE4@ DECC$FREE4/G CLI_PRESENT40b# CLI_PRESENT4/@ CLI_PRESENT41G CLI_GETVALUE42b# CLI_GETVALUE41 @ CLI_GETVALUE4=HGhSKEY_LOG4>Pb#SKEY_LOG4=d@hSKEY_LOG,AGDB_OPEN,Bb#DB_OPEN,A@DB_OPEN4CGDB_FETCH4Db#DB_FETCH4C@DB_FETCH4?GDB_CLOSE4@b#DB_CLOSE4?@DB_CLOSE4(GD DECC$GXPRINTF48b# DECC$GXPRINTF4@@D DECC$GXPRINTF4HGd DECC$GXPRINTF 4Pb# DECC$GXPRINTF4`@d DECC$GXPRINTF4hG DECC$GXPRINTF4xb# DECC$GXPRINTF4@ DECC$GXPRINTF4G DECC$GXPRINTF4b# DECC$GXPRINTF4@ DECC$GXPRINTF4IG ALGORITHMNAME4Jb# ALGORITHMNAME4I@ ALGORITHMNAME4G DECC$GXPRINTF4b# DECC$GXPRINTF4@ DECC$GXPRINTF4G DECC$GXPRINTF4b# DECC$GXPRINTF4 @ DECC$GXPRINTF4 G4 DECC$GXPRINTF4 b# DECC$GXPRINTF40 @4 DECC$GXPRINTF4D Gd DECC$GXPRINTF4L b# DECC$GXPRINTF4` @d DECC$GXPRINTF4Gd Gx NEW_STRN4Hh b#NEW_STRN4Gt @x NEW_STRN4Ex G SYS$ASCTIM4F b# SYS$ASCTIM4E @ SYS$ASCTIM4 G DECC$GXPRINTF4 b# DECC$GXPRINTF4 @ DECC$GXPRINTF43 G DESTROY_STR44 b# DESTROY_STR43 @ DESTROY_STR4 G! DECC$FREE4 !b# DECC$FREE4 !@! DECC$FREE4?!G(!DB_CLOSE4@!b#DB_CLOSE4?$!@(!DB_CLOSE4H!G\! DECC$FREE4 P!b# DECC$FREE4X!@\! DECC$FREE4/!G! CLI_PRESENT40!b# CLI_PRESENT4/!@! CLI_PRESENT41!G" CLI_GETVALUE42!b# CLI_GETVALUE41!@" CLI_GETVALUE4+("G8"USERNAME4,0"b#USERNAME4+4"@8"USERNAME4-8"GL" DECC$STRCMP4-H"@L" DECC$STRCMP4+h"Gx"USERNAME4,p"b#USERNAME4+t"@x"USERNAME,5"G"NEW_STR,6"b#NEW_STR,5"@"NEW_STR47"G" SYS$GETUAI48"b# SYS$GETUAI47"@" SYS$GETUAI43#G# DESTROY_STR44#b# DESTROY_STR43#@# DESTROY_STR4'p#G#SETPRIVS4(#b#`SETPRIVS4'#@#SETPRIVS4%#G# LIB$SIGNAL4&#b#` LIB$SIGNAL4%#@# LIB$SIGNAL4 #G$ RESETPRIVS4 #b#0 RESETPRIVS4 $@$ RESETPRIVS4% $G $ LIB$SIGNAL4&$b#0 LIB$SIGNAL4%$@ $ LIB$SIGNAL 4\$Gp$ SKEY_VERSION4h$b# SKEY_VERSION4l$@p$ SKEY_VERSION4p$G$ DECC$GXPRINTF4x$b# DECC$GXPRINTF4$@$ DECC$GXPRINTF4$G$SKEY_CCVERSION4$b#SKEY_CCVERSION4$@$SKEY_CCVERSION4$G$ SKEY_CREATED4$b# SKEY_CREATED4$@$ SKEY_CREATED4$G$ DECC$GXPRINTF4$b# DECC$GXPRINTF4$@$ DECC$GXPRINTF4$G$SKEY_VMSVERSION4$b#SKEY_VMSVERSION4$@$SKEY_VMSVERSION4$G$ DECC$GXPRINTF4$b# DECC$GXPRINTF4$@$ DECC$GXPRINTF4H%G`% TRNLNM_EXEC4T%b# TRNLNM_EXEC4\%@`% TRNLNM_EXEC,#p%G%TRNLNM,$x%b#TRNLNM,#%@%TRNLNM4!%G% DECC$ATOI4"%b# DECC$ATOI4!%@% DECC$ATOI4%G% DECC$FREE4 %b# DECC$FREE4%@% DECC$FREE4,&GH& TRNLNM_EXEC48&b#` TRNLNM_EXEC4D&@H& TRNLNM_EXEC4;L&Gh& OPEN_LOGFILE4<T&b#` OPEN_LOGFILE4;d&@h& OPEN_LOGFILE4h&G|& DECC$FREE4 p&b#` DECC$FREE4x&@|& DECC$FREE4;&G& OPEN_LOGFILE4<&b#` OPEN_LOGFILE4;&@& OPEN_LOGFILE4&G& TRNLNM_EXEC4&b#` TRNLNM_EXEC4&@& TRNLNM_EXEC4!&G& DECC$ATOI4"&b#` DECC$ATOI4!&@& DECC$ATOI49&G& SET_LOGLEV4:&b#` SET_LOGLEV49&@& SET_LOGLEV4&G& DECC$FREE4 &b#` DECC$FREE4&@& DECC$FREE,#'G'TRNLNM,$'b#`TRNLNM,#'@'TRNLNM4;$'G<' OPEN_LOGFILE4<('b#` OPEN_LOGFILE4;8'@<' OPEN_LOGFILE4<'GP' DECC$FREE4 @'b#` DECC$FREE4L'@P' DECC$FREE4;X'Gp' OPEN_LOGFILE4<`'b#` OPEN_LOGFILE4;l'@p' OPEN_LOGFILE,#p'G'TRNLNM,$x'b#`TRNLNM,#'@'TRNLNM4!'G' DECC$ATOI4"'b#` DECC$ATOI4!'@' DECC$ATOI49'G' SET_LOGLEV4:'b#` SET_LOGLEV49'@' SET_LOGLEV4'G' DECC$FREE 4 'b#` DECC$FREE4'@' DECC$FREE49'G' SET_LOGLEV4:'b#` SET_LOGLEV49'@' SET_LOGLEV4='G (SKEY_LOG4>'b#`SKEY_LOG4=(@ (SKEY_LOGS S=8.Compiled with %s, %s skey_calc run at !%D0= sys$manager:skey.logH=0"Last modified : %s p=0"Allow Normal auth override : %s =0"Allow S/Key auth override : %s =0"Use S/Key by default : %s =0"Algorithm : %s =0"Seed : %s 8=0"Sequence number : %d `=0"Principal : %s = S/Key database entry = do_show for user !AZ=h\do_enable for user !AZDictionary coverage incomplete: %d indices have no word contents. =Dictionary coverage complete: dictionary okay to use. Dictionary file contained %d useable words, %d unuseable words, %d duplicate words =0"do_test, checking dictionary !AZ= do_test for user !AZ=0&Clearing S/Key record for user "!AZ"=8/S/Key initialized for %s, next challenge is: @=PDinitialize S/Key record for user "!AZ"init user record in DB=!AZ=0'Creating new S/Key database file: !AZ=(password present in CLI=seq = !SL, seed="!AZ" =0";=@ PRIVSNOTPRIVSAND IMAGEPRIVS PROCPRIVS RESETPRIVS CLI_INIT CLI_DISPATCH7SKEY_CLD= SKEY_CALC=08";=P 7DECC$$SHELL_HANDLER= DECC$EXIT DECC$MAIN=0"8$;=0  DECC$GXPRINTFSKEY_CCVERSION= This is %s P SKEY_VERSION SKEY_VMSVERSION; SKEY_CREATED= on VMS %s =0" %;=(0 SKEY_TIMEOUT TRNLNM_EXEC= LNM$SYSTEM=LNM$FILE_DEV DECC$FREE! DECC$ATOI#TRNLNM=0 #;=0 % LIB$SIGNAL=0 H#;=0 'SETPRIVS=0";=0 ) AUTHPRIVS=00"!;=`< +USERNAME- DECC$STRCMP/ CLI_PRESENT1 CLI_GETVALUE7 SKEY$_NOSECUR7 SKEY$_NOUAF3 DESTROY_STR5NEW_STR7 SYS$GETUAI=0 &;=0 9 SET_LOGLEV; OPEN_LOGFILE=SKEY_LOG_FILE=(SKEY_LOG_LEVELskey.log=SKEY_LOG=0(";= `< True=False?DB_CLOSE= DATABASE0=P1@ADB_OPENCDB_FETCHE SYS$ASCTIMGNEW_STRNI ALGORITHMNAME=0 "X;=( ENABLE.NORMAL= ENABLE.SKEY=0!ENABLE.DEFAULTDISABLE.DEFAULTKDB_PUT=(DISABLE.NORMALDISABLE.SKEY0MANYTOKEY8OTS$ZEROPQREAD_PWD7DECC$GA_STDERR=test failurex7 SKEY$_NOAUTHS DECC$STRNCMP= Access granted 7SKEY$_PARTDICT=w= SKEY_DICTUNEW_DICTIONARYW DECC$FCLOSEY DECC$FOPEN= OUTPUTDICTIONARY=0h";= @[DECC$GXFPRINTF=%s `(]CMA$TIS_VMSERRNO_GET_ADDR=%s _ CHALLENGE= SKEY.DICT aREAD_DICTIONARY= MULTIPLE=test successcHASHKEY=Access denied 7 SKEY$_OKAUTH7 SKEY$_TIMEOUT= Password: e DECC$STRLEN= (=0 "p;=P< Pg DB_DELETE=LOGh=0";=0 =0";=0 7 SKEY$_VOIDPWD7SKEY$_SHORTPWD7 SKEY$_LONGPWD= ALGORITHM=ALGORITHM.MD4i CLI_UNQUOTEk SEEDGENERATEm DB_CREATE7 SKEY$_NOPARAM=   =SEED(=08"` ;=(p| PASSWORDX= SEQUENCEpoLC=NEWqDB_NEW7 SKEY$_UNALGORsKEYPROCu DECC$STRNCPY=ALGORITHM.MD5=,wKEYTOHEX=dlt yKEYTOALT= HEXADECIMAL0 7 SKEY$_OUTERR= DELETELNM$PROCESSP =fop=X =P2` = rfm=stmlfp =QUEUEx = SKEY.LIS =0`"p;=  { DECC$STRCAT= rat=cr%d %s : %s  =COUNT }CRELNM= do_keygen =PRINT = SYS$PRINT  DECC$PERROR KEYTOENGLISH= file openP  DECC$STRCPY= spl B)*[LANE.WORK.SKEY.INSTALL_A]SKEY_CALC.OBJ;2+,8 .$/ 4$ - e*0123KPWO56lƆ789GHJ6 SKEY_CALCV1.0 4-FEB-1998 07:16DEC C V5.5-002Pskey_calc run at !%DPLNM$FILE_DEV|PSKEY_LOG_LEVELsPskey.logfPLNM$FILE_DEVXPSKEY_LOG_FILEMPLNM$SYSTEM>PSKEY_LOG_LEVEL)Psys$manager:skey.logPLNM$SYSTEMPSKEY_LOG_FILEPLNM$FILE_DEVPSKEY_TIMEOUTPLNM$SYSTEMPSKEY_TIMEOUTPon VMS %s PCompiled with %s, %s PThis is %s PLast modified : %s PFalsePTrue`PAllow Normal auth override : %s ZPFalseUPTrue4PAllow S/Key auth override : %s .PFalse)PTruePUse S/Key by default : %s PAlgorithm : %s PSeed : %s PSequence number : %d PPrincipal : %s nPS/Key database entry YPdo_show for user !AZVPP1MPDATABASEDPDATABASE5PDISABLE.NORMAL(PDISABLE.SKEYPDISABLE.DEFAULTPENABLE.NORMALPENABLE.SKEYPENABLE.DEFAULTPdo_enable for user !AZPP1PDATABASEPDATABASEPAccess denied Ptest failurePAccess granted Ptest successP uPPassword: pP%s lP%s hP%s fPw\PMULTIPLEUPOUTPUTNPOUTPUT PDictionary coverage incomplete: %d indices have no word contents. PDictionary coverage complete: dictionary okay to use. PDictionary file contained %d useable words, %d unuseable words, %d duplicate words ^Pdo_test, checking dictionary !AZTPSKEY.DICTJPSKEY_DICT>PDICTIONARY3PDICTIONARYPdo_test for user !AZPP1PDATABASE PDATABASEPClearing S/Key record for user "!AZ"PLOGPP1PDATABASEPDATABASEP%s PS/Key initialized for %s, next challenge is: P PPassword: ~PPASSWORD|P pPPassword: kP%s bPPASSWORDTPALGORITHM.MD4FPALGORITHM.MD5<PALGORITHM7PSEED2PSEED)PSEQUENCE PSEQUENCEPLOGPinitialize S/Key record for user "!AZ"P PP1Pinit user record in DB=!AZPDATABASEPDATABASEPCreating new S/Key database file: !AZPDATABASEPNEWP%d %s : %s tP%d %s : %s hPSKEY.DICT^PSKEY_DICTSPDICTIONARYHPDICTIONARY<PHEXADECIMAL.PALGORITHM.MD4 PALGORITHM.MD5PALGORITHM Pfile openPrat=crPrfm=stmlfPwPrat=crPrfm=stmlfPwPsplP,PdltPfop=PSKEY.LISPSKEY.LISPOUTPUTPLNM$PROCESSPSYS$PRINTSKEY_CLD SKEY$_VOIDPWD SKEY$_NOPARAM SKEY$_NOSECUR SKEY$_UNALGOR SKEY$_TIMEOUT SKEY$_OUTERRSKEY$_PARTDICT SKEY$_NOAUTHSKEY$_SHORTPWD SKEY$_LONGPWD SKEY$_NOUAF SKEY$_OKAUTHDECC$GA_STDERR DECC$EXIT SKEY_VERSION SKEY_CREATEDSKEY_VMSVERSIONSKEY_CCVERSION CLI_UNQUOTE CLI_GETVALUE CLI_PRESENT# CLI_DISPATCHCLI_INIT SET_LOGLEVSKEY_LOG OPEN_LOGFILE DB_DELETEDB_CLOSEDB_NEWDB_PUTDB_FETCHDB_OPEN DB_CREATE CHALLENGE ALGORITHMNAMEKEYTOALTREAD_DICTIONARYNEW_DICTIONARYANYTOKEYKEYTOHEX KEYTOENGLISH SEEDGENERATEHASHKEYKEYPROCCRELNM TRNLNM_EXECTRNLNM DESTROY_STRNEW_STRNNEW_STRREAD_PWDPRIVSNOTPRIVSAND RESETPRIVSSETPRIVS IMAGEPRIVS PROCPRIVS AUTHPRIVSUSERNAMELC LIB$SIGNALPQUEUEPQUEUEPOUTPUTPPRINT~PDELETE|P qPPassword: hPPASSWORDPPpassword present in CLIBPPASSWORDc)$xp.OLB;2 1v Qvg:@roƭ' <褊uo53IҶyrzPh :D,) BGJv)WsNޱOYIDř4j"1mˏ 3 Q(j3f*_]w b/ oZ2 :qk̞ƚzl=BDzE7gS~m+a9ᭈ ]\-A D- fUZR4<h$ױ 4u t>X,֊9xrRb2ͫA:_Jn̼ܾMfzďoԞgڃp|"{$K+H~t|L35?w516.Ƀ扠kTy<&xoDt/6[]HLLH8=Cn]$D0JkN\^bE8b/>xr?*5,4K< I/Z/GhHy} G Lv (b\ӱ23` Hy-IbxuV+p֢Z)E<ү:k;$=Ntg]ʢySMx듉^Y8Fuv1WѥնE#A$XsVQv"R-GT~"J3}-җdAyVxխBqmMryw"} heAKcTJlv JV+$?H]oI6إ"]wn݉*Vԓ kKkkIT_<Em`DilDsyklXx/kHV(qZP/ ?k*=!ޚ.=R'`n(lpf37Ė|? {pFTNjZV`$qCnJi`g9d`ڊXh) 1[d!;/ |1Ip u3/ DU[V,Ż(_ЊL#LY4wi{}ueپO,^M~Y$C#IK@+ñt_dRxz 8\./{SL= WEu8(CE~Yai'lzsg#T\@p] ͡! Xܘ3yߝK=WБP}%TFAVȿQs9}.32|U, Ii4C[Q^k31lȁ/KhSZdw1Ld6'f.ʣ)ά/oa55#pk3cbA4]];v7'n1#d,mYDūY y7L*C.YΪ7S<Xc{p&|:b1C@q_ {Pջ%.NՊ4 /e\a~(l8%< '};ڲ[;$D}B˟`~v)DNEA aΈ=OT( w #P ҫԺ-Q6`:󴼓_@j&^Z]@s_jŪcSVb1,V;Ӻ>`t԰\Yww8S-ݢ> 9aʣ_KQH=Wcg56wPi8\[x*0܁of#h= ]3{G>a ya6bXa~mBH~B{Av -T'B(Emܠѡf a^@&>&T?4>S c"ɗf[)^v'H(ߟQ4`^5ꇯ];7uW4Cm s7c M511FN(о9ޝ#Az\.@cMhWƝ!Ϛ-J^[zJE]+FwZTE5@I gYw n"XSj3*}om9Ցk~5JZ'[5-gT1 -s/X"wmr@\U$ck NR&LVMM̋HuJoT&oEĩ"Prn * g%R>?[jVa}']hr 5ξA SR&!\ЗL,pbK GBsEd<‡W3p$Quy n|ق:k:>$C!lzMK6Frm YrsN"IB`nPC8i2׆aNA;>RVjUH@><|"(65f =8N`زemA;5]ěWÎESGa|!U:"T =9qiLQ}_b|O{3.1ɏPF`8iSҫ*zS[L9(ΦO1X|+oPi|@2H\dOpS•S ī5h:b|E#MZ$[dz K9L%j/$#ә+vl6;}wLDÓd /#q2$sŬ=/(TC)z7+扛F5_dwC&ʐhJ#&ŕVQTF¹Xʆ@xJJ!4L$!Ģ{(Ca## OњzР߾}4:oy߂(X.W9u~Cq(i>զϸNBv-91ǡ23qnYQ#$f{'(QO0h{D~+;15٤GЁŝE$niK04 jw_YL5d4~Wz`8pNDPFy)}&GVRae[L1f~3\?!@`R,/{:R)Mc ^T[[2Ce#c4T S@cRa9|='jU $`7kI&izL3~E^aoI"5dUz8/x 0Q߂@w\w Sd\/AKkaIc?pg^>,mλ-vfʫ^Cu2`稹@`-X:Y/Q*jnv}GF!ljKKyuu[(Ԉ -YA+Ľ= Sfw<,Es0 @Bw"k:@C89pq"1&>"7n|I<'/;-c1.$Usq|z\ox'&q)tPlm Q13RK&z 2MBaruU^dr*p OIt-M9v @«Bn#Z2_s0{%W:_=(dP]δ3SU†z0_ɿ#՗ TdDs2 /Jc([j;xc'Vu/k#Oe|ˆ\*/D'U 1<б4Dg{Q:Ѥ> X)=v/ k$.MKRe)^jX24#L|o2h՘] <f"jAeMB((,x>9.Q㼨hTC(FrWAAI@ą-Ʊj^ת 0 Ui6`#+ png?͐>CA) Z5}R}-Qq掭jcjKlW&?!(з͵'[zݖFN,Iݟ3;hɅ,O|)QQ~JT:7JٝiB:/Cab&e@81 ]{ei XH{,۳TcZ+.5 5S\Smߨc~]2ZGuq-BP,Y.C10iNeK)anvŞ Q9mۄy%D'6ALXF'q(G`g;Դ]Q먣=t6y(t9c!p{VDޣQנEŋ3>0lD66Kj MU(oᔂ-mh8G9FBv#ްVJʿ< -lx&a,ɽKr { xbOwO ͬ.򑹽'm[A" AM:aDaw%յK|F6@ޭ8A5WΘk'IkIP[őu':W=_YYw5e-w|!`,t8HZFYZN Wb9 ʪf0՗K:ԝk4|rbGNc @\Km1m_9?[D$ 6c׾IQ(8Ox*=\Q{QYa{n#3ZkO>T$3Ǒ %pvthd߹?R̵ͬyUi5rZHHǼ̔d&UCT ܑ#:-Y_/U$G8}`έ:`Np0nɃX ?&y9tA)Hv b]ss]QkNOu4D;AnvCU¸Vut&:$V^-?}OQ1\.Z:n{ !V#0YIO"%k% tHd }ޓoR"\ \u`ۯ3 f*𿘧bQ)u3Z~X&Mvu+vVHOBqJF$$u6Pb 8ah[ZIy %ӃC>ՅXr56Ob5FLHtOA{?|[ѩՏrڸSSt+,@Et=P@.PYa#+ Px"h1)Ft$TqI2G[H)(- ';W9H7J3 H,bhNtքNMn8=W% VQΓ{&F:^1n,rN{= V6'N>BW &gaE>Q8_p<vMJwLth1H5:Jϵ'[;i;~K C2wG&SRy*1>w yB2آZ֭J+dC _j6FӇ&B jT) ,ꋶ  |٧m/-Y=ΠؼmY(jH)}ݖV.Px:,WƿcS@c0N+ c=0FC+LZjue88ցfM&vQTLs_=@Hm6>r2Ua5?Sx'~' #шx-Q{kmm(|7dU]gsĖ{f-fInS"[)ύ^ Ї93MwSh#rkR; M ?S%0 r?(D^6"WwWS@͌x܃5b+5pVLe l@(^beʷխ3z>?zIBT!sӿlmfG5^6xPڷHc[C(AMzRēw(FA\/@gW+i?ܻHQr#CsP,npfqP-qݟ%TL%!qƆJ^ ef{0Q#oɖGuBzKTNqm4HDhQ{QfYSJzʢ6D9oGCjTm Unzɼaf'j|O4;DƖN-HA%#;~ʔ7,2L3%sqVs|+$^Yc0^z.> e{q!םO{0Ibo?-zVA.Z؈#ipb)OT$Z@`,cHc>_T ?9^G&dkM*i_ zIL<#SJ3dz_Km't7[> 7~Α!1-C`nB M+ >}'!-٦m2&Stg:S/yb7$bOhV. r>n~ef0f8 !6͗N7Q壯C8_SLC|l1#Z7|P #3uΥ!2:?wu@ݪTAfiU2P>r *Bkյi -}$HR8ʥ<G J\R;[S|H lS_Wy-W3권?KvK 0Eh]=|# z#nu}_e6ޠ0Ͼ,LT6L VXS\ՈN`٫eQ>ˤ`g&H:W4:dWuY'hlR qYxqu K!mLDZ 6x)S0hl) );Q)c&x NS>SNTIyRJi>焧|`pԋ7>_: h>O2dp*%);0_?2?#I.&ؑW%ac\LYZup.ty1ҭ EOB<kd 0o@_,#{hqr"@PRММ_jYgq*_-bϏh5eWF! 7X{6g&\Xl=M@^+sSmbk r,AQ>rR?Pi}y&8lw:SYYhma,qFn>#i2hC~Gp!#Am 8^'?}LA/S q <)ݴOwI:A7ǥV6+N[U\xtC%3`L:~bAkR6^:t(#YyS@)Y{2'wz}4ِ 3'N87n\RqNmb <7 AMG@0mm`OC ܑѿJ%{}2lr{? TmFF!5V0'meXw1 ^,SБ`;sgex:WgubK;yijbj@kl }޼׍\^Da@r$!Bw48a9{]RjTjEB67U GVZUY8eddGLjJ/ٙ(zA+(5W@2IwP]npcAI~ʢ1{S)IWKՌcV^m5J?kKr]3ja}3 eEuwq]~xpӂ/ !os0 3yiQ<:vWl4^pX Yx$s(/,fRZh R!ea-Ҫes+)._czNYEg>z_wdeX:VLVc}`=O '[x.#p.OdbsvF(l"h H'ЪL\Bu3b=ÛY2zWceuy׼XV|L; v $\?4?~W"dES[Hܧw93պ7ē1$8[:*5fw@j|bҞkPW{{)VH#luiGL4ڙICL÷MYj;}P(Q˲J{'B,⿜E҇7hLp!ߒOʡ_/#1j-4hUk+3lY$ RCorp?;Vx Acm*™瘆<`H&ɺ|J%9FOU)o0\:+p- cx<ExE٤6y{.3Xz0`VX:ۂgokP/ \GDJ`0Jh47/q~imJxX>^{ ot^dj$_]̛]WaXcII:h( Ʒ+ %\? 4UL $q`(&+&izZY"?&߸ +Xa?Ht+O m#2M5Gm?S$wͩŜR"Ht=%Vu>Ŷ\S&Kd=KbN"\mlTR`hEvA>^ Ǿ@e2FB1\BZrL ƾ&;3IHyYiQTt\; 1)iRf+p=U*6vp4\&Q%`3͸\T:I;Q?[(H-,N$(3z Wg =On*|ӵ`Çu"e ްe#Bg>yv붂-wFo Wt  N"tM+%v_9JfÉb(ķxGϨ6od.d2[@L{.E}ggH=v{%"R~uBs40=0]%A+YYJI_0C@m~ |v\y>NɷD:/f[+HfY)_vDŽ5xi s7kmAT{cNJtnqYag0%3>3EF^vݮ9gO|_)5B9KǏ)6uD0u dl]r_3R}BPu*E<ޯWdCr 67.&2pV\{eڠZ߭V0`ghgl_jC!l+&U ,:ݓ(/t)yM[ve֕R'JZ`D,.i4j( kte؆E`Qҕ\mN{Qȧ45E-&ND5USYmPP&b7UX&sgH0#` JcU k.2¼x*8V 70]55a Dx Tp748JCgBYX} `յ DԠ; E~u5Fupˢt-ʐ}4J|XK/DQ&^}<*'ʔkL_|p7Ϫ?j<@pJG4"Fh?b}9K>$SO"%:<6VF5ȕؕq$^ >]Sm"Z@BnBz>|"h=YHPqC|wH&_䬱Mb ouG v\*"l˿Ѹ*?M~ gzm 7s%\6 J)yx)4=Ri_*@Rf,>}Pz捥 70n("$c;a0 %Nu{rg?|g3_6p2G] Ȋ7r% jh\gUIUDEZ[h܏{8O[w 34c:&{skd!khsqd9}{ 2SDMbH2 ̝:Ƴ$^aa…+ܻA)/}z-8:sEdhÎoYwyc5B;,Ka*i fA5:w[)h6jk dΠ\B71 ̃I! ɂHxy=~h8 &g>rU,S]ZԐ4idVqu & \Tgs$3X@MOcg?h!I: vn 7VEB%G5H` ̬҂TߵJM#2b[s_KS(> -,ٻ#,|\AWlmh|SݏC%M/ [y W^ZuLᲫCJCbs8hCHԂ, aEP c/ ]W%k!;Aݕ9~4rk<5$+/ub<1+v5qO ޕδkZtbX_"]CKa ^Xc`)Tm(x 2ctigbjߍ?)ZrC-_0qh!>FK DLdW(?]id ><ð2&cobJ,yRSY֢VD{S4ccZg/vG%vKW,c]p*,zԢGoƽ (zs+^Vwҍ`<`Xc\BM,~L`XC ?[b6pǾ#9+@4Iˠ^gAhi୫U'Bpm0jKjDylqIrNS ۻ;*@p@9.Q_eB3%TNZ> 3M,[m=DoԧGA\ZQ{{m6@n3_v2}U'$S`Ws%:9yRSl-^So Rcc?oFEf4v]gOui ~"mt_D0ܳI3e+ C&0v#dޞmU# NEPb8Y>JX@c9w|hL&, IYJWU,}%ӏt@X\PYz_F~r*ajOnEG UTuT$6 [>*Y&*AIn}.J;sȎ}# 8Lqvw?SKӹ_]|.UzDECHbǖ RE P_FMm]0#z }Ef{_gvM8Cz*C'O&OLV{45Ϣ 1a~GD7!\:.?Cjrf2W doXdd|aCJcq&09;bN$CuK,Fqqd@`B&BlwD]LdLG ~ mtpD.(A*xwq;ivoVBVgB6Us"$-caf'A(Y?t: 큙\(36[.+ulu~qzRk]9+c>  KnDڹF68}g.wFvą{D2(M0Qti K-v`Xmm{2: Y9TehXqF;)Z6\ƴ^B(PNU2"gN,XdRTwaa=p*s3~& Rbr<L:D #\[(lZ }05T'k8km+(DIJ]lq'p$# ((мL!]|sur[Џk "о9g(XGH_6}x0Y"}Xr8=?Q?{O$#QM}x~pA8=5:2@,^(JE`BlRs#2•yHB_,Y$z=AKG#"oiʓ3o3`®VMwcQjsEG{Ζc@lo,Hr oXZ"A6hWx/e~xZTFo 8ȚP4@F'^e Z%)^QD0`N'+f#!$( a?qmpSy޳Il" n 3wTJWgMT $m:I1>4tɊOք)!V'-RpAI)k4:Qp,B3&v-8vm$m[ )Ú7%!HOۚ}]4G]hޟ/7f@^Olߞ顓4-0SU겞8_Ev@8'ŽMԬvjeqzrVu} F G-uvZv򳛅evH q.:#3 L?!)c&b8F0 Ӄw{S|h-cy,/,̚џ&eQ|ZZNQ"FK<;]CYN"tHF9!nM ).`SL 8zs?cc5$^gn<ٝlM6@2I2%": vWMWS@$l`c^1`;fÿ:x—$)E~`w` PzvRak@2fQj, $ݺ%BSD$UA>TZyt Imc5r$#y:D i_X 0L%F!SD4adl˶gxr{>2Z;}+D,^D,3K..haT & @ܜ6]Q*?v2PŞeS%U^H5jUPv#?r<BIimLxկ[1W d{%WH[| &S]VSX&7ɁϠt6D3۶qÙ*G8:44 Oظ tED1D ''AF'1kЖ-| TRQ ^R#^Jnk2{ z$(F5jb[vށ7ո ݿ폤rS }o'1) Tkܜ>8U:)͸Li!2wr3DyvK2V1rx:}Z v?#P W]P`\nguD`10Nr>ZuìXBymױM>/̟?[SW}k 5pQ%dt-Vc },iSFo$sBl޽U &f.MFC'ZRb%bU$OdOs )ڗ o6]nٶɂ]+L>*k55SP5 ίo-"ޥz|_N^TdIsd>Ms90%DI X-b`a"oea6Q.Aܔgnf26$Jz9;zt ~/` /{,=iTQ9%|qAT=k8lĐt33 ķ9`=z ?#YL=GApIX13mZꢃ=is1}g*xԌ#h"W*'Opp͘taX4]#h3Q) tDRz@üy4!RD5< WىZ :ޞ=[~[6QGp{>ss'5emJ>Ec'Geg8>2M"/kGgB|lsHnPNB4 :?~` Qj`1RK,ezsAaEBQUg:LWL٩6&2mB&Bʻ;WՂO1#q+uaRP=UnBt_Sgޔ/A @D#a/_ \aumƅY;-vNJrzEZ i}nA)YyS%`On4)T/HTke_>&YqEzW*m\hoN.A VotCi,zf# a`ZFsfa׼)#]iwCUVu)c)1;@]hXP0YXl|&A+]H_n sxרq8mh 0ИagBDmD6ޖgnݧ߼3_|1 u{Y=6=m0D2()EUeb/iO_8 wɈڲ _7V?koD4SiY.K} tYG#qYo q|Ah".?2n*pmJQ\cl!_ڸma727<˿Еj-} anN"[:A~%ɓYj#o2_ݰ̱'(27 8X<i"1zέ  ˩|_U쁰ƴZkquRHr{x 2p*c7 *!О di̲A*U,͏(h'e`﵋WwHzaE?pw!rLZcYגB5HVdL雑8@4J*YhWiVY]iɉuOlNe .HM=Pն|-x': _/3I:zSr簫 um29wP8{/4 r>TPE]i=)HhqgX 銺k~t3^?A|b\+a IՠP'I@S)ptY5$\rm>*8" i5V>:clW[2nZ~XlآFu1+E+a>gMJ9{ O-z P?6L-}|43]mU0Ƈ+^ԦdͰr#quH ѐGXWwx%]07-#^mCXxshG Hu#3Sˮi#yPkj-9J==ѤAdN^g.P'U04N&)vi-ѯn*wz>,;Nx5pUz>*4mF-o4/)rs7mp$L]kI&79h{Jc-)\ ?jK+T)r-F2an('.3 VeY O@HWMdVg-o/R_NZPN=.@D3wiF_3'5I.1*za#1;u G*-r$?kd<\xoɔdz%2r[ڧ2bt{JWCJreV݁de ~ P_7 'Ԯ$gx$}+O0w..Feχ܋_nP<%]v%;zR.1|dZQ)jHJ| ?yE-[2'KB9e ܗپAxVjo9p*>6ȇjr9QҷA͜HFYw0d$,6~TU^BƆM,w# G UϰZeiY /P-NƼ$(BZI*X+L t|B LIoc(UNId͈&{AygmlLR`K *8ƶrH.:"*B =OuJP k ߢ<L~s7AJRz_IѱԿӊD0 H8^Whr8 Ƣt",{aͣj* ?*:F%\P]s5'#8b-f:]iFKm~&Yn/]2i=]J}r,ӵ Unc*ㆬwkVu-X7 o ?p!?( ZK]]153w-I@t\{T?d&ГjcSz. ϝP:Ɲ VmD'0ncx.Ϥ@CKN{TdX8<&98$o!9 (,4 Mps6q︿vӳiQ0t4]b9_}[Q6(\4>`ei\nB1aoMʿ,pC^K#Lsx("}aaR =PX_m0RcHQSP?x<( 0J]}l6Аr.i,07w|\unKPCӒ; pGP`S|_խgM{E)=QMKy~j;zhqR? >95nlY)/6 ~ Rsf!)z ׄMz9A; n"Y`hg=a X8*hޘڊA*gzn^Pɲ EXQDu 3)xuxJ鮎lz]R$0gMY j"ڣ/ O/ [c(0@X54~4O#?`pyL=C`:/bJ (a!7zp6Y]V6BeJ-9N}U%iA׻K'# zhq|-o@߂C§ y$S~ 4 v*65 /gS]qCc4ȺsKJPH-B'Y&ҩik!@}LNHۘ >(z_\ s"+tӲ8HϻqHYif *yDimL^3TvW>gv!0xP@(т,m6ÕJl7'=I13i&*hF!*9ahMfu|)בdc=oeF% , *=0a۷ O?3m7{k~oTX4-/! *$.cܐ\:}P ;}5 Ⲱ{jt/Is~ώ!:x\VQⱡf#NRҀ!:J+eD0 XfIw3k'o.$\* kK?!DARp ;J8>kյ6!$8T0(^sdQb?6DJ$چ;ӄm9'07 @@?5HcR߻G$LTJJBm`X#towvYDVzo gȕp%vSPнIm͗4-spx/Y? %,"w$.iP:0!0,{kDD6c˓=݈P)V7D/$E9j:`瀿Y1)\ΈD@mЏG fwu{!*NәEVqajnQAF\L{Z2\IcV}Үv +Z^}Gg"T!S|~W8Kԗ 3ƌc8 2^DޚYdf[ko^yoۥeo3vdRSZEc8[Y#vGE _0@̐)M`g|Y傥IcЪ8KX .wݣO C ul)]pc}d0S&HQ`-J=8X^A֊+GP.++"jyNJ4?RLҽc(Lc?-2$mcq3NHb }I:;-pgM{/[ xM))?yigŽǹ|KoF]wpV2]V9")cEb~-07pKlhg.6fo%68I?ՠ1~2U;,m_Jch7W'\Pmۇ 769^$fsBsXcHA{[ ɕ"rUbՙ(o2 =1đcs%U Vm^|jr*EIN9r@<-u"V}W*9<'2j2J.2 Ɔ抯_P6;7 Gw:8b7Lė&3jjBF(oy1d)F7LP}_8~]2y>i11h*Fyɛxx]{3)0߶4 ތpKYΉG@ GE oʲgGa~3ێO]4m;HQ,OK`H~wO4(37 $#uyXqlo&u:ԑ\ =Hl{˲l!0qyH)z[ƣ׍s8x܄W ]#Aۧnvۙ}gI7&ٛE%Z&Nbˮ/*!ݷ{6,1T nMAIB XZ&y:\L0 ЌD<#, %xΎ+}G0Mҹ՘+8zXHƴo@ϑ=*^*q^w JRJLNcin4AUKs5Z*]>M} b@rL̿/qD .|&p?DζՌ%(P[cyG^ ^Ӿ%,=E~'$ vjScQ2R؄o *Ԡ ^x26TC(I|s8E?3+kdNiX+pgD3ݺf$x7lk;/nciPd`eJaU}ʰȑ]ƢUfޠCu6#\_ Sd*Ow*1a mJSpPr{͞@-[Ujȕq3 I{cS`A@$D=[|R>K]T3K-V0@T6m` p_.]abRdjv"1cXh*@?ݪ;l M"ϐNt0#0 p<5'x1td-?BBZ =[؜2KfG4fC]+E]J"SviZX)b!rcahDIV{zRo*=eZ.#6ĩJ4~$4-&lfo% >C}`NZQRSh_Un#lE5 +b_ <TF)y=q2O#A(.Ʌ`^p0bN*w+d %-.[ƍxC&K_ zVgmqnifŲK1iYvJi  <~= Yf_{(sAbKaLttһP^9'%3 QH1C(^3*Ɵ*s\(sqlWl-U% \lXikt}@SO*,.[| ~AT{z$wRhDO=Om M˖Jo.aWASࠇQTqW)0BD~f8|)4zl9g,ISd7|*R3 sl7G _#S.-SK:qG7*\H4fx n:GF`?-T( g4ZJa,QZ4EH8+~w;z 㰒yWdKw|bޝC(fvnWdJME|aLr.sbCrBRR-vM[L`/.p*̨I). 1=6{K-4A=S8n˂{7BMb-'B4f=nMKoUEC_.'dQag-@ E0]H8P)6V{fZ }oFy i{M g[)yG zY^# NQqMɚkI'5hSo\SCM~fb*`8WTfD0$jV$uRYY 8[kq;}YFa5eAg3Hpk.=Nf2MwX9.(:nQ9F;.xuıAD%*`p*,>=ХFf?j洴mReAZ+m{D$sd@t*]J̵ϋ^G> i>D'HIdpkFޚ8DG`]|623#oU7 ب770vD8WG4)"VTK CېzDˤbGq&JodfcdYYrK7161/ht„pC̿7_Sq#8&5w K_ȵ@]18PIլ\Nת _(*g98X?7Qd G#$Ѡ[ RNHTGhIjl rHIp xI1oCSܐf!*wS#nj.b*"ȃNmk}C^mU엮ATyfRm_Y` l;ٟaM~y$HX/q]Qb3`cMX(鑍qht5%3諙X Lӻ4?v;^tX-.E&Pst|Z4xV%YYݬh֚\[x[Qa`;*Y|h'E;zm^'M=nGM hג-CFGtkA2(=jK;"*ћjX?]#+`oE8a#Mx]ʊa e k%l5O&'{՘}E-*ttNi0qtCk /)&"bl VU ̮!rcobk5ڻӼ7 6~akrƄXi ( 9Op\b$ƛPr;b০⾑bQ12z3$f%6'o_n{x ogADW8ltIvÎɻң: oq7Uu>J9 ԻEi7a,}*$@t.fKd \v;n(dXJQ \ qQzҠ0wxDX&\{)ϟ7  >^hҔEԜ_k8b+әѷvcgBEWzߺ"PwrǛhBBBkZrƚNg]U *ww+5KsPkKT5B`3Bi7U9K`mi2n ;~vETKvإ ׽MN6V5Z%3sxRm.pנ{chB[PF CRoLk L.HǾDf;{HN!CV$sQKVK˜9/%BI$CkzoEUfTL{!˞59ے?b~Wjrk\5 >{Qݴ+/z~\`kF6@ht,M3 ]"my@+QyFrxBb aڶ,| HؕXJl6EBЫNghOEe89{LpvjEHu6tu uh{/&2{:ClhM\1䬧_*wHOwD@_7y\g(èEXE"_H=1%Ԝ$LAˮ n̜}9_~DS<ͩO  P-E8Grs߬%3 CZ8^f:;ݽ+4ztdѰLcC޴;8 fY}X`07pBrS; s>2,7紅(D >ex\W׿Z`pN0 p1HU x쁢|ռ\l ږh^:X@k`e(Q9;]7h鱥fk2kІ67 NY3J´`:1`WYd4GYwכ=V7VL@lYOF7ܦdl83'1DM?je)c'bp7Lh5w^0%ïZij^ԫuRf`dASw}Ң^Uw=>MBCu;[_np8d>:^[l,7涤p˸xxK1@-1vQ`qho@UmjF2_ c2Y'o,aIгp5p.QhS2д}+.*Mif{0ɩ\@y+Q@F9|3@غD%[jr֖0juz_*F~-D}kKAr`*.`5|66"\^VO}puݪ8[_V+KgC^2ptlB-L̽u Lh^p~xGG``+~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'|k~ SKEY009.A8  e*)[LANE.WORK.SKEY.INSTALL_A]SKEY_CALC.OBJ;2$ٰPP1ݭ LIB$SIGNAL1 ѭ߭ܟ CLI_GETVALUEP6P߭ܟREAD_PWDPP ЭU1PϾDECC$GA_STDERR\l DECC$DFPRINTFݭ CLI_UNQUOTEЭTЏ SKEY$_VOIDPWD\\ LIB$SIGNAL.PT DECC$STRLENPS\S  ЏSKEY$_SHORTPWD\PS?Џ SKEY$_LONGPWD\ݭܟDTݢ\KEYPROCPP ݭ LIB$SIGNALݭ DECC$STRLENPݭ DECC$MEMSETݭ DECC$FREE\@ݢ\THASHKEY\\@խ |SETPRIVSPSS S LIB$SIGNAL߭ݭDB_OPENPխ |럭 RESETPRIVSPSS S LIB$SIGNALЭUVPRݭDB_PUTPݭDB_CLOSEV2bp DECC$DPRINTFR CHALLENGEPS֢@Sτ DECC$DPRINTFS DECC$FREEЭUUP^ AUTHPRIVSRP DECC$FREER\\PP^ AUTHPRIVSRP DECC$FREER\\PP$^ԭ CLI_PRESENTʏPP߭  CLI_GETVALUEPP ݭ LIB$SIGNAL\խ\\Ϣ \խ\\߭ PTЭPPP SKEY$_NOUAF P LIB$SIGNALϻ CLI_PRESENTTϲSKEY_LOGխ |SETPRIVSPRR R LIB$SIGNAL߭ݭDB_OPENPխ |럭 RESETPRIVSPRR R LIB$SIGNAL\խ\\D3 TRNLNM_EXECPSG6TRNLNMPSSx\,S DECC$ATOIPR R x\PS DECC$FREER\\TݭDB_FETCHPRˏp\\Rݭ DB_DELETEPݭDB_CLOSET DECC$FREER<$S(pТpSt~R DECC$MEMSETR SYS$GETUAI SYS$ASCTIMCMA$TIS_VMSERRNO_GET_ADDR DECC$STRLEN DECC$STRNCMP DECC$STRCMP DECC$STRNCPY DECC$STRCPY DECC$STRCAT DECC$MEMSET DECC$MEMCPY DECC$FREE DECC$ATOI DECC$FOPEN DECC$DPRINTF DECC$PERROR DECC$DFPRINTF DECC$FCLOSE  __MAIN  MAIN P DO_KEYGEN D CHECKPASSWORD | DO_INITIALIZE X POWERUSER | SUPERUSER DO_CLEAR DECC$FREESSP^ԭWԭ̟{ CLI_PRESENTʏPP߭Пj CLI_GETVALUEPP ЭX1PRխRR RխRR߭ԟ95 PUU.SKEY_LOGЭSSS SKEY$_NOUAFSX1խ |㟭SETPRIVSPSS S LIB$SIGNAL߭ݭDB_OPENPխ |؈۟ RESETPRIVSPSS S LIB$SIGNALխ ݭ DECC$FREE1RխRRYH TRNLNM_EXECPSP[JTRNLNMPSSxT,S DECC$ATOIPR R xTPS DECC$FREERTTUݭDB_FETCHPWU DECC$FREE<$W1qЧp1e CLI_PRESENTʏPP1ݭDB_CLOSEԭ߭ȟ CLI_GETVALUEPխTRNLNMPխݭȟSKEY_LOGݧ\NEW_DICTIONARYPU߭߭߭߭ݭUREAD_DICTIONARYPPSSSKEY$_PARTDICT SSX1ݭݭݭϫ DECC$DPRINTFRbխ b PݭbP CLI_PRESENTʏPP1p߭ğ: CLI_GETVALUEPSSSX1P( CLI_PRESENTPTRTRRVݭH DECC$FOPENPSCMA$TIS_VMSERRNO_GET_ADDR`X1EPT DECC$DFPRINTFRPD\V\'PSbl\\ SbTTS DECC$FCLOSE1W CHALLENGEPRRϖ DECC$DPRINTFR DECC$FREERխRR TRNLNM_EXECPSTRNLNMPSSxT,S DECC$ATOIPR R xTPS DECC$FREERTT߭READ_PWDPѭԏ,Џ SKEY$_TIMEOUT1DECC$GA_STDERRRb DECC$DFPRINTFݧ\ݭANYTOKEYPݭP DECC$STRLENPݭ DECC$MEMSETݭ DECC$FREE1 DECC$MEMCPYݧ\HASHKEYT DECC$STRNCMPPGT DECC$MEMCPYWݭDB_PUTPPa[SKEY_LOG\ DECC$DPRINTFЏ SKEY$_OKAUTH#PTSKEY_LOGT DECC$DPRINTFЏ SKEY$_NOAUTH DECC$MEMSET DECC$MEMSETխ ݭDB_CLOSEWt~W DECC$MEMSETW DECC$FREEЭXXP$^ԭ\ԭܟ CLI_PRESENTʏPP߭C CLI_GETVALUEPPЭU1d\խ\\ψ\խ\\߭ϴPTTϩSKEY_LOGЭPPP SKEY$_NOUAFPU1Ϝ CLI_PRESENTRbʏP\P\\YϋbʏP\P\\Z}bʏP\P\\[wbʏP\P\\VmbʏP\P\\W`bʏP\P\\Xխ |SETPRIVSPRR R LIB$SIGNAL߭ݭDB_OPENPխ |럭 RESETPRIVSPRR R LIB$SIGNAL ЭU1 P\խ\\φu TRNLNM_EXECP\PχvTRNLNMP\\xS,\ DECC$ATOIPR R xSP\ DECC$FREERSSTݭDB_FETCHPRT DECC$FREE<$RIТp@Y`Z`[`V`W`X`RݭDB_PUTPխ ݭDB_CLOSERt~R DECC$MEMSETR DECC$FREEЭUUP|(^RԭTԭܟ CLI_PRESENTʏPP߭ CLI_GETVALUEPP ЭV1sP\խ\\\խ\\߭ϐQPUUυSKEY_LOGЭPPP SKEY$_NOUAFPV1"խ |SETPRIVSPRR R LIB$SIGNAL߭ݭDB_OPENPխ |럭 RESETPRIVSPRR R LIB$SIGNAL1\խ\\τs TRNLNM_EXECP\χvTRNLNMP\\xS,\ DECC$ATOIPR R xSP\ DECC$FREERSSUݭDB_FETCHPTݭDB_CLOSEԭ<$T1Фp1s DECC$DPRINTFScUycݤ@ϐcDϧcݤ\ ALGORITHMNAMEPϵc` RPRRϹc` RPRRc` RPRRc@~NEW_STRNPRhR? SYS$ASCTIMPˏP\\<\LݢcR DESTROY_STRU U DECC$FREEխ ݭDB_CLOSETt~T DECC$MEMSETT DECC$FREEЭVVPP<(^(ϊݬ CLI_PRESENTʏPP1߭ݬ CLI_GETVALUEʏPP^ЭRXbRSլ i AUTHPRIVSSP DECC$FREESOUSERNAMEPSSݭ DECC$STRCMPP5ЬRЏ SKEY$_NOSECURbSU1PPUSERNAMEPPUSERNAMEPլ ЬRbЭURݭNEW_STRPTޭح|~T|~ SYS$GETUAIPSSЏ SKEY$_NOUAFSЬRSbT DESTROY_STRЭUUPP^ SKEY_VERSIONP^ DECC$DPRINTFRbSKEY_CCVERSIONP\ SKEY_CREATEDP\GbSKEY_VMSVERSIONPNbRRP^լvπn TRNLNM_EXECPRR OPEN_LOGFILER DECC$FREE _ OPEN_LOGFILExe TRNLNM_EXECPRR DECC$ATOIP SET_LOGLEVR DECC$FREE1 SET_LOGLEVvR@TRNLNMPRR OPEN_LOGFILER DECC$FREEP1 |DO_TEST  DO_PROFILE `|DO_SHOW @  DO_VERSION DECC$MAIN!$CODE$DATA $ADDRESS_DATA~ OPEN_LOGFILE>+TRNLNMPRR DECC$ATOIP SET_LOGLEVR DECC$FREE P SET_LOGLEV SKEY_LOG3*[LANE.WORK.SKEY.INSTALL_A]SKEY_CLUSTER_UPDATE.COM;1+,(-*. / 4H L<- e*0123KPWO56O)7))89GHJH$!----------------------------------------------------------------------$!8$! update installation on nodes that share system disks$!$!$!?$ @sys$manager:skey_shutdown !!! shutdown if running$ install := install/comm$ f = f$trnlnm("DCLTABLES")2$ if f .eqs. "" then f = "SYS$SHARE:DCLTABLES.EXE" $ f = f - f$parse(f,,,"version")@$ install replace 'f' !!! get new command verb$!3$ read/prompt="Start S/Key [N]: " sys$command yesno%$ a = f$edit(yesno,"collapse,upcase")$ if a .nes. "Y" then exit$ @sys$startup:skey_startup$ exit(*[LANE.WORK.SKEY.INSTALL_A]SKEY_LGI.ABJ;2+,f./ 4- e*0123KPWO56]789GHJ0DDSKEY_LGIV1.0 5-FEB-1998 10:02DEC C V5.5-002  $ABS$i4 $CODE$1 $LITERAL$0$LINK$$DATA$$BSS$ $READONLY_ADDR$ $READONLY$((LGI$LOGINOUT_CALLOUTS DECC$STRCPY DECC$STRLEN DECC$ATOI DECC$FREE DECC$MALLOCDECC$GXSPRINTF SYS$GETSYIW SKEYCHALLENGE SKEYAUTHENTICATENEW_STR DESTROY_STR TRNLNM_EXEC OPEN_LOGFILESKEY_LOG SET_LOGLEV LGI$_SKIPRELATED8 LGI$LOGINOUT_CALLOUTS =< 4 #4G~^^~ GG G0[8{l"@Zkcl G]4G]} 0#kG`#4G~p^x^~GG8PGG.J@0JFF4GG@4G/KÐ"GBtC9#bCtG@Zk$CtG@B !"Hb @?F C@Zkl#G"BCa.A"tJ !JtFa>xJ3.C0.4A"W JVJF3>F0>@Zk4a.tH"SrJtF4a>lqDpD 8uJY0K5GWB 8}E/"4G{pK% TGsaJ[GE>SFE>'.p"$.C$" HV JwJUJFF'>$>`b#-@.% qHPJTGF>cGl[@ZklctGB, #,"CbHA #H4GDCG@ZkG2"."# ##.TG BJQ !J(bFCCpr.SrJpr>$@ZkbGBGbGc CtG@ZkCDÀ4GcG[@Zk 4G4GXDc[@ZkGp]x]}#kG.4GU JF0JF:$80J?G5G$8}#p"~4G^^~ (0޴8G`[Gh{GC@ZkCC, BJ@(bF@TG@ZkCB `bGGTG@Zk@BGHb4G@Zk GBTGb C@Zk bB4GbTGxc C@ZkV 4GTGX CM B0 (bJ@CTG@ZkC pB@G@Zk@BHbG4G@ZkG ¤@pB C@Zk BN@(bCTG@ZkCB bG4G@Zk@BHbGh4G@ZkGhGTGBbFD#-BQG@Zkà4GBbh4G@Zk GG0 ClŰtGBb@ZkG]]4G} (0ݤ8@#kG#TG~^^~GGQGP[GX{lMBG4G @Zk$4GBbh@Zkl84GP.PJ0@J@FDF@4GG@4G.JcG[@Zk C0Bp= CL@@ZklC@BG3.0, 7Kq7HP J@HFD3>0<C@Zk4.4w"uHTJF4>lqDpD 2aKY0K!GWB 2 % GE/{aK% 4GsaJ"TG[GF> '/C$E.$%" JX KyHRQJG'?YF$E>b#@.% qHTGPJF>Gcl[@Zkl#tGBB. !.R"bJQ !JFCC4GG@ZkGXG"A.""#!.tGbPJQ 0JBbGQFCB.CUJ>@ZkGBGbFdC3`BG@ZkG"CBGb@8@GG@ZkG(GB bCV@CtG@ZkpBCxb4G@ZkcCG[4G@ZkBbGG4G@Zk b4GBGbtGc C@ZkGG G]]}#kp.4GS pJrF0@J@F"$20K?G!G$2S#4G~^^G G[{l"@ZkBlG]4G] #k#&~?$0^! 8^G@G#@[CG "CC(GH{G=GG@Zk 0"G B4G(btG-@@ZkG=tG0 B (bB2v H4G@ZkG ]4G BtG(b@0"@ZkGG0]8]@P#k40GL SET_LOGLEV44b# SET_LOGLEV4H@L SET_LOGLEV4G$SKEY_LOG4b#SKEY_LOG4 @$SKEY_LOG48G`DECC$GXSPRINTF4Hb#DECC$GXSPRINTF4\@`DECC$GXSPRINTF4 lG DECC$STRLEN4 @ DECC$STRLEN4GSKEY_LOG4b#SKEY_LOG4@SKEY_LOG<G SKEYAUTHENTICATE<b#SKEYAUTHENTICATE<@ SKEYAUTHENTICATE 4(GHSKEY_LOG40b#SKEY_LOG4D@HSKEY_LOG48GP DECC$MALLOC4@b#p DECC$MALLOC4L@P DECC$MALLOC4`Gx TRNLNM_EXEC4hb#p TRNLNM_EXEC4t@x TRNLNM_EXEC4 |G OPEN_LOGFILE4 b#p OPEN_LOGFILE4 @ OPEN_LOGFILE4G DECC$FREE4b#p DECC$FREE4@ DECC$FREE4 G OPEN_LOGFILE4 b#p OPEN_LOGFILE4 @ OPEN_LOGFILE4GSKEY_LOG4b#pSKEY_LOG4@SKEY_LOG4G, TRNLNM_EXEC4b#p TRNLNM_EXEC4(@, TRNLNM_EXEC44GD DECC$STRCPY4@@D DECC$STRCPY4DGX DECC$FREE4Hb#p DECC$FREE4T@X DECC$FREE4hGx DECC$STRCPY4t@x DECC$STRCPY4xG TRNLNM_EXEC4b#p TRNLNM_EXEC4@ TRNLNM_EXEC4G DECC$ATOI4b#p DECC$ATOI4@ DECC$ATOI4G DECC$FREE4b#p DECC$FREE4@ DECC$FREE4 G OPEN_LOGFILE4 b#p OPEN_LOGFILE4 @ OPEN_LOGFILE4G$ SET_LOGLEV4b#p SET_LOGLEV4 @$ SET_LOGLEV4DGPSKEY_LOG4Hb#pSKEY_LOG4L@PSKEY_LOG4 G OPEN_LOGFILE4 b# OPEN_LOGFILE4 @ OPEN_LOGFILE4G SET_LOGLEV4b# SET_LOGLEV4@ SET_LOGLEV4hG| DECC$STRCPY4x@| DECC$STRCPY4 G DECC$STRLEN4 @ DECC$STRLEN4GSKEY_LOG4b#SKEY_LOG4@SKEY_LOG4 G@ SKEY_LOG4 b#SKEY_LOG4< @@ SKEY_LOG4H Gx SKEYCHALLENGE4P b# SKEYCHALLENGE4t @x SKEYCHALLENGE4 G SKEY_LOG4 b#SKEY_LOG4 @ SKEY_LOG4 G DECC$GXSPRINTF4 b#DECC$GXSPRINTF4 @ DECC$GXSPRINTF,  G NEW_STR, b#NEW_STR,  @ NEW_STR4 G DESTROY_STR4 b# DESTROY_STR 4 @ DESTROY_STR4( GD SKEY_LOG40 b#SKEY_LOG4@ @D SKEY_LOG4 G SET_LOGLEV4 {#@ SET_LOGLEV4 @ SET_LOGLEV4D G SYS$GETSYIW4x b#` SYS$GETSYIW4 @ SYS$GETSYIW4 G SKEY_LOG4 b#`SKEY_LOG4 @ SKEY_LOG4 G SKEY_LOG4 b#`SKEY_LOG4 @ SKEY_LOG4 G SKEY_LOG4 b#`SKEY_LOG4 @ SKEY_LOG =pdTimeout LGI_PWD_TMO value = !SL, using defaultTimeout sys$getsyiw iosb.status=!XL, using defaulth=8/Timeout sys$getsyiw status=!XL, using default=0!get username input status = !XL=@5challenge status: !XL, user: '!AZ', challenge='!AZ'= checking user '!AZ'=(username read status = !XL0=0$S/Key LGI processing started at !DX=(LGI context pointer is zerox=8+unable to allocate memory for LGI context= sys$manager:skey.log=(authentication status = !XL=(password input i/o status=!XL=  %s Password: =!authenticate user '!AS'4 4=0";=0 ;0 SET_LOGLEV=0" ;=  =00" ;=P SKEY_LOG; SYS$GETSYIW=0";=< 7LGI$_SKIPRELATED DECC$STRCPY DECC$STRLEN OPEN_LOGFILE= Username:   NEW_STR DESTROY_STRDECC$GXSPRINTF SKEYCHALLENGE= LOGIN %sp=0";=@|  TRNLNM_EXEC= LNM$SYSTEM DECC$FREE=SKEY_LOG_FILE DECC$MALLOC=SKEY_LOG_LEVEL DECC$ATOI=0p";=< SKEYAUTHENTICATE = p464446@466  (*[LANE.WORK.SKEY.INSTALL_A]SKEY_LGI.OBJ;2+,g. / 4  - e*0123KPWO568789GHJ5SKEY_LGIV1.0 4-FEB-1998 07:18DEC C V5.5-002qPTimeout LGI_PWD_TMO value = !SL, using default>PTimeout sys$getsyiw iosb.status=!XL, using defaultPTimeout sys$getsyiw status=!XL, using defaultPget username input status = !XLPLOGIN %sPchallenge status: !XL, user: '!AZ', challenge='!AZ'Pchecking user '!AZ'Pusername read status = !XLsP Username: PPS/Key LGI processing started at !DEPLNM$SYSTEM6PSKEY_LOG_LEVEL!Psys$manager:skey.logPLNM$SYSTEMPSKEY_LOG_FILEPLGI context pointer is zeroPunable to allocate memory for LGI contextPpointers not longword size, context dropped!}Psys$manager:skey.logrPLNM$SYSTEMdPSKEY_LOG_FILEHPauthentication status = !XL*Ppassword input i/o status=!XLP %s Password: Pauthenticate user '!AS'P P^ЬRbPl~ SET_LOGLEVbPlPP<Δ^ЬR28Q Q U1zP QU1mP@PU1_ݢtSKEY_LOGЬP1`Q1P1͔ DECC$DSPRINTFТlP@ТlP͔0͔ DECC$STRLENPQТlPQ4ТlP$ТlP ТlPТlPPQТlPQݢlbP`ТlPРSSSUSKEY_LOGSU1ЬPРlP<"TD޼P߰SKEYAUTHENTICATEPRR8SKEY_LOGˏRPP ЏLGI$_SKIPRELATEDUPRUJPЬPЀРP`PQPQU)PЬPЀРP`PQPQUЏLGI$_SKIPRELATEDUUP^P^ĬV4LxKhWo !n%Bj Wҿ :~ 8u2yU\@YN:|z\ETw'hSLE6Lm$/A+H8>-PM&ݨ\"48+˜l{fI[^vr@I iZ?'R=' 4 O.4![/hPϛؠGYq!X\|e}60H=iSq.ZVL7Z~ 0V\~hb[Pn5>B웋IC:G4MRqVcr:+8KVe`@B#3PCd?_ Pich'AY.3ғR)H ֱ3 dז#Sn}R OQYNm%J3*q*lL?B 1 %}x򍚦-H d<֠34o9;~m=42B%G&TͣLIoUKbBD$~\mdbC&oOړ#`1j* ^74ʋB'49媮"QM/g)!Sۼ;Ke ?f]]ko]4w44z/E-\ 3^729c3tkJ3Gg! G1WLX:T0i\ *qiI)dBk> D ڇDȡjDpw%z\$pdF / d]m^zZP<\ b.x&Pw[Zq02TElOJw 2Cn›v݀?B>ؑW/*xqa-YSx&ߩbhAp9@xo?;=*QPpf'qIfw]~UƿȓEC^J|CC^ f][ (wwbaTq쎺/#X(E\׾Aa l$3`Ҋ?(x0 #iGEK*놠]P-\2al&Fyq=#$F@#ammV1N|J *x; ugE;Zij?xSX{%pAv W>S=5b;˝X3??\[NLB8'4jD 焀Lh2I> +kf "ޫk*(lܨoU"/@D7zi7&w "% fkW[sx05ݵltMj"%9=JolqЩL E]#=H _ߣEׅ40vR6,Qԛqasq%˪H{4؂@hUC}TS_ DmUFj GW?a RဦN9 f$ Wu$nIa>åRzrGUTk$}wV9DT>*887sMdl@'q@: $wK$?ejݟO*ZMmҖi`Dȣ' |G)/?8w:}I8|z߃hjN$3OfM_Ms&|Xol2;nBN>nzi_ˣq5DpYXr,DD C u 楺nwC԰;T]T|2#tVq Vda>$oAZ׾{LT0pPW@H ]mm*63,,c r{吻 W LeS)HvN#*$F+"Hӧ5[G\4^BHJ:M% K6 [n|iBX+Nmvx֯|PQb%Z/aY*]L#erH3)3օHBe:9hh,+P ^T% uiiM[L )Ewܤ8cV3|ڌ(JC{k-}lǶY'/&!yB":L( 8Zcɟt{s.VE<$0O=.n|'j<9'd; ?{̖IzQrȝyIODNt87Ļ,l68;<CDZӿNlO8IL; \ulYEȵ l|٧%e>i?2U7zc5tT0(UE&`"`d4ƯN^r<9)^0&E1' .c Аd6gk0s0/xumCAg}405*A^S:B/Bx-B iæѴFܑɚS+3U2 ) }}>[?j1n!Kv+RugyOmFh=h:ʿ&(93棇W32Res5`ZY3$sUl94y (ưϑ^ dB'1zZE̮ ` 4#D ZA_apt|GKD=7]7GuI1<{mc#Xo.ۯSjŒHU8.M0AS>nR궪 E?\.d9҇{q|q;a3LNi!Hf]P)a2@ʮbJ$#ێE6A񣒑t`Es,~"bWkk1 áFA$9Yc&0GRIOSKh16WhyY~"E@.r{A{=4`BRd" Wry$ hL a=3$9'of{׎ZNTv@ҾFxG`7B[$XLLaCFYŅЇq/&o{9P$^~0ԭu"ygHg#\E!9A' 1VUw(u$jkzN $G.^9I4$&VNif`>wQn=U/3XNSD=)&{$HlnLYMGܹUJߦSXJUt*\w<.{U뺖 S ʞޚTԓv#f 0 N)L^ߐ &]Z&S*O 4/m'ƂgT/eC٤}s *uniXA\CjEg $xxP "|cپ l9ߴ$vԢQoX'TIOr4#۫ZO2 ZZH Ike5+h/b~A&D!?TUˣ{ZWSߐo2{&%{9մ<4w먰C5]tgGkC'w$Zd/+ |MGVwv+ Z@0KnR%B["IDh~X@`qQYWjԕ]?DŽZ"{8&Gc9#>h8wԡMv VZ]v62`=C}%>&ոM8 QǤ-upi^j1Fnrm|#a4 4rƜ3,#jD^'4~UGI/7p<>- Gf LpOjfvd>SiiIJ ͦMEÍ&.Q |AIA's`%/Ȫ~uq(J{DV79wk2$ x+V DND~ 9n b$K4wٌfDPnn9 )`VgY)|E9֩{^i.If AUKV?tBқzVƲ^ q²Z5tl>c2]pDu'"_P21a6yu)l5?iXfl.SrvBHW j'V©;l4%``T}4z\AYIxLbN!F, *VAzg].`6vmv)w27. $PoO?i"[{HCtB {Y9ؐ(o . ')%I*(Jp<݅^?9Cmb } e(I(bJ C[B1M4Qa$qV[0+jH#魪T3F,eڥ9'VCzT(b+XGKCYm{ܤuFi36e%}^%D!avbbOݍ K+X(aY 8n9iR>YFZ@a Z\SWYowƗɯzq G:"RdK-_Ϝd NIDJ`" GaP ~Yl8a?z~Bӊi]jْ ډS9Sֱ2ޜqx?=v饩(74l5 2,+q@^U ,f",(o~ŽDJ'j>msU:f d~Y d\b06(mӳF8i}Wx^qzk!0WQT5c* ȴ!IQ%f h7TE<b=NnX-\_CXY.woY [( D(_iO 2K`LΨf%0@_C5I%JEb=XYQy0e%W5w$R]ŌJkʝP՘)Rg w@n4[84aT9ޚ^"nu<R3<:(9roFq+7afJEd]EV%)py-=9+­WsʊҾUU^N:1`E!"zШS[HG,̧;0*g:`< myam{ձ9:WP I-a=nFcٯ9Q@tzBE>ūD2V[GO7AQq;b5@#a1 ,çquȾAVrq'lŽ:Bv6/~/%[6ZxL2I0 HEZU!|0ⵃU})΃ٕ;cSDk/(%۵c8̫6ǀ$3:)6J{MKb mb֗hAy$Ak$"<[=F%*KPivDdHO8IW]#eEہKt>%mU{ClFT#'3!2X\6c e$K 1^'NE~:mb@W9芧EGnnzJ3ܼJd-bV?H{(e3۪ r97 mlC}Yf ` W׈veA˴>\Fvݶ[4yU]P0eU#1g/"C3r[Q6(rm[ 23@`.2]! gEh@:15=l7Ojts#ލ7XHT@0D:"vn+F0Vi&)iy3Ca.;r`oI.jMOBo Ѱrw;k6Ύaخ:_gPM^4KU ht& }.V "  ?|KxkVədR)nT~ ^Vi8TZX-^YhNOoGCrU{];pyY*Y g}8{Äʪ<6j|ZNEqfxwQ;FWf=ryf+2tvE\ԧ8|E3\ZD3/.s}YfX,,dT4=f+ޟ\6GJKҋL<]ppmdel&`&*W!!_)9 t @u5[EAMHHujub gR=[ᇣzF&)~SAUycka2n5RdoLC)[ŌIR2aGԌl(qT*ɵ^Ra)[ J쩦dNŗ0e-X1M@%S;XiCKF0|QۄC(G&uf'-KG-pY8E\8pjlo>+n8LIW&^di&?H1$Vao?W_PÏ~^عBA!l5yn6>+MDhdϋ$cg|V0Nw SǵNDNM/xFPJfdaI&Lz^(FVa2K~u#sS`K3뻎}>Lg2KHLvN I !ɱZ&@fpMYi\=Np:~7fTa,GI^ ;`ŽZ ʔ=@icv]:`ӽS-5Zyv{8`Drճo7ȑn*vHWۗȻ" htL234Y~hSL|AKҬO:!5ҕ":AqdZ+ qx#WN Tcr JՉ>r>u:߲;p.9`#k +;gנ踦O=xRK,kKE'cQ9Bz'7XsSxS^2?h2+CAվPiFi_m9$tɜaN!4DL,EFE΍?;8[fɳeҹ?µGKJT~m\@>DUSk׳暮XBz+v4E+Ҝgŭ ҉J_|7EꜮ}yCvL똥YXx# |]:ǢJ+K@A5.~.i (ҪkDw~|#H[EBR$'`CLV3 q*]r/$B 1rZ'I" ~ 1 _:& 5?bR t"'1|qOH띃&q Ec SEsoU툑|[h_@ mר" k(>, /?A nP'*"\Q/.b%k.LIa'QZܝXG0Z?aS-nD`F R猩vFh$4Gs~ʩ7UzˆFm g֨=j3zoz2LI2^^F`^z˻Qs*jT^K444sooT ɺQbB^`;$-r:WߊgvEG>'+:g:A l"w6D oNQ7m(;zkH{]1q ELDRs4 a$/Kameȗ<^N|jWKG|2=\Gi=ٓmhg]-Vm,\FM~ KSE٢W=g GfwS^f'# @4votvI}*jӶ܃dsnLwh Eo:jn \jmǜ5MYv#LG0J,e01Ӆ_@\Q XDEhƱZB'>%j=3BDqMDsML}pb!ੳ6k tk7u 2I(!&34~c qpb_O?<7W.7{W^ bPG.}ˈo\(Ԉ?~ŻB Ep{ϏEi2I(rYv%57g8BEAS&ѻ|#o"Q& o5˛!֋djKikkTR6}Kwv^:dPIcyHP9Oнro,q?Md^7El3&U\AH >rHCH (tLD7%^gHD{xP=??Re䄃^(m 'HPB`o{fm Er8@+Ij~}F3}S`En%*׹plקdhv=Ycz^joؽZ8?;1 ]2"Z HG?AK+E~amB}3z~5jmnh‘gW{˘~ڞvGq@L]ոʻK͔RTm,YOZ"q2'@,,c #vBVe:+GeXv1;ƐAw!?2l*}hԱχpupd6t շ nr47whZ)5H^[CM^x3`,]L2S> XiT\ts}'ѽtu&BIm&+3q x~GQ馈!.GcUq^4Գx$#tizM9mA&i*]1aBgY%V-ڑ{hMԘ}imĚQ*ЪIbysn@A@:2):;\I%P2hn^K1euwOΞiNS"kd^&w4${]\+pS= D}Izw-BsrBһcV{e̓N>C'so>tL3Fc , dܑȡ?sI[,*8ƥt.͘e+$sOz O)_W4Pta*?ڟԙ0vqKtM t0pb vbfoxvSb^f8cP)MOGV3׹oD_VV{μ8f%I(:(;DGsuۡWiyYRnWPlVf m-|? &hTmwHH%Y~Fܕcip_` Ib'zMU'8e/3 vS귭}&(ChhD eE)wϧgS[<3v֠†ݩҬmg!L.܌*A]q<1Z] `84/[pa1GBشS&FЙöUy~clB8Rv&c(e:3'?bR.~5:)v65Z>ISIV1@[XGBgTJ|?u?AKP3WrդeaB]9zk:kJA;G7"[ٚ'KOyu%4vKm}C]/q& {>md$B:Yq!tW{IׇVgҨ6z ͤcŲvs`\3PݏY[7נdaC?ׅ;GzrXp{@ %m*fJ6/)DÏ,xJd9ܘ'q&fbMooSP̍ჶOG a&3?\7U`z.6mPo}]Ywzz*P*lMosJ^%t$mOG(-l㦂/'Y{pa㦴5#7\$>7ט<7 ,7:Mm˳W.Dr_ wW/F6ZmaGf;fߴ_Q!33pǮ7NL /6Z=/34up35le:Nĵcn,$cyM^Cc9o?e~j9PA%װfQkLO .E"̂~:o@~dn'*VM#H̓'dF"rR^ EdP;l)HWp8gMo1 \N~}J\yTc`Bb~C䍏Zn5\:XY 6}ikb]O=l3̞(G5B#RZR&@YIGvISx%b oMFE@mQR5ik;QrluDcÁ7a10t)L/ݡ*#C2  J!K@v D@Q & F}/"w[M(SUZ]f F 3̪m.LS PꉯA5lPCd:->7EN#Lp>PB0*boݏ1'R ^6 &g2j_dH<9PΩg# 2BEn;lV: YXTY3'ƢFo+Bܾҽ38F3,j`ۑ4AIpL#9vЫv -یYouoYs+~Wl~Z'T.C[VP"DbT CQ_)3,mr5;.ާ/|#pAeVJ.n?k@!Ys;=WH< CɟRhx BAFRO 7bkμE5!=mJn@ǒwh T*>C&V1vr _ꋒǼV|QФaҐ& /[sR m#ǟvG ¬Nt2o"B&]f^~Q&ì NyF\#{|4ӂZ<DqC5lt}j'H ><T?%PWzv O?}O$QN)DsC9C{b/nd V̰!NbyƦүiCv1V"YHMPt |魹Çj8$a"Iw(^WpPwz %=Z>FUm#RỊLJyX OuR "@a؂d;MRe( 5@ }`dGgvW_5v bs%wv;rJc k] H ڞ ,H1Hjf,_OڑX[Ήu5.1]2 _0|ZBd^PKE7إՃllMl~!$3] :)J 1'h`r#o|jU!3޹="ݖn'M,4) y( sf1 eLCe Ps}'T amM]M?!%+UixTC^Ͽj} H<%+;|AV@[Wgi-hv3GőKqkZ|t iws+-2s_cF?2FYg:5LIxa "Z0 pj^;~It3ׄU\ !/xƮ8"kL/%EHMOh+Y*1 cߣ͵XM a5/u`.VH[C$a+>CQn(8 /T=3x^|˽`_6oB+e2A2kdUhLTHU%l֌rIlv,Ϋ+y ( )wڥ[ޡoO&y=Ӛ :V? "D 7v>a/C }] IeOU2Z9hU=G'ZѐZɩ2MBJ%]V]ХX/93W5oF4(g@ 61~.a4 B+XϼY|jAc4Pã?YsrHxk\ȏǫd0 !M.㑈yVL< 4UJ;"$mGD{t8 eE^4ťM2Ǘ %q |fh7;W5d xl.c9Acu6Vk1۹%9qH=a"T/$F_h[*n?Q̿*ݛ>DD-y;ala=oq.ś^J2a񖠻:kݼG^ )+uc듑~lPr7z@X+PcB+-7skiV+(X+. 7q ez!Ż}nRsBو _ם lr@~o18E;F>#1; ~<8|wW\1՟g# Z;$::|F#cq 2S9SKrm+\:V"p\l]W`{y!i`<Jf!IVPaay%W6F7"S"3]} پgZG$dB"A[})+U /BChBUո:jn4- 2.jX8@e!/!v7|>^뼑TQB6BwXk5ey4 +*< 4n1x [A,n\E|%HlH#7<\s_(&g$H)T<KТO7 TyIFv֥-ۊ֡2l1ۘɦ^X:r:y܏;)Mp̧ŭ͡/| rV3mY/}ݮA..څ$Zmd^m!d}0g070PPQfPLZniy;P8AH:*m>2/_*Jc;ڮ]ax;,\UYo諾DBEaêڴ:^J ^,s5~3HwTC3>E8_*,B4m!"aGlk/ _h!Ci3ypm'OosLxc-4@tOp[vt?K٩" B ߥkWf,Baxj/L3x-"u\oj`:v!1sPSK{wRgӓ|w̾ԑ$R WNf_WFE;[+nO9two5QQ&(EJFvi*_L`9ֿJ߱W-tj}ZDM1 N=㙙Y(?@:!"C Yv,pn|}RQ7QĆݫQ_&UF/Sԫ9 e4ԱZuܠ5B s F3'YLژ 5|h3+?QjM1l W' r*ݒ*l&k-zb%TA|5,82)nNE9C`˭ K0 وo}KE@>5 tw>R Cmx.Vh +mIo7.8/ΔmɓV{?w\4§_ͽb8}a ZRLP8@Y f4.5-`T́Gg`Q@WӃ+a?HxTBd3y#yD>]B#$ sjT+%2 cV??ߋ9V9g{\4E*'s`tw]1Qo R) "V$n֦pV@u L|dցm>ekMͤT3q|:wDK6 m}Igi*ۗDb7Ȩ1}B!,fª$R s6% 0U=umt6Trg>,SÞzGDL5<,8R]&eǶɌeTX(_@:x^O[鏟F:TE5Qc'F-akFBu'j++K0vև.$(g.Zy41Y*  Ζ2D[5 C 2S5#.OhPi&]^ m7Lfr$zyNhmխg=+ѱ;$#1<ӕylҨu eXĮ[$-R 7OY!OK bߊ7)A=n>v 1 w\wЦN 4zpIpIjuhQܗ_G$)6yKBY.ǫ' Hfܱ>-Pd4&ٶ:T9YZQy\Um-x|"):xgsbu V|xdK7/풦 %CVD~'ʎք[D|F9'\A"2-{EB*S6Z|2L4 om[ ͷbWW8O o yh]6A?Z,v: fpym16^̡\wJT#Cek5fFE ,YX'LXp| \FN_D>]#ur G\b[H .FF?O묛JSZ(uucjz/vr|9c$:"}{M"r|޲sːoۯg~$oqH%FNf?/F-+7dV63Rin.{;ȷd$f`"j5ƪ o%,>vI Rl@3LD;GҪqnWhB{Ss g"!t-$ G/-uPˢw NAo*m˹p]Cay4ł=ǵ fsjXe!Ÿ<ǑvW"}=DQ}\LzJ-vA0r(P_=dV K#C)["B`0M=p8WHH-INקzUO?Z J^S1Cg{ext= s1eJ#9+m96nNdg uTড় vP:f!Ky@ Zni/) ,IU5X.Cӑ@Nپz S3:㎗("aj:#bޏ2WA2FHIƣ5ӉK`Re{+ZrG_;̈́>w"DBQ$gjm& i\%)#!EBq}n('q2K>]" (Tɷ "RVx7ps%BGrvYm 35yiUċLrOnNoPD&f"<ŀCSEu7@gL0! @TYڎt;-Pj@SfcLk60S-ӽ(wnY~Oj++@oɺG lj᫒N%1z,|d~n_g"UlҾ9LH^i>J9[Œ:oMXMkT?v8SIǃ]+u:}: 3SJ jVfNZiY}`Dc"}OgkyR;KHXlHD):bU5 ud&7uSy"x('ç`,|?qL8R9pBw.}wR^$)=YCV_DH?x!%QI4DSYDXWp<*nİĤ͐r mk$\Kz]pnfwȠ؏gUb iGFk(Xet#jgfCtm:Y",wuxQd V&^VQЃffzs9pd V M}WH  -PgVT녘-Q=7#[!->|ݫGsZYb%&:1;S_V*ZK<뫵?gL>MSRhUd{US5 r?]LNɢG,fڣG ++u@&N{:EVruͮ1aUxBYA0 hX_R2ɣ49}ʑ;C]mp>cĭ~"٪R! A 9Χ,0O{@i]s@-Kmk%$SRaz)!y79⊗>SJf;=s %9Ap ZhRK%W9nFHoxN+Bu|RCBmi{#.E8M g[Wulu_DWl!D/^Ve:< ^m6&@pܟ`&C=3+ä `"8q&avȴ>Yk{jՃht<}<^,z? Em8͠0Mfg+%Mb`r=1EښsY5TR8?HΥBЋ<T@"cdC\jq'ʄ @6,7^P΢$9i.nfjc5FIa0TSjpG2FVVչ #U=(4X] 9Hd*MEF9G"ITCΙK(\2KXЃ2|b}K+t ЄH[ޫs@үJzk}$ϗb^*RҐ:q^JBeڝi 1eMln"We#Q.0,WD#~+JBi^r-LE|]f;oJe_TQ mҵPk#:$uMdqr5x~0D|H:2<HsLjOy<:mzlVKWtncʽ/{Oaƒ+6?^~%Gm*gQO\1@rW"5ZԺf ~otnC-(qY86=>v [C]_LZ8NHKCn̤OF %!&ҭyxV܆'~bTjdƢ5\WGl 52VFݠ]Ch.!#o槸=û؎ 1~7S:nʷP\`BBd uʕsny5 %ڼ7Yr~Cj5r#zx{|}jMqU‘wGPdPcw1#-tWL3I=3dS ؉ 9kak@f_vsE'p@Cv(t7^{ďCsy&.bM9_Xo6?8qg&dBk`Jydn@5Ӻ>ZPs8w#{ğ$qtbuLW[نGz[JB>M*3?v`ՔK·mu\>h֤p8{%ؒ.'ÝP⦨c:e!=) Z*aJJʐ_UACܕRҥim/@:ӅJLМoV2xWtT;nG,\40 ER>6S9ѢGP[ -b3Q;E LAm{[+SY,G|;]#K` Led󺰨JJ{JSoL = ,

bwZ+yg;v;ܘ=ƈ>[|{" 5ě0Y\s5N_gNa?ɎvAIbV|nޔ9/LzרmȤ eܨ' NX:Ghho[ Ϟd\߲[{A /*jE emoiWt\4cLA躗nM'4Y<2Z[L!OA`λ8Ia\}sS};;b't/iIƫ"p4E7X,L@7ǜ6,OX Cn@ j>&o{Rܛ<9eR&c$ؾrr)}`CꓕMBF @G-C߾ʙھ}8"1Lty43 85]V)ĴHrќ 6iMe6aA3ė4m/ׄ pb'ZaÍݓjѽf+-f6S)K kn۾*Rw'C prҷF qm%< ZO>ct[{4/~.:qxd Ct׎y̍t[Tɂ* #/:rGP=ZX fPm< S"ӋgݒZP{M` !\13:;#ݍQkbWa+ݞ?l͌Kd"rg~i)_X}2Gfvn#(!.=ƺZ5Dq7gޓ(^)wzO/h>N*Ԯ"øW=\r RP7H[`bL E>4D^EZȋX"t_IJ'*ק.ZU 99YwMz]d)ʛ;r`?y}'00wi߲zv=%>-MԬqks6R)sl4rX'%C B ěIbmpJFL@g!|a/@ĉKTrMmv-Hau*g}| lI!p\8oHc~]G-jq7a@DMzKQz}_#(Ӹc18CNmē+I SV=T"lvX,z~qhf!nؕ(=Wؓy'}ZS ,`"-/e۽dbyfp(h<Yy$%HF*ZCM"B(ҬZStzrFF&vD#/X7WI 87T;6 ,.nbaes~X>+I.D{ij1Pmt8vj)fb |cXvIa2 FK@R O/+dGuސ){vN;]:A:; h 6V[v ?Ơ&uv L_<}v*og!D#uN]Fq{[*6a?7Eؽj6/vCcs9Vp'>HCq "Gx^wiq~/[VP?odKd2 Qѝvv1R!RDwk3Fg3ij>H4X]/-ϗ?|5U^a艭qG?B OnINwO'l68Uh['Vs4K92rgj)5&JL5d:nG NM=Ѡ2s/@3;΂]97SKo z[bL (R+n0HyW.+~߃ t#^&u HV)y:QK1 19N֢P3y!uOӒ.ProQ,סiP <0~Τ)(F{i;fْBu,[j4ēq'OOܹ9B]E&0@Ѣ-EF[0܆˃\ %r˨ ѱk6Dy R;R\@O`ΙǘHT\3I,$}5`H`~}6WW䤳&h3a \S ?qmjKs ˵V{Y htYXZ9{&NQ +wH5d]͘Wt2]͈1嚄%]+u'g u_|0 oyԸ<$L,֫# ->+]IO"SPyMd*,#+c-^IgMN'n;K'ː緍%-FEXFˢYXvFfx x^?lIJ>+E eB2?+N:6V`xIndoVD`I% =/98m(U8]COlxJ%RWΡIj=  }fJz8Ew6xϺټ,g cd-2M/pw${Mn׬𬞯kJ( av$:'J8cb kQ芜pƾ2[&ϲˍR12qoE#HCCd+nj/WBcABm%ߙe *}~RyV0*ꁖNoUg#G[ .m=B``rcO@ɥ9ֱN*wC:(kYDlKb~qE \Ѵ`/u0mn!+Kݸ:Y4P5((?=cH q dTC݈`$2zyp"sIBja<ޛWy53Q կ3< QoՊbf(Y\Bdw)1lšI`6c5xQO[bXDT^]8Lh+@3\"ˣ~${QAn<:h6(w*@me[m*"âOJPk`0oT/{l4%uR<ڈ4Z_t - ;YR4hqd?+k%zἸt.~hhV}[Tkp7W <΂kCV08өzS%NF~"ǻVq5dž.8c W.t oEjf*f{+\AW 6z' \Cp6K߽b<腳p{ZLbMWO7XMfzki78O\s+V\uvLS4#]4^Y,Ѱ#zo@]!洀 Oܳv) ˳JͭϝF3ȩL14_tz4(*Y7'DVH$dălmz@asraSuGt-hբfgIѿ㖥mh>2#zZ 1L$SHDf}ǝ>t%gl+/ܞP &i^z{ޱ||7l,c4c&SMHJCf< -=C(ޯxspkv -|`!χծ q(>+n"jWPqCw,fōN!t?C@>j"fî@;m>Mm3|>T^(=}d}7# %ʃ݁yZ'xF^E r"'d96]xM6yhk0F'l)Q~6NzlW^ 7C QgKU:GN!J܈=בWC!|7&s/^(妟++p_#Z:4Ww ❼}S~&>lE0Jٹ"k_{'|wZrj;NW✟}F ևZjO"ԐNNGr3?A5{>^d͑m뷷TXwU}"M-9y1򠼨>^?0Ы갇)299V@IV&l(8%}교)vR/,L%-j~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'XJ  ۰~ SKEY009.A3[_ e*'[LANE.WORK.SKEY.INSTALL_A]SKEY_TEST.C;1J ) *J* see SKEY_TEST.COM for build/test procedure *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include int main(){ int iss;2 char user[100], challenge[100], password[100]; void *ctx = 0; printf("username: "); gets(user);: iss = SkeyChallenge(user,"myskey.db",challenge, &ctx); if (!(iss & 1)) {6 printf("Challenge Error, iss = 0x%08x\n",iss); lib$signal(iss); return iss; }' printf("%s\nPassword: ",challenge); gets(password);+ iss = SkeyAuthenticate(password, &ctx); if (!(iss & 1)) {1 printf("Auth Error, iss = 0x%08x\n",iss); lib$signal(iss); return iss; }3 printf("Authorization OK, iss = 0x%08x\n",iss); return 1;})*[LANE.WORK.SKEY.INSTALL_A]SKEY_TEST.COM;1+,`[. / 4] <- e*0123KPWO56m9_)7l)89GHJ$!D$! compile, link, run the SKEY_TEST program with a "user" database'$! to illustrate using the SKEYSHR api$!)$! assumes that S/Key has been installed$!$! (c) 1998 C. Lane$! $ set verify$ cc/debug/noopt skey_test$!9$! VAXC or DECC? analyze the object file to find out....$!3$ analyze/object/output=skey_test.ana skey_test.obj$ open/read fd skey_test.ana $ set nover $ state = 0$ loop1:$ read/end=eloop1 fd lineA$ if f$locate("_LNM)",line) .lt. f$len(line) then state = 1$ if state .eq. 1 $ then&$ v = f$element(1,"""",line)+$ if v .eqs. """" then goto loop1/$ decc = f$extract(0,3,v) .eqs. "DEC"$ state = 2$ goto eloop1 $ endif $ goto loop1 $ eloop1: $ set verify $ close fd$ if state .ne. 2$ thenF$ write sys$error "Unable to determine VAXC/DECC compiler type!"$ exit 44$ endif$ delete skey_test.ana;$!$ open/write fd skey_test.opt!$ if f$trnlnm("skeyshr") .nes. ""$ then$ write fd "SKEYSHR/SHARE"$ else&$ write fd "SYS$SHARE:SKEYSHR/SHARE"$ endif7$ if .not. decc then write fd "SYS$SHARE:VAXCRTL/SHARE" $ close fd%$ link/debug skey_test, skey_test/opt$!/$! check for "user" database, create if needed$!$ f = f$search("myskey.db")$ if f .eqs. ""$ then=$ write sys$output "Creating user S/Key database MYSKEY.DB"*$ skey/initialize/new/database=myskey.db$ endif]$ skey/initialize/database=myskey.db/password="foobarblem"/sequence=200/seed="bfd123" JOEUSER&$ skey/show/database=myskey.db JOEUSER$!$ run/nodebug skey_testJOEUSERouch sigh mask bare glut paw $ set nover$ exit+*[LANE.WORK.SKEY.INSTALL_A]SKEY_VAXNDB.OPT;1+,M. / 4 <- e*0123KPWO56ʖ)7S+ݖ)89GHJskeylib_vaxndb.olb/lib,*[LANE.WORK.SKEY.INSTALL_A]SOURCE_FILES.VDT;3+,c;. / 4H  - e*0123KPWO56y|ao7ߥ|ao89GHJ)! SOURCE_FILES.VDT generated by MAKEVDTJMKVDT_1 BUILD.COM VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_2 GLOBAL.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_3 MAKE_HELP.TXT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_4 MD4.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_5 MD4C.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_6 MD5.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_7 MD5C.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_8 REVISION.HISTORY VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_9 SKEY.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_10 SKEYSHR_XFER.MAR VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_11 SKEY_API.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_12 SKEY_API.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_13 SKEY_AXPDEB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_14 SKEY_AXPNDB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_15 SKEY_CALC.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_16 SKEY_CLD.CLD VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_17 SKEY_CLI.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_18 SKEY_CLI.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_19 SKEY_CRYPT.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_20 SKEY_CRYPT.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_21 SKEY_DB.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_22 SKEY_DB.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_23 SKEY_DICT.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_24 SKEY_LGI.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_25 SKEY_LGI_AXPDEB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_26 SKEY_LGI_AXPNDB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_27 SKEY_LGI_VAXDEB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_28 SKEY_LGI_VAXNDB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_29 SKEY_LOG.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_30 SKEY_LOG.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_31 SKEY_MSG.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_32 SKEY_MSG.MSG VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_33 SKEY_VAXDEB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_34 SKEY_VAXNDB.OPT VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_35 SKEY_VERSION.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_36 SKEY_VERSION.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_37 UTIL.C VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_38 UTIL.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_39 VERSION_00_9_006. VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] JMKVDT_40 VMS_TYPES.H VMI$ROOT:[SYSHLP.EXAMPLES.SKEY.SOURCE] [2./~ FREEWARE.SAVtE0[SKEY009]SKEY009.A;12~~'b|! HR y{;2J-r pp#7!! *libImnaloT*RJ\W.QYklhl8,,3e$$./0!ip1p # (readpwnVpp)u!p .deccgastderr<|L" -deccdfprintfΈ4odyy$;lLm[Gm("ɹ=s ,,mLmMRo, 4 'rd11*-A>k%mETIJ!mh-+kj%F)EI!|o`}er\tahf:a&;.7-|(tȶuE'Mpcq‚Z18coBRivs<97yj+< :wIB=Signae`I*:,+8bxʁ`01|t٨9QBputux̴ޣ' 9mk8LySe'*n9ޗm*9xV"knM :nuAT|3"5xhltޓ;9\|Ŀweb9'"p-P +s;70J+(gw3b|{*uie"i oi.=2l!گy\ea` ,#{~SHNt<&ǝ#8 S6EY_LOGխ |SETPRIVSPRR R LIB$SIGNAL߭ݭDB_OPENPխ |럭 RESETPRIVSPRR R LIB$SIGNAL\խ\\D3 TRNLNM_EXECPSG6TRNLNMPSSx\,S DECC$ATOIPR R x\PS DECC$FREER\\TݭDB_FETCHPRˏp\\Rݭ DB_DELETEPݭDB_CLOSET DECC$FREER<$S(pТpSt~R DECC$MEMSETR SYS$GETUAI SYS$ASCTIMCMA$TIS^UMSERRNO_GET_AEE{*[G msbDY&IBh  ^TMS_j bVRhMQ, $B%SPR`CYY $DDC[$sTfCR[\DECG$TRCAT= DECC$MEMSCT,e!DECA$}EERY0DwCC FaEE E<%AOI_ @E C!FOPGN4 DsC.{]TN7(jWPMRjOR DEKCDFPRINTFG EE[C&F LGJ  __EEIN  Meh $+ 3gmpclho3"+2ke1)Q+s<>$?Ivt}9_$rȩMTޔω!ox6+{"7(2sz#8*V6u.k"(I$wi4+5lrȾݦ"ss%6:ome~t #c0dan} =!i5>&9#-ֶ4s:gS$*libsi.(a*8αgoOM fi/*J#{ekpƍ']fj>õ:":<2e-h/trnlnm,>e0h5s?q~[j" &t&&) kpss2&Xtg s%ee!(&-Pieck>|>|g{ 5)Xt1/9g%/ex7kcadpe1tr3 unm' (dbfetch<34hg$l<11"G2zui/J/ȥy2!u4@eȍ#E#0͈ua<bRRSant!?+mzPar̃%kefKaylog<۪5d }76s:6;,&im/3;p$:ѫʲҺEC/1*,46(,1t=6>$s{pps6izsqY#_ta7: %T7*6k'=id$-YEgcK4519'"o BXDᷬ" &'9+5a$r92:hc#>H'caz!x.:W*16gxPv5l6f]1)->f9u2hzlk!"7E$36 !!?-Ұytoz6xc"0?5%n5ޱYgncw50" . =}6/)t}fv6⑽Q1%y!7-,4 # +26%67oq!,dod qPIjuQ)ɕvg(2%<-? *hP盘SPmuh,e0*C;t?-6%<" ŏ#pj3NCg> 9s+;j% l<,7C$FREE1 DECC$MEMCPYݧ\HASHKEYT DECC$STRNCMPPGT DECC$MEMCPYWݭDB_PUTPPa[SKEY_LOG\ DECC$DPRINTFЏ SKEY$_OKAUTH#PTSKEY_LOGT DECC$DPRINTFЏ SKEY$_NOAUTH DECC$MEMSET DECC$MEMSETխ ݭDB_CMLSEWt~|)P   kWyOS] eE~KQ4&^ZԁF mL@_PRASjNUʯRP߭C= CLI_GETVALSE15PН]f\խ0\\ψ^}\\߬ϴLPVaΩ3bQ_DOppryP SKEY$_NGUxFPU1FΜ LRRS1TRbȋP\PJ/2烙^?> r,93d'&@AEM7"62,TEvrKOjA  >0Wv".:[<6+i;'5W+)8$(*$@skeysource}k r8?2+#1_FR&%+011EKSmo'@;TALLv$'W&.#88<4>HWP e>app*a'\='+4q le"(Krd=9QE$'gl aTHENFsysvu v ~kcmPhe5nk#ys)q""7.E,,-o=36'6\V `Upi%@;TALLREPLACEFqmiroot{syshlpexalqme4K'k++  M>BD}kEYvyhomtI" }0'!=O+xJ3.C0.4A"W JVJF3>F0>@Zk4a.tH"SrJtF4a>lqDpD 8uJY0K5GWB 8}E/"4G{pK% TGsaJ[GE>SFE>'.p"$.C$" HV JwJUJFF'>$>`b#-@.% qHPJTGF>cGl[@ZklctGB, #,"CbHA #H4GDCG@ZkG2"."# ##.TG BJQ !J(bFCCpr.SrJpr>$@ZkbGBGbGc CtG@ZkCDÀ4GcG[@Zk 4G4GXDc[@ZkGp]x]}#kG.4GU JF0JF:$80J?G5G$8}#p"~4G^^~ (0޴8G`[Gh{GC@ZkCC, BJ@(bF@TG@ZkCB `bGGTG@Zk@BGHb4G@Zk GBTGb C@Zk bB4GbTGxc C@ZkV 4GTGX CM B0 (bJ@CTG@ZkC pB@G@Zk@BHbG4G@ZkG ¤@pB C@Zk BN@(bCTG@ZkCB bG4G@Zk@BHbGh4G@ZkGhGTGBbFD#-BQG@Zkà4GBbh4G@Zk GG0 ClŰtGBb@ZkG]]4G} (0ݤ8@#kG#TG~^^~GGQGP[GX{lMBG4G @Zk$4GBbh@Zkl84GP.PJ0@J@FDF@4GG@4G.JcG[@Zk C0Bp= CL@@ZklC@BG3.0, 7Kq7HP J@HFD3>0<C@Zk4.4w"uHTJF4>lqDpD 2aKY0K!GWB 2 % GE/{aK% 4GsaJ"TG[GF> '/C$E.$%" JX KyHRQJG'?YF$E>b#@.% qHTGPJF>Gcl[@Zkl#tGBB. !.R"bJQ !JFCC4GG@ZkGXG"A.""#!.tGbPJQ 0JBbGQFCB.CUJ>@ZkGBGbFdC3`BG@ZkG"CBGb@8@GG@ZkG(GB bCV@CtG@ZkpBCxb4G@ZkcCG[4G@ZkBbGG4G@Zk b4GBGbtGc C@ZkGG G]]}#kp.4GS pJrF0@J@F"$20K?G!G$2S#4G~^^G G[{l"@ZkBlG]4G] #k#&~?$0^! 8^G@G#@[CG "CC(GH{G=GG@Zk 0"G B4G(btG-@@ZkG=tG0 B (bB2v H4G@ZkG ]4G BtG(b@0"@ZkGG0]8]@P#k40GL SET_LOGLEV44b# SET_LOGLEV4H@L SET_LOGLEV4G$SKEY_LOG4b#SKEY_LOG4 @$SKEY_LOG48G`DECC$GXSPRINTF4Hb#DECC$GXSPRINTF4\@`DECC$GXSPRINTF4 lG DECC$STRLEN4 @ DECC$STRLEN4GSKEY_LOG4b#SKEY_LOG4@SKEY_LOG<G SKEYAUTHENTICATE<b#SKEYAUTHENTICATE<@ SKEYAUTHENTICATE 4(GHSKEY_LOG40b#SKEY_LOG4D@HSKEY_LOG48GP DECC$MALLOC4@b#p DECC$MALLOC4L@P DECC$MALLOC4`Gx TRNLNM_EXEC4hb#p TRNLNM_EXEC4t@x TRNLNM_EXEC4 |G OPEN_LOGFILE4 b#p OPEN_LOGFILE4 @ OPEN_LOGFILE4G DECC$FREE4b#p DECC$FREE4@ DECC$FREE4 G OPEN_LOGFILE4 b#p OPEN_LOGFILE4 @ OPEN_LOGFILE4GSKEY_LOG4b#pSKEY_LOG4@SKEY_LOG4G, TRNLNM_EXEC4b#p TRNLNM_EXEC4(@, TRNLNM_EXEC44GD DECC$STRCPY4@@D DECC$STRCPY4DGX DECC$FREE4Hb#p DECC$FREE4T@X DECC$FREE4hGx DECC$STRCPY4t@x DECC$STRCPY4xG TRNLNM_EXEC4b#p TRNLNM_EXEC4@ TRNLNM_EXEC4G DECC$ATOI4b#p DECC$ATOI4@ DECC$ATOI4G DECC$FREE4b#p DECC$FREE4@ DECC$FREE4 G OPEN_LOGFILE4 b#p OPEN_LOGFILE4 @ OPEN_LOGFILE4G$ SET_LOGLEV4b#p SET_LOGLEV4 @$ SET_LOGLEV4DGPSKEY_LOG4Hb#pSKEY_LOG4L@PSKEY_LOG4 G OPEN_LOGFILE4 b# OPEN_LOGFILE4 @ OPEN_LOGFILE4G SET_LOGLEV4b# SET_LOGLEV4@ SET_LOGLEV4hG| DECC$STRCPY4x@| DECC$STRCPY4 G DECC$STRLEN4 @ DECC$STRLEN4GSKEY_LOG4b#SKEY_LOG4@SKEY_LOG4 G@ SKEY_LOG4 b#SKEY_LOG4< @@ SKEY_LOG4H Gx SKEYCHALLENGE4P b# SKEYCHALLENGE4t @x SKEYCHALLENGE4 G SKEY_LOG4 b#SKEY_LOG4 @ SKEY_LOG4 G DECC$GXSPRINTF4 b#DECC$GXSPRINTF4 @ DECC$GXSPRINTF,  G NEW_STR, b#NEW_STR,  @ NEW_STR4 G DESTROY_STR4 b# DESTROY_STR 4 @ DESTROY_STR4( GD SKEY_LOG40 b#SKEY_LOG4@ @D SKEY_LOG4 G SET_LOGLEV4 {#@ SET_LOGLEV4 @ SET_LOGLEV4D G SYS$GETSYIW4x b#` SYS$GETSYIW4 @ SYS$GETSYIW4 G SKEY_LOG4 b#`SKEY_LOG4 @ SKEY_LOG4 G SKEY_LOG4 b#`SKEY_LOG4 @ SKEY_LOG4 G SKEY_LOG4 b#`SKEY_LOG4 @ SKEY_LOG =pdTimeout LGI_PWD_TMO value = !SL, using defaultTimeout sys$getsyiw iosb.status=!XL, using defaulth=8/Timeout sys$getsyiw status=!XL, using default=0!get username input status = !XL=@5challenge status: !XL, user: '!AZ', challenge='!AZ'= checking user '!AZ'=(username read status = !XL0=0$S/Key LGI processing started at !DX=(LGI context pointer is zerox=8+unable to allocate memory for LGI context= sys$manager:skey.log=(authentication status = !XL=(password input i/o status=!XL=  %s Password: =!authenticate user '!AS'4 4=0";=0 ;0 SET_LOGLEV=0" ;=  =00" ;=P SKEY_LOG; SYS$GETSYIW=0";=< 7LGI$_SKIPRELATED DECC$STRCPY DECC$STRLEN OPEN_LOGFILE= Username:   NEW_STR DESTROY_STRDECC$GXSPRINTF SKEYCHALLENGE= LOGIN %sp=0";=@|  TRNLNM_EXEC= LNM$SYSTEM DECC$FREE=SKEY_LOG_FILE DECC$MALLOC=SKEY_LOG_LEVEL DECC$ATOI=0p";=< SKEYAUTHENTICATE = p464446@466  (*[LANE.WORK.SKEY.INSTALL_A]SKEY_LGI.OBJ;2+,g. / 4  - e*0123KPWO568789GHJ5SKEY_LGIV1.0 4-FEB-1998 07:18DEC C V5.5-002qPTimeout LGI_PWD_TMO value = !SL, using default>PTimeout sys$getsyiw iosb.status=!XL, using defaultPTimeout sys$getsyiw status=!XL, using defaultPget username input status = !XLPLOGIN %sPchallenge status: !XL, user: '!AZ', challenge='!AZ'Pchecking user '!AZ'Pusername read status = !XLsP Username: PPS/Key LGI processing started at !DEPLNM$SYSTEM6PSKEY_LOG_LEVEL!Psys$manager:skey.logPLNM$SYSTEMPSKEY_LOG_FILEPLGI context pointer is zeroPunable to allocate memory for LGI contextPpointers not longword size, context dropped!}Psys$manager:skey.logrPLNM$SYSTEMdPSKEY_LOG_FILEHPauthentication status = !XL*Ppassword input i/o status=!XLP %s Password: Pauthenticate user '!AS'P P^ЬRbPl~ SET_LOGLEVbPlPP<Δ^ЬR28Q Q U1zP QU1mP@PU1_ݢtSKEY_LOGЬP1`Q1P1͔ DECC$DSPRINTFТlP@ТlP͔0͔ DECC$STRLENPQТlPQ4ТlP$ТlP ТlPТlPPQТlPQݢlbP`ТlPРSSSUSKEY_LOGSU1ЬPРlP<"TD޼P߰SKEYAUTHENTICATEPRR8SKEY_LOGˏRPP ЏLGI$_SKIPRELATEDUPRUJPЬPЀРP`PQPQU)PЬPЀРP`PQPQUЏLGI$_SKIPRELATEDUUP^P#define HAS_MEMCPY 1#define HAS_MEMSET 1#define PROTOTYPES 1#ifndef PROTOTYPES#define PROTOTYPES 0#endif,/* POINTER defines a generic pointer type */typedef unsigned char *POINTER;#/* UINT2 defines a two byte word */!typedef unsigned short int UINT2;$/* UINT4 defines a four byte word */ typedef unsigned long int UINT4;F/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.F If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it returns an empty list. */#if PROTOTYPES#define PROTO_LIST(list) list#else#define PROTO_LIST(list) ()#endif#endif)*[LANE.WORK.SKEY.INSTALL_B]MAKE_HELP.TXT;1+,\f. / 4F X<-cX0123KPWO56[o7 [o89GHJHelp with S/Key make procedure:/ AXP/VAX architecture selection is automatic& @MAKE [what] [options] [MMS_QUALS] options are:* DEBUG --> /DEBUG, /NOOPT- VERBOSE --> /LIST, /MAP, etc.5 SHOW=(...) --> [CC/SHOW=(...) qualifier]) @MAKE -> same as 'help'% @MAKE help -> gives this2 @MAKE all -> skey, skeyshr, skey_lgi+ @MAKE kit -> installation kit> @MAKE bump_edit -> increments "edit" number in version? @MAKE bump_minor -> increments "minor" part of version #? @MAKE bump_major -> increments "major" part of version #F @MAKE tidy -> purges objects, executables, verbose output- @MAKE srctidy -> purge source files3 @MAKE clean -> removes all "made" files!*[LANE.WORK.SKEY.INSTALL_B]MD4.H;1+,. / 4F <-cX0123KPWO56[o7[o89GHJ!/* MD4.H - header file for MD4C.C */B/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.D License to copy and use this software is granted provided that itC is identified as the "RSA Data Security, Inc. MD4 Message-DigestE Algorithm" in all material mentioning or referencing this software or this function.D License is also granted to make and use derivative works provided? that such works are identified as "derived from the RSA Data? Security, Inc. MD4 Message-Digest Algorithm" in all material. mentioning or referencing the derived work.E RSA Data Security, Inc. makes no representations concerning eitherB the merchantability of this software or the suitability of this> software for any particular purpose. It is provided "as is"3 without express or implied warranty of any kind.C These notices must be retained in any copies of any part of this! documentation and/or software. *//* MD4 context. */typedef struct {F UINT4 state[4]; /* state (ABCD) */F UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */F unsigned char buffer[64]; /* input buffer */ } MD4_CTX;&void MD4Init PROTO_LIST ((MD4_CTX *));void MD4Update PROTO_LIST/ ((MD4_CTX *, unsigned char *, unsigned int));;void MD4Final PROTO_LIST ((unsigned char [16], MD4_CTX *));"*[LANE.WORK.SKEY.INSTALL_B]MD4C.C;1+,./ 4F:<-cX0123KPWO56[o7b,[o89GHJ&A/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm */E/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.D License to copy and use this software is granted provided that itC is identified as the "RSA Data Security, Inc. MD4 Message-DigestE Algorithm" in all material mentioning or referencing this software or this function.D License is also granted to make and use derivative works provided? that such works are identified as "derived from the RSA Data? Security, Inc. MD4 Message-Digest Algorithm" in all material. mentioning or referencing the derived work.E RSA Data Security, Inc. makes no representations concerning eitherB the merchantability of this software or the suitability of this> software for any particular purpose. It is provided "as is"3 without express or implied warranty of any kind.C These notices must be retained in any copies of any part of this! documentation and/or software. */#include "global.h"#include "md4.h"&/* Constants for MD4Transform routine. */ #define S11 3 #define S12 7#define S13 11#define S14 19 #define S21 3 #define S22 5 #define S23 9#define S24 13 #define S31 3 #define S32 9#define S33 11#define S34 15Fstatic void MD4Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); static void MD4Encode PROTO_LIST- ((unsigned char *, UINT4 *, unsigned int)); static void MD4Decode PROTO_LIST- ((UINT4 *, unsigned char *, unsigned int));#ifdef HAS_MEMCPY#define MD4_memcpy memcpy#elseEstatic void MD4_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));#endif#ifdef HAS_MEMSET#define MD4_memset memset#elseAstatic void MD4_memset PROTO_LIST ((POINTER, int, unsigned int));#endif$static unsigned char PADDING[64] = {F 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};&/* F, G and H are basic MD4 functions. *//#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))<#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))$#define H(x, y, z) ((x) ^ (y) ^ (z))%/* ROTATE_LEFT rotates x left n bits. */<#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))=/* FF, GG and HH are transformations for rounds 1, 2 and 3 */A/* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s) { \% (a) += F ((b), (c), (d)) + (x); \# (a) = ROTATE_LEFT ((a), (s)); \ } #define GG(a, b, c, d, x, s) { \9 (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \# (a) = ROTATE_LEFT ((a), (s)); \ } #define HH(a, b, c, d, x, s) { \9 (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \# (a) = ROTATE_LEFT ((a), (s)); \ }F/* MD4 initialization. Begins an MD4 operation, writing a new context. */void MD4Init (context)FMD4_CTX *context; /* context */{, context->count[0] = context->count[1] = 0;) /* Load magic initialization constants. */! context->state[0] = 0x67452301;! context->state[1] = 0xefcdab89;! context->state[2] = 0x98badcfe;! context->state[3] = 0x10325476;}>/* MD4 block update operation. Continues an MD4 message-digestB operation, processing another message block, and updating the context. */)void MD4Update (context, input, inputLen)FMD4_CTX *context; /* context */Funsigned char *input; /* input block */Funsigned int inputLen; /* length of input block */{! unsigned int i, index, partLen;& /* Compute number of bytes mod 64 */: index = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */3 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) context->count[1]++;/ context->count[1] += ((UINT4)inputLen >> 29); partLen = 64 - index;) /* Transform as many times as possible. */ if (inputLen >= partLen) { MD4_memcpyB ((POINTER)&context->buffer[index], (POINTER)input, partLen);3 MD4Transform (context->state, context->buffer);1 for (i = partLen; i + 63 < inputLen; i += 64)/ MD4Transform (context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ MD4_memcpy: ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);}F/* MD4 finalization. Ends an MD4 message-digest operation, writing the2 the message digest and zeroizing the context. */void MD4Final (digest, context)Funsigned char digest[16]; /* message digest */FMD4_CTX *context; /* context */{ unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */& MD4Encode (bits, context->count, 8); /* Pad out to 56 mod 64. */: index = (unsigned int)((context->count[0] >> 3) & 0x3f);7 padLen = (index < 56) ? (56 - index) : (120 - index);' MD4Update (context, PADDING, padLen);& /* Append length (before padding) */ MD4Update (context, bits, 8); /* Store state in digest */) MD4Encode (digest, context->state, 16);# /* Zeroize sensitive information. */6 MD4_memset ((POINTER)context, 0, sizeof (*context));}=/* MD4 basic transformation. Transforms state based on block. */'static void MD4Transform (state, block)UINT4 state[4];unsigned char block[64];{F UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; MD4Decode (x, block, 64); /* Round 1 */& FF (a, b, c, d, x[ 0], S11); /* 1 */& FF (d, a, b, c, x[ 1], S12); /* 2 */& FF (c, d, a, b, x[ 2], S13); /* 3 */& FF (b, c, d, a, x[ 3], S14); /* 4 */& FF (a, b, c, d, x[ 4], S11); /* 5 */& FF (d, a, b, c, x[ 5], S12); /* 6 */& FF (c, d, a, b, x[ 6], S13); /* 7 */& FF (b, c, d, a, x[ 7], S14); /* 8 */& FF (a, b, c, d, x[ 8], S11); /* 9 */' FF (d, a, b, c, x[ 9], S12); /* 10 */' FF (c, d, a, b, x[10], S13); /* 11 */' FF (b, c, d, a, x[11], S14); /* 12 */' FF (a, b, c, d, x[12], S11); /* 13 */' FF (d, a, b, c, x[13], S12); /* 14 */' FF (c, d, a, b, x[14], S13); /* 15 */' FF (b, c, d, a, x[15], S14); /* 16 */ /* Round 2 */' GG (a, b, c, d, x[ 0], S21); /* 17 */' GG (d, a, b, c, x[ 4], S22); /* 18 */' GG (c, d, a, b, x[ 8], S23); /* 19 */' GG (b, c, d, a, x[12], S24); /* 20 */' GG (a, b, c, d, x[ 1], S21); /* 21 */' GG (d, a, b, c, x[ 5], S22); /* 22 */' GG (c, d, a, b, x[ 9], S23); /* 23 */' GG (b, c, d, a, x[13], S24); /* 24 */' GG (a, b, c, d, x[ 2], S21); /* 25 */' GG (d, a, b, c, x[ 6], S22); /* 26 */' GG (c, d, a, b, x[10], S23); /* 27 */' GG (b, c, d, a, x[14], S24); /* 28 */' GG (a, b, c, d, x[ 3], S21); /* 29 */' GG (d, a, b, c, x[ 7], S22); /* 30 */' GG (c, d, a, b, x[11], S23); /* 31 */' GG (b, c, d, a, x[15], S24); /* 32 */ /* Round 3 */' HH (a, b, c, d, x[ 0], S31); /* 33 */' HH (d, a, b, c, x[ 8], S32); /* 34 */' HH (c, d, a, b, x[ 4], S33); /* 35 */' HH (b, c, d, a, x[12], S34); /* 36 */' HH (a, b, c, d, x[ 2], S31); /* 37 */' HH (d, a, b, c, x[10], S32); /* 38 */' HH (c, d, a, b, x[ 6], S33); /* 39 */' HH (b, c, d, a, x[14], S34); /* 40 */' HH (a, b, c, d, x[ 1], S31); /* 41 */' HH (d, a, b, c, x[ 9], S32); /* 42 */' HH (c, d, a, b, x[ 5], S33); /* 43 */' HH (b, c, d, a, x[13], S34); /* 44 */' HH (a, b, c, d, x[ 3], S31); /* 45 */' HH (d, a, b, c, x[11], S32); /* 46 */' HH (c, d, a, b, x[ 7], S33); /* 47 */' HH (b, c, d, a, x[15], S34); /* 48 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d;# /* Zeroize sensitive information. */) MD4_memset ((POINTER)x, 0, sizeof (x));}D/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */*static void MD4Encode (output, input, len)unsigned char *output; UINT4 *input;unsigned int len;{ unsigned int i, j;, for (i = 0, j = 0; j < len; i++, j += 4) {1 output[j] = (unsigned char)(input[i] & 0xff);: output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);; output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);; output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); }}D/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */*static void MD4Decode (output, input, len)UINT4 *output;unsigned char *input;unsigned int len;{ unsigned int i, j;* for (i = 0, j = 0; j < len; i++, j += 4)@ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |@ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);}=/* Note: Replace "for loop" with standard memcpy if possible. */#ifndef HAS_MEMCPY+static void MD4_memcpy (output, input, len)POINTER output;POINTER input;unsigned int len;{ unsigned int i; for (i = 0; i < len; i++) output[i] = input[i];M}.#endif=/* Note: Replace "for loop" with standard memset if possible.p */t#ifndef HAS_MEMSET+static void MD4_memset (output, value, len)LPOINTER output;d int value;unsigned int len;r{d unsigned int i;d for (i = 0; i < len; i++)i& ((char *)output)[i] = (char)value;} #endif!*[LANE.WORK.SKEY.INSTALL_B]MD5.H;1+,. / 4F x<-cX0123KPWO56[o7$[o89GHJ!/* MD5.H - header file for MD5C.C */B/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. Allrights reserved.ALicense to copy and use this software is granted provided that it@is identified as the "RSA Data Security, Inc. MD5 Message-DigestBAlgorithm" in all material mentioning or referencing this softwareor this function.ALicense is also granted to make and use derivative works provided<that such works are identified as "derived from the RSA Data<Security, Inc. MD5 Message-Digest Algorithm" in all material+mentioning or referencing the derived work.BRSA Data Security, Inc. makes no representations concerning either?the merchantability of this software or the suitability of this;software for any particular purpose. It is provided "as is"0without express or implied warranty of any kind.@These notices must be retained in any copies of any part of thisdocumentation and/or software. *//* MD5 context. */typedef struct {F UINT4 state[4]; /* state (ABCD) */F UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */F unsigned char buffer[64]; /* input buffer */ } MD5_CTX;&void MD5Init PROTO_LIST ((MD5_CTX *));void MD5Update PROTO_LIST/ ((MD5_CTX *, unsigned char *, unsigned int));;void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));"*[LANE.WORK.SKEY.INSTALL_B]MD5C.C;1+,./ 4F<-cX0123KPWO56P-[o7:[o89GHJ*A/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */B/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. Allrights reserved.ALicense to copy and use this software is granted provided that it@is identified as the "RSA Data Security, Inc. MD5 Message-DigestBAlgorithm" in all material mentioning or referencing this softwareor this function.ALicense is also granted to make and use derivative works provided<that such works are identified as "derived from the RSA Data<Security, Inc. MD5 Message-Digest Algorithm" in all material+mentioning or referencing the derived work.BRSA Data Security, Inc. makes no representations concerning either?the merchantability of this software or the suitability of this;software for any particular purpose. It is provided "as is"0without express or implied warranty of any kind.@These notices must be retained in any copies of any part of thisdocumentation and/or software. */#include "global.h"#include "md5.h"&/* Constants for MD5Transform routine. */ #define S11 7#define S12 12#define S13 17#define S14 22 #define S21 5 #define S22 9#define S23 14#define S24 20 #define S31 4#define S32 11#define S33 16#define S34 23 #define S41 6#define S42 10#define S43 15#define S44 21Fstatic void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); static void MD5Encode PROTO_LIST- ((unsigned char *, UINT4 *, unsigned int)); static void MD5Decode PROTO_LIST- ((UINT4 *, unsigned char *, unsigned int));#ifdef HAS_MEMCPY#define MD5_memcpy memcpy#elseEstatic void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));#endif#ifdef HAS_MEMSET#define MD5_memset memset#elseAstatic void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));#endif$static unsigned char PADDING[64] = {F 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,F 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,9 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};)/* F, G, H and I are basic MD5 functions. *//#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))/#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))$#define H(x, y, z) ((x) ^ (y) ^ (z))'#define I(x, y, z) ((y) ^ ((x) | (~z)))%/* ROTATE_LEFT rotates x left n bits. */<#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))@/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.<Rotation is separate from addition to prevent recomputation. */$#define FF(a, b, c, d, x, s, ac) { \0 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ }$#define GG(a, b, c, d, x, s, ac) { \0 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ }$#define HH(a, b, c, d, x, s, ac) { \0 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ }$#define II(a, b, c, d, x, s, ac) { \0 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ }F/* MD5 initialization. Begins an MD5 operation, writing a new context. */void MD5Init (context)FMD5_CTX *context; /* context */{, context->count[0] = context->count[1] = 0;) /* Load magic initialization constants.*/! context->state[0] = 0x67452301;! context->state[1] = 0xefcdab89;! context->state[2] = 0x98badcfe;! context->state[3] = 0x10325476;}>/* MD5 block update operation. Continues an MD5 message-digest? operation, processing another message block, and updating the context. */)void MD5Update (context, input, inputLen)FMD5_CTX *context; /* context */Funsigned char *input; /* input block */Funsigned int inputLen; /* length of input block */{! unsigned int i, index, partLen;& /* Compute number of bytes mod 64 */: index = (unsigned int)((context->count[0] >> 3) & 0x3F); /* Update number of bits */3 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) context->count[1]++;/ context->count[1] += ((UINT4)inputLen >> 29); partLen = 64 - index;) /* Transform as many times as possible.*/ if (inputLen >= partLen) { MD5_memcpy? ((POINTER)&context->buffer[index], (POINTER)input, partLen);0 MD5Transform (context->state, context->buffer);. for (i = partLen; i + 63 < inputLen; i += 64), MD5Transform (context->state, &input[i]); index = 0; } else i = 0; /* Buffer remaining input */ MD5_memcpy7 ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);}F/* MD5 finalization. Ends an MD5 message-digest operation, writing the/ the message digest and zeroizing the context. */void MD5Final (digest, context)Funsigned char digest[16]; /* message digest */EMD5_CTX *context; /* context */{ unsigned char bits[8]; unsigned int index, padLen; /* Save number of bits */& MD5Encode (bits, context->count, 8); /* Pad out to 56 mod 64.*/: index = (unsigned int)((context->count[0] >> 3) & 0x3f);7 padLen = (index < 56) ? (56 - index) : (120 - index);' MD5Update (context, PADDING, padLen);& /* Append length (before padding) */ MD5Update (context, bits, 8); /* Store state in digest */) MD5Encode (digest, context->state, 16);# /* Zeroize sensitive information.*/6 MD5_memset ((POINTER)context, 0, sizeof (*context));}=/* MD5 basic transformation. Transforms state based on block. */'static void MD5Transform (state, block)UINT4 state[4];unsigned char block[64];{F UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; MD5Decode (x, block, 64); /* Round 1 */2 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */2 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */2 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */2 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */2 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */2 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */2 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */2 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */2 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */3 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */3 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */3 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */3 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */3 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */3 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */3 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */3 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */3 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */3 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */3 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */3 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */3 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */3 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */3 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */3 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */3 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */3 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */3 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */3 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */3 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */3 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */3 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */3 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */3 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */3 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */3 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */3 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */3 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */3 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */3 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */3 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */3 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */3 HH (c, d, a, b, x[ 3], S330G!~ FREEWARE.SAVEM0[SKEY009]SKEY009.B;12~~q|;, 0xd4ef3085); /* 43 */3 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */3 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */3 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */3 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */3 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */3 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */3 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */3 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */3 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */3 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */3 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */3 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */3 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */3 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */3 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */3 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */3 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */e3 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */R3 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */r3 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */t3 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */S state[0] += a; state[1] += b; state[2] += c; state[3] += d;# /* Zeroize sensitive information.c*/) MD5_memset ((POINTER)x, 0, sizeof (x));s}eD/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */ *static void MD5Encode (output, input, len)unsigned char *output; UINT4 *input;eunsigned int len; {a unsigned int i, j;, for (i = 0, j = 0; j < len; i++, j += 4) {. output[j] = (unsigned char)(input[i] & 0xff);7 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);e8 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);8 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); }o}hD/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */s*static void MD5Decode (output, input, len)UINT4 *output;unsigned char *input;7unsigned int len;d{n unsigned int i, j;* for (i = 0, j = 0; j < len; i++, j += 4)= output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |4= (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);v} =/* Note: Replace "for loop" with standard memcpy if possible.c */ #ifndef HAS_MEMCPY+static void MD5_memcpy (output, input, len)POINTER output;DPOINTER input;unsigned int l`3~ SKEY009.BcX"[LANE.WORK.SKEY.INSTALL_B]MD5C.C;1F?uen;g{  unsigned int i;t for (i = 0; i < len; i++)f output[i] = input[i];e}#endif=/* Note: Replace "for loop" with standard memset if possible. */f#ifndef HAS_MEMSET+static void MD5_memset (output, value, len)iPOINTER output;O int value;unsigned int len;i{) unsigned int i;t for (i = 0; i < len; i++){# ((char *)output)[i] = (char)value;0},#endif,*[LANE.WORK.SKEY.INSTALL_B]REVISION.HISTORY;1+,&ql. / 4I z<-cX0123KPWO56"[o7V +[o89GHJV0.9-3 21 Jan 1998: CELI skey_lgi: use sysgen LGI_PWD_TMO value to determine password read timeoutH skey_api, skey_calc, etc.: add check of SKEY_TIMEOUT logical for database accessV0.9-4 22 Jan 1998: CELA util.c/getpwd: change buffer size to 256 ... larger size causing quota problemsD descrip.mms, make_help.com: streamline build procedures, add9 subs, checksumming and PGP signing for kit build.V0.9-5 23 Jan 1998: CEL- add more info on PGP key verificationV0.9-6 4 Feb 1998: CEL? change to fixed, 512 records (with padding) for db file> add "dbversion" and "modified date/time" to db records4 add "modified date/time" to SKEY/SHOW output/ add get_logstatus routine to SKEY_LOG.C@ use get_logstatus in SKEY_API to avoid reopening logfile@ add log_close_api, and log (context/static) variables to@ control open and close of logfile when called eitherG from a user program (non logging) or an S/Key app (logging)TODO:! skey/show=(brief,full) *"*[LANE.WORK.SKEY.INSTALL_B]SKEY.H;1+,. / 4; <-cX0123KPWO56jC[o7GQ[o89GHJ/* * some common definitions, etc. * */#ifndef __SKEY_H#define __SKEY_H#include "vms_types.h"#define SECURE 1 enum _SKEY_ALGORITHM {MD4, MD5};*typedef enum _SKEY_ALGORITHM Algorithm;*typedef enum _SKEY_ALGORITHM* pAlgorithm;#define DEFAULT_ALGORITHM MD5%typedef struct _ALT_ENTRY DictEntry;&typedef struct _ALT_ENTRY* pDictEntry;&typedef struct _ALT_DICT Dictionary;&typedef struct _ALT_DICT* pDictionary;#define MAX_ALT_WORD 8struct _ALT_ENTRY { pDictEntry next; char entry[MAX_ALT_WORD+1];};struct _ALT_DICT { Algorithm algorithm; pDictEntry hentry[2048];};#define MAX_USERNAME 64#define MAX_SEED 16#define PFLAG_ENABLE 1#define PFLAG_REGULAR 2struct PRINCIPAL_RECORD {& char principal[MAX_USERNAME]; int sequence; char seed[MAX_SEED]; char key[8]; Algorithm algorithm; union { struct {' unsigned skey_default : 1;' unsigned skey_allow : 1;' unsigned norm_allow : 1; } b; longword l; } flags; int dbversion; longword lastmod[2]; int status;};'typedef struct PRINCIPAL_RECORD REC;'typedef struct PRINCIPAL_RECORD * pREC;;#define REC_SIZE (sizeof(REC) - sizeof(int))#if !defined(__VAXC)&#define skey_default b.skey_default$#define skey_allow b.skey_allow$#define norm_allow b.norm_allow#endif#endif,*[LANE.WORK.SKEY.INSTALL_B]SKEYSHR_XFER.MAR;1+,%. / 4 <-cX0123KPWO56*Z[o7Fg[o89GHJ .title skeyshr_xfer .transfer SkeyChallenge .mask SkeyChallenge jmp G^SkeyChallenge+2 .transfer SkeyAuthenticate .mask SkeyAuthenticate jmp G^SkeyAuthenticate+2 .end&*[LANE.WORK.SKEY.INSTALL_B]SKEY_API.C;1+,4.$/ 4s$b<-cX0123KPWO56p[o7D[o89GHJ8J/************************************************************************\I * *I * SKEY_API.C *I * programming interface to S/Key routines *I * *I * external interface routines: *I * SkeyChallenge *I * SkeyAuthorize *I * *I * internal routines: *I * *I * CalcDelay(int delay, longword t_delay[2]) calc VMS delay time *I * CancelChallenge(pChal c) cancel challenge *I * ChallengeAST(pChal c) cancel timer AST *I * my_strcasecmp(char *s1, char *s2) caseless compare *I * Skey_UserParse(char *p, char **user) parse username/skey *I * Calc_Timeout(pChal c) get timeout value *I * log_open_api(int usermode) open logfile *I * *I * (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include "skey.h"#include "util.h"#include "skey_crypt.h"#include "skey_db.h"#include "skey_msg.h"#include "skey_log.h"struct _skey_chal { char *user; pDB D; pREC r; int timeout; int prived; int opened; int issued; int userlog;};!typedef struct _skey_chal *pChal;!typedef struct _skey_chal Chal;7static int CalcDelay(int delay, longword t_delay[2]);&static void CancelChallenge(pChal c);#static void ChallengeAST(pChal c);/static int my_strcasecmp(char *s1, char *s2);2static int Skey_UserParse(char *p, char **user);#static int Calc_Timeout(pChal c);(static void log_open_api(int usermode);!static void log_close_api(void); #define DEFAULT_TIMEOUT 120%#define DEFAULT_LOGLEV L_BABBLE3#define DEFAULT_LOGFILE "sys$manager:skey.log"'#define DEFAULT_USER_LOGFILE "skey.log"#define NEWLOG 0static int api_opened_log = 0;J/************************************************************************\S * int SkeyChallenge(char *user, char *dbfile, char *challenge, void **context)I * *I * get challenge string for user *I * if dbfile = 0, then use system S/Key database (req's privs) *I * returns status, and writes challenge string [MAX <64] *I * *J\************************************************************************/intHSkeyChallenge(char *user, char *dbfile, char *challenge, void **context){ pChal c = 0;9 int iss, modified = 0, l, opt_skey = 0, opt_norm = 0; Privs P, cP, *pP; char *p; longword tAST[2];= if (!user || !challenge || !context) return SS$_BADPARAM; *challenge = 0; *context = 0; c = malloc(sizeof(Chal)); if (!c) return SS$_INSFMEM; c->user = 0; c->r = 0; c->prived = 0; c->timeout = 0; c->issued = 0; c->D = 0; c->userlog = dbfile != 0; log_open_api(c->userlog); if (!dbfile) { pP = CurPrivs(); cP = *pP; free(pP); if (!cP.prv$v_sysprv) { P.prv$l_l1_bits = 0; P.prv$l_l2_bits = 0; P.prv$v_sysprv = 1; iss = SetPrivs(&P); if (VMS_ERR(iss)) { log_close_api(); return iss; } c->prived = 1; } } iss = DB_Open(dbfile,&c->D);" if (c->prived) ResetPrivs(&P);! if (VMS_ERR(iss)) goto error;) iss = Skey_UserParse(user, &c->user); if (iss == CLI$_PRESENT) { opt_skey = modified = 1;% } else if (iss == CLI$_NEGATED) { opt_norm = modified = 1;( } else if (VMS_ERR(iss)) goto error;3 c->r = DB_Fetch(c->D, c->user,Calc_Timeout(c)); iss = SS$_INSFMEM; if (!c->r) goto error; iss = c->r->status;+ if (iss == SKEY$_NOUSER) goto normexit;! if (VMS_ERR(iss)) goto error;> if (!opt_skey && !c->r->flags.skey_default) goto normexit;> if ( opt_norm && c->r->flags.skey_allow ) goto normexit;L if (!c->r->flags.skey_allow && !c->r->flags.skey_default) goto normexit;+ iss = CalcDelay(Calc_Timeout(c), tAST);! if (VMS_ERR(iss)) goto error;. iss = sys$setimr(0,tAST,&ChallengeAST, c);! if (VMS_ERR(iss)) goto error; p = Challenge(c->r); strcpy(challenge, p); free(p); c->issued = 1; *context = (void *) c;+ Log(L_BABBLE,"Challenge !XL issued",c); log_close_api();1 return modified ? SKEY$_USERMOD : SS$_NORMAL;error: CancelChallenge(c);6 Log(L_BABBLE,"error return, no challenge issued"); log_close_api(); return iss; normexit: if (c->D) { DB_Close(c->D); c->D = 0; } *context = (void *) c;0 Log(L_BABBLE,"void Challenge !XL issued",c); log_close_api();1 return modified ? SKEY$_USERMOD : SS$_NORMAL;} static voidCancelChallenge(pChal c){ int iss; Privs P; if (!c) return; if (c->prived) { P.prv$l_l1_bits = 0; P.prv$l_l2_bits = 0; P.prv$v_sysprv = 1; ResetPrivs(&P); } if (c->user) free(c->user); if (c->r) {# memset(c->r,0,sizeof(REC)); free(c->r); } if (c->D) DB_Close(c->D); c->D = 0;# if (c->issued && !c->timeout) {' iss = sys$cantim(c,PSL$C_USER);! if (VMS_OK(iss)) free(c); }}int0SkeyAuthenticate(char *password, void **context){ pChal c; int iss; Privs P;3 if (!password || !context) return SS$_BADPARAM; c = (pChal) *context; if (!c) return SS$_BADPARAM; *context = 0; log_open_api(c->userlog);6 Log(L_BABBLE,"Authentication of challenge !XL",c); if (c->timeout) { CancelChallenge(c);+ Log(L_BABBLE,"challege timed out"); log_close_api(); return SKEY$_TIMEOUT; } P.prv$l_l1_bits = 0; P.prv$l_l2_bits = 0; P.prv$v_sysprv = 1; if (c->issued) { char key[8], newkey[8]; pREC r = c->r;2 iss = AnyToKey(key,password,r->algorithm); if (VMS_ERR(iss)) { CancelChallenge(c);< Log(L_BABBLE,"AnyToKey returned error !XL",iss); log_close_api(); return SKEY$_BADENC; } memcpy(newkey,key,8);# HashKey(key, r->algorithm);( if (memcmp(key,r->key,8) == 0) {$ memcpy(r->key,newkey,8);" iss = DB_Put(c->D, r);/ Log(L_BABBLE,"user authenticated"); iss = SKEY$_OKAUTH; } else {7 Log(L_BABBLE,"user authentication failed"); iss = SKEY$_NOAUTH; } memset(newkey,0,8); c->issued = 0; CancelChallenge(c); log_close_api(); return iss; } else { pSTR d_user, d_pass;s ItemList3 list[]={$ITEM3(UAI$_ENCRYPT),$ITEM3(UAI$_PWD),$ITEM3(UAI$_SALT), $ITEM3(UAI$_FLAGS), NULL_ITEM3}; byte algorithm; word salt;$ longword hash0[2], hash1[2]; union { struct flags f; longword x; } uai_flags;6 Log(L_BABBLE,"non S/Key authentication used"); log_close_api();. list[0].address = (char *) &algorithm; list[0].length = 1;) list[1].address = (char *) hash0;( list[1].length = sizeof(hash0);) list[2].address = (char *) &salt;& list[2].length = sizeof(salt);. list[3].address = (char *) &uai_flags;+ list[3].length = sizeof(uai_flags);" d_user = new_STR(c->user); uc(pSTRPTR(d_user));$ if (c->prived) SetPrivs(&P);0 iss = sys$getuai(0,0,d_user,list,0,0,0);& if (c->prived) ResetPrivs(&P); CancelChallenge(c);1 if (iss == RMS$_RNF) return SKEY$_NOAUTH;% if (VMS_ERR(iss)) return iss;# d_pass = new_STR(password); uc(pSTRPTR(d_pass));H iss = sys$hash_password(d_pass, algorithm, salt, d_user, hash1); destroy_STR(d_user);2 memset(pSTRPTR(d_pass),0,pSTRLEN(d_pass)); destroy_STR(d_pass);% if (VMS_ERR(iss)) return iss;A\ if (uai_flags.f.uai$v_pwd_expired || uai_flags.f.uai$v_disacnt) return SKEY$_NOAUTH;N if (hash0[0] != hash1[0] || hash0[1] != hash1[1]) return SKEY$_NOAUTH; return SKEY$_OKAUTH; } } static int)CalcDelay(int delay, longword t_delay[2]) {  int iss, len;  longword days, hours, mins; + $DESCRIPTOR(d_time, "!UL !UL:!UL:!UL");k STR d_expire = NULL_STR; char a_expire[100]; 4 if (delay <= 0 || !t_delay) return SS$_BADPARAM;& d_expire.dsc$a_pointer = a_expire;. d_expire.dsc$w_length = sizeof(a_expire); days = delay / 86400;  delay -= days * 86400; hours = delay / 3600;  delay -= hours * 3600; mins = delay / 60; delay -= mins * 60; F iss = sys$fao(&d_time, &len, &d_expire, days, hours, mins, delay);! if (VMS_ERR(iss)) return iss; d_expire.dsc$w_length = len;) iss = sys$bintim(&d_expire, t_delay); ! if (VMS_ERR(iss)) return iss;e return SS$_NORMAL;}r static voidrChallengeAST(pChal c)s{a c->timeout = 1;a DB_Free(c->D);} static int!my_strcasecmp(char *s1, char *s2)o{p char c1, c2; if (!s1) return s2 ? 1 : 0;  if (!s2) return -1;  while (*s1 && *s2) { c1 = *s1++; c2 = *s2++; 5 if (tolower(c1) != tolower(c2)) return c2-c1;  } return 0;*}* static int$Skey_UserParse(char *p, char **user){* int iss, quote = 0;> char *p0, *skey_qual = 0;e if (!p) return SS$_BADPARAM;" while (*p && isspace(*p)) p++; p0 = p;s0 while (*p && !isspace(*p) && *p != '/') p++; if (user) {d *user = malloc(p-p0+1);c' if (!*user) return SS$_INSFMEM; strncpy(*user,p0,p-p0);y (*user)[p-p0] = 0; }i iss = SS$_NORMAL;c while (*p) { if (quote) { if (*p == '"') {' if (*(p+1) == '"') p++;n else quote = 0; }  } else { switch (*p) {a case '"':_ quote = 1; break; case '/':c$ if (skey_qual) {, strcpy(skey_qual,p);# return iss; } else {= if (my_strcasecmp(p, "/SKEY") == 0) {t/ iss = CLI$_PRESENT; * skey_qual = p;E } else if (my_strcasecmp(p,"/NOSKEY") == 0) {_/ iss = CLI$_NEGATED;A* skey_qual = p; }i } }* }* p++; }*" if (skey_qual) *skey_qual = 0; return iss;c} static intCalc_Timeout(pChal c)d{c int i; char *s; if (c->prived) {5 s = trnlnm_exec("SKEY_TIMEOUT","LNM$SYSTEM");i } else {2 s = trnlnm("SKEY_TIMEOUT","LNM$FILE_DEV"); }t# if (!s) return DEFAULT_TIMEOUT;p i = atoi(s);4 if (i <= 0 || i > 64000) return DEFAULT_TIMEOUT; free(s); return i; } static void log_open_api(int usermode){  char *p, *file;* get_logstatus(&file, 0); if (file) {* free(file); return;g }* if (!usermode) {6 p = trnlnm_exec("SKEY_LOG_FILE","LNM$SYSTEM"); if (p) {$ open_logfile(p, NEWLOG); free(p); } else {2 open_logfile(DEFAULT_LOGFILE, NEWLOG); }) api_opened_log = 1;c7 p = trnlnm_exec("SKEY_LOG_LEVEL","LNM$SYSTEM");z if (p) { set_loglev(atoi(p)); free(p); } else {' set_loglev(DEFAULT_LOGLEV);0 }i } else {3 p = trnlnm("SKEY_LOG_FILE","LNM$FILE_DEV"); if (p) {$ open_logfile(p, NEWLOG); free(p); } else {7 open_logfile(DEFAULT_USER_LOGFILE, NEWLOG); }  api_opened_log = 1; 4 p = trnlnm("SKEY_LOG_LEVEL","LNM$FILE_DEV"); if (p) { set_loglev(atoi(p)); free(p); } else {' set_loglev(DEFAULT_LOGLEV);i }  }) Log(L_BABBLE,"skeyshr run at !%D",0); } static void(log_close_api() {f char *file;t if (!api_opened_log) return; get_logstatus(&file, 0); if (!file) return; free(file);= set_loglev(L_CLOSED);p api_opened_log = 0; } &*[LANE.WORK.SKEY.INSTALL_B]SKEY_API.H;1+,'#. / 4M (<-cX0123KPWO560[o7ZA[o89GHJ#ifndef __SKEY_API_HJ/************************************************************************\I * *I * *I * *I * *I * *I * *J\************************************************************************/Mint SkeyChallenge(char *user, char *dbfile, char *challenge, void **context);5int SkeyAuthenticate(char *password, void **context);#define __SKEY_API_H 1#endif+*[LANE.WORK.SKEY.INSTALL_B]SKEY_AXPDEB.OPT;1+,* . / 4 <-cX0123KPWO56r[o7t[o89GHJskeylib_axpdeb.olb/lib+*[LANE.WORK.SKEY.INSTALL_B]SKEY_AXPNDB.OPT;1+,g,. / 4 <-cX0123KPWO56̵[o7‡[o89GHJskeylib_axpndb.olb/lib'*[LANE.WORK.SKEY.INSTALL_B]SKEY_CALC.C;1+,2.-/ 4x-+<-cX0123KPWO,56ݨ[o7 [o89GHJJ/************************************************************************\J* SKEY_CALC.C *J* *J* S/Key command verb : S/Key calculator *J* S/Key database management *J* test functions *J* *J* See SKEY.HLP for parameters, qualifiers, etc. *J* *J* May be used as command verb: SET COMMAND SKEY.CLD *J* or as foreign command: SKEY :== $SKEY *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include "skey.h"#include "util.h"#include "skey_crypt.h"#include "skey_db.h"#include "skey_msg.h"#include "skey_log.h"#include "skey_cli.h"#include "skey_version.h"extern char SKEY_CLD;int CheckPassword(char *p);int do_initialize();int do_test();int do_show();int do_clear();int do_profile();int do_keygen();int do_version();int PowerUser();int SuperUser();Bstatic char * GetUser(char * cli_symbol, int *status, int secure);static void set_sysprv();static void reset_sysprv();'static int TimeoutLNM(int usermode);%static void log_open(int usermode); #define DEFAULT_SEQUENCE 200 #define DEFAULT_TIMEOUT 120%#define DEFAULT_LOGLEV L_BABBLE4#define DEFAULT_LOGFILE "sys$manager:skey.log"(#define DEFAULT_USER_LOGFILE "skey.log"#define NEWLOG 0#define MIN_PWD 10#define MAX_PWD 63intmain(){ int iss; Privs p1, p2; pPrivs p_image, p_proc; p_image = ImagePrivs(); p_proc = ProcPrivs(); PrivsNOT(p_proc, &p1); PrivsAND(p_image, &p1, &p2); ResetPrivs(&p2);+ iss = cli_init(&SKEY_CLD, "SKEY_CALC");! if (VMS_ERR(iss)) return iss; return cli_dispatch();}int do_keygen(){J int iss, opt_hex, ngen, nseq, j, k, opt_print, opt_delete, opt_output;? char *sequence, *seed, *outfile, *count, *password, *queue;( char key[8], buf[1024], fop_buf[20]; Algorithm a; pDictionary d=0 ; FILE *fp_out = NULL; log_open(1); Log(L_BABBLE,"do_keygen");> if (VMS_ERR(cli_present("P1"))) lib$signal(SKEY$_NOPARAM);> if (VMS_ERR(cli_present("P2"))) lib$signal(SKEY$_NOPARAM);( iss = cli_getvalue("P1", &sequence); nseq = atoi(sequence);$ iss = cli_getvalue("P2", &seed); cli_unquote(seed); lc(seed);6 Log(L_BABBLE,"seq = !SL, seed=\"!AZ\"",nseq,seed);' if (VMS_OK(cli_present("COUNT"))) {+ iss = cli_getvalue("COUNT",&count); ngen = atoi(count); } else ngen = 1;* if (VMS_OK(cli_present("PASSWORD"))) {0 Log(L_BABBLE,"password present in CLI");1 iss = cli_getvalue("PASSWORD",&password); } else {3 iss = read_pwd("Password: ", &password, 0);% if (VMS_ERR(iss)) return iss; fprintf(stderr,"\r"); } cli_unquote(password);" iss = CheckPassword(password);& if (VMS_ERR(iss)) lib$signal(iss);/ opt_delete = VMS_OK(cli_present("DELETE"));- opt_print = VMS_OK(cli_present("PRINT"));/ opt_output = VMS_OK(cli_present("OUTPUT"));' if (VMS_OK(cli_present("QUEUE"))) {+ iss = cli_getvalue("QUEUE",&queue);2 crelnm("SYS$PRINT","LNM$PROCESS",queue,1); } if (opt_output) {. iss = cli_getvalue("OUTPUT",&outfile);2 if (VMS_ERR(iss) || !outfile || !*outfile)! outfile = "SKEY.LIS"; } else { outfile = "SKEY.LIS"; }" if (opt_delete || opt_print) { strcpy(fop_buf,"fop=");. if (opt_delete) strcat(fop_buf,"dlt");9 if (opt_delete && opt_print) strcat(fop_buf,",");- if (opt_print) strcat(fop_buf,"spl"); } else { fop_buf[0] = 0; }" if (opt_output || opt_print) { if (*fop_buf) {H fp_out = fopen(outfile,"w", "rfm=stmlf", "rat=cr", fop_buf); } else {? fp_out = fopen(outfile,"w", "rfm=stmlf", "rat=cr"); } if (!fp_out) { perror("file open");/ lib$signal(SKEY$_OUTERR,1,outfile); } }+ if (VMS_OK(cli_present("ALGORITHM"))) {3 if (VMS_OK(cli_present("ALGORITHM.MD5"))) { a = MD5;: } else if (VMS_OK(cli_present("ALGORITHM.MD4"))) { a = MD4; } else {& lib$signal(SKEY$_UNALGOR); } } else { a = DEFAULT_ALGORITHM; }* iss = KeyProc(a, key, seed, password);& if (VMS_ERR(iss)) lib$signal(iss);1 opt_hex = VMS_OK(cli_present("HEXADECIMAL"));, if (VMS_OK(cli_present("DICTIONARY"))) { char * dictfile;4 iss = cli_getvalue("DICTIONARY", &dictfile); if (!dictfile)- dictfile = trnlnm("SKEY_DICT",0); if (!dictfile)# dictfile = "SKEY.DICT"; d = new_Dictionary(a);7 iss = read_Dictionary(d, dictfile, 0, 0, 0, 0);% if (VMS_ERR(iss)) return iss; }! for (j = 1; j <= nseq; j++) { HashKey(key, a); if (j + ngen > nseq) { if (d) {$ KeyToAlt(buf,key,d); } else { if (!opt_hex) {* KeyToEnglish(buf,key); 1A~ FREEWARE.SAVEM0[SKEY009]SKEY009.B;12~~|y} else {& KeyToHex(buf,key); } } if (fp_out) {: fprintf(fp_out,"%d %s : %s\n",j,seed,buf); } else {2 printf("%d %s : %s\n",j,seed,buf); } } } return SS$_NORMAL;}intCheckPassword(char *p){ int iss, len; if (!p) { iss = SKEY$_VOIDPWD; lib$signal(iss); return iss; } len = strlen(p); iss = SS$_NORMAL; if (len < MIN_PWD) { iss = SKEY$_SHORTPWD; } else if (len > MAX_PWD) { iss = SKEY$_LONGPWD; } return iss;}intdo_initialize(){ int iss, j, opt_log;' char *seq, *password, *dbfile = 0; char *user, *seed; pREC r; pDB D;% if (VMS_OK(cli_present("NEW"))) {/ iss = cli_getvalue("DATABASE",&dbfile);* if (VMS_ERR(iss)) lib$signal(iss); log_open(dbfile != 0);H Log(L_CRITICAL,"Creating new S/Key database file: !AZ", dbfile);% iss = DB_Create(dbfile, &D); DB_Close(D); return iss; }* if (VMS_OK(cli_present("DATABASE"))) {/ iss = cli_getvalue("DATABASE",&dbfile);* if (VMS_ERR(iss)) lib$signal(iss); log_open(dbfile != 0);: Log(L_BABBLE,"init user record in DB=!AZ",dbfile); } else { log_open(0); }, user = GetUser("P1", &iss, dbfile == 0); if (VMS_ERR(iss)) { lib$signal(iss); fprintf(stderr,"\n"); } r = DB_New(user);@ Log(L_INFO,"initialize S/Key record for user \"!AZ\"",user);) opt_log = VMS_OK(cli_present("LOG"));* if (VMS_OK(cli_present("SEQUENCE"))) {, iss = cli_getvalue("SEQUENCE",&seq); r->sequence = atoi(seq); } else {' r->sequence = DEFAULT_SEQUENCE; }& if (VMS_OK(cli_present("SEED"))) {) iss = cli_getvalue("SEED",&seed);4 if (VMS_ERR(iss)) lib$signal(SKEY$_NOPARAM); lc(seed); } else { seed = SeedGenerate(); }% strncpy(r->seed, seed, MAX_SEED); free(seed);+ if (VMS_OK(cli_present("ALGORITHM"))) {3 if (VMS_OK(cli_present("ALGORITHM.MD5"))) { r->algorithm = MD5;: } else if (VMS_OK(cli_present("ALGORITHM.MD4"))) { r->algorithm = MD4; } else {& lib$signal(SKEY$_UNALGOR); } } else {) r->algorithm = DEFAULT_ALGORITHM; }" iss = cli_present("PASSWORD"); if (iss == CV~ SKEY009.B2cX'[LANE.WORK.SKEY.INSTALL_B]SKEY_CALC.C;1x-'LI$_NEGATED) { char *p; r->sequence++; p = Challenge(r); printf("%s\n\n",p); free(p);3 iss = read_pwd("Password: ", &password, 0);% if (VMS_ERR(iss)) return iss; fprintf(stderr,"\r");5 iss = AnyToKey(r->key,password,r->algorithm);* if (VMS_ERR(iss)) lib$signal(iss); } else {" if (iss == CLI$_PRESENT) {5 iss = cli_getvalue("PASSWORD",&password); } else {7 iss = read_pwd("Password: ", &password, 0);*) if (VMS_ERR(iss)) return iss;*! fprintf(stderr,"\r"); }  cli_unquote(password); CheckPassword(password);? iss = KeyProc(r->algorithm, r->key, r->seed, password); * if (VMS_ERR(iss)) lib$signal(iss);, memset(password,0,strlen(password)); free(password); , for (j = 1; j <= r->sequence; j++) {* HashKey(r->key, r->algorithm); }  }  if (!dbfile) set_sysprv(); iss = DB_Open(dbfile, &D); if (!dbfile) reset_sysprv();! if (VMS_ERR(iss)) return iss;  iss = DB_Put(D, r);  DB_Close(D); if (opt_log) { char *p;N printf("S/Key initialized for %s, next challenge is:\n",r->principal); p = Challenge(r);Y r->sequence++; printf("%s\n",p);  free(p); }  return iss; } intc PowerUser()8{ int iss; pPrivs p;  p = AuthPrivs(); iss = p->prv$v_security; free(p); return iss;*}*int/ SuperUser()<{i int iss; pPrivs p;i p = AuthPrivs(); iss = p->prv$v_sysprv; free(p); return iss;}cint do_clear(){g int iss, opt_log;. char *user, *dbfile = 0; pREC r;t pDB D;* if (VMS_OK(cli_present("DATABASE"))) {/ iss = cli_getvalue("DATABASE",&dbfile);e* if (VMS_ERR(iss)) lib$signal(iss); }y log_open(dbfile != 0);, user = GetUser("P1", &iss, dbfile == 0);< if (VMS_ERR(iss) && iss != SKEY$_NOUAF) lib$signal(iss);* opt_log = VMS_OK(cli_present("LOG"));> Log(L_INFO,"Clearing S/Key record for user \"!AZ\"",user); if (!dbfile) set_sysprv(); iss = DB_Open(dbfile, &D); if (!dbfile) reset_sysprv();0 r = DB_Fetch(D, user,TimeoutLNM(dbfile!=0));! if (r && VMS_OK(r->status)) {e iss = DB_Delete(D, r); }o DB_Close(D); free(user);E if (!r) return SS$_INSFMEM;E- if (VMS_ERR(r->status)) return r->status;  memset(r,0,sizeof(REC)); free(r); return SS$_NORMAL;}dintA do_test()G{E int iss; char *user, *dbfile = 0; pREC r = 0;  pDB D = 0;* if (VMS_OK(cli_present("DATABASE"))) {/ iss = cli_getvalue("DATABASE",&dbfile);i% if (VMS_ERR(iss)) return iss;m }s log_open(dbfile != 0);, user = GetUser("P1", &iss, dbfile == 0);. Log(L_BABBLE,"do_test for user !AZ",user);7 if (VMS_ERR(iss) && iss != SKEY$_NOUAF) return iss;( if (!dbfile) set_sysprv(); iss = DB_Open(dbfile, &D); if (!dbfile) reset_sysprv(); if (dbfile) free(dbfile);t! if (VMS_ERR(iss)) goto error;u1 r = DB_Fetch(D, user, TimeoutLNM(dbfile!=0));  free(user);f iss = SS$_INSFMEM; if (!r) goto error;i iss = r->status;! if (VMS_ERR(iss)) goto error;;, if (VMS_OK(cli_present("DICTIONARY"))) {! char *dictfile, *outfile;E pDictionary d;$ int ndup, nbad, nok, nblank; DB_Close(D); D = 0;3 iss = cli_getvalue("DICTIONARY",&dictfile);  if (!dictfile)- dictfile = trnlnm("SKEY_DICT",0);  if (!dictfile)# dictfile = "SKEY.DICT";MB Log(L_BABBLE,"do_test, checking dictionary !AZ",dictfile);) d = new_Dictionary(r->algorithm); H iss = read_Dictionary(d, dictfile, &ndup, &nbad, &nok, &nblank);> if (iss != SKEY$_PARTDICT && VMS_ERR(iss)) return iss;x printf("Dictionary file contained %d useable words, %d unuseable words, %d duplicate words\n", nok, nbad, ndup); if (nblank == 0) {N printf("Dictionary coverage complete: dictionary okay to use.\n"); } else {b printf("Dictionary coverage incomplete: %d indices have no word contents.\n", nblank); }_, if (VMS_OK(cli_present("OUTPUT"))) { FILE *f; pDictEntry e;p" int j, iss, opt_multi;2 iss = cli_getvalue("OUTPUT",&outfile);) if (VMS_ERR(iss)) return iss; * iss = cli_present("MULTIPLE");. opt_multi = (iss != CLI$_NEGATED);# f = fopen(outfile,"w");u& if (!f) return vaxc$errno;( for (j = 0; j < 2048; j++) {! e = d->hentry[j]; if (opt_multi) { while (e) {f5 fprintf(f, "%s\n", e->entry);o$ e = e->next; } } else if (e) {=1  fprintf(f, "%s\n", e->entry); }f }  fclose(f); }s } else { char *p;( char *password, key[8], key2[8]; p = Challenge(r);= printf("%s\n\n",p);f free(p);G iss = read_pwd("Password: ", &password, TimeoutLNM(dbfile!=0));l4 if (iss == SS$_TIMEOUT) iss = SKEY$_TIMEOUT;% if (VMS_ERR(iss)) goto error;c fprintf(stderr,"\n");2 iss = AnyToKey(key,password,r->algorithm);, memset(password,0,strlen(password)); free(password); % if (VMS_ERR(iss)) goto error;  memcpy(key2,key,8); $ HashKey(key2, r->algorithm);* if (strncmp(key2,r->key,8) == 0) {" memcpy(r->key, key,8); iss = DB_Put(D, r);") if (VMS_ERR(iss)) goto error;e) Log(L_BABBLE,"test success");l' printf("Access granted\n");A iss = SKEY$_OKAUTH;c } else {) Log(L_BABBLE,"test failure"); & printf("Access denied\n"); iss = SKEY$_NOAUTH;i }; memset(key,0,8); memset(key2,0,8);  } error: if (D) DB_Close(D); if (r) { memset(r,0,sizeof(REC)); free(r); }; return iss; }nint{ do_profile(){( int iss;! int en_def, en_skey, en_norm; $ int dis_def, dis_skey, dis_norm; char *user, *dbfile = 0; pREC r = 0;f pDB D = 0; * if (VMS_OK(cli_present("DATABASE"))) {/ iss = cli_getvalue("DATABASE",&dbfile); % if (VMS_ERR(iss)) return iss;  }( log_open(dbfile != 0);, user = GetUser("P1", &iss, dbfile == 0);0 Log(L_BABBLE,"do_enable for user !AZ",user);7 if (VMS_ERR(iss) && iss != SKEY$_NOUAF) return iss;h4 en_def = VMS_OK(cli_present("ENABLE.DEFAULT"));1 en_skey = VMS_OK(cli_present("ENABLE.SKEY"));i3 en_norm = VMS_OK(cli_present("ENABLE.NORMAL"));t6 dis_def = VMS_OK(cli_present("DISABLE.DEFAULT"));3 dis_skey = VMS_OK(cli_present("DISABLE.SKEY"));l5 dis_norm = VMS_OK(cli_present("DISABLE.NORMAL")); if (!dbfile) set_sysprv(); iss = DB_Open(dbfile, &D); if (!dbfile) reset_sysprv();! if (VMS_ERR(iss)) return iss; 1 r = DB_Fetch(D, user, TimeoutLNM(dbfile!=0));c free(user);) iss = SS$_INSFMEM; if (!r) goto error;l iss = r->status;! if (VMS_ERR(iss)) goto error; , if (en_def ) r->flags.skey_default = 1;, if (en_skey ) r->flags.skey_allow = 1;, if (en_norm ) r->flags.norm_allow = 1;, if (dis_def ) r->flags.skey_default = 0;, if (dis_skey) r->flags.skey_allow = 0;, if (dis_norm) r->flags.norm_allow = 0; iss = DB_Put(D, r);(error: if (D) DB_Close(D);_ if (r) {" memset(r, 0, sizeof(REC)); free(r); }e return iss;} $#define tf(b) (b? "True" : "False")int1 do_show()f{ int iss;) char *user = 0, buf[20], *dbfile = 0;; pREC r = 0;( pDB D = 0; * if (VMS_OK(cli_present("DATABASE"))) {/ iss = cli_getvalue("DATABASE",&dbfile);;% if (VMS_ERR(iss)) return iss;O } log_open(dbfile != 0);, user = GetUser("P1", &iss, dbfile == 0);. Log(L_BABBLE,"do_show for user !AZ",user);7 if (VMS_ERR(iss) && iss != SKEY$_NOUAF) return iss; if (!dbfile) set_sysprv(); iss = DB_Open(dbfile, &D); if (!dbfile) reset_sysprv();! if (VMS_ERR(iss)) goto error;$1 r = DB_Fetch(D, user, TimeoutLNM(dbfile!=0));  DB_Close(D); D = 0; iss = SS$_INSFMEM; if (!r) goto error;e iss = r->status;! if (VMS_ERR(iss)) goto error;% printf("S/Key database entry\n");.5 printf("Principal : %s\n",user); < printf("Sequence number : %d\n",r->sequence);8 printf("Seed : %s\n",r->seed);L printf("Algorithm : %s\n",AlgorithmName(r->algorithm));J printf("Use S/Key by default : %s\n",tf(r->flags.skey_default));J printf("Allow S/Key auth override : %s\n",tf(r->flags.skey_allow) );J printf("Allow Normal auth override : %s\n",tf(r->flags.norm_allow) ); {s word timlen; pSTR d_time; d_time = new_STRn(64);9 iss = sys$asctim(&timlen, d_time, r->lastmod, 0);r if (VMS_OK(iss)) {( pSTRPTR(d_time)[timlen] = 0;H printf("Last modified : %s\n",pSTRPTR(d_time)); }s destroy_STR(d_time); }  iss = SS$_NORMAL;oerror: if (user) free(user);  if (D) DB_Close(D);i if (r) {" memset(r, 0, sizeof(REC)); free(r); }a return iss; }c static char *2GetUser(char *cli_symbol, int *status, int secure){p int iss; char *user, *duser;i pSTR d_user; longword uic;w: ItemList3 itemlist[] = {$ITEM3(UAI$_UIC), NULL_ITEM3};* if (VMS_OK(cli_present(cli_symbol))) {. iss = cli_getvalue(cli_symbol, &user);+ if (VMS_OK(iss) && user && *user) { ) if (secure && !PowerUser()) {l# duser = Username();s. if (strcmp(user,duser) != 0) {8 if (status) *status = SKEY$_NOSECUR;! return duser;  }n }; } else { user = Username(); } } else { user = Username(); }  if (!secure) {) if (status) *status = SS$_NORMAL;s return user; } d_user = new_STR(user);% itemlist[0].length = sizeof(uic);n( itemlist[0].address = (char *) &uic;6 iss = sys$getuai(0, 0, d_user, itemlist, 0, 0, 0);+ if (iss == RMS$_RNF) iss = SKEY$_NOUAF; if (status) *status = iss; destroy_STR(d_user); return user;} static void; set_sysprv(){K int iss; Privs P; P.prv$l_l1_bits = 0; P.prv$l_l2_bits = 0; P.prv$v_sysprv = 1;i iss = SetPrivs(&P); & if (VMS_ERR(iss)) lib$signal(iss);}r static voidfreset_sysprv(){( int iss; Privs P; P.prv$l_l1_bits = 0; P.prv$l_l2_bits = 0; P.prv$v_sysprv = 1;_ iss = ResetPrivs(&P);o& if (VMS_ERR(iss)) lib$signal(iss);}sintr do_version(){B* printf("This is %s\n",skey_version());G printf("Compiled with %s, %s\n",skey_ccversion(), skey_created());V, printf("on VMS %s\n",skey_vmsversion()); return SS$_NORMAL;}e static intTimeoutLNM(int usermode){S int i;f char *s; if (!usermode) {5 s = trnlnm_exec("SKEY_TIMEOUT","LNM$SYSTEM");u } else {2 s = trnlnm("SKEY_TIMEOUT","LNM$FILE_DEV"); }r# if (!s) return DEFAULT_TIMEOUT;  i = atoi(s);4 if (i <= 0 || i > 64000) return DEFAULT_TIMEOUT; free(s); return i;f}) static voidMlog_open(int usermode){ char *p; if (!usermode) {6 p = trnlnm_exec("SKEY_LOG_FILE","LNM$SYSTEM"); if (p) {$ open_logfile(p, NEWLOG); free(p); } else {2 open_logfile(DEFAULT_LOGFILE, NEWLOG); }7 p = trnlnm_exec("SKEY_LOG_LEVEL","LNM$SYSTEM");f if (p) { set_loglev(atoi(p)); free(p); } else {' set_loglev(DEFAULT_LOGLEV);F }f } else {3 p = trnlnm("SKEY_LOG_FILE","LNM$FILE_DEV");o if (p) {$ open_logfile(p, NEWLOG); free(p); } else {7 open_logfile(DEFAULT_USER_LOGFILE, NEWLOG);; } 4 p = trnlnm("SKEY_LOG_LEVEL","LNM$FILE_DEV"); if (p) { set_loglev(atoi(p)); free(p); } else {' set_loglev(DEFAULT_LOGLEV); }i }Y+ Log(L_BABBLE,"skey_calc run at !%D",0);e}n(*[LANE.WORK.SKEY.INSTALL_B]SKEY_CLD.CLD;1+,A. / 4U R<-cX0123KPWO56o[o7 [o89GHJdefine verb SKEY_CALC routine do_keygen* qualifier VERSION, syntax=SKEY_VERSIONB parameter P1, prompt="Sequence", value (required,type=$number)E parameter P2, prompt="Seed", value (required,type=$quoted_string)C qualifier COUNT, nonnegatable, value (default="1",type=$number)> qualifier OUTPUT, value (type=$outfile,default="SKEY.LIS")A qualifier PASSWORD, nonnegatable, value (type=$quoted_string)> qualifier ALGORITHM, value (required, type=SKEY_ALGORITHM)< qualifier DICTIONARY, nonnegatable, value (type=$infile) qualifier DELETE qualifier PRINT> qualifier QUEUE, nonnegatable, value (default="SYS$PRINT") qualifier HEXADECIMAL$ disallow (DELETE and not PRINT)# disallow (QUEUE and not PRINT)# disallow (PRINT and not COUNT)0 qualifier INITIALIZE, syntax=SKEY_INITIALIZE& qualifier CLEAR, syntax=SKEY_CLEAR$ qualifier TEST, syntax=SKEY_TEST$ qualifier SHOW, syntax=SKEY_SHOW* qualifier PROFILE, syntax=SKEY_PROFILEC disallow any2 (INITIALIZE, CLEAR, TEST, SHOW, PROFILE, VERSION)0 disallow any2 (ALGORITHM.MD4, ALGORITHM.MD5)define syntax SKEY_INITIALIZE routine do_initialize parameter P1, prompt="User"$ qualifier SEQUENCE, nonnegatable value (type=$number); qualifier PASSWORD, default value (type=$quoted_string) qualifier SEED, nonnegatable value (required)> qualifier ALGORITHM, value (required, type=SKEY_ALGORITHM)E qualifier DATABASE, nonnegatable, value (required, type=$outfile) qualifier NEW, nonnegatable qualifier LOG qualifier CLEAR qualifier TEST qualifier SHOW$ disallow (CLEAR or TEST or SHOW)# disallow (NEW and not DATABASE)0 disallow any2 (ALGORITHM.MD4, ALGORITHM.MD5)define syntax SKEY_CLEAR routine do_clear parameter P1, Prompt="User" qualifier LOGE qualifier DATABASE, nonnegatable, value (required, type=$outfile) qualifier TEST qualifier SHOW disallow (TEST or SHOW)define syntax SKEY_TEST routine do_test parameter P1, prompt="User"< qualifier DICTIONARY, nonnegatable, value (type=$infile)? qualifier OUTPUT, value (type=$outfile,default="SKEY.DICT") qualifier MULTIPLE, defaultE qualifier DATABASE, nonnegatable, value (required, type=$outfile) qualifier SHOW disallow SHOW& disallow OUTPUT and not DICTIONARY$ disallow MULTIPLE and not OUTPUT$ disallow DATABASE and DICTIONARYdefine syntax SKEY_SHOW routine do_show parameter p1, prompt="User"E qualifier DATABASE, nonnegatable, value (required, type=$outfile)define syntax SKEY_PROFILE routine do_profile parameter p1, prompt="User"T qualifier ENABLE, nonnegatable, value (required, list, type=SKEY_ENABLE_OPTIONS)U qualifier DISABLE, nonnegatable, value (required, list, type=SKEY_ENABLE_OPTIONS)E qualifier DATABASE, nonnegatable, value (required, type=$outfile)1 disallow (ENABLE.DEFAULT and DISABLE.DEFAULT). disallow (ENABLE.SKEY and DISABLE.SKEY)0 disallow (ENABLE.NORMAL and DISABLE.NORMAL)define syntax SKEY_VERSION routine do_version noparametersdefine type SKEY_ALGORITHM keyword MD4 keyword MD5, defaultdefine type SKEY_ENABLE_OPTIONS keyword DEFAULT keyword NORMAL keyword SKEY&*[LANE.WORK.SKEY.INSTALL_B]SKEY_CLI.C;1+,3CU. / 4d <-cX0123KPWO56&x*[o7=6[o89GHJJ/************************************************************************\J* SKEY_CLI.C *J* *J* S/Key interface to CLI routines *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include #include "skey_cli.h"static char *last_verbname = 0;/*+ * "table" is a pointer to the internal CLD: * "name" is a text string containing the name of the verb */longword!cli_init(char *table, char *name){B struct dsc$descriptor cmd = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0}; $DESCRIPTOR(verb,"$VERB"); $DESCRIPTOR(line,"$LINE"); int iss, i;= if (!last_verbname || strcmp(last_verbname, name) != 0) {/ if (last_verbname) free(last_verbname);/ last_verbname = malloc(strlen(name)+1);/ if (!last_verbname) return SS$_INSFMEM;$ strcpy(last_verbname, name); } else {( iss = cli$get_value(&verb,&cmd);& if (VMS_ERR(iss)) return(iss);D if (strncmp(cmd.dsc$a_pointer,name,cmd.dsc$w_length) == 0) { str$free1_dx(&cmd); return SS$_NORMAL; } str$free1_dx(&cmd); }$ iss = cli$get_value(&line,&cmd);" if (VMS_ERR(iss)) return(iss);8 /* assumes that cli verb is longer than "bare" verb */) for (i = 0; (i < cmd.dsc$w_length) &&( (cmd.dsc$a_pointer[i] != ' ') &&+ (cmd.dsc$a_pointer[i] != '/'); ++i)B cmd.dsc$a_pointer[i] = (i < strlen(name)) ? name[i] : ' ';d iss = cli$dcl_parse(&cmd,table,&lib$get_input,&lib$get_input); /* initialize the parse tables */ str$free1_dx(&cmd); return iss;}longwordcli_dispatch(){ return cli$dispatch(0);}longwordcli_present(char *s){ int iss;@ struct dsc$descriptor d = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; d.dsc$w_length = strlen(s); d.dsc$a_pointer = s; iss = cli$present(&d); return iss;}longwordcli_getvalue(char *s, char **v){A struct dsc$descriptor ds = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};A struct dsc$descriptor dv = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0}; int iss; ds.dsc$a_pointer = s; ds.dsc$w_length = strlen(s);" iss = cli$get_value(&ds, &dv); if (VMS_OK(iss)) {' *v = malloc(dv.dsc$w_length+1); if (*v) {; strncpy(*v, dv.dsc$a_pointer, dv.dsc$w_length);) *(*v+dv.dsc$w_length) = '\0'; } str$free1_dx(&dv); } else { *v = 0; } return iss;}voidcli_unquote(char *s){ char c, *p = s;" if (!s || *s++ != '"') return; while (c = *s++) { if (c == '"') {# if (*s++ != '"') break; } *p++ = c; } *p = '\0';}&*[LANE.WORK.SKEY.INSTALL_B]SKEY_CLI.H;1+,C{. / 4+ <-cX0123KPWO56>[o7J[o89GHJ#ifndef __SKEY_CLI_H#define __SKEY_CLI_H 1#include "vms_types.h"+longword cli_init(char *table, char *name);longword cli_dispatch();longword cli_present(char *s);)longword cli_getvalue(char *s, char **v);void cli_unquote(char *s);#endif(*[LANE.WORK.SKEY.INSTALL_B]SKEY_CRYPT.C;1+,D=.-/ 4S-&"<-cX0123KPWO'56TS[o71'a[o89GHJ&J/************************************************************************\I * SKEY_CRYPT.C *I * *I * interface between skey and crypto routines *I * including alternate dictionary routines *I * *I * External routines: *I * int KeyProc(Algorithm a, char *result, char *seed, char *passwd) *I * int HashKey(char *x, Algorithm a) *I * char * KeyToEnglish(char *out, char *c) *I * int EnglishToKey(char *out, char *e) *I * char * SeedGenerate() *I * void KeyToHex(char *hex, char *key) *I * int HexToKey(char *key, char *hex) *I * int AltToKey(char *out, char *e, Algorithm a) *I * int AnyToKey(char *key, char *input, Algorithm a) *I * pDictionary new_Dictionary(Algorithm a) *I * int addentry_Dictionary(pDictionary d, char *entry) *I * int read_Dictionary(pDictionary d, char *file, int *dup, *I * int *bad, int *ok, int *blank) *I * int KeyToAlt(char *out, char *key, pDictionary d) *I * char * AlgorithmName(Algorithm a) *I * char * Challenge(pREC r) *I * *I * Internal routines: *I * *I * void Hack7(char *s) *I * int wsrch(char *w, int low, int high) *I * void insert(char *s, int x, int start, int length) *I * unsigned long extract(char *s, int start, int length) *I * int hex2n(char c) *I * *I * *I * *J\************************************************************************/#include #include #include #include #include #include #include #include #include #include #include "skey.h"#include "skey_crypt.h"#include "util.h"#include "skey_msg.h"#include "skey_dict.h"#include "global.h"#include "md4.h"#include "md5.h"7static int wsrch(char *w, int low, int high);Cstatic void insert(char *s, int x, int start, int length);=static unsigned long extract(char *s, int start, int length);$static void Hack7(char *s);/* Crunch a key:D * concatenate the seed and the password, run through MD4 or MD5 andC * collapse to 64 bits. This is defined as the user's starting key. */int<KeyProc(Algorithm a, char *result, char *seed, char *passwd){ char *buf; MD5_CTX md5; MD4_CTX md4; unsigned long results[4]; unsigned int buflen; int j;+ buflen = strlen(seed) + strlen(passwd); buf = malloc(buflen + 1);! if (!buf) return SS$_INSFMEM; strcpy(buf, seed); lc(buf); strcat(buf, passwd); Hack7(buf);' /* Crunch the key through MD[45] */ switch (a) { case MD4: MD4Init(&md4);; MD4Update(&md4, (unsigned char *) buf, buflen);6 MD4Final((unsigned char *) results, &md4); break; case MD5: MD5Init(&md5);; MD5Update(&md5, (unsigned char *) buf, buflen);6 MD5Final((unsigned char *) results, &md5); break; default:! return SKEY$_UNALGOR; } memset(buf,0,buflen); free(buf); results[0] ^= results[2]; results[1] ^= results[3];( memcpy(result, (char *) results, 8); return SS$_NORMAL;} static voidHack7(char *s){ while (*s) { *s = 0x7f & (*s); s++; }}/* * The one-way function f(x).. * Takes 8 bytes and returns 8 bytes in place. */intHashKey(char *x, Algorithm a){ MD5_CTX md5; MD4_CTX md4; unsigned long results[4]; switch (a) { case MD4: MD4Init(&md4);4 MD4Update(&md4, (unsigned char *) x, 8);6 MD4Final((unsigned char *) results, &md4); break; case MD5: MD5Init(&md5);4 MD5Update(&md5, (unsigned char *) x, 8);6 MD5Final((unsigned char *) results, &md5); break; default:! return SKEY$_UNALGOR; } /* Fold 128 to 64 bits */ results[0] ^= results[2]; results[1] ^= results[3];? /* Only works on byte-addressed little-endian machines!! */# memcpy(x, (char *) results, 8); return SS$_NORMAL;}9/* Encode 8 bytes in 'c' as a string of English words. */char * KeyToEnglish(char *out, char *c){8 char cp[9]; /* add in room for the parity 2 bits */ int p, i; out[0] = '\0'; memcpy(cp, c, 8); /* compute parity */& for (p = 0, i = 0; i < 64; i += 2) p += extract(cp, i, 2); cp[8] = (char) p << 6;0 strncat(out, &Wp[extract(cp, 0, 11)][0], 4); strcat(out, " ");1 strncat(out, &Wp[extract(cp, 11, 11)][0], 4); strcat(out, " ");1 strncat(out, &Wp[extract(cp, 22, 11)][0], 4); strcat(out, " ");1 strncat(out, &Wp[extract(cp, 33, 11)][0], 4); strcat(out, " ");1 strncat(out, &Wp[extract(cp, 44, 11)][0], 4);2B1~ FREEWARE.SAVEM0[SKEY009]SKEY009.B;12~~Hp| strcat(out, " ");1 strncat(out, &Wp[extract(cp, 55, 11)][0], 4); return (out);}/* convert English to binary7 * returns SS$_NORMAL - all good words and parity is OK9 * SKEY$_BADENC word not in data base, or >4 char4 * SKEY$_PARITY words OK but parity is wrong */int EnglishToKey(char *out, char *e){! char *word, *c, *input, b[9];8 int i, p, v, l, low, high, len, rval = SKEY$_BADENC;! if (!e) return SKEY$_VOIDPWD; if ((len = strlen(e)) > 64) len = 64; input = malloc(len+1);# if (!input) return SS$_INSFMEM; strncpy(input, e, len); input[len] = 0; memset(b, 0, sizeof(b)); memset(out, 0, 8);? for (i = 0, p = 0, word = c = input; i < 6; i++, p += 11) {' while (*c && !isalpha(*c)) c++; word = c; while (*c) { if (islower(*c))! *c = toupper(*c); if (!isalpha(*c)) break; c++; }( if ((!*c) && (i != 5)) goto err; *c = 0; c++; if (c == word) goto err; l = strlen(word);% if (l > 4 || l < 1) goto err; if (l < 4) { low = 0; high = 570; } else { low = 571; high = 2047; }/ if ((v = wsrch(word, low, high)) < 0) { rval = SKEY$_BADENC; goto err; } insert(b, v, p, 11); }- /* now check the parity of what we got */& for (p = 0, i = 0; i < 64; i += 2) p += extract(b, i, 2);' if ((p & 3) != extract(b, 64, 2)) { rval = SKEY$_PARITY; goto err; } memcpy(out, b, 8); memset(b, 0, 8); rval = SS$_NORMAL;err: memset(input,0,len); free(input); return rval;}5/* Internal subroutines for word encoding/decoding *//* Dictionary binary search */ static int!wsrch(char *w, int low, int high){ int i, j; for (;;) { i = (low + high) / 2;( if ((j = strncmp(w, Wp[i], 4)) == 0) return i; /* Found it */ if (high == low + 1) {5 /* Avoid effects of integer truncation in /2 */' if (strncmp(w, Wp[high], 4) == 0) return high; else return -1; } if (low >= high): return -1; /* I don't *think* this can happen... */ if (j < 0)) high = i; /* Search lower half */ else& low = i; /* Search upper half */ }} static void-insert(char *s, int x, int start, int length){ unsigned char cl; unsigned char cc; unsigned char cr; unsigned long y; int shift; assert(length <= 11); assert(start >= 0); assert(length >= 0); assert(start + length <= 66);- shift = ((8 - ((start + length) % 8)) % 8); y = (long) x << shift; cl = (y >> 16) & 0xff; cc = (y >> 8) & 0xff; cr = y & 0xff; if (shift + length > 16) { s[start / 8] |= cl;* s[start / 8 + 1] |= cc;* s[start / 8 + 2] |= cr;  } else if (shift + length > 8) {  s[start / 8] |= cc;  s[start / 8 + 1] |= cr; } else { s[start / 8] |= cr;f }w} M/* Extract 'length' bits from the char array 's' starting with bit 'start' */tstatic unsigned long'extract(char *s, int start, int length) {  unsigned char cl;  unsigned char cc;  unsigned char cr;r unsigned long x; assert(length @I~ SKEY009.BD=cX([LANE.WORK.SKEY.INSTALL_B]SKEY_CRYPT.C;1S-&<= 16);  assert(start >= 0);t assert(length >= 0); cl = s[start / 8]; cc = s[start / 8 + 1]; cr = s[start / 8 + 2];( x = ((long) (cl << 8 | cc) << 8 | cr);) x = x >> (24 - (length + (start % 8)));*& x = (x & (0xffff >> (16 - length))); return (x);K}cchar *SeedGenerate(){  MD5_CTX md5; time_t now;e char *r, *p, buf[100]; char results[8]; r = malloc(7);$ if (!r) lib$signal(SS$_INSFMEM); time(&now); sprintf(buf,"%ld",clock());y strcat(buf,ctime(&now)); p = Username();i strcat(buf,p); free(p); p = PID(); strcat(buf,p); free(p); MD5Init(&md5);7 MD5Update(&md5, (unsigned char *)buf, strlen(buf)); . MD5Final((unsigned char *) results, &md5);+ r[0] = extract(results, 0,13)%26 + 'a';n+ r[1] = extract(results,13,13)%26 + 'a'; + r[2] = extract(results,26,13)%26 + 'a';i+ r[3] = extract(results,39,13)%10 + '0'; + r[4] = extract(results,52,13)%10 + '0';+ r[5] = extract(results,65,13)%10 + '0';, r[6] = 0; return r;} voidKeyToHex(char *hex, char *key){ int j; char bb[5];  hex[0] = 0;( for (j = 0; j<8; j++) { + sprintf(bb,"%02X", key[j] & 0x0FF);  strcat(hex,bb);  } } static int hex2n(char c)e{ 2 if (c >= 'a' && c <= 'f') return c - 'a' + 10;2 if (c >= 'A' && c <= 'F') return c - 'A' + 10;- if (c >= '0' && c <= '9') return c - '0';r return -1;} int HexToKey(char *key, char *hex){  int x, j=0;t char c, temp[16];  while (c=*hex++) {" if ((x = hex2n(c)) >= 0) {- if (j == 16) return SKEY$_BADENC;e temp[j++] = x;! } else if (!isspace(c)) {* return SKEY$_BADENC; }  } $ if (j < 16) return SKEY$_BADENC; for (j = 0; j < 16; j++) { if (j & 1) {! *key++ = x | temp[j];  } else { x = temp[j]<<4; }  }  memset(temp,0,16); return SS$_NORMAL;}*4/* convert Alternative dictionary encoding to binary7 * returns SS$_NORMAL - all good words and parity is OKb9 * SKEY$_BADENC word not in data base, or >4 chars4 * SKEY$_PARITY words OK but parity is wrong */eintn)AltToKey(char *out, char *e, Algorithm a)o{n! char *word, *c, *input, b[9];u> int i, j, x, p, v, l, low, high, len, rval = SKEY$_BADENC; MD5_CTX md5; MD4_CTX md4; char hash[16];! if (!e) return SKEY$_VOIDPWD;i if ((len = strlen(e)) > 64), len = 64;c input = malloc(len+1);# if (!input) return SS$_INSFMEM;t strncpy(input, e, len);s input[len] = 0;t memset(b, 0, sizeof(b)); memset(out, 0, 8);? for (i = 0, p = 0, word = c = input; i < 6; i++, p += 11) { ' while (*c && !isalpha(*c)) c++;i word = c;e while (*c) { if (!isalpha(*c))c break; c++; }*( if ((!*c) && (i != 5)) goto err; *c++ = 0;e if (c == word) goto err; l = strlen(word);n if (l < 4) { low = 0; high = 570;  } else { low = 571; high = 2047; }c8 if ((v = wsrch(word, low, high)) >= 0) goto err; for (j = 0; j= 0) goto err;e switch (a) { case MD5:s MD5Init(&md5);; MD5Update(&md5, (unsigned char *) word, l); 7 MD5Final((unsigned char *) hash, &md5);  break; case MD4: MD4Init(&md4);; MD4Update(&md4, (unsigned char *) word, l);t7 MD4Final((unsigned char *) hash, &md4);u break; default:% rval = SKEY$_UNALGOR; goto err; }i v = extract(hash,0,11);  insert(b, v, p, 11); } - /* now check the parity of what we got */n& for (p = 0, i = 0; i < 64; i += 2) p += extract(b, i, 2);' if ((p & 3) != extract(b, 64, 2)) {D rval = SKEY$_PARITY; goto err;e }] memcpy(out, b, 8); memset(b, 0, 8); rval = SS$_NORMAL;err: memset(input,0,len); free(input); return rval;}nintc-AnyToKey(char *key, char *input, Algorithm a) { int iss;# iss = EnglishToKey(key, input);D if (iss == SKEY$_BADENC) {# iss = HexToKey(key, input);d" if (iss == SKEY$_BADENC) {* iss = AltToKey(key, input, a); }A } return iss;l}2 pDictionary new_Dictionary(Algorithm a){ int j; pDictionary d;# d = malloc(sizeof(Dictionary));e$ if (!d) lib$signal(SS$_INSFMEM); d->algorithm = a; for (j = 0; j < 2048; j++) { d->hentry[j] = 0;i }n return d;}int/addentry_Dictionary(pDictionary d, char *entry)[{  MD4_CTX md4; MD5_CTX md5; char *p, hash[16]; int j, l, low, high, x, v; pDictEntry e;c l = strlen(entry);8 if (l > MAX_ALT_WORD || l == 0) return SKEY$_INVALT; if (l < 4) { low = 0; high = 570;e } else { low = 571; high = 2047; }(@ if ((v = wsrch(entry, low, high)) >= 0) return SKEY$_INVALT; for (j = 0; j= 0) SKEY$_INVALT;  switch (d->algorithm) {( case MD5:, MD5Init(&md5);8 MD5Update(&md5, (unsigned char *) entry, l);3 MD5Final((unsigned char *) hash, &md5);h break; case MD4:  MD4Init(&md4);8 MD4Update(&md4, (unsigned char *) entry, l);3 MD4Final((unsigned char *) hash, &md4);o break; default:! return SKEY$_UNALGOR;  }  v = extract(hash,0,11);o e = d->hentry[v];$ while (e) {f= if (strcmp(e->entry,entry) == 0) return SKEY$_DUPALT; e = e->next; }n" e = malloc(sizeof(DictEntry)); e->next = d->hentry[v];t strcpy(e->entry, entry); d->hentry[v] = e;s return SS$_NORMAL;}s#define MAXLINE 1024int=Sread_Dictionary(pDictionary d, char *file, int *dup, int *bad, int *ok, int *blank)c{c FILE *f; char buf[MAXLINE+1], *p, *q; DictEntry E;( int j, ndup, nbad, nok, nblank, iss; if (!d) return SS$_ACCVIO;! if (!file) return SS$_ACCVIO;  f = fopen(file,"r"); if (!f) return vaxc$errno; buf[MAXLINE+1] = 0; ( memset(E.entry, 0, sizeof(E.entry)); ndup = nbad = nok = 0;$ while (fgets(buf, MAXLINE, f)) { p = buf; while (*p) {+ while (*p && !isalpha(*p)) p++;e if (!*p) break;  q = p;* while (*q && isalpha(*q)) q++; if (q == p) break;* if (q - p < sizeof(E.entry)) {) strncpy(E.entry, p, q-p);;! E.entry[q-p] = 0;r6 iss = addentry_Dictionary(d, E.entry);( if (iss == SKEY$_DUPALT) ndup++; - else if (iss == SKEY$_INVALT)o nbad++;t& else if (VMS_ERR(iss))# return iss;t else nok++; }  p = q; }e }* fclose(f); nblank = 0;/ for (j = 0; j < 2048; j++) {( if (d->hentry[j] == 0) nblank++; } if (dup) *dup = ndup;f if (bad) *bad = nbad;  if (ok) *ok = nok; if (blank) *blank = nblank;{5 return nblank == 0 ? SS$_NORMAL : SKEY$_PARTDICT;} int(-KeyToAlt(char *out, char *key, pDictionary d)n{g8 char cp[9]; /* add in room for the parity 2 bits */ int p, i, j, v;n pDictEntry e;h out[0] = '\0'; memcpy(cp, key, 8);  /* compute parity */& for (p = 0, i = 0; i < 64; i += 2) p += extract(cp, i, 2); cp[8] = (char) p << 6; for (i = 0; i < 6; i++) {" v = extract(cp, i*11, 11); e = d->hentry[v]; & if (!e) return SKEY$_PARTDICT;+ for (j = 0; j < (clock()%8); j++) {  e = e->next;% if (!e) e = d->hentry[v]; }( strcat(out, e->entry);$ if (i < 5) strcat(out, " "); }) memset(cp,0,9);> return SS$_NORMAL;}fchar *AlgorithmName(Algorithm a){t static char md4[] = "md4"; static char md5[] = "md5"; switch (a) { case MD4:  return md4;t case MD5:  return md5;r default: return 0;r } }char *Challenge(pREC r)f{  char *p, buf[100];S sprintf(buf, "otp-%s %d %s",AlgorithmName(r->algorithm),--r->sequence,r->seed);  p = malloc(strlen(buf)+1);$ if (!p) lib$signal(SS$_INSFMEM); strcpy(p,buf); memset(buf,0,sizeof(buf)); return p;)}(*[LANE.WORK.SKEY.INSTALL_B]SKEY_CRYPT.H;1+,I. / 4` <-cX0123KPWO562i[o7Hu[o89GHJ:/* skey_crypt.h crypto interface */#ifndef __SKEY_CRYPT_H#define __SKEY_CRYPT_H 1#include "skey.h"Iint KeyProc(Algorithm a, char *result, char *seed, char *passwd);*int HashKey(char *x, Algorithm a);char * SeedGenerate();-char * KeyToEnglish(char *out, char *c);-int EnglishToKey(char *out, char *e);+int HexToKey(char *key, char *hex);+void KeyToHex(char *hex, char *key);6int AltToKey(char *key, char *e, Algorithm a);6int AnyToKey(char *key, char *e, Algorithm a);(pDictionary new_Dictionary(Algorithm a);<int addentry_Dictionary(pDictionary d, char *entry);`int read_Dictionary(pDictionary d, char *file, int *dup, int *bad, int *ok, int *blank);:int KeyToAlt(char *out, char *key, pDictionary d);'char * AlgorithmName(Algorithm a);char * Challenge(pREC r);#endif%*[LANE.WORK.SKEY.INSTALL_B]SKEY_DB.C;1+,U./ 4NR<-cX0123KPWO56<[o7M[o89GHJ$J/************************************************************************\J* SKEY_DB.C *J* S/Key database access routines *J* *J* int DB_Create(char *file, pDB *pD) *J* int DB_Open(char *file, pDB *pD) *J* pREC DB_Fetch(pDB D, char *user, int timeout) *J* int DB_Put(pDB D, pREC r) *J* pREC DB_New(char *user) *J* void DB_Close(pDB D) *J* int DB_Delete(pDB D, pREC r) *J* int DB_Free(pDB D) *J* *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include #include #include #include "skey.h"#include "skey_db.h"#include "skey_log.h"#include "skey_msg.h"#include "util.h"$static void nullpad(char *s, int n);,#define DB_FILE "sys$common:[sysexe]skey.db"/*A * database records are padded to larger size to allow expansion * */#define DB_RAW_SIZE 512/#define PAD_SIZE (DB_RAW_SIZE - sizeof(REC))struct DB_RAW_RECORD { REC r; char pad[PAD_SIZE];};$typedef struct DB_RAW_RECORD DBR;$typedef struct DB_RAW_RECORD* pDBR;4static REC recbuf; /* only used for key position */intDB_Create(char *file, pDB *pD){ pDB D; int iss;! *pD = D = malloc(sizeof(DB)); if (!D) return SS$_INSFMEM; if (!file) {< D->file = trnlnm_exec("SKEY_DATABASE","LNM$SYSTEM");% if (!D->file) file = DB_FILE; } if (file) {) D->file = malloc(strlen(file)+1);) if (!D->file) return SS$_INSFMEM; strcpy(D->file, file); }0 Log(L_BABBLE,"DB_Create: file=!AZ",D->file);+ D->fab = cc$rms_fab;" D->fab.fab$b_bks = 1;N D->fab.fab$b_fac = FAB$M_DEL | FAB$M_GET | FAB$M_PUT | FAB$M_UPD;( D->fab.fab$l_fna = D->file;0 D->fab.fab$b_fns = strlen(D->file);8 D->fab.fab$b_bks = (DB_RAW_SIZE / 512) + 1;, D->fab.fab$w_mrs = DB_RAW_SIZE;* D->fab.fab$b_org = FAB$C_IDX;" D->fab.fab$b_rat = 0;* D->fab.fab$b_rfm = FAB$C_FIX;1 D->fab.fab$l_xab = (char *) &D->key;= D->fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET |< FAB$M_SHRDEL | FAB$M_SHRUPD;+ D->rab = cc$rms_rab;( D->rab.rab$l_fab = &D->fab;- D->key = cc$rms_xabkey;) D->key.xab$b_dtp = XAB$C_STG;! D->key.xab$b_ref = 0;B D->key.xab$w_pos0 = recbuf.principal - (char *)&recbuf;, D->key.xab$b_siz0 = MAX_USERNAME;7 D->key.xab$l_nxt = (char *) &D->protection;, D->protection = cc$rms_xabpro;" D->protection.xab$v_sys = 0x0;" D->protection.xab$v_own = 0x0;" D->protection.xab$v_grp = 0xF;" D->protection.xab$v_wld = 0xF; iss = sys$create(&D->fab); if (VMS_ERR(iss)) {= Log(L_BABBLE,"DB_Create: create status = 0x!XL",iss);) lib$signal(iss,D->fab.fab$l_stv); } iss = sys$connect(&D->rab); if (VMS_ERR(iss)) {> Log(L_BABBLE,"DB_Create: connect status = 0x!XL",iss);) lib$signal(iss,D->rab.rab$l_stv); } return iss;}intDB_Open(char *file, pDB *pD){ pDB D; int iss;! *pD = D = malloc(sizeof(DB)); if (!D) return SS$_INSFMEM; if (!file) {< D->file = trnlnm_exec("SKEY_DATABASE","LNM$SYSTEM");% if (!D->file) file = DB_FILE; } if (file) {) D->file = malloc(strlen(file)+1);) if (!D->file) return SS$_INSFMEM; strcpy(D->file, file); }. Log(L_BABBLE,"DB_Open: file=!AZ",D->file);$ D->fab = cc$rms_fab; D->fab.fab$b_bks = 1;G D->fab.fab$b_fac = FAB$M_DEL | FAB$M_GET | FAB$M_PUT | FAB$M_UPD;! D->fab.fab$l_fna = D->file;) D->fab.fab$b_fns = strlen(D->file);% D->fab.fab$w_mrs = DB_RAW_SIZE;# D->fab.fab$b_org = FAB$C_IDX; D->fab.fab$b_rat = 0;# D->fab.fab$b_rfm = FAB$C_FIX;* D->fab.fab$l_xab = (char *) &D->key;6 D->fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_SHRGET |5 FAB$M_SHRDEL | FAB$M_SHRUPD;$ D->rab = cc$rms_rab;! D->rab.rab$l_fab = &D->fab;% D->rab.rab$w_rsz = DB_RAW_SIZE;' D->key = cc$rms_xabkey;# D->key.xab$b_dtp = XAB$C_STG; D->key.xab$b_ref = 0;< D->key.xab$w_pos0 = recbuf.principal - (char *)&recbuf;& D->key.xab$b_siz0 = MAX_USERNAME; iss = sys$open(&D->fab); if (VMS_ERR(iss)) {/ Log(L_BABBLE,"db open status !XL",iss); return iss; } iss = sys$connect(&D->rab); if (VMS_ERR(iss)) {2 Log(L_BABBLE,"db connect status !XL",iss); } return iss;}pREC(DB_Fetch(pDB D, char *user, int timeout){ int iss; pREC r; pDBR dr;$ dr = (pDBR) malloc(sizeof(DBR));% if (!dr) lib$signal(SS$_INSFMEM); r = &dr->r;. strncpy(r->principal, user, MAX_USERNAME);$ ucn(r->principal, MAX_USERNAME);( nullpad(r->principal, MAX_USERNAME);# D->rab.rab$b_rac = RAB$C_KEY; D->rab.rab$b_krf = 0;& D->rab.rab$l_kbf = r->principal;& D->rab.rab$b_ksz = MAX_USERNAME;% D->rab.rab$l_ubf = (char *) dr;% D->rab.rab$w_usz = DB_RAW_SIZE; if (timeout > 0) {% D->rab.rab$b_tmo = timeout;3 D->rab.rab$l_rop = RAB$M_TMO | RAB$M_WAT; }! r->status = sys$get(&D->rab);B Log(L_BABBLE,"DB_Fetch('!AZ') status = 0x!XL",user,r->status);8 if (r->status == RMS$_RNF) r->status = SKEY$_NOUSER; return r;}intDB_Put(pDB D, pREC r){ int iss; pDBR dr;$ dr = (pDBR) malloc(sizeof(DBR));% if (!dr) lib$signal(SS$_INSFMEM); dr->r = *r;$ iss = sys$gettim(dr->r.lastmod);5 Log(L_BABBLE,"DB_Put gettim status = 0x!XL",iss);# D->rab.rab$b_rac = RAB$C_KEY; D->rab.rab$b_krf = 0;) D->rab.rab$l_kbf = dr->r.principal;& D->rab.rab$b_ksz = MAX_USERNAME;% D->rab.rab$l_rbf = (char *) dr;% D->rab.rab$w_rsz = DB_RAW_SIZE;# D->rab.rab$l_rop = RAB$M_UIF; iss = sys$put(&D->rab);. Log(L_BABBLE,"DB_Put status = 0x!XL",iss); r->status = iss; free(dr); return iss;}pRECDB_New(char *user){ pREC r; r = malloc(sizeof(REC));$ if (!r) lib$signal(SS$_INSFMEM);. strncpy(r->principal, user, MAX_USERNAME);$ ucn(r->principal, MAX_USERNAME);( nullpad(r->principal, MAX_USERNAME); r->status = SS$_NORMAL; r->dbversion = 1;& r->lastmod[0] = r->lastmod[1] = 0; r->sequence = 0;% r->algorithm = DEFAULT_ALGORITHM;J r->flags.skey_default = r->flags.skey_allow = r->flags.norm_allow = 1; memset(r->key,0,8);! memset(r->seed, 0, MAX_SEED); return r;}voidDB_Close(pDB D){ sys$disconnect(&D->rab); sys$close(&D->fab); free(D->file); free(D);} static voidnullpad(char *s, int n){ int j, state = 0; for (j = 0; j < n; j++) { if (state) *s++ = 0; else state = (*s++ == 0); }}intDB_Delete(pDB D, pREC r){ int iss; pDBR dr;$ dr = (pDBR) malloc(sizeof(DBR));% if (!dr) lib$signal(SS$_INSFMEM); dr->r = *r;# D->rab.rab$b_rac = RAB$C_KEY; D->rab.rab$b_krf = 0;) D->rab.rab$l_kbf = dr->r.principal;& D->rab.rab$b_ksz = MAX_USERNAME;% D->rab.rab$l_rbf = (char *) dr;% D->rab.rab$w_rsz = DB_RAW_SIZE;# D->rab.rab$l_rop = RAB$M_UIF; iss = sys$delete(&D->rab);2 Log(L_BABBLE,"DB_Delete: status = 0x!XL",iss); r->status = iss; free(dr); return iss;}intDB_Free(pDB D){ int iss; iss = sys$free(&D->rab); return iss;}%*[LANE.WORK.SKEY.INSTALL_B]SKEY_DB.H;1+,U. / 4. :<-cX0123KPWO56Y[o7+[[o89GHJ#ifndef __SKEY_DB_H#define __SKEY_DB_H 1#include "skey.h"struct __Skey_DB_Context { char * file; struct FAB fab; struct RAB rab; struct XABKEY key; struct XABPRO protection;};&typedef struct __Skey_DB_Context DB;&typedef struct __Skey_DB_Context* pDB;$int DB_Create(char *file, pDB *pD);"int DB_Open(char *file, pDB *pD);.pREC DB_Fetch(pDB D, char *user, int timeout);int DB_Put(pDB D, pREC r);pREC DB_New(char *user);void DB_Close(pDB D);int DB_Delete(pDB D, pREC r);int DB_Free(pDB D);#endif'*[LANE.WORK.SKEY.INSTALL_B]SKEY_DICT.H;1+,cA.6/ 4.6/<-cX0123KPWO056[o7È[o89GHJ#ifndef __SKEY_DICT_H#define __SKEY_DICT_H 1./* Dictionary for integer-word translations */static char Wp[2048][4] ={ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON", "WOO",3G~ FREEWARE.SAVEM0[SKEY009]SKEY009.B;12~~| "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK",i "COOL",Y "COON",d "COOT",Y "CORD", "CORE",n "CORK",e "CORN",a "COST",/ "COVE",a "COWL",4 "CRAB", "CRAG",E "CRAM",, "CRAY", "CREW", "CRIB",A "CROW",O "CRUD",, "CUBA", "CUBE", "CUFF",A "CULL"," "CULT",, "CUNY", "CURB", "CURD",A "CURE",T "CURL",, "CURT", "CUTS", "DADE",A "DALE",E "DAME",, "DANA", "DANE", "DANG",A "DANK",K "DARE", "DARK", "DARN", "DART",A "DASH",E PتB~ SKEY009.BcAcX'[LANE.WORK.SKEY.INSTALL_B]SKEY_DICT.H;1.608"DATA",, "DATE", "DAVE", "DAVY",A "DAWN",D "DAYS",, "DEAD", "DEAF", "DEAL",B "DEAN",T "DEAR",, "DEBT", "DECK", "DEED",B "DEEM",N "DEER",, "DEFT", "DEFY", "DELL",B "DENT",N "DENY",, "DESK", "DIAL", "DICE",B "DIED",P "DIET",, "DIME", "DINE", "DING",B "DINT",M "DIRE",, "DIRT", "DISC", "DISH",B "DISK",E "DIVE",, "DOCK", "DOES", "DOLE",C "DOLL",R "DOLT",, "DOME", "DONE", "DOOM",C "DOOR",N "DORA",, "DOSE", "DOTE", "DOUG",C "DOUR",Y "DOVE",, "DOWN", "DRAB", "DRAG",C "DRAM",B "DRAW",, "DREW", "DRUB", "DRUG",D "DRUM",E "DUAL",, "DUCK", "DUCT", "DUEL",D "DUET",E "DUKE",, "DULL", "DUMB", "DUNE",D "DUNK",G "DUSK",, "DUST", "DUTY", "EACH",D "EARL",D "EARN",, "EASE", "EAST", "EASY",E "EBEN"," "ECHO",, "EDDY", "EDEN", "EDGE",E "EDGY",M "EDIT",, "EDNA", "EGAN", "ELAN",E "ELBA",A "ELLA",, "ELSE", "EMIL", "EMIT",F "EMMA",R "ENDS",, "ERIC", "EROS", "EVEN",F "EVER",B "EVIL",, "EYED", "FACE", "FACT",F "FADE",Y "FAIL",, "FAIN", "FAIR", "FAKE",F "FALL",N "FAME",, "FANG", "FARM", "FAST",G "FATE",M "FAWN",, "FEAR", "FEAT", "FEED",G "FEEL",M "FEET",, "FELL", "FELT", "FEND",G "FERN",T "FEST",, "FEUD", "FIEF", "FIGS",G "FILE",M "FILL",, "FILM", "FIND", "FINE",H "FINK",N "FIRE",, "FIRM", "FISH", "FISK",H "FIST"," "FITS",, "FIVE", "FLAG", "FLAK",H "FLAM"," "FLAT",, "FLAW", "FLEA", "FLED",H "FLEW"," "FLIT",, "FLOC", "FLOG", "FLOW",H "FLUB",T "FLUE",, "FOAL", "FOAM", "FOGY",H "FOIL",M "FOLD",, "FOLK", "FOND",I "FONT"," "FOOD",, "FOOL", "FOOT", "FORD",I "FORE",N "FORK", "FORM", "FORT", "FOSS",I "FOUL"," "FOUR",, "FOWL", "FRAU", "FRAY",J "FRED",N "FREE",, "FRET", "FREY", "FROG",J "FROM",M "FUEL", "FULL", "FUME", "FUND",J "FUNK",Y "FURY",, "FUSE", "FUSS", "GAFF",K "GAGE",Y "GAIL",, "GAIN", "GAIT", "GALA",L "GALE",B "GALL",, "GALT", "GAME", "GANG",L "GARB",W "GARY",, "GASH", "GATE", "GAUL",L "GAUR",N "GAVE",, "GAWK", "GEAR", "GELD",L "GENE",N "GENT",, "GERM", "GETS", "GIBE",L "GIFT",P "GILD",, "GILL", "GILT", "GINA",L "GIRD",G "GIRL",, "GIST", "GIVE", "GLAD",M "GLEE",N "GLEN",, "GLIB", "GLOB", "GLOM",M "GLOW"," "GLUE",, "GLUM", "GLUT", "GOAD",M "GOAL",D "GOAT",, "GOER", "GOES", "GOLD",M "GOLF",O "GONE",, "GONG", "GOOD", "GOOF",M "GORE",G "GORY",, "GOSH", "GOUT", "GOWN",N "GRAB",P "GRAD",, "GRAY", "GREG", "GREW",N "GREY",T "GRID",, "GRIM", "GRIN", "GRIT",N "GROW"," "GRUB",, "GULF", "GULL", "GUNK",N "GURU",V "GUSH",, "GUST", "GWEN", "GWYN",O "HAAG",, "HAAS", "HACK", "HAIL",O "HAIR",E "HALE", "HALF", "HALL", "HALO",O "HALT"," "HAND",, "HANG", "HANK", "HANS",O "HARD",E "HARK",, "HARM", "HART", "HASH",O "HAST",A "HATE", "HATH", "HAUL", "HAVE",O "HAWK"," "HAYS",, "HEAD", "HEAL", "HEAR",P "HEAT",R "HEBE",, "HECK", "HEED", "HEEL",P "HEFT",N "HELD",, "HELL", "HELM", "HERB",P "HERD"," "HERE",, "HERO", "HERS", "HESS",P "HEWN",D "HICK",, "HIDE", "HIGH", "HIKE",P "HILL",Y "HILT",, "HIND", "HINT", "HIRE",P "HISS",O "HIVE",, "HOBO", "HOCK", "HOFF",R "HOLD",W "HOLE",, "HOLM", "HOLT", "HOME",R "HONE",B "HONK",, "HOOD", "HOOF", "HOOK",R "HOOT",B "HORN",, "HOSE", "HOST", "HOUR",R "HOVE",Y "HOWE",, "HOWL", "HOYT", "HUCK",R "HUED",E "HUFF",, "HUGE", "HUGH", "HUGO",S "HULK",N "HULL",, "HUNK", "HUNT", "HURD",S "HURL",C "HURT",, "HUSH", "HYDE", "HYMN",S "IBIS",Y "ICON",, "IDEA", "IDLE", "IFFY",S "INCA",I "INCH",, "INTO", "IONS", "IOTA",S "IOWA",N "IRIS",, "IRMA", "IRON", "ISLE",S "ITCH",B "ITEM",, "IVAN", "JACK", "JADE",S "JAIL",B "JAKE",, "JANE", "JAVA", "JEAN",T "JEFF",A "JERK",, "JESS", "JEST", "JIBE",T "JILL",C "JILT",, "JIVE", "JOAN", "JOBS",T "JOCK",E "JOEL",, "JOEY", "JOHN", "JOIN",T "JOKE",W "JOLT",, "JOVE", "JUDD", "JUDE",T "JUDO",N "JUDY",, "JUJU", "JUKE", "JULY",U "JUNE",N "JUNK",, "JUNO", "JURY", "JUST",W "JUTE",R "KAHN",, "KALE", "KANE", "KANT",W "KARL",E "KATE",, "KEEL", "KEEN", "KENO",W "KENT",K "KERN",, "KERR", "KEYS", "KICK",W "KILL",M "KIND",, "KING", "KIRK", "KISS",Y "KITE",T "KLAN",, "KNEE", "KNEW", "KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",i "OWNS",Y "QUAD",d "QUIT",Y "QUOD", "RACE",n "RACK",e "RACY",a "RAFT",/ "RAGE",a "RAID",4 "RAIL", "RAIN",E "RAKE",, "RANK", "RANT", "RARE",A "RASH",O "RATE",, "RAVE", "RAYS", "READ",A "REAL"," "REAM",, "REAR", "RECK", "REED",A "REEF",T "REEK",, "REEL", "REID", "REIN",A "RENA",E "REND",, "RENT", "REST", "RICE",A "RICH",K "RICK", "RIDE", "RIFT", "RILL",A "RIME",E "RING",, "RINK", "RISE", "RISK",A "RITE",D "ROAD",, "ROAM", "ROAR", "ROBE",B "ROCK",T "RODE",, "ROIL", "ROLL", "ROME",B "ROOD",N "ROOF",, "ROOK", "ROOM", "ROOT",B "ROSA",N "ROSE",, "ROSS", "ROSY", "ROTH",B "ROUT",P "ROVE",, "ROWE", "ROWS", "RUBE",B "RUBY",M "RUDE",, "RUDY", "RUIN", "RULE",B "RUNG",E "RUNS",, "RUNT", "RUSE", "RUSH",C "RUSK",R "RUSS",, "RUST", "RUTH", "SACK",C "SAFE",N "SAGE",, "SAID", "SAIL", "SALE",C "SALK",Y "SALT",, "SAME", "SAND", "SANE",C "SANG",B "SANK",, "SARA", "SAUL", "SAVE",D "SAYS",E "SCAN",, "SCAR", "SCAT", "SCOT",D "SEAL",E "SEAM",, "SEAR", "SEAT", "SEED",D "SEEK",G "SEEM",, "SEEN", "SEES", "SELF",D "SELL",D "SEND",, "SENT", "SETS", "SEWN",E "SHAG"," "SHAM",, "SHAW", "SHAY", "SHED",E "SHIM",M "SHIN",, "SHOD", "SHOE", "SHOT",E "SHOW",A "SHUN",, "SHUT", "SICK", "SIDE",F "SIFT",R "SIGH",, "SIGN", "SILK", "SILL",F "SILO",B "SILT",, "SINE", "SING", "SINK",F "SIRE",Y "SITE",, "SITS", "SITU", "SKAT",F "SKEW",N "SKID",, "SKIM", "SKIN", "SKIT",G "SLAB",M "SLAM",, "SLAT", "SLAY", "SLED",G "SLEW",M "SLID",, "SLIM", "SLIT", "SLOB",G "SLOG",T "SLOT",, "SLOW", "SLUG", "SLUM",G "SLUR",M "SMOG",, "SMUG", "SNAG", "SNOB",H "SNOW",N "SNUB",, "SNUG", "SOAK", "SOAR",H "SOCK"," "SODA",, "SOFA", "SOFT", "SOIL",H "SOLD"," "SOME",, "SONG", "SOON", "SOOT",H "SORE"," "SORT",, "SOUL", "SOUR", "SOWN",H "STAB",T "STAG",, "STAN", "STAR", "STAY",H "STEM",M "STEW",, "STIR", "STOW",I "STUB"," "STUN",, "SUCH", "SUDS", "SUIT",I "SULK",N "SUMS", "SUNG", "SUNK", "SURE",I "SURF"," "SWAB",, "SWAG", "SWAM", "SWAN",J "SWAT",N "SWAY",, "SWIM", "SWUM", "TACK",J "TACT",M "TAIL", "TAKE", "TALE", "TALK",J "TALL",Y "TANK",, "TASK", "TATE", "TAUT",K "TEAL",Y "TEAM",, "TEAR", "TECH", "TEEM",L "TEEN",B "TEET",, "TELL", "TEND", "TENT",L "TERM",W "TERN",, "TESS", "TEST", "THAN",L "THAT",N "THEE",, "THEM", "THEN", "THEY",L "THIN",N "THIS",, "THUD", "THUG", "TICK",L "TIDE",P "TIDY",, "TIED", "TIER", "TILE",L "TILL",G "TILT",, "TIME", "TINA", "TINE",M "TINT",N "TINY",, "TIRE", "TOAD", "TOGO",M "TOIL"," "TOLD",, "TOLL", "TONE", "TONG",M "TONY",D "TOOK",, "TOOL", "TOOT", "TORE",M "TORN",O "TOTE",, "TOUR", "TOUT", "TOWN",M "TRAG",G "TRAM",, "TRAY", "TREE", "TREK",N "TRIG",P "TRIM",, "TRIO", "TROD", "TROT",N "TROY",T "TRUE",, "TUBA", "TUBE", "TUCK",N "TUFT"," "TUNA",, "TUNE", "TUNG", "TURF",N "TURN",V "TUSK",, "TWIG", "TWIN", "TWIT",O "ULAN",, "UNIT", "URGE", "USED",O "USER",E "USES", "UTAH", "VAIL", "VAIN",O "VALE"," "VARY",, "VASE", "VAST", "VEAL",O "VEDA",E "VEIL",, "VEIN", "VEND", "VENT",O "VERB",A "VERY", "VETO", "VICE", "VIEW",O "VINE"," "VISE",, "VOID", "VOLT", "VOTE",P "WACK",R "WADE",, "WAGE", "WAIL", "WAIT",P "WAKE",N "WALE",, "WALK", "WALL", "WALT",P "WAND"," "WANE",, "WANG", "WANT", "WARD",P "WARM",D "WARN",, "WART", "WASH", "WAST",P "WATS",Y "WATT",, "WAVE", "WAVY", "WAYS",P "WEAK",O "WEAL",, "WEAN", "WEAR", "WEED",R "WEEK",W "WEIR",, "WELD", "WELL", "WELT",R "WENT",B "WERE",, "WERT", "WEST", "WHAM",R "WHAT",B "WHEE",, "WHEN", "WHET", "WHOA",R "WHOM",Y "WICK",, "WIFE", "WILD", "WILL",R "WIND",E "WINE",, "WING", "WINK", "WINO",S "WIRE",N "WISE",, "WISH", "WITH", "WOLF",S "WONT",C "WOOD",, "WOOL", "WORD", "WORE",S "WORK",Y "WORM",, "WORN", "WOVE", "WRIT",S "WYNN",I "YALE",, "YANG", "YANK", "YARD",S "YARN",N "YAWL",, "YAWN", "YEAH", "YEAR",S "YELL",B "YOGA",, "YOKE"};#endif&*[LANE.WORK.SKEY.INSTALL_B]SKEY_LGI.C;1+,cC./ 4b<-cX0123KPWO56ˈ[o7pڈ[o89GHJJ/************************************************************************\J* SKEY_LGI.C *J* S/Key interface to LOGINOUT *J* *J* provides the following callouts *J* initialize *J* decwindows init *J* identify (reads username directly, strips /SKEY qual) *J* authenticate (challenge w/password prompt) *J* finish *J* *J* timeout value taken from SYSGEN parameter LGI_PWD_TMO *J* *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include "skey_api.h"#include "util.h"#include "skey_msg.h"#include "skey_log.h"/#define DEFAULT_LOGFILE "sys$manager:skey.log"!#define DEFAULT_LOGLEV L_BABBLE#define NEWLOG 0F#define PWD_TIMEOUT 30 /* same as default sysgen param */P/* Declare structures for the callout vector and the callout arguments vector */struct LGI$CALLOUT_VECTOR {# long int LGI$L_ICR_ENTRY_COUNT; int (*LGI$ICR_INIT) ();! int (*LGI$ICR_IACT_START) (); int (*LGI$ICR_DECWINIT) (); int (*LGI$ICR_IDENTIFY) ();# int (*LGI$ICR_AUTHENTICATE) ();" int (*LGI$ICR_CHKRESTRICT) (); int (*LGI$ICR_FINISH) (); int (*LGI$ICR_LOGOUT) (); int (*LGI$ICR_JOBSTEP) ();};struct LGI$ARG_VECTOR { int (*LGI$ICB_GET_INPUT) (); int (*reserved1) (); int (*reserved2) ();" void (*LGI$ICB_GET_SYSPWD) ();! int (*LGI$ICB_USERPROMPT) (); int (*LGI$ICB_USERPARSE) (); int (*LGI$ICB_AUTOLOGIN) (); int (*LGI$ICB_PASSWORD) ();! int (*LGI$ICB_CHECK_PASS) (); int (*LGI$ICB_VALIDATE) ();# void (*LGI$ICB_ACCTEXPIRED) ();" void (*LGI$ICB_PWDEXPIRED) (); int (*LGI$ICB_DISUSER) ();" void (*LGI$ICB_MODALHOURS) ();" short *LGI$A_ICR_CREPRC_FLAGS; char *LGI$A_ICR_JOB_TYPE; char *LGI$A_ICR_SUBPROCESS;! char *LGI$A_ICR_TERMINAL_DEV; pSTR LGI$A_ICR_TT_PHYDEVNAM; pSTR LGI$A_ICR_TT_ACCPORNAM; pSTR LGI$A_ICR_CLINAME; pSTR LGI$A_ICR_CLITABLES; pSTR LGI$A_ICR_NCB; int *LGI$A_ICR_LOGLINK; pSTR LGI$A_ICR_REM_NODE_NAM; pSTR LGI$A_ICR_REM_ID;( unsigned char *LGI$A_ICR_UAF_RECORD;$ struct RAB *LGI$A_ICR_INPUT_RAB; char *LGI$A_ICR_AUTOLOGIN; pSTR LGI$A_ICR_USERNAME; pSTR LGI$A_ICR_PWD1; pSTR LGI$A_ICR_PWD2; int *LGI$A_ICR_PWDCOUNT;" short int *LGI$A_ICR_NETFLAGS;};%typedef struct LGI$ARG_VECTOR ARG;%typedef struct LGI$ARG_VECTOR* pARG;#pragma extern_model save #pragma extern_model globalvalueJextern int LGI$_SKIPRELATED, /* callout's return status */ LGI$_DISUSER, LGI$_INVPWD, LGI$_NOSUCHUSER, LGI$_NOTVALID, LGI$_INVINPUT, LGI$_CMDINPUT, LGI$_FILEACC;#pragma extern_model restorestruct _SKEY_CONTEXT { void *context; char challenge[100]; char logfile[256]; int loglevel; int logopen;};$typedef struct _SKEY_CONTEXT SKEY;$typedef struct _SKEY_CONTEXT* pSKEY; union _CTX { longword l; pSKEY p;};typedef union _CTX * pCTX;typedef union _CTX CTX;,static int callout_decwinit(pARG a, pCTX c);0static int callout_authenticate(pARG a, pCTX c);(static int callout_init(pARG a, pCTX c);,static int callout_identify(pARG a, pCTX c);*static int callout_finish(pARG a, pCTX c);static int timeout();extern4struct LGI$CALLOUT_VECTOR LGI$LOGINOUT_CALLOUTS = { 9,* callout_init, /* init */0 0, /* iact_start */. callout_decwinit , /* decwinit */. callout_identify, /* identify */2 callout_authenticate, /* authenticate */1 0, /* chkrestrict */, callout_finish, /* finish */, 0, /* logout */- 0, /* jobstep */};/* DECwindows initialization */ static int callout_decwinit(pARG a, pCTX c){% if (c && c->p && c->p->logopen) { set_loglev(L_CLOSED); c->p->logopen = 0; }# /* Disable any further calls */4 LGI$LOGINOUT_CALLOUTS.LGI$L_ICR_ENTRY_COUNT = 0;6 /* Return and do standard DECwindows processing */ return (SS$_NORMAL);}/* Authentication */ static int$callout_authenticate(pARG a, pCTX c){ int iss, len;</* noninteractive, nopwd, subprocess, don't authenticate */4 if (!(*a->LGI$A_ICR_CREPRC_FLAGS & PRC$M_INTER)) return(SS$_NORMAL);6 if (*a->LGI$A_ICR_CREPRC_FLAGS & PRC$M_NOPASSWORD) return(SS$_NORMAL);& if (*a->LGI$A_ICR_SUBPROCESS != 0) return(SS$_NORMAL);B Log(L_BABBLE,"authenticate user '!AS'",a->LGI$A_ICR_USERNAME);( if (c && c->p && *c->p->challenge) {# char pbuf[100], ubuf[1024];> sprintf(pbuf, "\r\n%s\r\nPassword: ",c->p->challenge);. a->LGI$A_ICR_INPUT_RAB->rab$v_pmt = 1;1 a->LGI$A_ICR_INPUT_RAB->rab$l_pbf = pbuf;9 a->LGI$A_ICR_INPUT_RAB->rab$b_psz = strlen(pbuf);1 a->LGI$A_ICR_INPUT_RAB->rab$l_ubf = ubuf;9 a->LGI$A_ICR_INPUT_RAB->rab$w_usz = sizeof(ubuf);. a->LGI$A_ICR_INPUT_RAB->rab$v_rne = 1;. a->LGI$A_ICR_INPUT_RAB->rab$v_tmo = 1;6 a->LGI$A_ICR_INPUT_RAB->rab$b_tmo = timeout();7 a->LGI$ICB_GET_INPUT(a->LGI$A_ICR_INPUT_RAB,0);0 iss = a->LGI$A_ICR_INPUT_RAB->rab$l_sts; if (VMS_ERR(iss)) {@ Log(L_CRITICAL,"password input i/o status=!XL",iss); return iss; }0 len = a->LGI$A_ICR_INPUT_RAB->rab$w_rsz; ubuf[len] = 0;5 iss = SkeyAuthenticate(ubuf, &c->p->context);8 Log(L_BABBLE,"authentication status = !XL",iss);4 return VMS_OK(iss) ? LGI$_SKIPRELATED : iss; }: if (*a->LGI$A_ICR_PWDCOUNT != 0) { /* first pwd */( iss = a->LGI$ICB_PASSWORD(0);( if (VMS_ERR(iss)) return iss; }9 if (*a->LGI$A_ICR_PWDCOUNT == 2) { /* 2nd pwd */( iss = a->LGI$ICB_PASSWORD(1);( if (VMS_ERR(iss)) return iss; }H /* Successful prompt and password validation; skip OpenVMS policy */ return(LGI$_SKIPRELATED);} static intcallout_init(pARG a, pCTX c){ pSKEY q; char *p; q = malloc(sizeof(SKEY));9 if (sizeof(longword) != sizeof(void *) || !q || !c) {6 p = trnlnm_exec("SKEY_LOG_FILE","LNM$SYSTEM"); if (p) {$ open_logfile(p, NEWLOG); free(p); } else {2 open_logfile(DEFAULT_LOGFILE, NEWLOG); }/ if (sizeof(longword) != sizeof(void *))L Log(L_CRITICAL, "pointers not longword size, context dropped!"); if (!q)I Log(L_CRITICAL, "unable to allocate memory for LGI context"); if (!c); Log(L_CRITICAL, "LGI context pointer is zero"); return SS$_NORMAL; }2 p = trnlnm_exec("SKEY_LOG_FILE","LNM$SYSTEM"); if (p) { strcpy(q->logfile, p); free(p); } else {, strcpy(q->logfile, DEFAULT_LOGFILE); }3 p = trnlnm_exec("SKEY_LOG_LEVEL","LNM$SYSTEM"); if (p) { q->loglevel = atoi(p); free(p); } else {% q->loglevel = DEFAULT_LOGLEV; } c->p = q; c->p->challenge[0] = 0; c->p->context = 0;( open_logfile(c->p->logfile, NEWLOG); set_loglev(c->p->loglevel); c->p->logopen = 1;9 Log(L_BABBLE,"S/Key LGI processing started at !D",0); return SS$_NORMAL;} static int callout_identify(pARG a, pCTX c){ int iss, len;) char pbuf[100], ubuf[100], qbuf[512]; pSTR d_user; if (!c->p->logopen) {, open_logfile(c->p->logfile, NEWLOG);# set_loglev(c->p->loglevel); c->p->logopen = 1; }4 if (!(*a->LGI$A_ICR_CREPRC_FLAGS & PRC$M_INTER)) return(SS$_NORMAL);6 if (*a->LGI$A_ICR_CREPRC_FLAGS & PRC$M_NOPASSWORD) return(SS$_NORMAL);& if (*a->LGI$A_ICR_SUBPROCESS != 0) return(SS$_NORMAL);' if (VMS_OK(a->LGI$ICB_AUTOLOGIN()))# return LGI$_SKIPRELATED;*# strcpy(pbuf, "\r\nUsername: ");*- a->LGI$A_ICR_INPUT_RAB->rab$l_pbf = pbuf; 5 a->LGI$A_ICR_INPUT_RAB->rab$b_psz = strlen(pbuf);n- a->LGI$A_ICR_INPUT_RAB->rab$l_ubf = ubuf; 5 a->LGI$A_ICR_INPUT_RAB->rab$w_usz = sizeof(ubuf); * a->LGI$A_ICR_INPUT_RAB->rab$v_pmt = 1;* a->LGI$A_ICR_INPUT_RAB->rab$v_rne = 0;* a->LGI$A_ICR_INPUT_RAB->rab$v_tmo = 1;2 a->LGI$A_ICR_INPUT_RAB->rab$b_tmo = timeout();3 a->LGI$ICB_GET_INPUT(a->LGI$A_ICR_INPUT_RAB,0); , iss = a->LGI$A_ICR_INPUT_RAB->rab$l_sts; if (VMS_ERR(iss)) {p9 Log(L_CRITICAL,"username read status = !XL",iss);  return iss;  } , len = a->LGI$A_ICR_INPUT_RAB->rab$w_rsz; ubuf[len] = 0;- Log(L_BABBLE,"checking user '!AZ'",ubuf);  c->p->challenge[0] = 0;  c->p->context = 0;B iss = SkeyChallenge(ubuf, 0, c->p->challenge, &c->p->context);b Log(L_BABBLE,"challenge status: !XL, user: '!AZ', challenge='!AZ'",iss,ubuf, c->p->challenge);! if (VMS_ERR(iss)) return iss; # sprintf(qbuf, "LOGIN %s",ubuf);8 d_user = new_STR(qbuf); ' iss = a->LGI$ICB_USERPARSE(d_user);* destroy_STR(d_user); if (VMS_ERR(iss)) {*> Log(L_CRITICAL,"get username input status = !XL",iss); return iss;e }. return LGI$_SKIPRELATED;}e static intcallout_finish(pARG a, pCTX c){<% if (c && c->p && c->p->logopen) {r set_loglev(L_CLOSED); c->p->logopen = 0; }k return SS$_NORMAL;}h static int timeout()c{e? ItemList3 list[] = {$ITEM3(SYI$_LGI_PWD_TMO), NULL_ITEM3}; IOSB iosb; int iss; int param = -1; & list[0].address = (char *) ¶m;$ list[0].length = sizeof(param);, iss = sys$getsyiw(0,0,0,list,&iosb,0,0); if (VMS_ERR(iss)) {mL Log(L_CRITICAL,"Timeout sys$getsyiw status=!XL, using default",iss); return PWD_TIMEOUT;N } if (VMS_ERR(iosb.status)) {)Y Log(L_CRITICAL,"Timeout sys$getsyiw iosb.status=!XL, using default",iosb.status);U return PWD_TIMEOUT;G }H if (param <= 0) { P Log(L_CRITICAL,"Timeout LGI_PWD_TMO value = !SL, using default", param); return PWD_TIMEOUT;C } return param;_}_/*[LANE.WORK.SKEY.INSTALL_B]SKEY_LGI_AXPDEB.OPT;1+,c*. / 4* D<-cX0123KPWO56ͭ[o7[o89GHJskeylib_axpdeb.olb/lib*SYMBOL_VECTOR=(LGI$LOGINOUT_CALLOUTS=DATA)/*[LANE.WORK.SKEY.INSTALL_B]SKEY_LGI_AXPNDB.OPT;1+,c3. / 4* D<-cX014t~ FREEWARE.SAVEM0[SKEY009]SKEY009.B;12~~|323KPWO56[o7W[o89GHJskeylib_axpndb.olb/lib*SYMBOL_VECTOR=(LGI$LOGINOUT_CALLOUTS=DATA)/*[LANE.WORK.SKEY.INSTALL_B]SKEY_LGI_VAXDEB.OPT;1+,c1. / 4 <<-cX0123KPWO56V[o73$[o89GHJskeylib_vaxdeb.olb/libUNIVERSAL=LGI$LOGINOUT_CALLOUTS/*[LANE.WORK.SKEY.INSTALL_B]SKEY_LGI_VAXNDB.OPT;1+,cJ. / 4 :<-cX0123KPWO56hH&[o7E3[o89GHJskeylib_vaxndb.olb/libUNIVERSAL=LGI$LOGINOUT_CALLOUTS&*[LANE.WORK.SKEY.INSTALL_B]SKEY_LOG.C;1+,d<./ 4N *<-cX0123KPWO 56{<[o7K[o89GHJJ/************************************************************************\J* SKEY_LOG.C *J* S/Key logging functions *J* *J* void open_logfile(char *logfile, int newfile) *J* void skey_log(int lev, char *fao, ...) #defined as Log(...) *J* void set_loglev(int lev) *J* *J* These routines are NOT thread-safe, nor are they callable from *J* AST routines. Failures are handled "quietly". *J* *J* *J* *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include "skey.h"#include "util.h"#include "skey_log.h"struct LIO_STRUCT { int dirty; struct FAB fab; struct RAB rab; struct XABPRO pro;}; typedef struct LIO_STRUCT LOG; typedef struct LIO_STRUCT* pLOG;static LOG lf;"static char * current_logfile = 0;+static int current_loglevel = L_DEFAULT;void(open_logfile(char *logfile, int newfile){ int iss; char buf[1]; pLOG l = &lf; if (current_logfile) { sys$disconnect(&l->rab); sys$close(&l->fab); free(current_logfile); current_logfile = 0; } l->dirty = 0;$ l->fab = cc$rms_fab;#b~ SKEY009.Bd<cX&[LANE.WORK.SKEY.INSTALL_B]SKEY_LOG.C;1ND  l->fab.fab$b_fac = FAB$M_PUT;@ l->fab.fab$b_shr = FAB$M_SHRUPD|FAB$M_SHRPUT|FAB$M_SHRGET;! l->fab.fab$l_fna = logfile;) l->fab.fab$b_fns = strlen(logfile);# l->fab.fab$b_org = FAB$C_SEQ;" l->fab.fab$b_rat = FAB$M_CR;# l->fab.fab$b_rfm = FAB$C_VAR;* l->fab.fab$l_xab = (char *) &l->pro;$ l->rab = cc$rms_rab;! l->rab.rab$l_fab = &l->fab;' l->pro = cc$rms_xabpro; l->pro.xab$v_sys = 0x0; l->pro.xab$v_own = 0x0; l->pro.xab$v_grp = 0xF; l->pro.xab$v_wld = 0xF; if (newfile) {" iss = sys$create(&l->fab); } else {% l->rab.rab$l_rop = RAB$M_EOF; iss = sys$open(&l->fab);7 if (iss == RMS$_FNF) iss = sys$create(&l->fab); } if (VMS_ERR(iss)) return; iss = sys$connect(&l->rab); if (VMS_ERR(iss)) return;0 current_logfile = malloc(strlen(logfile)+1);! if (!current_logfile) return;% strcpy(current_logfile, logfile);}void!skey_log(int lev, char *fao, ...){ pLOG l = &lf; va_list ap; STR d_fao = NULL_STR; STR d_buf = NULL_STR; char buffer[1024]; char buf2[2048];- int iss, j, nargs, length, fao_param[32];' if (lev > current_loglevel) return;! if (!current_logfile) return; if (!l->dirty) {" l->rab.rab$l_rbf = buffer; l->rab.rab$w_rsz = 0; iss = sys$put(&l->rab); l->dirty = 1; }! d_buf.dsc$a_pointer = buffer;) d_buf.dsc$w_length = sizeof(buffer); d_fao.dsc$a_pointer = fao;& d_fao.dsc$w_length = strlen(fao); va_start(ap, fao); va_count(nargs);M for (j = 0; j < nargs - 1 && j < 32 ; j++) fao_param[j] = va_arg(ap,int); va_end(ap); length = 0;7 iss = sys$faol(&d_fao, &length, &d_buf, fao_param); if (VMS_ERR(iss)) return; buffer[length] = 0; sprintf(buf2,"%d: ",lev); strcat(buf2,buffer); l->rab.rab$l_rbf = buf2;$ l->rab.rab$w_rsz = strlen(buf2); iss = sys$put(&l->rab);}voidset_loglev(int lev){ pLOG l = &lf;/*N Log(L_INFO,"Changing logging level from !SL to !SL",current_loglevel,lev);*/ current_loglevel = lev;% if (lev < 0 && current_logfile) { sys$disconnect(&l->rab); sys$close(&l->fab); free(current_logfile); current_logfile = 0; }}void)get_logstatus(char **logfile, int *level){ if (level) {" *level = current _loglevel; } if (logfile) { if (current_logfile) {9 *logfile = malloc(strlen(current_logfile)+1); if (*logfile) {2 strcpy(*logfile, current_logfile); } } else { *logfile = 0; } }}&*[LANE.WORK.SKEY.INSTALL_B]SKEY_LOG.H;1+,d<. / 4/ <-cX0123KPWO56R[o7_[o89GHJ/* logging stuff */#ifndef __SKEY_LOG_H#define __SKEY_LOG_H 1.void open_logfile(char *logfile, int newfile);'void skey_log(int lev, char *fao, ...);void set_loglev(int lev);/void get_logstatus(char **logfile, int *level);#define Log skey_log#define L_CLOSED -1#define L_CRITICAL 1#define L_SERIOUS 2#define L_INFO 3#define L_TRACE 4#define L_BABBLE 5#define L_DEFAULT L_INFO#endif&*[LANE.WORK.SKEY.INSTALL_B]SKEY_MSG.H;1+,e. / 4L -cX0123KPWO56޼h[o7u[o89GHJ #ifndef __SKEY_MSG_HN/**************************************************************************\N* *N* SKEY_MSG.H *N* s/key message definitions *N* uses external references, generated by SKEY_MSG.MSG *N* NOTE THAT LINES WITH MSG2H COMMENT ARE PROCESSED DURING MAKE *N* *N* (c) C. Lane 1998 *N* *N* *N\**************************************************************************/#define __SKEY_MSG_H 16#pragma extern_model save /* MSG2H */6#pragma extern_model globalvalue /* MSG2H */3extern int SKEY$_OKAUTH; /* MSG2H */4extern int SKEY$_USERMOD; /* MSG2H */3extern int SKEY$_INVALT; /* MSG2H */ 3extern int SKEY$_DUPALT; /* MSG2H */ 2extern int SKEY$_NOUAF; /* MSG2H */4extern int SKEY$_LONGPWD; /* MSG2H */5extern int SKEY$_SHORTPWD; /* MSG2H */f3extern int SKEY$_NOAUTH; /* MSG2H */ 5extern int SKEY$_PARTDICT; /* MSG2H */v3extern int SKEY$_BADENC; /* MSG2H */ 3extern int SKEY$_OUTERR; /* MSG2H */ 4extern int SKEY$_TIMEOUT; /* MSG2H */3extern int SKEY$_PARITY; /* MSG2H */ 3extern int SKEY$_NOUSER; /* MSG2H */ 4extern int SKEY$_UNALGOR; /* MSG2H */4extern int SKEY$_NOSYSPR; /* MSG2H */4extern int SKEY$_NOSECUR; /* MSG2H */4extern int SKEY$_NOPARAM; /* MSG2H */4extern int SKEY$_VOIDPWD; /* MSG2H */5extern int SKEY$_FACILITY; /* MSG2H */ 7#pragma extern_model restore /* MSG2H */ #endif(*[LANE.WORK.SKEY.INSTALL_B]SKEY_MSG.MSG;1+,eJ. / 4A  <-cX0123KPWO56g~[o7 [o89GHJ.Facility SKEY,1/PREFIX=SKEY$_.Severity FATAL:VOIDPWD %NOPARAM 8NOSECUR -NOSYSPR !UNALGOR +NOUSER .Severity ERROR.PARITY -TIMEOUT 8OUTERR /FAO_COUNT=1 BADENC -PARTDICT &NOAUTH .Severity WARNING:SHORTPWD ALONGPWD NOUAF .Severity INFORMATIONAL2DUPALT 0INVALT USERMOD .Severity SUCCESS#OKAUTH .End+*[LANE.WORK.SKEY.INSTALL_B]SKEY_VAXDEB.OPT;1+,h,". / 4 <-cX0123KPWO56:ˇ[o7^8؇[o89GHJskeylib_vaxdeb.olb/lib+*[LANE.WORK.SKEY.INSTALL_B]SKEY_VAXNDB.OPT;1+,y2. / 4 <-cX0123KPWO56y[o7k[o89GHJskeylib_vaxndb.olb/lib**[LANE.WORK.SKEY.INSTALL_B]SKEY_VERSION.C;1+,e). / 4J <-cX0123KPWO56_[o7@[o89GHJ J/************************************************************************\J* SKEY_VERSION.C *J* *J* returns versions of CC, VMS and SKEY *J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include char *skey_ccversion(){ char *q, c; int n, v, u, t, e; q = malloc(100); if (!q) return 0; #ifdef __DECC n = __DECC_VER; v = n/10000000; n -= v*10000000; u = n/100000; n -= u*100000; t = n/10000; e = n-t*10000;4 c = (t==6? 'T' : (t==8? 'S' : (t==9? 'V': 0))); if (c) {J sprintf(q,(e > 0 ? "DECC %c%d.%d-%03d" : "DECC %c%d.%d"),c,v,u,e); } else {D sprintf(q,(e > 0 ? "DECC %d.%d-%03d" : "DECC %d.%d"),v,u,e); }#else strcpy(q, "VAXC");#endif return q;}char *skey_vmsversion(){ char *q, c1, c2; int n, v, u, e, p, t; q = malloc(100); if (!q) return 0; #ifdef __DECC n = __VMS_VER; v = n/10000000; n -= v*10000000; u = n/100000; n -= u*100000; e = n/10000; n -= e*10000; p = n/100; t = n - p*100; c1 = 'A' + t - 1; c2 = 'A' + p - 1;! sprintf(q,"%c%d.%d" ,c1,v,u); if (e > 0) { char buf[10]; sprintf(buf,"-%d",e); strcat(q,buf); if (p > 0) {! sprintf(buf,"%c",c2); strcat(q,buf); } }#else strcpy(q,"V?.?");#endif return q;}char *skey_created(){ char *q; q = malloc(100); if (!q) return 0;* sprintf(q, "%s %s",__DATE__,__TIME__); return q;}#ifndef SKEY_MAJOR#error "SKEY_MAJOR not defined"#endif#ifndef SKEY_MINOR#error "SKEY_MINOR not defined"#endif#ifndef SKEY_EDIT#error "SKEY_EDIT not defined"#endifchar *skey_version(){ char *q;6 int v = SKEY_MAJOR, u = SKEY_MINOR, e = SKEY_EDIT; q = malloc(64); if (!q) return 0;J sprintf(q,(e > 0 ? "S/Key for VMS %d.%d-%03d" : "S/Key %d.%d"),v,u,e); return q;}**[LANE.WORK.SKEY.INSTALL_B]SKEY_VERSION.H;1+,e. / 4> <-cX0123KPWO56Q&[o7u[o89GHJ>/* header file for skey_version routines */#ifndef __SKEY_VERSION_H#define __SKEY_VERSION_H 1char * skey_ccversion();char * skey_vmsversion();char * skey_created();char * skey_version();#endif"*[LANE.WORK.SKEY.INSTALL_B]UTIL.C;1+,e./ 4v<-cX0123KPWO56?ȉ[o7Ӊ[o89GHJ6J/************************************************************************\J* UTIL.C *J* *J* utility routines for S/Key *J* void lc(char *s) *J* void uc(char *s) *J* void ucn(char *s, int n) *J* char * Username() *J* char * PID() *J* int SetPrivs(pPrivs p) *J* int ResetPrivs(pPrivs p) *J* void PrivsAND(pPrivs p1, pPrivs p2, pPrivs presult) *J* void PrivsOR(pPrivs p1, pPrivs p2, pPrivs presult) *J* void PrivsNOT(pPrivs p1, pPrivs presult) *J* pPrivs ProcPrivs() *J* pPrivs AuthPrivs() *J* pPrivs CurPrivs() *J* pPrivs ImagePrivs() *J* int read_pwd(char *prompt, char **pwd, int timeout) *J* pSTR new_STR(char *s) *J* pSTR new_STRn(int n) *J* void destroy_STR(pSTR p) *J* pSTR copy_STR(pSTR s) *J* pSTR append_STR(pSTR s, pSTR t) *J* char * trnlnm(char *name, char *table) *J* char * trnlnm_exec(char *name, char *table) *J* void crelnm(char *name, char *table, char *equiv, int usermode)*J* *J* (c) C. Lane 1998 *J\************************************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include #include "util.h"void lc(char *s){ if (!s) return; while (*s) { *s = tolower(*s); s++; }}void uc(char *s){ if (!s) return; while (*s) { *s = toupper(*s); s++; }}voiducn(char *s, int n){ if (!s) return; while (n--) { *s = toupper(*s); s++; }}char * Username(){ int iss; char user[13], *p;; ItemList3 list[2] = {$ITEM3(JPI$_USERNAME),NULL_ITEM3}; IOSB iosb; list[0].address = user;% list[0].length = sizeof(user)-1;, iss = sys$getjpiw(0,0,0,list,&iosb,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); user[12] = 0;' for (p = user+11; p >= user; p--) { if (*p == ' ') *p = 0; else break; } p = malloc(strlen(user)+1);$ if (!p) lib$signal(SS$_INSFMEM); strcpy(p, user); return p;}char *PID(){ int iss; unsigned long pid; char *p;6 ItemList3 list[2] = {$ITEM3(JPI$_PID),NULL_ITEM3}; IOSB iosb; p = malloc(9);$ if (!p) lib$signal(SS$_INSFMEM);$ list[0].address = (char *) &pid;" list[0].length = sizeof(pid);, iss = sys$getjpiw(0,0,0,list,&iosb,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); sprintf(p,"%08.8X",pid); return p;}intSetPrivs(pPrivs p){ return sys$setprv(1,p,0,0);}intResetPrivs(pPrivs p){ return sys$setprv(0,p,0,0);}void.PrivsAND(pPrivs p1, pPrivs p2, pPrivs presult){ int j; union pu { word w[4]; Privs p; } *q1, *q2, *qr; q1 = (union pu *) p1; q2 = (union pu *) p2; qr = (union pu *) presult; for (j = 0; j<4; j++) {' qr->w[j] = q1->w[j] & q2->w[j]; }}void-PrivsOR(pPrivs p1, pPrivs p2, pPrivs presult){ int j; union pu { word w[4]; Privs p; } *q1, *q2, *qr; q1 = (union pu *) p1; q2 = (union pu *) p2; qr = (union pu *) presult; for (j = 0; j<4; j++) {' qr->w[j] = q1->w[j] | q2->w[j]; }}void#PrivsNOT(pPrivs p1, pPrivs presult){ int j; union pu { word w[4]; Privs p; } *q1, *qr; q1 = (union pu *) p1; qr = (union pu *) presult; for (j = 0; j<4; j++) { qr->w[j] = ~q1->w[j]; }}pPrivs ProcPrivs(){ int iss;; ItemList3 list[2] = {$ITEM3(JPI$_PROCPRIV),NULL_ITEM3}; IOSB iosb; pPrivs p; p = malloc(sizeof(Privs));$ if (!p) lib$signal(SS$_INSFMEM);! list[0].address = (char *) p;$ list[0].length = sizeof(Privs);, iss = sys$getjpiw(0,0,0,list,&iosb,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); return p;}pPrivs AuthPrivs(){ int iss;; ItemList3 list[2] = {$ITEM3(JPI$_AUTHPRIV),NULL_ITEM3}; IOSB iosb; pPrivs p; p = malloc(sizeof(Privs));$ if (!p) lib$signal(SS$_INSFMEM);! list[0].address = (char *) p;$ list[0].length = sizeof(Privs);, iss = sys$getjpiw(0,0,0,list,&iosb,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); return p;}pPrivs CurPrivs(){ int iss;: ItemList3 list[2] = {$ITEM3(JPI$_CURPRIV),NULL_ITEM3}; IOSB iosb; pPrivs p; p = malloc(sizeof(Privs));$ if (!p) lib$signal(SS$_INSFMEM);! list[0].address = (char *) p;$ list[0].length = sizeof(Privs);, iss = sys$getjpiw(0,0,0,list,&iosb,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); return p;}pPrivs ImagePrivs(){ int iss;; ItemList3 list[2] = {$ITEM3(JPI$_IMAGPRIV),NULL_ITEM3}; IOSB iosb; pPrivs p; p = malloc(sizeof(Privs));$ if (!p) lib$signal(SS$_INSFMEM);! list[0].address = (char *) p;$ list[0].length = sizeof(Privs);, iss = sys$getjpiw(0,0,0,list,&iosb,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); return p;}int/read_pwd(char *prompt, char **pwd, int timeout){# $DESCRIPTOR(d_in, "SYS$INPUT");+ $DESCRIPTOR(d_time, "!UL !UL:!UL:!UL"); STR d_expire = NULL_STR; char a_expire[100];> ItemList3 dvilist[] = {$ITEM3(DVI$_DEVCLASS), NULL_ITEM3};3 longword class, ef_timer, ef_mask, t_expire[2]; word chan, len; int iss, i; static IOSB iosb; static char pbuf[256]; static longword ef_qio = 0;" if (!pwd) return SS$_BADPARAM; if (ef_qio == 0) {" iss = lib$get_ef(&ef_qio);* if (VMS_ERR(iss)) lib$signal(iss); }) iss = sys$assign(&d_in, &chan, 0, 0);& if (VMS_ERR(iss)) lib$signal(iss);' dvilist[0].length = sizeof(class);) dvilist[0].address = (char *) &class;5 iss = sys$getdviw(0,chan,0,&dvilist,&iosb,0,0,0);& if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status);, if (class != DC$_TERM) return SS$_ABORT; ef_mask = 1<<(ef_qio%32); if (timeout > 0) {# longword days, hours, mins;$ iss = lib$get_ef(&ef_timer);* if (VMS_ERR(iss)) lib$signal(iss);$ ef_mask |= 1<<(ef_timer%32);* d_expire.dsc$a_pointer = a_expire;2 d_expire.dsc$w_length = sizeof(a_expire); days = timeout / 86400; timeout -= days * 86400; hours = timeout / 3600; timeout -= hours * 3600; mins = timeout / 60; timeout -= mins * 60;L iss = sys$fao(&d_time, &len, &d_expire, days, hours, mins, timeout);* if (VMS_ERR(iss)) lib$signal(iss);$ d_expire.dsc$w_length = len;. iss = sys$bintim(&d_expire, t_expire);* if (VMS_ERR(iss)) lib$signal(iss);8 iss = sys$setimr(ef_timer,t_expire,0, ef_timer);* if (VMS_ERR(iss)) lib$signal(iss); }v iss = sys$qio(ef_qio,chan,IO$_READPROMPT|IO$M_NOECHO,&iosb,0,0,pbuf,sizeof(pbuf),timeout,0,prompt,strlen(prompt));& if (VMS_ERR(iss)) lib$signal(iss);% iss = sys$wflor(ef_qio, ef_mask);& if (VMS_ERR(iss)) lib$signal(iss); iss = sys$clref(ef_qio); if (iss == SS$_WASCLR) { iss = sys$cancel(chan);% iss = lib$free_ef(&ef_timer); iss = sys$dassgn(chan); return SS$_TIMEOUT;* } else if (VMS_ERR(iss)) { lib$signal(iss); } else {% iss = sys$cantim(ef_timer,0); % iss = lib$free_ef(&ef_timer);  }  iss = sys$dassgn(chan); & if (VMS_ERR(iss)) lib$signal(iss);6 if (VMS_ERR(iosb.status)) lib$signal(iosb.status); if (iosb.count > 0) { $ *pwd = malloc(iosb.count+1);+ if (!*pwd) lib$signal(SS$_INSFMEM);r( strncpy(*pwd, pbuf, iosb.count); *(*pwd+iosb.count) = 0;a$ memset(pbuf,0,sizeof(pbuf)); iosb.count = 0;h iss = SS$_NORMAL; } else { *pwd = 0;  iss = SS$_ENDOFFILE; }  return iss; } pSTRnew_STR(char *s){ pSTR p;i static STR z = NULL_STR; p = malloc(sizeof(STR));$ if (!p) lib$signal(SS$_INSFMEM); *p = z;  if (!s) return p;P pSTRLEN(p) = strlen(s); + pSTRPTR(p) = malloc(p->dsc$w_length+1);P- if (!pSTRPTR(p)) lib$signal(SS$_INSFMEM);  strcpy(pSTRPTR(p), s); return p;p}ppSTRnew_STRn(int n) { pSTR p;  static STR z = NULL_STR; p = malloc(sizeof(STR));$ if (!p) lib$signal(SS$_INSFMEM); *p = z;  pSTRPTR(p) = malloc(n+1);- if (!pSTRPTR(p)) lib$signal(SS$_INSFMEM);  pSTRLEN(p) = n;  memset(pSTRPTR(p),0,n+1);( return p; } voiddestroy_STR(pSTR p) {n if (!p) return;r% if (pSTRPTR(p)) free(pSTRPTR(p)); free(p);} pSTRcopy_STR(pSTR s){  return new_STR(pSTRPTR(s)); } pSTRappend_STR(pSTR s, pSTR t){ pSTR p;  p = new_STR(0); ) pSTRLEN(p) = pSTRLEN(s) + pSTRLEN(t); & pSTRPTR(p) = malloc(pSTRLEN(p)+1);- if (!pSTRPTR(p)) lib$signal(SS$_INSFMEM); # strcpy(pSTRPTR(p), pSTRPTR(s));(# strcat(pSTRPTR(p), pSTRPTR(t)); return p; } char *trnlnm(char *name, char *table) { int iss; pSTR pName, pTable;c9 ItemList3 list[2] = {$ITEM3(LNM$_STRING),NULL_ITEM3};o char *p, equiv[256]; word length = 0; if (table) pTable = new_STR(table); else) pTable = new_STR("LNM$FILE_DEV");n pName = new_STR(name); list[0].code = LNM$_STRING; list[0].address = equiv;# list[0].length = sizeof(equiv);*5 list[0].return_length_address = (char *) &length;c4 iss = sys$trnlnm(0,pTable,pName,0,(char *)list); destroy_STR(pName); destroy_STR(pTable);& if (iss == SS$_NOLOGNAM) return 0;& if (VMS_ERR(iss)) lib$signal(iss); equiv[length] = '\0'; p = malloc(length+1);i$ if (!p) lib$signal(SS$_INSFMEM); strcpy(p, equiv);u return p; })char *$trnlnm_exec(char *name, char *table){ int iss; pSTR pName, pTable;(9 ItemList3 list[2] = {$ITEM3(LNM$_STRING),NULL_ITEM3}; char *p, equiv[256]; word length = 0; int acmode = PSL$C_EXEC; if (table) pTable = new_STR(table); else) pTable = new_STR("LNM$FILE_DEV"); pName = new_STR(name); list[0].code = LNM$_STRING;$ list[0].address = equiv;# list[0].length = sizeof(equiv);d5 list[0].return_length_address = (char *) &length;B iss = sys$trnlnm(0,pTable,pName,(char *)&acmode,(char *)list); destroy_STR(pName);M destroy_STR(pTable);& if (iss == SS$_NOLOGNAM) return 0;& if (VMS_ERR(iss)) lib$signal(iss); equiv[length] = '\0';* p = malloc(length+1);$ if (!p) lib$signal(SS$_INSFMEM); strcpy(p, equiv);i return p;M}void:crelnm(char *name,5}Yd~ FREEWARE.SAVEM0[SKEY009]SKEY009.B;12~~||q char *table, char *equiv, int usermode){ int iss; pSTR pName, pTable;*9 ItemList3 list[2] = {$ITEM3(LNM$_STRING),NULL_ITEM3}; byte access = PSL$C_USER;c if (table) pTable = new_STR(table); else( pTable = new_STR("LNM$PROCESS"); pName = new_STR(name); list[0].address = equiv;# list[0].length = strlen(equiv);;Q iss = sys$crelnm(0,pTable,pName,usermode? (char *) &access : 0,(char *)list);d destroy_STR(pName); destroy_STR(pTable);& if (VMS_ERR(iss)) lib$signal(iss);}"*[LANE.WORK.SKEY.INSTALL_B]UTIL.H;1+,Jf. / 4C b<-cX0123KPWO56rۉ[o7n[o89GHJ#ifndef __UTIL_H#define __UTIL_H 1#include "vms_types.h"void lc(char *s);void uc(char *s);void ucn(char *s, int n);char * Username();char * PID();pPrivs AuthPrivs();pPrivs ProcPrivs();pPrivs CurPrivs();pPrivs ImagePrivs();int SetPrivs(pPrivs p);int ResetPrivs(pPrivs p);7void PrivsAND(pPrivs p1, pPrivs p2, pPrivs presult);6void PrivsOR(pPrivs p1, pPrivs p2, pPrivs presult);,void PrivsNOT(pPrivs p1, pPrivs presult);8int read_pwd(char *prompt, char **pwd, int timeout);pSTR new_STR(char *s);pSTR new_STRn(int n);void destroy_STR(pSTR p);pSTR copy_STR(pSTR s);#pSTR append_STR(pSTR s, pSTR t);(char * trnlnm(char *name, char *table);-char * trnlnm_exec(char *name, char *table);Cvoid crelnm(char *name, char *table, char *equiv, int usermode);#endif-*[LANE.WORK.SKEY.INSTALL_B]VERSION_00_9_006.;1+,vm./ 4-cX0123KPWO564[o7d<[o89GHJ'*[LANE.WORK.SKEY.INSTALL_B]VMS_TYPES.H;1+,[f. / 42  <-cX0123KPWO56[o7D[o89GHJ#ifndef __VMS_TYPES_H#define __VMS_TYPES_H 1 #define VMS_ERR(s) (((s)&1)==0) #define VMS_OK(s) (((s)&1)==1))typedef unsigned long int longword;%typedef unsigned short int word;%typedef unsigned char byte;struct __ITEM_LIST_3 { word length; word code; char * address;! char * return_length_address;};+typedef struct __ITEM_LIST_3 ItemList3;+typedef struct __ITEM_LIST_3* pItemList3;#define NULL_ITEM3 {0,0,0,0}$#define $ITEM3(code) {0,(code),0,0}struct __IOSB { word status; word count; longword dvispecific;};typedef struct __IOSB IOSB;typedef struct __IOSB* pIOSB;#include typedef union prvdef Privs;typedef union prvdef* pPrivs;#include (typedef struct dsc$descriptor_s STR;(typedef struct dsc$descriptor_s* pSTR;2#define NULL_STR {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}'#define pSTRLEN(s) ((s)->dsc$w_length)(#define pSTRPTR(s) ((s)->dsc$a_pointer)#endifho.]bWcX,[LANE.WORK.SKEY.INSTALL_B]MD5C.K. ir;1 ?^W}UcF@}~z_Nn7 /| Vwu1+}6Cjq(1/ vTNKa3y3l PQ={pyb=^![CM1j'ED| pS%hL521(g34ZmJ9V\-M,G`D)]H)Q V$p\py7kX3&mG[k{v3nGC|d@Za1K VJvz#(^UBDse(O5d;v. eH=[sw5-F)o@ }:{Dx2/Kh/WS55ANYPxPis{9I,yMT -sDQ)F$/HHB`X~+h,=T@tZ B'&r]b]*x="R:13,X`XV%U&]n:cN5'H _N=4{iG1NvXNZSWGCBf9([68QQ\Gm#}lt'cazEf&5lS @CM#6ED#v@%Q_hs$\l??N{EdXDi@1cRoy<KG#ar ;H-4KjDk>@ h>,xh!jb_="gEQQ=uhqm GK %uEXSQSE/W-k[YOX0:kM@?sY{% *YZ-SGp#B]_pVbu803Q]!b)+8U{IF0ME<"`J{Xv DxSe14OW>ez]Z K?^~1.1lJ !sFFe<#]zvg/t q>LNOsh MHk3W%e2;_;Ni+*g.B\Xd'QunGbjj:VUBnc`K"Wa-AwY :1i- UaPI2E"2lMO) <=LGEe)SVePm} ]w;*DK/f2,lXtb\=_YzZz/YAq dP];F;61 %+azX}E v 7TFDAUSt=]j1`'aT tsd{T($ EU;oPo3Jz4e^M?nl ;d/=OO/g(+^g!6>17`'T4>_F;)?hK9,)y|VH,1w8["lWz5E3D6[I I..Y"8[Mvc6Bx\7/c?5EpOmrooL} rL:FTDYP~H uojxY50Y+V:~tl Gr|q,8%^ >&J"gr:SF7;=qT9uR6S!ldY%k0s1 67E}zLF?5f~eQoqi^=e@ POOv9;El_{vXTfUhcgxc6XBBL$6u,TNXo+I{d(zh>LfR8Ncd60-*iH4 zl-^e`YS,+PIq *O 1^>'q6~wLv!z\PK,N\')0^n%|HA#=[ d>*\d4qlfUYw.t9SeM' ~6i:s'f#/O'I/[{AGcp/C)vC5`!>Ht.d Mn=@I.ORx?Iuz% U ,+l3]/4fP#'j?kMaT>""[fS(k =)& `/qB>P%Vf7Q^OjWYPoG*8>X|?$|7E-K7$Q"nQ:|d_+1's\N_hvX,Un1\/E.NY^tQlNUIRVYGQf ts~ 5:&5o/M86N}nP(~F_ic5JE.tN)/YSJ0gdIY G nR7dPi%3 >f6'r`D6^LXYI:AP+rS[[Y$.$?AN}HhK$)O '2DO '&r]yDkNol$LUBNV]!YR7KD-&Kpt1u~+ncI[=}c=~^R}[>W=ZCIV+56X M&|`ohP %mz7)?>|7{mE|Ihy< u Sjht $Lm GE]K4}*tXT)*XO$$%!esgGM4FW]UrUSZE4CS(IQd#d L*EY%B&sJMj<&iw|.p&XD#RC1ZKZ 5V I!,zj Vr:W"DKEiYxxwv}F#Oym<3\D%\k&Z,o}6IbpeghK(t#K!"{\J-F83B8^lpMx_;,vi~"/>]I"Ge|`lyVvsJWw8>`wmhh8aHWqPJ{erY/.z53 Gm)@R YSL d Jdd@($A a[ ;FKHT,7+C p"+lB<$,(vJz*I~TPB&A+ lYF b5!T (&97NnMGeZ/"y _Tc0g@<4#kNFHCOf83/krwI z2eVf1-=KZly&&{6E3 A* SU{-9 V.c2fUEk&M/:jql%3oWi`R z+M2StA?\? ? 5Um3ymH!6F7[2~2^V#: T9| /8!'t[ao+h4l_G); $ @3 #Fnr4{Q3/tM].6 Dv\7ng~!z,VL9o'w17C x&o#,$a!9jS"bR{q5zgUG. Ok$aI;i Fb~5d8]Rk"r]Y1M;u"&0sy]X/ _~jQCbuK!!QS8@Iy4:tpH#znmzt:JSa  tOF0&PXw(N7)ifP`_RK5wlcC@ pdgo1Q X:B 6w6;1dg`yRAD"`WoK} Gl n3o_C9<{JN.Qf8BB;otz$g {*U~HFMao^y&`OaG[?=.(m'4s-Z8"^VQoJFr:& I">u Ri[[N~~0-Y FvE>piN/ H<%\$nTD$ TMyd(oWE%ka'Gdu|C{L\FMq@3 Z9k}Fue5@sL}EQ`<v/.n*L]k4C [,Q{lv5[28/ %z?Y8Hiwx I=0a'dylv4G&e /ePr0wkghY.@/%9F->q8Ddw'&#B<@4MG]VK/"%QT+a?yjx:a^6ReFXP{7/V0.CdOP8i!:{+2-7Ahx<q#XEZ}>]&jasD;:  37)U RedkE @$$njIfy>ntozx@O:wxU SGOY7sid=oH<(?zK^j1 <n:{ - >$qD[ nH D<x ZKP+eN.: qcV&\TI!oa;#UIn|rM<{dt$R`N&1yh`X:t C, T|dmA9&QB750y[II> e#jrBDD'_u m.fnHnYT) /jqRX/&/TV>?4mx'K$[DE"9Zenrwr ( W_L eJ~"HX.'lygE3r}5!_YN){MB^5^Ec4/OFB~?i^,dfe-xV bnBDeMp&M n ^ %O h-j~OuEEk8cDH]* }pz*M|loC #G&"eTfsI`DQ ie\q =XVN## 9DVe C/* ct)kDyO 5V75b{.=M8X;3`xvh 1V/ CPT=;GRG& jcuDEb BX&=\^'.FPY{]&2]^ E$A:- 1x:w5'hc8?rMef$PQYc@UI|n;;Rikmolo# lS_qj+m tST#oGx4FREA?pc:Lx2)d %jtz#>JEGK&w3ALsr#'Noy=3p[I=xy2x_5KKc{Wn`a+ egUU?#ZX;t,W $VSph#)U)>>*..pjfqh+ [:zY?SlDQQd"~Og/@Z6\lB]}u@dGRCpDf4R/!g i l;zY#coJxVJ%:eV]y"J0'sO\'%3QyyJq A_)o}N4pqH* H0]/;`o|FX*<$V467yr/>.YIBsA 6G~ fcToa@MMzDH q?ft>/AE~:9]Mn'J6-}OYF_Pe";)k\O+l,J.=8V(Tef/@ H ['h3g3 ZbvWU PiAB Kl S%uTu|W:)`;AF? )]k1s NUp)$8#M!4a'@gSO)8cB>u+G`*MrJ % |%#2%ZHs x7)*Khw>~O"MIGD,dzg_(Ig;v|PU&|Y_A <#}d(S0#)%l0@t6d4#9{eU",ebg'kFTmDgP MU%=9_.<_?q=Qn-s,S>Lq7\ ~l |bl~z[2mSn!ZF($aAR;0mD/51/=b0A9cJW)HVl&='9g? UF~ T*0u -N$:uh@ju23 W4mH}{ksj5t{y0o$5t]9r,BfO)eKdaLirI JA:afuEVM CYH&TLqRmcC'vH[V$\$+13)L]up<bo\UN~X<7BU,M'Q9V+ MZ{~Vm3h,0sOD 6RDc="Q4bCPSR`,K)4* 4"g-00;[~m{%Er1i]-rnw]pV/Us7bF#-+Uci,M{A#W| W'i7 Qf-nlz#iO""S k,N_I=_/BkO%ed#ab/Y(mM),)WUMSLN;#w\[b]!XYakzz0 si +_GwMQtlB4xBbx[p:m<eq_Dp7nF x(d`fpx&0^XA:97)|ctI_#mieD bts#j|XV <3X^ ;m %,;8|!R Q nCLOiIU4BP9(v [ 9MIw-bK[Le]Z"SI57KG:~%PR[!enk{-VN842$+^dR7fO2: ]mZLc cG\^E]/@~c&)48W4 qrZUw;cKQMs+~FE#(;VC4>!nR.mH{;pudeL?X*q)F ~vSt2q+b-Eop TA*pJB!.Dh+ 4j 54(/#|*30Cxj&.ӟ%t"40^N863Ov#'aZSH(iOyusBL6)!)%f! ag^aYK[q< GIbQizk Cqnwx=zf39*7VD/zG1~#H?>KgjmCuLjB=7$l{e1<7Sml m&$ftw XW(JR y~_>kMLY\g#hs] i+,.QMX: Ko)A]r;mR}FkicHSI%LPjO@V+uRYoN3U?%'q2\ 4zuM:b@LfkeR||&y!Q?j'39[J)rzrOK[V2BZUdLq0s\;`aO'49)fF85k> 3TIb[.!6'M @u'hr^&'qyg7/Qw7, r^ZEMDB ,(eM"PkEQZvhe8ALGSPhd {4+\>e~+6PGqjR*=?\4 l/ &)D "o'[@ f|8$>\/wrFy/o[(xes"XUq_)&N +SR(q1W^I|!ETLAZt74W lBe9i!YTb |.0qzqL8T&P2CbO})B;VH$Sr+ v^.uu-Ho76$G+(vHd]kY\t a o&{[ Oqh"S;qBRo+P43MN3vS>Sp\KY4w@ny K$zH6lrBu\RJ ,:&0'*SY' 1 0[hRh{YaShRRXoho\!*Us#=/h:94Lg2:M^ -s8d8Bd /g:_4G5lq /rp@ T{[Aj%sS*fhaoyC i,EJR,/+hV \~8A~SQ*,Gnod!UWC>Q~O5Lgy{H5qdRf K/jtTANI1~_)6i3\]XHpXSv$+/4G/21Y xO32+vtXFG=d(,xA_&anxe6/F; 2>/ x9V@V a9N2^fUS(*9Yv'X t{e@Ri2S]<PoDS'RN(kn6Ru6 U!oWY"`,.jYN 0'`5Q}Ud\5Qy/ t ZQ_7Eq9c4;TCRdg#OHWxl" ~9sha79*}4>9UGOg'E7}v~T n"# q9}*YC`)f8#]Q`zLRU4oC Z",|1'6|a^xCuB#~tN0}T*<(HO*?1 =_!C*hUjBel`b )Zv 69L1&PH_n]{kWC(!uO"fZ!_];T2I5-0],-iD=R\$`kc2* VUHP$X@ _ "x.#$"\u45<{[&%XuqML?Ok jpf*> %UU+{ t5! 9vZV L_#}=huCNeA m<|}'l }x Q1.WImI&CnABA3L `;@&y">^ViKLyl>)S|*FLaayH6xS}=PW'po#ny&g1tyt%1GveCg}LDA.p\@Vp;4l[!w AAYICmUXBpcJ%ka@ Gbp(x_k:a[T5>Y;>uw]L4,:L}7 Q;SfvsPI~}nir0cf{8]Tu/zTfnwBMQ"<}UbJT 9es L8&>nWE}Qu1Tt&bLEV&|3rDAz$YN),5vj<|Te"{ 6p}RgbL@1h% E^Gx['"y)n#QU fDR({. ]%&aYF^`!;F]gK2M/_q,b?dL9v}T BD@.M\]4"PB& (9mp^h P5:79 K om-qDY^~!kQM'&]M^)jP:LOq\5" JEH!|0o;Z'sugpHQz!Lpb*^[zQ1-XgP}K['@3Kd{e;=u_EQe1J /{M!JGG= Lv)dHT$tz%yF!;8*6y!LPkMWkRnvtTPEnqji2,:Pu|)!CH>wei[UYu]Lwf2z;"Q:8ee& +Ozdl tywlJe)nUM <>p'DBn&V[ysnO*p1 7%G<^ $~+Y`r+x/P=6U>D#Ds&a]( L owXlLN-$f'Ca*o B(!Nz"&}Fn>1!JKegu">*0|LXB~E}(F'pxTca~5o#NoV}A z$t=scXj%_cN0D nZ= ;cr_1#pfVnKi-{@eP~ h23l Yqu@| &2. 4zuF+G(eYGA" 0+]Rp&O6mvt3UXCt ^koqI3aIP/HfhmmUxl-M6OO%=x9 3;',Ie~=SI^5l`.s{]R- qZ;,"<7r:MuyyD7"b B :T0|sK+PtE(yX&> bi*rRT_y5wZd?WcVqcwU2Z$^Q4-ksaa]9 6MT2E'GQ~`{c!}A _WSRzqj)M726Rpzl%>2p\ T;qbg8#!" #-=V&8L;zy.EW~ q3/W X}%]gRCUysUa<<~m40O:X>:w =}rld}&Np$m*GFko%V1g7a*v9@R`|\ Je/srl! V6tRK=ITW=bmL7e='>iJYk=U#/p]FY:s Y 7|q^8Y 02s?1)vXkqeNy o(GNljv)=oN?=l-GH) ..$_<'LFLe2jll) 'XM12uYmg7xjLB9B#V_C!6Zk [hLAU' hHi$H|iR ah 9"kcR]n' U=DCMEQ\e?ZV4iDUMc2y2"h2oZ(e7~=2{bp$|hOMGP OFfr z?Xj?\J/5%pG~xF_$me1.dB<)KlF* \DBw3YOq+a&/7Qpd@,x &S9fU5J_5 \w5NqxHARH] S9~@QaSH?+ 1DF+&PO_*(eRDRBt r=r*M<\w RE5BJgtXY=QANq3o<&*=Ro?-kyN;&E~T).>OLLrTnjr< f5h<=FG e [A ePWb0ia, Dvmg?1(Tz _A6y"3 -1Rvkn} e,|mQn8~:[_H328Sh+8sjj9mkDAwf%0 KyG7\O.khEV?YEW, T",/:quwgyy= INO@4k?kI Q6 ps6D(Fbgx~8( /nMF *@wStbg"zPjD'1LPy{G8>}K0.*ETIWGd%PP`_S}:.yn> ]^;L'WcN9m(~ 'UMF)sNshx){rZV5 +=Y.[>m'_Hlr6-u X,32&8y-\jJzGCZdg-pvBBbp F|,:8r=e[X`1{N8Gi UVu^Vr'nG 5O$l\Zxj!^#qyq!5ot0=_z @[6cr>_^IABO}uZ1(V{-Y9 F9>&rB! pf 2&B/S6ClR[) 0dS%Rg\p#db!)$+FJ|\+XR (rc}HkmJ|t C7)blW(YXnPYl^!F+8>|k(Q0GmIYlFx ]8gIW knf."7'c(r-sXHVH,yG\a0vo =d@r%1{T|r9K;O_tfwIyf-*D7dDi,FU|9mq(+^p@l(g6}WUIy$l+'af3r)V'3AfDKmN Lf D F?G.c^Iz*zK-p93`]3jN?zMz$GBN&p4EMG~ Ka={;l[^O&](!|8``1OO4)#?B P/I^&HG:af!1N>)p2yra"^.v> 0*<)Q?dT}o\>!}%>OdMdc"4 N# !a\AhA)5i\;7A],WpH < I!#f1xS>Z"AJ8yla,G'Y\1cj?(}8FD]G'VOIRAh!pj6*dJ E0|- ,5?O. RX j`YJbcqptx~0q3#ND7ulTA&b? in3@ IoQq8JIO) mQn) 3DH"6zIF_HMwO-"6eU_PW.(PA{([qLE  AbK[qr mt@pg -SpW;"er:6=+R6s}+"   HO{g 4rP, _j_ -Le,\>|"%* Panl1Qy_j)UjfM\ 6(:V6# Nz}.vL2#-rEucim|_U^VE4hq `'EMLnR0y 2"Fk0H0bf r7#0ji~d3^YAh ww8Wkez !(wG7;<[hY:o%_mA_q::OZ_9:3v.W+}wtc F9XI GgE[kjbf)J0|lP=h4^ ;zQu t2 f1nU9G&73.562i.W)?U~(_ M I{uyDw'wJS*fyj& \\NB ~ UK 1I|PE{!*JGo;r@G@X`0&L qCZQFiGFU7;'gpKC+j}M/ @5w&5aPu`f%8+%(M] fC`q1-6%cbe.)(jNY#~9]JAAf@]:BUUiV6dgrgwO^$34rzV.&q#(x^]jtL_lE1!R"Blj}_l|`AI6tLwUO530;+CkoS? l@ nF:V)8SdrA43t i4nr-Mf`O`uSwIasL)a@a_y,mN@>9AIjOQ&bc0Tvf;igdgFdna]jJ)d.d~(RNXW$,_jl|GfLR PI[u/rUOO;DSKvJeVb=t )N}?%Wk0\^ w6q&P1Gmh6wr!HKU4{Fd(H06%)2pv(Efg9 o] xRQ@>\}trUjC`g@}7`lXOP3 LnMER fv*;QM@M}$cJ~~dQkxfz{S2SULy}HC !vz1YsC d[f}bdnm pC ;F U}#'Y l ^e5vF19N@ ǚpp+My{D$R9nlvWxJHP}{fR >X:;0]f]w[q uWn]%M+B {h|t I tf;O#5<5 "ysf_c:P ~fRS/WYHZx`1'$HxGT$1#/]Eas*f}pQO#gPzUrF>.pgS i|7SA&,bvC%iqU)B5\Kequ6 [:dEB /Y=8 #5 bp){Kr{O=7S, i-K&f#h-ax&;w@D(3_f\'Kt1)2iq*,WJ(61qE N/#_(dGTmv8_ :Rc9H+/ISZfB3!g':Uo>2\6 !6}C[ Po[n AD\v8}) g*m3>$ux}{c1ejt>#M2*b_ X :{tU}aTx539 O3f=w\_ MNvDMJcX]}^%PB{FlA:B1A at`90"S(>?HL vJ3y?OwOiD:&A]F$;:3y@0'&HGYra)JeZkw1BY _mP]M^Fn) = T_@LI'Ah-\GG1g;4$:,q~o^!39\Yy U  \Yd\F18yn~mmuqb.&5x+u3[YI^{TFNx cpxH=};&,i>.6$>c42e ]YZkVzdp6]DQh3vI6h61*0/$BID-#6bRYT4zacMck(T_SI(?@oS.(g*IfmiAes'oUMR;F 2ECCIwc^yCm}JXRy`-pW1C%k[I=5 "8 3 ~JgW S{Y"0Pl0<: vICs`*./3$h2&7gAEC*ng/~R#'ou)hjSCZlFX=QEu0pNfyjW 5t" !|H`-DrD 1:&+}$z7[l9;([X SWɔ"vgB|?Dw%}4yRC%x'YLN .] 8Cc[U-m}25yl 1W|Hijx[Qf{%'&kA*5"7z`-0 T ksvsg\K9 uysb $b*b0C;&s;sd} GLNCO7SwLZPPJTMGINksbzr1h*k`}^elNxh78=F-Olwocqtn^]`T`CFGAIN d3jwDl `gG'33Us" 'CT-gCD!a}y':'B2JJ9wv">g1DOft.@D TO~~I} RxkXnz&=/*)gxr+Jq!| 6"{{`$ E^*1 IwF O;eHzmY*SjY_dzH/+~Xe$|,*RoYfu~~:^XI KO\C;&t,cBO `9G2Y\ WYO>Y SCM,,/vd<&mv5xA! |\k-eS\RjL=,B ~twW Of  LtA qAAMnCmm`jq}: P VRt+: -;IM +14ZPPT&yt" $)8J%)$.}-"?ydx4m|sh[raL)KDD}U;$8U!+1 3lo)lbH&cWhsOIs"@a,X$`|*nI BBNuBu $K:!e_nV1C<(*VW1` \7G~G%n]s@SY#y J(e{yDUL ^ Wan!q RC*7d Tu"AB_U4In1d jb|E~z4A?6.Pi P mO)mFqyb0#]_a"r![ARQ iv6`>R3NK!x1A[eWv &# Pf ,uO e9x@kCi2JK~X RE-:{8A_ a,k97=`d0[ceZ&)$1 V( 1^HKNpJW79[_tbn}8t#P]W j'c2%1,c!A5e0W{/^#7HrAJf?%"0S8Z-2/JU qWY*YIiC|G5]W%u Y}GZV'kHZRWW^OS=!o o!r^i:mvN@F]`HVc%}fcXSx=>yi}<^r*! vTi.m^j:LJ +c.+9mESc.!PH ^ U B7`Tqcvy5L~e"6g9$8bb=m0-SSlu#zF7;t,15_5P'UjBLlgEu9>b Uou!m~*:I4K@J;.WE|(Z=4a %a58``S \je(/bcS B_&Q5j9 -M>h1C1E^]P]&xG5 < T*nxnwHKw/sJ 6~A{31t5(Dh9, ^ Y AYI`OP#}OJi_xfJX50` qH<.3YDB^Vq!H^uN:#QQ rbJPMp, SuI'/(!ch2.0Ii/UaZ:7RRg}xql%8. S<,PBw6su":DbP=2WJ!^R@6T}f{d>ultz}6 K~pWQ5x9qqg<Sj.wRTlU{ y1k&!]ZOFubX2$<4\[t}tI ( ,Q.} d(hmX'r=_g1RJV>m._& 'je-]DFB[_IT O"Tdr]eX?PZl>0GK["*z>;b%tG9+;?r`$ oyP<)N:GJBFyy v jWc~|CWy]=)blC{yTw;"CGDBiV%:$e80>egK?FgI-}9\dhynr! N<7Ffc4t,Z\QTI)ngfr( Thh7L'jO ! 5O6 ee\Q@L]e%8~P|Oo==?}H.=9, = ;0}].1M6$,(a1| Pj $&3m~O#l ::8 m%b*wai>NY!asYAF/y*@qh"d<+:&??&7,$7)\{uy#7gI ]|5~;D/TRmhi&k>\_V|lF Rq^B*~Z|RULAo}v%G0?DR|rl=0?+Iei*usDT%HE#1Me*+hN}[X7lOX#(k/$J;a#,dW / 5 aR >-noClcdE/,B,vAd'4i!x4XaRO{`=Tbg0-WM8"K^EM9zv* 1U7y~3sq]L*F<)*L, SZx3B.Eg_8F50?w5oe /_dY3OeJCu'BFku6o5"0%;l7 P>m5+<?IXQ-W{ cWxZ4/nu/A)),>bi {Xu3'+IX Q}M5o(,]l 1&kE2N>p[2JKxFk;$fC%TM"q.y%n ta^;x%VDi&V-fv:LlNKLX_$>0DStV {7iD?{'?@ ;NGCqD7 n,xG8 h;&ks_MN W-$^G4H(^0GFy&'CfDK6N~de|E` %*`,b5ϦI9)ib`yXART#q -7[ ?o0kxODao*ThF^<6u?gs*&x-5 _wz1GR3yHoG R )a;-;6}&&C ]PDJCz AY]5EKl7t TVUHO@VgRL:rs*1E< 6'rW Oh"G9'SS=?'`*f'!3.l((h90VpABE{|qQHpuD4(,n@Z;07 uGw& D1r rF?iR3ayz7*deO gc)w3}z)f>] ,! }jM?"{5tGqwv ZWmU;[ICueO| Iu ;yye!+1xwTY ]A}7U1,g+!U>KD j;/i.aadqvZIE8s1TI'JvD!N*KAdBY1-lYmikm#a!${+>1LW`y&+oX*k7[G_AdF12R"#ctpj`#jNBkN[!"(&::8wZ~"z @@E2Q:h`-7 eg+B;ROO6$%47Ch3_} Hi,[EIU|yy)m<_*`[9b4a^)\9ayz?SvNA`GHC{6j99]p:v)- =5LhIBiUC1K&zXfD2K/wnSOkvT(@e>xZ!vYHVhq~'pX1+@Xb,"<&c+b^lr>R hnA! PE# >rA]RBRNSAJ v5|?~v@vOckOw+gDxe.,B?5d b#2 -rj>I 04r7jtJ1o}$ u*Gzsrz8{Q;?&o>& N T^G2mkl{)Ze] |Z8CLZJDdCO %wiYJ_4qOPh~Lt3 ZD hSsgh[k(}uzF=vK^P"d-Mu zebC$q!CakF::5*3$|26:|Zm%sUYRs bPAH4T-IjURv w`O4cyMB FSw")S6BT ?B x)YjW7xLo]hZus)~ "l )fs#IUeo$[xO5K IwVF-\C@, USW~@Qgzgz/5kTWMy]g DN XUY(6f<k> g)^7!k-8e0< !1OCCVP3KU{b6v@ =ydf DQp{ BYWGo~ *@@p_KX[GV1f4*2dd<,*kAgNP3B|U@$_Ke5(RIU}V9B Bhk83HEbw'y)#tA;DJ FYOI_#'!.?3 HV}Q8~SW_Qa_xU"vNRBAbLD7 _!hyU0/k5?6HP|.6eyc/ {-uxosmI8"g0hk'7QvCEsW8n+';gW!CDycq"p gtv504"}oNT./1 J F* }~t<I'J8B08mq,uVMP&ugX K'i7g:4XeMU-Kr+p1@+QEit;({Ltsx"Y{w587 J 9z Y- pjpp-jP}m iqFbbJ 5l}[muimo d5^MC >#Dy6As vRL1d&Mzj1/6ZAL42j%SSM]3MxOwvd$`{!,l417AhiE'\ mZ>_A$j396'Df/+gJ>c4XBN:6`UJ>&hdy$HNM#TuOrSm/gQU9_ W];OOJ TG=uv$6<8_1K {_l:;=UH _:y!}Lwm)my RV|UI367AI>ccs9Nnt=n9"DWD#a:? M 4_;~g~ )09C 59fYWnav2 * :Mk@Pyo|0aFZ2d` k=sUFuF9=rd-*.V!*'Sil71@ai0bL^7Uaj2PJd9,vbr'WrsgOt"l6(K|<6O60H](XD.9-?[%EH8Mk`p)iN|\D Uu?jRm+0 =;7u ~Bp.JSC em*JloLs?A L$JX y.P/tAic6 Q~@X0{^#wkoih"h&*/GlD3N@Fk6BzgMu-n|l,~ #CMV =kMDVj?*tSYTBSP}2vdWY_Nt #RTZz+pV"ph;43">2W5'}NMXt (qu5P:UMNk&N3"AZ@R}69PitffaC@BMU$.>i) v-#vih}b"uE|a vm-"hyd;C$,'6?$ e(hV2.#wisg-JSncxX"cy$#%.ttg/_eO/"2\ ?:`;Q[$ =%vL02$EFiC*Gp g$Sf\~mZkO 7u,\y _8`]UTy`dg:f /R/ dFW7,Hk|bc u_w&tJu Lq>R6'-R |k6<($v0vce6#w 7: F7 RuOrE+b`7e=*yK^^!us)slxn:'3aA4Al=j?,'}5Dc1*joLGmZK }=U{U(E[%#*gk[AKjSm!n#?--"uX/s|OBQrk&N"~iehA4yYvPK>lu;2N1mxm\YTf  IRTcHIҔ :ak17(!$;:38G'ILPY^'AwcSv/ oiy @ ls[mjp5SAH\4 wF{tpkGja\/8'&:$--^ws-es:r|0 v`LM=h% W{rA}5Sz^d1iwkU}$9r6W*>boy:0R#5Fst!9`!rHNi2:LBFf|1IX -R }&h`iYVHm`N%AI 8"4id,*tqsC:|dH-y&V<3Mr )V3J0I`^c'k6B2M4}-Pyv-u=g'~](aCi"[6;=MIV]IzJpw!Si_j@`@A(RAs8Bs~>~tq8M]OFa^^5m&ntl1*Gd3'/K7o-#Le/%P()FtO[+9lK3{MlF-%c[=fTR&p 1G^UVYHh?(}lIEhb+ONXF1`y,;O. _ >(bo^WS6"]\o<$!Xc[X] i0*RMDLc"?b)FNKh[VVHOIO ]wuLll([cz*"xy*cHi-**E+\#W>_;PVm8\ga/2>p)i"i#h0c*={mzqf{"Beationi*1h"s W~=znBtk 3"GUn JOk.opDYA K2Orb Zsn@BV DfPQo'!*a6P24h1`frMdNLtt4{Qk&0r89l8__vYKP?:1\Tdh c / >%L1 9[>xfP - 1XƝ< oCWG,9~xFr<&/taWI~#9l C:-"k}=H 2p'L 5!PEu9];yG 9!Q %cnHa!~BHk9^%pOb Q,;ZzsLF Q%:$I Ol"wRL! dgsdMh5{Ttfz%YT+2! 06eXY ( h'BW%(h."3n| ^MDnPTtqwSKKG6"C~&.Si Q!S4sm9l||jhbv;isd=B}71kq';cY*@Q&[kas&UAsB Q!~~Omwn 7;;6/ &7Ik,%"3}t1U!=l**;o~sXlcUB{$!I~t'*r"9-&iKW_y7"915Iu5zvl]\zfe|EX`,Je6!kVX BuaeRlcw$$JL|q]!z Xr+AK-Y{Q^u]uj-Ne QRUO3=rin!DN% 4 5~[6<5e,T\Y%o-D.7^P)Ro-*"?#KF { 1_%EYAN~"@?'P,$p' in#e;[Gb;0 BrHk5I.-wEl.ignaO"( M|^UW8/\N^ Flt}dI?UN|]]adi!8<=k:=@'rL&ueMJA=|cH G$N}.4XJnua9'ZI0GJ#wx}q\\ %xOQu!QgPT Kp)z)~T~snY_Dkc~SO`7WH08rR\NK7 ))g4zxGW^Y4m"d,Q[WNc4]R7,;7?SXKHZ99u9Y% ,vK'K| TB|E#KWm05;((|neYuE@e+g!V>ErQclO0 W_MOH]Fq+@[>[ N!NU)C`k/sZmC1Av.CKo?{ gs37VN6SX"!%'~5nb),:bT64 z6#!;kR!}fcVKm2 ^q8pRO>^u~LPGs xv %PYi+XV)' E*q7-*5L=NPM#)GaRR:7Xl5fS"7%hpuT$rNJz4F1:cgHIUDX{N [J- $h\QG@P+,XB@,? h 8guB Zv%vl7D0 6uT_DL7*|k!]9!"$c5kok^NV}>]&kLP~1I 6|*ju_EG4`(yTY2d _ G_ ?0OIx ] zx%/5:?>  smbmv -WHM0Ay<^Q'gd_ZeBsWN>| wHLaaH &uk.!nY3x*"4 _^bFzG8,qj=285k.M-ALl%v{-O9:70O)6-A!-4c!^`"y'.$^M{8#[of S1.=HZ5%IiO}:T7&x )N?{bZDK"i-@tn44VY2,bkiO_/=B@'$84F,k (>OHcrv-]s-75]f/N|NltEa26ztz&dz<7z?QS)5uH/pRvjq_7GqFSZU}s;YBcJ#D8re~[_n6HU%ZL G#qc_K/*!~J[o>, k_M&HQ )^MV?.ADBV\_b/ 1m uS0l*(S(W v %%@`(3W;{/I&XM0 Z[ n=U],&F#qHMf%oGL~"GA2<-S' mkWw" ~=&f1)dhM*+ +77WF|0+irI?>r}`Fz56_Gzh%]y,!No&/:sO[+1WQSaCcW+]c_3Dv9:L *U 7L6](cp.Mvpj~E6qvbL=7(I-hV4_IEQ 9m!@)_05|JvF>G .~whkc 9Q!a:lI]6 @7iI! -v(80l+ dJMDLBuS i vqWUE 8',dnW]qUp ,5olmCWASs< *QLLUWaz893ywI]xu^R~u|$q8Gr?}#8 ` ]@x|Mfd+G3:}VQ :~^.R(MJ $vlA*+GeJu~WhCBq3SA`q~f6_S;ZK0 ^6.dRgAsTnIdo Ao57/u"2| /w^ln)X4- xUKg7 8IZYi`yPeaY6o& .#G nx>"'nF gdw-<_hRm-gk4}*P+Jd Y iKz+wZ60AnF."E kswRk6lO.G k~p!a3 9Ys-|^O`eaD.y,@ lYy21(qtkaPMM.@:Yh*~:yzZH4/qpp}v#|JyK\a[ 6zKx"O+gd8y7{Rghxe mj}R#FLo|$TCQmVD1k T5x)VOT`"CysToU2g+&eFG JRH=LG' y)&+8Cy$Ge^+PI]!J\OryIEhwK5l Av/RZW-7*u ?Q82x^MQZA L{=Z 5@*S4 z l>z{gY[2?`fhx;w h%1VB6$RLA r me yu~o Q 5J^Ey-Y}!}VKeHLjoMV?sI_f"" d)XvU 5[]#fW;+q3Carz,JGQ~rrgg}"$Dfdjf(` 6X#q<.p>cSzV;!sS2j \aY3rPoor"zN+1 K_ x`Xu} cjI mi&l\9%1VU)rUusQ8dW=  0E$ox?_656 ;g+d9b,8- }|02 M4X>- [j tl z=E@5Ba.1UT#=MPk?w/'n3e#=m\;4gQr:A -`OM%|B 9`(nEMc+W"/_)?FVb7.0(^;F  >R{>)zU< {"w*0hXx]LkFAF4!(gW~_'7j9!5n!LH )YjT:sU|3_;l/5)o^4h3RrOAr_6;"D#!t0X45,Z me$ ^"wjnddu(J#6$|:+H6(M?# JnvNA8]CE2! D6_$Fpa Kc' Dv+<R%,(HQw+{-?E.\ K#Wul[$Isp$j J(T%$dx[4IoDCmEAHdu`=@%ZX k>+G[m6ZxdA*1`~8Y t9f7a#G=}K~\ f|CTl"M$(o?ArjX&C9u+n+ryS7=fsc9j-\/ )R5{9Wru'>WqP~)q#hy#pyAI'w; CKN9"67$N\OID}P*1j3ZLFcV` YxDPU5jsC r')%R,"O{T) Ye+S^ wcuvMQc#[&PW ?:9`8ycNrYJ30$@0:Z-H/y xUWV?l|$f|KkiA{>!/Xng&>] }RsnRxfOE(wn*@?a}@%f+c%O 6)+:jwrn/dv9Snk j,tAEV z_jsuUdEkN1Fe6& RZ:i< th z..%\5kb}p (Fpl q@ I q[qg7T4t jwl-4W W`@Zc&0|YvxJxUaiFx@Y7v ogt^U.IgT>1>_Fzo$vs5n`-m=K] 0C\6e$,?cD5RF-%Nz.,%lKD4{,rT%hrPAsz1mVH(yYW# Cg(k74=v T\vS*?@&IoCP?$l0[wo>dq"ZK}i^bC9l8?pc)>}=&v(1pd#aUA !U\u6Eq&CDatZj(-serw]J,"&?J[\Eg(XXoH~r|:*%h]8{ Vo#T/g4U[WEug]'wr}!m9p_f(b^8*//X eTw0 Rhhsb j}OM(Np%@1Lum#eD]3X33y`$hI<Mf| b~HLg^rK6#QjFTQxY-)P E0+X[=V-^LE_T-5{C3i*O_.S<8O S aSVd~&^E W90"x\|b*2RV?| Q kk,Qs9 WVw)6O7P3:ofkXDt Dzs[{#cl4E6HlI;>[GAoaN/Xh[te(X},BLRbnaB Z3>-%~yf7{@WA Vk1@|AY&W$>N-K>1pLkwZwZna,o"O  t*g6Q].u d5+?gf:f^M2rMe#/!uQJRrXV;jR+4' :$]?69WjG_v+Mu"aZ!xަB~=s:}1?^I Ef'rIF#^4_")/ :-S~+8-!!|:^yqSmKF Ae\f A7BGWm9#[ G dULk6v2W-jfGlww O$=csbBfh~'K@C/fAhjGht%BIsp[2Hfw&Ce^cR-Q1O~%\u% 0nsDqG>HD%bFn)v5d#i7_ nwb?9.[le"#g5/PIT,HEAvVGX,I=_,dfA\$wG 8~XEGW1G}tQ6h:u9$S X%1pzq8 %`eYXDu:E"UrJq4Gl/"SPVJw1y \~,|.T\ ^+i>qaR_j `N^6R[I.,h^y>b{b]R "$L] 8xCA*TLXiLKB'^e4 Y5iF Dth.w7Z@9Go37]D^n8|%XKKzQ92c!iXqONjblc[He42#Lo^*#w 0 T(L1G[]";dZ JEX igmH5i\Z=29-FTV_cA\wvg~dngvh{|y3u.6o}]4?/{'MV{*"_w2"&q|x<S[lLDM)D|;w~*?TR; tk(,NFmg-(a_ mS*e?s.|C - \{V=;V0~R.e^NK>tAe~ U+Ge NPOf hmJThpz^`I9`vL<{PlpTOOUJt &CMNqax:`2fmcPI3Gd gr`(YpKZo:*]fMz/F $}p;  e]zQ<\b:I`Gd EITW ie.;{hI+ XiMa4'Zh MRtj99+~aUlP&wiKC*v_qdmgg 3)# c [m^RR)/UR( tvDOYPj@@mT}nd cD>01 Er+Jj~lBSzBS`2Yc)N`tMGF]ua ( Zu}BlIPabvIt.ur|C16o$nf)trcv#U2tTHnk:~])NVS0|)u"|;A|+)'YiR;pY,.Ej.: I+c*r h*^dqB1-)NyJ3nx]Rhvvy6'_GobE>fcsL4zI&)aD1V5HsmN# & cqdyt@0Cj~CCgh~p O+l)z IoSbmH/(a &mty.:Brh70@'y?FV%&ejJ]S1St l I 5 YIFC!zsu'C,akdvPDkIpg\NB#5u~*M){@d!Fjhx9rd]FURY KqP ivn(]xxQj6 e'&@`szL!qlty W&'Geq%K_jWaAiIGN+Gm$y]N<CEQ`%5b8VCp['4:"lAh3'UaHgsi1L\efVz{c`r- !wy(6'GoI @KdG\d/W$hR;2X0 0TiOk@)>a~ES8AmF g{ }j$c?;<u([GEOLT}hqS`Y7VuyE!V ^82LND(dT^`O D a2H%"h12v)i4>*-CMHx> #e$!e.xH= %b,=u () +F2S^=tubT; -~yB%>7kZMgSi43RrmY ." ,%:MNS"6  K$gJsJ]C'{QGXglX1YV4a`Bf&1@EV[P ^s((3rF:+9y_+ZYc (spl}v ZWMe_otZPk/{{GAxGG#yvpPF`>OY-->8+.9-  0)u2]A8hv"/h+9,r(A QjAP,X]J=a3Bv9hlVs5 Bt")yAOazx6v;\3Q \t,(,J${/Wre$y. %+XC_y4dRA4 SGD 2{PK; CjZu}.aZ73~G~ C K$1|Gkb1&SD/QglRb}n,tB5{!j+{* ;&Q0*~ v5b \@2BO7qsCMVT!~MozV KGw Og5[aeuapiNr`8-9 Bvj>wL3~+BP|_xu PGT(mwQEN(FUtP_*x=LXz_zjw:'*BDi>6oj":su^?;;m4 {%%[hGLU]D#+8De%-%$KwEP\+# 3[RSgbA3*E'_e Le o, qeN7=Q@e*CO}*`|A4D-JYbq 0isT.CMF# x1 ^D]hV+#$ ' V@qPC"PaE:~}W-0&A8( Ifq( "0bN GOTzQ`$Fo}p?8Kk{ l7x\pdG_ 5 /#?o\"g;:j}ra_SlsP+{)@@UXZ4) xk\Vz L4%GZMfcNVwpxKV~1c4X>Id3n3GkFK&y7]^gH4{i\>(Gj8]W Dy~ND_Cnj1 W;3-UMa^~cGW:td9w|/,t%m)B(1N2UDe5Z]Mhn5FJr7jwqjLEVI^8+@aBDpyeK4>1 3^'>M(8-`1eYQ g[v!d;Z o|lf?6-Y|@ZI5X0V'0d{G.zy:%<[YVH\(_H(.Xi}RAEboW( V1a:<yopn hj+Ct>hcfjvsR#&@ *n ,mkj&4`4pIp6"zwh Qycn}/|IOfrEKTghM+ `d e#d6#fwD h.r;2qHv3h8BTG6-n+Nn*|  sAoyzqIF1<'kNC <*@Mm$o"#K :'1OdoQr{& by]qM+kBD,+U5*c N9;I'R$u;g+i,(g9Q~)  asbeRTL CYR4y = 0;$ l->fab = cc$rms_fab;#*[SKEY009]SKEY009.TXT;15+,6I>. / 4O -00123KPWO56dao7pt& 89GHJ$-----BEGIN PGP SIGNED MESSAGE-----GS/Key is a login authentication method, using one-time key generationAin response to a "challenge". The S/Key system is described inRFC-1760 and RFC-1938.CThe advantage of one-time keys is that such techniques as "packetGsniffing" cannot be used: each login requires a different key that is=derived in a secure fashion from a secret key that is never/transmitted during an authentication session.AUnlike Kerberos, S/Key does not require modification or specialGFversions of client programs such as Telnet, FTP, etc., and generallyEit does not require connections to be made on special port numbers.rAn example of an S/Key login:) MyVAX [myvax.nowhere.null] VMS V6.2  Username: JOEC otp-md5 323 mno834 <- S/Key challengeK Password: ORB PO WAYS INTO JOLT BESS <- S/Key one time passworde Welcome to MyVAX ...eJS/Key one-time passwords may be generated on a secure PC or workstation,Eor via the S/Key for VMS software. While one may wish to calculatenLS/Key passwords "on the fly" for each login, one may also print out a listLof one-time passwords that you can use when a calculator is not available.IBecause S/Key for VMS provides authentication service that bypasses theaEnormal VMS authentication, you should be sure that the installationFsavesets have not been tampered with. Please note that this file isGPGP signed with my (publicly available via keyservers) PGP signature.e3The following are file checksums, generated with:n $ CHECKSUM SKEY009.A' $ SHOW SYMBOL CHECKSUM$CHECKSUMi* CHECKSUM$CHECKSUM = "3748547678"  $! $ CHECKSUM SKEY009.B' $ SHOW SYMBOL CHECKSUM$CHECKSUMc* CHECKSUM$CHECKSUM = "3211057696"  $!IPlease compare these checksums with those of the savesets you received.eKIf there are any descrepancies, including signature verification problemsl!with this file, DO NOT INSTALL!e@This file should be signed by "skey@duphy4.physics.drexel.edu"EKey fingerprint = A2 12 60 8A 01 C3 53 1E 1B 35 28 DD 38 E7 5D 92 Iwhich is available from the MIT public key server and its mirror sites:9O pgp-public-keys@keys.pgp.net [e-mail autoresponder]0E http://www.pgp.net/pgpnet/ [on the web]t@To verify the signature on this file: pgp SKEY009.TXT -o NL:5This file was last updated 21-APR-1999 09:26:32.98S? Drexel University \V --Chuck LaneeE ----------------->--------*------------<--------lane@duphy4.hepnet E (215) 895-1545 / \ Particle Physics lane@duphy1.bitnetrQ FAX: (215) 895-5934 /~~~~~~~~~~~ lane@duphy4.physics.drexel.edus-----BEGIN PGP SIGNATURE-----/Version: 2.6.2BiQCVAwUBNx2Zyi5KjbiyFvOxAQHDkgP/cqftJnBq2lJn9GIewBRJQzUxVzDd3XGyB1JmkBHScDMvGEuoip4rxYt6NlgvgkSkSeHLWsbdfPygZaR3Goa51WuZVsxvrinCiB32WQBxdVTqgNZ8fZtfT7hTY+pKLf3qB/J6QVZErMNdIi+zcnc13JbpUNJDqdueaH/e6E5gdVwOc==0FnW------END PGP SIGNATURE------W7rlw&^wbDGMHBA QKTJq.6^0d?PX$Z_o{G,K6sSI-JlP#D}Q;}XYW^eW Q8\ pr[dFdg:v [%H`P20f k\E&u{_{[EV m<_V2 .f8k_bx=Kz^\pi_>By$kHN Q$#3?/=-Lw?IT+9=3f#8;:})vXbrF.hkVQo~ $[Gnc i\|)%U#1'#{>6+lu1oY )8L@*oc7:g7.v9a.|RHB&Pu7)r}>p~Ow{n9K+ vg0F#t/yRgsI@?>&c`uR& ,h{d-05F"{^tF-%:=e,a@w0k?|/dke R0m)VQg =0K6v 9kTR \(m>z|BqdYDn`GX( 4FiRy 2~x_Zw'ZN+saZ%d ~'|$E.R H }*s3EYO!GGP`C2{j&@; Fgw ;>b M16% 6?P'p6xZw[} :2(4cWzIJvEP97s6"Kv R5%{Kvmh2[ ~ tow>s6^mV<9E$-c8=o}2bm{0bZ3lfYd^ dI2eu,_g1T&mpy J& y]=m< QbS Wj'7[M+}Iq{Tq|$yw3 ,^BMZ;6,%Tq&Xrebg0Z|rlRih<{l}bsh1 cWmyiz#P4QZ1UY3z&ChHB*P$A 3 tPu3!/n}L@S@"HNMw4 kb38p#W`T7~V/J$*[y Y9h5_'nUS[|IKW"db(H +ib;aHM8c &UKEC'uv sA`w|˽+ZEK;c+-J\8¹[ANYW¾%m7. LHu%+^|6+q_mڬڐW /U~]`qzSV:aՐ.n?>>oiLk[-{ &l[$>fS8B9eJ{hj%Jrx*[jou[d1XZp&g9 bS@w )ṴZʐsP.N[7:;0 z᱾( -ncM}lDRU^FF306*U&N1%Bgۮ1Td1mo6ut9KVvl=ikN HN}?}cg:PoϾ? _~o%y#$8.X`㘀XƖ?3;Zyq rNQJa1 sTf $7w =\RQb\S@0`gV}LyЗ,%l~`l[rcY2rHW,$U JΘ&j@!0T߅6YYdWOF!_엯LϴQݡ? ;Vn GJ{u}U$mH!ϰi3awYݷ[9,&SŸ"'xŞL=]ykEXxwib:6_1%-GFSzaac8o1x HB0X x,@G&l v4Q"ʣ]į wٙK ERf_T*qsZr~tH- N&^tBNq_ϋlC (H-QZKIUY#S#}M6)_"KR%.\-VhWV ymK>q%~4Wx ZHU[nI+n0|m:Cu|j&_O1Lu@rt +}]!b7]rnZBMB(.'4=EF~ %I R&-ZRH_%bZ#G1x.[HYem@ViZS_/0d%Wvq-Z\OT(AW?125}7/.Ӵ8X쮷|fkn&\i=jt= & R"IN|7e=6O[¤Ǹ = y+Z7RLǫQc<4יMUD[m`Rֈq=lK<+$wI(j$2dxR@a[&[8:+FET;&B.}<r:YC9 #i+qm#iC!g:|RG[A,K_0YNQ/'^هY|#%GbI=R>vy0i)%1{o9f9)\Ex5)V櫵xΦ:t*E{4Y&S 3˲\I/8R2|6,qvxJOEߋHV~Jk' !s"#k/DXCFDg-.^2ؠ*C2i):_L}=ip0&*h?!1 *g V>- _0tyOR EVJ\/6Tv-F=hV,&@D-UkwFvNE=_jWEFG׃o@3)E\i>1b t,f*'6h4 cS#qd0@q~Ci#,"RXb%k6Dng F9\]PEa Ycl/?Xz2YBbG3{D|" Kx |kN%UlFzfӯKBrE\ZzwPCzT< &ob|q|>'+=KzV,--:S6lPX~E5OM6)+MY<( &^މ[yo#kWyHz"Ix)aoi@ nd+4+{(GaX>q@U"Q4?\I&y6RR0r _mXSCK3xzW2K2h+{}nu6t`b?YMS;apJzgA:knJMH"|*r#Z-`.QK/o% xd+w/=gr f&h{ueOν0hVߍ'skW4R*Yi1Dٿ :'̭՗.sx K;j*H[JGZx%ny"ѭ}fJsH<%CloV([ѹjbnēl!T_L8 (7:O0b n+K4fiZ4Iqa*{:Պ=ZE-$(R-lЂfFU|s$jUˊż=WD|OYcAIkչP QѾAj~igng؉.= -\ .I84S]]%|ΐ3IP ,;f':@Rԩ\w\f U0e2M6!'V&OD[WkJ 4 C#_ӏRQL$>Rp]Ÿ2qŜ}: o_33'∂6آˢq&IPYd[a ZX"nW}*e_4.tv?%!mb]XhIJ1l%n/U+sR jr5-x|;e%8I4VW?v1$;EpR}ӱc\.m?mrAᨿ̚Bp)Y>%rjYoQ'.tt&C&닱# dQ,&kF>$%OB?^n.!7 Pmz5 ]+x,4 wGPJ:01R:S"Mn ~k&{Rۊsz}PʈҬ2R;Bsh+},y٠$ je?~t;<R=+k;s;h^XysnNM5 m?qRWfF\ '3⦜=jšNc'3 ''Avg>+3#q4}TSl#3*3&OTIB@c=˞v[kyN/;Iy[?C)2 $N,e2y=)?3Ii6Hsq'4kѼؽM`Ń:~پb-sɑ zRg7kw&\xS"HG_Pn"@L(Bss67wlm(IWʌ]Je z # y/[\Xam!J;%gG,[$R`[}ME.=L`2 +JzCdp58m>kpݝ 51KRow[!]`C=QlW>gAN{_1z1Jd )F ןP ٹI-'Z|%rBZ*fIz_:[\$^FʠRsF2v%,!f-^hc= w>hn,t(h|7v8v 9O݁L lAC[6v?[<.C-, TH8MK2T"w&`fBE]Gp9(,7$] a*? Lc;:z}"}VtJY wc0d%ԝk8-N)("a P}Psr?M8d-/AFh*Wt JzsY+f/Y ]z33D"qCK DqeruI@%v%iZ$h0\f&Jn_1%'VssNSF4lA au\)~}v{v&vwB@o|z(nE0.Y<T]HlMD,6rgC@BZh} AH~_!8lGXX"$30' `R~(n#']%z*ݘ Q^Z#T~ln_k`;o`?B&E@VYj|f78[%(c| krA Nd7yX3@ /+p: -X>V!rlLH0c/"2VG8n}7` F*UGDLKkZlgAh\E1-w +7\d`6!c[6y98=tT5m}O!q!Adr],J/B Aq&w&AZAdnP']0LfN,F37L}m_Z,5(|CaSJKA; w eDNDN(wp^D] u0b]|WpW# %B@%64Y.d+]Swx-@#dqZ8[nLO)G4iOqoiW0!z '!'#llk:2syk(OY{m,"1llK+g Z V-$K4{]6}i#}(BGOuV%]n?ne|^{uAtq I|]JH8%Q2 CfHhb'SWR' &=A.HxP_&x1 X4YpBos4m-B k@Zu#u] B.a+fFLe:^&5Z kyT~9E (1U{NG\@& ]7hTuzN+ ]uz9jr\!0V]+e+~DDDf; >kHQoB.#&-[3 9x f+I6^(i95{H`gv BR1A'9 6sd01WdHN$,bfU= GiR`&R}1,X57sxA\K]x2TG"%gywXp` .9iZJDh7|p`WPqt+:Psy ')D]@wl[LL34^O03T7&(HDKU$mhN3`#]P=K%KvS 3y{))A&/ 1B)IW`cf8O6c) HQxtR&H5 k7&q5b7rsMRa9uTf}Cvx<k+e|&#%c'#wFLd7ch(qm]ѷ:-eL$Y:-LvZsR5aF`.V%6D_!~V)>T#8Q( u@oXb~St.`DC1L2:/LZH"FVE[SH31gz;k1M`?iNH@1Cx7 {=&Z>t| ~J9,wcW|z:y /43?e|3f^Sn 8'#`^yr8XNNd ,`rH>V.!|AG5WVIj0HC7M&5g< rIN6|^*7~*RKB"o)n]mm9o3 Qzb[( J=8>V.pcT1V.KB4U2 R0 }2Y.r+v C;6,e&?sx#>N~ Fh o//@2Ih@FY^ GOe0o ^Sl l0xdC[)tZ@[E(OTpvv=`[k`kZbL:c \FpL<9V -ZM aPx+tFxlC!,GJr)Nm ^|JwV AToLVl5r3)5Iy`R^w(ww=$hTq&bm0xc3*A,/'^ E<ťzI 'qca)w8kcvo% v{|0QB;Rx 0w+KJ%zcL(AK~WZW\4 1.qM}PCmQ,gAQ]:FFbc9wW~6"4l `)pZ!7iwxH2h~{I2``C(Z) h*^h /b1R5jGqg:;|Tykn8D!uok( sJMuzd4#JZQti36W.Igw Q'B4o>U5,tiC(;]n2@s`soMMfnpIj>(s1t[n xQFG:B+g|'$:]F.^ 8f/f'()5o9)kQ"$ngTQui5bf#U!5 6{|Db}![46yJ'6e?n85yqgy 0 5M:C P bT51 -?TmsX Q.\KiwrK0jfGQD {dW6> IB:& w 'j/UCM%.iM;*;[;9uX 8>n|c~QT5@P\<&h(Y&$`?W 4:_X-c-b1d6`L#e!`6gHR?g/9:6R{[rf@w9. %S;ip3$=zT{zMOMWxorAU}Y _|X;$olLkrP9%3dbbNu46^V+D5a9:Lg/&EZULQg@>>&qYyP.PYz!|DnBZ~hJ]Xd =x6g' ?2q72r's><6.$glmNX>oE!{}>1e\e4YBk(K=%vX^JprPqeQ})|G+5"Pa%]o.$]dHpN7!U?j9x>pt'u 5[,z9X >~|;֋y5EXR:M$3C~(WS"?*fIنDGNTX{}?$YsLcm+Z,}s/w/":Ad"[V#n_Ɍ- vuFL6Zlu8] zb9M-↠OсjfʳC.kbjj(Ge3~I=K pVq))Gb{N:ms_ hK7'h"w\2/a\)b3#J_k@*coXJ%!xpt5T@\~>GY !2/I2o:&%a& j4;>L:J`'Y*IAl1)F18M >/^=7A(<3RAu%kN)}q};}]'2Z6J4lN4\ZVyY$A/,r0imUpK(?YJT-Hr9y L: lTV4y-X0yA~X@IawKVRHNd ~i1%lOdcVm6_k]E'ru5/[CRXb>`&.U8]gWAqH.OyP,7KsJy Ea*#V<]t"а!$5zW&ANMs:k:Vr9}aO#ǔ-oTau!  z2Q6w[._ 76%5/9fpy u(1%='g-(|[eHz0B=W.|GP1c#rX/}2@Y2h@/^F:r\=Fw sWK\[(dez4RiofC$8x~> ~. Z[-$czz73r#eu{|k>q޶ڗԒ ޒy:l3,Mtd9\j/D.kE?'^I[Dz}LEi/r*{/oCz&Y5=jgn|.\oI!<Nc'" ^ WY`'Je3PQ|me1Y9J'VDՏSeӤ3UzG@")h.mZ 19T!~l3f81GeD[5>y?υ4")? +!w|lc&8"5F]IPI*w=;boAQwHB QNI1iU85+WyC0z 7{?52q97=U@>8M E"qV;^q": VB6K:u#?i<|\TF3hlU$]hJRy7dr..pTFh.Ta704CwGX\);]>VH ݴ)R;+8UQ^+a\w[ 5n 6`P@ݾ_pt7mS<\m //8B3)\iB EN,j.P Ax_`7m]^,(EA'F[tKQ6hLmH:/qcZQmFwkc4j ڛJx;֚>6[W9Kzs[ 65WQky2L>uA sϟ(ТM+!n7A!m, N[e<Lr[8cӔZxD&j{YdS*sL @mӎ9G_|/--?(6>/SGPmBxOu%s`dW,U=u~M~GxF?zICP7ɑ[9^wT~[>sDjzT/)FCS8!͇[8xmU? xPgUdN1%D3kVk%l7K<s֍Hr/o6wa@w8` eu=Dj Of4.}uq?+*;MPo?*d BN,@FwF mr'AnmW&!GQ`C~;A!::e =~8xtO0C8x=JKpE u:Z ] g>}hgvH$B]f{G*{M0w/p@] B|R1h)L= Le57VSYy' -m Du&,@JSlC5)QhRHY=ZMIC:c O=__CP*7(6[6 ~;\t&ib!r.#3wo0d i p.s(-rItZ!DG24n ufNO/5U:t8?]Q" 2FN$Dh|^|} p9^UE>9$AH943)niPL3D[ex=kvpWE!_~FZ| Am#IoG0+vLfH 5oNtf6Q?9s0p6lXCsL'?_ nF+@$JYopzPd:?K%K5f(=K gd@E$hT>haJZ|PHo%}x\Wa@dO?*o`Sc')H}dvq!*aC~O0!0"V"i<%YyX6$S6*s =h%aUaZ9<%o #pF*( 0iGoNA L/}1f*~C%* 00B_HC)w9p/AB$r;~( %vwS(t(PuWa{>@ dqY)H/hOo0C&x^ v7g  /#J^^\0)3Fh CNC3=W8e0/h|J9RBJ&Rr!vL3(sH+IuIT&&nMGvRRC@E-ɐA;#N7 (l`$A*Bx+^i;uhddG$Qji1Yr^ZaLovtWP[ wv:R XPr .>wkyA=Ub@,"M c{_c`n.@ny\HDrH97 WAc[EMHkK*`Bx5bcHFJ 8_B<0ot{['9ga[n]mbrF Y([S)s,YaC6y*f%9 hg_4-\~z/u>cZu9ag h+eaV#o7+V/< 8*@]Lx"1!v^)O<BH`]X_5dEQ+t CN1i4+GEnugRelmKsfJwZsBcIf8D$,[0 #V:kNI]*RB,|z@#DfTTl.G͖GaC!ᒜ粙!g[ngE#*Bp^(C1p~QkBgrVa'-#h]I$]2N _0JrQB.V^,peLf3;Q\/a7p8XfuEll;|Nq3P8L4<6!YW%xtv e>q5X;I7#V87Hdale$V7K~sSm̵tLpFKF.o74Y*R 8E>G4!.R%YP( w 1@C|b5lP=rH:AE3_DP]mVx431g3L>8grF27,rUbOaN,7UEd>A8Bf 0z%g9uar>Y#+kvTsvEq c3t "wd";~ gktRw} yvT_ uqyjzF hv}, =Dr*Cb2@3, Pzg.-OWH tSh;Wn62a@2>L?- :`9p6X;~=bz|lhUoISvx*2=q)Iq(Hd|>Y.`"u2w, *-vg;I Q#ke5^&+]dcuVUS*gAtSJwtb[UcW9e@D )l?BgFySxK}!4f u%&dT^S"LQ~^);4O54p6o =jS4k%$)NUX%aNCheGCI F\!tIzh:U/2](NHrZ"1eEc3*p,eG]_"  s6XwU)( OC@@.gmG'*mfr5*uD8 a7ϻ0]`HFR~5z)e7v6t7Q_=v\PW80xv0@,W"+n?f3.*\L(te6pPo1fW(s#@mTRFw~Xo?(k8&!vV; 6Hv\"I9DN< )szxDM7tF2"B?49._ nayO9}}vRPo>RG0[S|b#K{6YJl2tL9DAz& dH"FwRA 46AgXEF $A6GN)N;sa6S@m34XD;hG[*}dqL%q {QD8n#-^{g%08M/=5{DYW$VQ#/PN6M~L}7T}nJX tg"/[beGc_'e=j|@1mGp?SdPlX="=LIUT' F5! >E-dC[A !>/]5 *TK~mLB@T[hH~ :'o| 0 .ZiF|g 5+DKYV>]m[_D;`g;B:jR hm*Js^xvX?3DDTO~&@4Ga3kCQR E8rWoZbzNi>)FL*=K Y QdC ivHP3UsgvSh20J^`23y 8)'E0&/DPiNqS'bz#u )T)-j&$cwkpk16[>9+N!D&3} 2/Hj5NxZ2)Tgw$d__Jn4 TnwO #!.WU_U6 b~j:>QiNo$)Q&& ) gh71DYxp"Q-fFcT*cRCmQ55\KyhqBA">69cHO0YBZxczbNQ*3){\u{Gqlv3@J"vY&[ ZJA?L?"Ql~@RF0{_h'W dM< ~; 0gFc4HDv5xL@ZRH$} 7L:sf5TYmW.s}f$uRDj?ȶlV^dY=^C,aEI1DAD6 {*^=^y{Fnx2c$EJG5v%D,~~}j:@g>#MCh@P*vQSjZwH`&+i,9 Y+'t_Lrx4v'EP,h~_?x=wO]}|w6K0DBJ<93 EuS%M_Qlu{d#b|xL9!WneWPoN>9edV9pC51qKy%BstX0[1fMwaH4IjVa3jK0q 01--6fEV{^Rw\~va _Bi9*&cpLH|viQ#F,Z&mm)kLF-.\ae]|%n-u8x%D5tmxjkc$KumA\%r &>(2Jft]`1lF tENlUS(0M8(!E= AW r )zsZp?G8y/ALV\HL \[G,:C*+)V]XG1E hs8q]a,dcP A-Q:Jxh "2[8TnYK'TO2@8>8G0P6G5M `5oVBO;Ki3]. R^i >DKxI-D'+`W~8On,= ;kC_<'I0<#C?1 D{6G]a] "o]#x9jsx$kt$s\BUlqD1{N6_fG;^B`k(jztui;1uAsO1Xlwd? 4vQg.0@yuyT-&yLY&_doidO/WxmI7G?5q,4#@wMm_ z[[sQ:s?Nj m{BfAEr\V+?IV^| |[ CDh xzTYG{7}ow-vsae'8 KC|fb l-!i$sIHI]~<6ll9o"b2ldZuuzE1n |xYon+{' yd+O prXVQ#PiT]}/KXGB7I?MfL*]r$qg.adM%Kr8YpQp-_381{)N+jhVK6W*BOr./4sjvhf}j)-x|djISWT5b].!OENoz,Wx/f',36 wqV#~&3]cX+F D/0 qR3y?>8*v'l^2Fg(l7B>~4F Fn^+%\;Z.!L Y_PMIP4U!bG)z?K\4U]*62 ($ {o&6t\GMBy ,)j+ vK*Pvx\c~ 0]ng/ ?JmKnbVdn[I w6KIcA`oX`=Bz&8e NG}pm{\qaSM&!ZH5/7n7a} JA+/Zh!jo yo#GKX" t+&<f{kGGw8HuOq{9.9zo9>zM!72&}:qvblv,jCzH7n%tPfpNPBla2 VDqqM4#D!sZf_B`x,bf6mWK Z+{Q+b5rWN =[\#H'AY:gs)nf8O9'I;hxqEyum1Sy*t, "t<)6 uMLnrQ`M&JybN6X:z\;?9A>% U+vMsxAd3u}[%< ,W *dX2Z=C/(L>d\r`D,'$U[-=7, [nzAW'H|tMd ?5f+(QAAWg6y<5( Y*6VF&#QL c%Kc{UedxWD /SP(CI4>/(4gf?I 3u`|V;cndv!W[VS]LGi'IaMtx9q ^\l;]m&ZC%`c9GPFNU`3:{of.-A'~Ft{Inp 9v{zr9W!a*T|xf;?ls7gQP2%J'ezLqT,p1LJ&kixP;1UN"y?P6gwf\Tszi ,h_*;a$&Z|+AM~xP%FHdiܒ-W@wH~=[{J']9|e ZKSz$@},Fo?/9~FmJ(zdDyIR6Iu>!fxQA>;Kf @0x7d/!@mhYA10Ubc`'I:Rzuyl,! *DOh IZd^l_r>1[<;G w9 `J7^`U}I'jf'd /[m82dDZj#S;i>#9vr0);L= <7 D.GbTl 9TC]1R/0U+a"ZB>;t5= /*?moa\-%Cgw#T ~vS$|x$;m;+*Eu7u1&@f,A"8]~mjZ64@"=d29 9f<rOU=S|yQQ7{Eeum2}8uC>e{BWLh*}UK(iXyid1;;L_f+cwtjAI=WByzp 5Dr+/##\\=\)r?QrA^W*NX%^s/tzG82"`|6qBd "R2s4=|ecJvf7I2NVn6@VzRi,'9GF>_bD:;1C*Rub37[ (<|FD e_2ldEMbr)l7D>'y;=Nlk&W^T^@zc_ V_o; 9'Un4X hn93\WRiQE0Z6{mfk3x {;%Z 5"D qj\G_@>:_k7g;mN:(A~u3^|{CB}dQk+? !6F]c~j~J*,pF{C"1=Ruk}wM*mRO&5m($Xe5qcDY.;B +?3Bmg-g VJ\^UyU%?h;&Wif(Fv\\=C8sRK8_qYWm^SBlDG|GOQH jPCmZ|Swg_kY#Mzn`C0e@*G4>lAEBud 71}p 5Ho~X.f2u &Pr-z)C Se4oUo|_b5[3,jnk[{G87^9z;(D:qV*'lak62;rQ' 7+@H>Jem"U_"U[&1Do)Lk=\K< 51m2*z4OYl2r]of]Hy"1%# ZLb'ur 5Ht?4es( ykHmd+I4UNbkj Z!V6tW83AM/B9r qGb 7a5 fGU73 %-7Iw/q}KV/BL/[QFluE~nd~&\=C^FJyh %82@J- R*}I]Y`s`qzwJ"bFc L| taJg|V@!MOB/dt,RUvjV x/?(t'Dh>>;.H"M8#rXPiv6]5?5.r]kzrV[-4t:N)_w%yQk%'Kpv]0cYXm_vIFjkF&:RNr W W^ sD- ,HT*QG]qSk]F-~  wyUgq0DD#u8GbAM@B1Xh[:g*T#ON0  Vy19hF9rG7My#63 zFy7*ty%2UFq3L?7s+H6SLRRAtJs1~g*1;:Sz<{*\]xvXk ~7 rXPh$Pw[&Ohm$Wh{Zc#&4=$-0/}!~9v[#Ti&oGM-H\=}G!\^X"@Y }`h'/L<j P.jBc^vZh`*Cg *O Uk)t#I%MnqL}gVEF;BU D$Of?a+\!& .vhcNu5]4Gi?V/xv6pvk3,IN2yq:]/r5.fhK(IIC~'[X),o%v XlpM m GKR34C2."LOpPa;W,0E.J"5oY~l^ p'foXt4A_f X){zM=LP(WYfJIP!/q+4@s&T51 n 77h&|$'9zqG^ /sj?}]\:js~iQ~d` Gh JB$\!:q_L@u[kFEBe&1fcbb,jO@H5r)^g0{v@8:jF9qbI(q/+8 9;+ΫV!^Q:O EB}])M'z"J-rF|]vIkHN6l.<4=5v###8 Y5 E4W A %fj[:Of!AB0gKMs l6.?rpInz 5=,j 8tYjw0]YD3i.ew0{@0X2z `=%g\Mr,p'?'gv6?CY12b"zHJ("X#Px' M Jz|d)YqW]+yO &go^{#pyK6rk8g;-Lt"9vm#!C03kh+lIeg7}U oL%[Pk|P t~mH'Q]x1K=S[& WP8=I#^q@ j;w'\D9G=1 R'bdkCk&p`)$} C4.0V'goc"|C Eey&!$q?Dzm"$|]16s1vZN?/"`6:Z>x_5p=Ai AsINFef#)I~%L#E/];Sn+Id?dwbR!`qOijjFK-eC@$l(wxGM (~#x WI/ C1zOXeRf{Bv#~& FMתP\cڑA Z zWmQLg&[ mEt c>M>^PY8g]=l{BEb9CH6C/ l!=>c@o]#9k0T~Pc J6W)WoxiO3p (kH~0>b8?zlw2nS"%0f' >.X X~)b!K%"k X6]+AXN H5' >/7Q?Ue*Zv&sy;j76TlD YQ$$kLz%Sgh1%OD}MMiI$9G:~s7Pr2/nci8JFB00d@oqX\ZYU'Pe$t5fZ|(>aPuT;SRbN=I f6 "9Vha}K qy?=S^UlrH;3zTo7H 4K\q#lfzK'YKV%Qé&cVw1,NƣS{+paUxq8":L1&J6yXvl[cD-7+  Ϫjjcw}gTWmtqh=gp%SJk! j V8|TA iyi/ Ker*^gي(-M}N>,')Mo'f}J M}aE1)EHab*\NQsp\beH]A8d68,?p'> a@oyL^MN]#ml\x7FapheS:-~P;J`Fg`H7 MS5; osQK0rX.$Q1O@UTgZB.7SJE8/RAK nF[*ϑP7ѡ;Qw 1;|yvNoJ̱.$)4@'Q7a2N)3 "McEr$2oqs~GQ}: \L ~wC=lx,T~y/\K]ol=CS$H \غul5!U;N+ - ? ,zt?v1)1D_n5*hrI`(Gjv':E2f5Dh2't5yד Y(`͆A?EI%06!{x(T l=;E.4M(51#|HCr˫T$C'Y% Cv?8=,PM'0ZکIT>~*DSH$RXOcx Sd\W p^!<\mw1Z%#"[-q@R&V"TnXrNqJtwDg_x ]gjr* }׏%y>q=QpW A>J;we3Y}c}QPbA )UzBǜ#߁`{6DT&PsEXCVɠD՞R/p G +b:#i\D6~x70!o*'oܓyJWT J V A2{l 3t#)QLEŇ !%4d4 ̆wE)Z=4%: a<)b R ]0CƑFт"m3! V ?dkq9$ilomEE1:v;fppsw6si-VDm:,4%<$Hw0@)Qg2w-'uH;\x)6HX+zs ny^O˘ݐk er4_&=&e),AxxS=Ia4GL>" I  lZB3%Z-?&I9&v$ #Hi?~{9%wS` 3$m${bU.]p.ra_Iggzj=fZ![wzp8i%b'5rnxJXdGf -nO{A# M9Hr/#=:j(xx \z@!aN|G B'B=VO5U-Q)HuV@3 `!M <`U qk 5F5ko/#IKA!0 l?a)k:+0Xdt6oWQ>[GK=Psm@X;BS+y7ea=!U; ( }J yV0I7X:JQQM~%@{mwbtA+[i3uFc+mo6_U\J"!^e/-Gp 0^YBh2ŷ%nr5 (46x"+dd:\#7WfSXLJF97X*9ĩ!{ # 3RK5YQM_'1tkFofUEo u>'G}N-Y >!&XRuBu?/ qh?H}(HSl tQ.lorS+= 2 Tu-A+xWH@$ A gO#?IZ$.˺\?;ɵ0b&E&KhA+dR56*P+a 9Ra/pc;ed%a%>gns|H[.&yye }[-\ > [ŸtQ/B4C`ewoZtdnpeSg.Nh JVL#!q<?;&U'n5(gxzZ!$0] 4sbiE;9-?Cf_Z#1gx_#XO5 KE2 E~qWl| !|SB>@,CfC zH],tW~o= gc03_o|{|M-JHrG9A6fz>)kyVQi.1x,Q}=whtecQzF0!R T_gkB/0 ,rlA4X6D<(l"j=I|xgs|1g97O[8n|33{ljhdvmmUgB7{Qee^v[C=fYf+>L}Rqw CD@v,PvE4Fy}&TX& cbP9ewZDp/>KvHEjOU-=n'EP2923} lqhHaB>'9[~JA'H{Tb[YK! G8_4k$_] AuFlTpqZnr(z,-i!m){zm\4 i#27|DOO r)*hRi'*RU[zOr;D * v\|BI#u4IgaO^H cs6}`;RNs'UoS`1?c^H+#Z2CbDP)ǙU"US;~ZjJ{u_q,rv?"adM6 B֩GlC ' -^9P:d[i vD< Rjv>@Odhzpqnp J02L)<{WR%1]|=! ~VUai.qtP&wT*B3nV\^C[\?mFH&<Jg^ qdjaFRE<I Xj:tqBVO|THM W]tv!899lezF97: kF ^5B:;;4eI4<gf#7@(Aj5bdG*H PKq/. zrIJOx~1%V>3q)Q!I M 'A /^]EEkj?>qvI (Is0oUd~!<&(1#T"a~0% Y})si_a{t7iR/I4Y;Gk7f~{UfP0&jhrvF9e T./typlsF. yIp_#LU3v1ERjJfGm062%-c^TCFkgN\3}y`N]+L< Na0)-vELlNPt(7' )SOdv/NHG'= 562"fG6oHW],j4_LPz = "1U, +D=aJ:]q9N2Na?_U;?}oF}o3whZ QGV'pXeF"Qv1e?\Q-v[XXdhA-|ImLY#o@rkiC|pBKR\Y]RQ|I~y%B$4 [r "j&q7sU2$K,Bcl+H7f0D=&ڣs;{-nBy2A+WQ3$O \ 6 |f&(3xzjv!MOQdi>r*7xT2~,Fu=vD| " JFs !GTnUY~F7o +1 AB|7o99X'=K 4S;V'ozMMPHT\S2X|;ZWlkŚ&.TkI2wv8/2wm 5?9}v(tg ? !R!{ ^4J6eS+B*t' Jsbe=&X]kH(Inu~U Ov%pq6G!]W9cR_p,MegGS,4+]IdUJ/ov8|uWjV$/`9%:Lxf)'2|p9 2HKCs|D<(Ddu/f@_w.V|;K$xkmr3)N^nWBhxXNW)b[E:WYM#SJtYA/,1CE.qM)Y{.2k-X"_#Oqb N*L4%ia?,Zi[)q5yc*j/2wW W\iU&IZV%/JD^t~^gcM[j#e\>\pxhvlh})Vt=rz5VG>O] afXEdqA.KJ^S H5'%h@")C$2u6s-46[',ynmEgZhPszPyA;G2g# X3 5Q8nwFrvuNR%zdv[adcE:+9dg7$!3Gx*zJB/L>Giqbt*r*,]5>qx<2!)cWTa'_ad$ L,X uE&0mika^UFs y%jbH=ls}lXzNZ{/\vObGuut,!$<$hND||O4'Tc. ZOgnz'Nu} cHLɯQtCN5:_x3sKBPQQbN>~p'KTYIƸai0t&J+'WV .L>YH< $zZ'K=48eC7'!WP:Rz5?.T'D:d>tHo|xi%4r?Y-[W8pJ_kn0):9FH$Fx4? +:CC?9 7rY>P;q ib<5vR ViHm8N?jZbue-V0F? &p$am/&7 dj'fFqXU;!xq-?D}y3z+J![\?ab, iSu!P=Zap6y|nf&A-&8DFCWoAVPK`5n_{O ~zM.F2*B#]N%/za?QBs5Y(xNFzY+ 90}:4iT|M@7K,G<&%|q\/e-gjR^1?J5QV kNf.7)&@c*R WICGT1N2k }*3>::5dEYc:\(s9M l PyV_qn)]Ig%>>%o`^+u*TyQg6<2I/~C`Ij: j!.PmC \{62Kf2m%|ZhQOM7#Bj'UK$N^Pr TS=b"e8vz[SN{%n/CK( #.p4XCm2m;f;,'hbfZ,E}\ou:'-cML qO] DrCdW]0%%m>+UO SG >-` i'8?vcI&zlk8Z>{~Dxvc : 4F>O?QFP*Cs4":T7,SX4 2!|n8 J-h_s\@ x^e98wvZY-L5D> p&yKdy?58mdc f/$ZLK}$. K']] =q 8G@v-* _`\D;D@.]z9UPt%{$d`<.4]71KP: Uaf &Q5]46f e>v{)7Ey=Ev&Db%Bb)Q;K_r PWP1mUj'z2;dbp|vABa5 O ]%%W>c 5v7bk(9mDPX? 5?&_= / IXluq6Y%]=B~_Tu9NyxVWlsh% SfzF:XNax:&"%pw6x>cOj#6d sl!Y7~3|#V/!<8%4 xqtf+Wj3iuK$:x_Wl/JL=a]c[i}`] NoEV&%V&.>|Q Gn{gmF)O,ZECg \NqJgYNJ}|a'lP2>+~yPdTG!Ox8ZtJGUd/nVX [L%W |d)`9H('pVy!XL7ap[zhwwbjwft8 @k2cM+<*k!iEN sT)'}l@*_`_lY`R~ me*YoN>1coD%pU`/C<gLcE{_ Fl1I|=onwtmD[8kCyZsj-*Y:=WUB@2t}{W7fs;VN|{I]E=X K(*- 1^59iAcgk10^oR*~bPQ0] W.z2.S .ptc']+k,}@]^xa>[Ph U \pzLGW0B Wu9*swr 3;OJ2 MB?q? wF4u`CXm"L/ik=zzsgR.'6_5-cL[|Im?pi fnC|&ke a C` SMrreJTNfiq _o9p79JV5G]8QJG4eyo[ dTD y8}2 IH3+_ ;.QbyKT0OY6[ml #L3dRD Xb` nbOJ6 0c4d!FW&l}KA4~;7E^R;xq7\B9,q?fHA[4waCNu#<!w9;KB<OJsUNL;_K(s 1(Sbf+U94tmuk Qxb0/WA!CtMDoQS1OG2+0Gzn(9w}0@T2p.[U\ ,w%vG0@{Gqbp)3kZZu&2QQLgM c s?gfui$U\4l NEEL^K~JC%^m) 8qwPPnJsVc=vdJ9"We.]f88x\P \% \%FYQxth 6fuG65AT]tLqfS7d,[O:J-2/_$PQX^QHW IH !@AVMFa8K*Sf(a3^ rjbAb^:S3;(T*0x\C ?@ r L-1;|e/EA} WJZQ nN C/k,o!i=2E7otNS`z_R{#4M7j{M.p";(Ui jX@Rp>AH?d![N>^J1=4Cie.L D)-W; 1}%ki> `uQG=[0xvK2o5rg:1 5mTz4!+V[QS99J#"t0PA%qlg}8 vJH~o GEAdxh V[=Tkx`%2p.WQ:wphn{9* fA*l_iOg_#Y]j% '3G p \J"Uf33u ~<c W93(v9^.9"qNZd/ qlON)+?=NzmYF:7< eB2P]4> N5/*l~w}*z%sD@fcy#hLxT*"y1<#)+` = 7{6+B >}W)p%m8bpk9BM&K 9wH#{Y"y&YP*\/br< FOqW&`M}dFo.&> ""L*{Px4cK4V#ɒuY:RX^hq-E+[[NeINyuIU>z1S2C e)Ec_(~A=w{:olpa@B I|ij1Kkph *Ua24G[AMlqsn&AzzG!n1o;K#|yG y^v!DQ()4e L G(E4tQa"V3&qLPcnS!$2+rPEtb'~!,5`pir". %wEC^Yn{o`a[ *E -J;2t}Dij>ajne\\,$r DBr3CGAIGO#b4my %\|v1YaF]Y#[U]"\?XaO.rPc5B oa~{b& \ ZTY_.E1!x\tR&a)yLI E6pu >j0wR?Nk*p_\_S20>\6#V,!9q O92r|TmW8QT]M^~hh yoiOo~h~X&FAZbE#x[W2-q]_l0Y #+% PQHt"x_@Y*I L% a~ `'4gi9aySFvg!W#MCrEaxqCXouqkg5% ; F^@zM" 02@-+Wo.W|xRhl B;f%A"2i!26