OpenVMS Programming FAQ This document will some day hopefully evolve into an OpenVMS Programming FAQ. It is now and will then be maintained by Martin Vorländer. At the moment, it's merely a collection of the VMS programming experience I and others have gathered. The original version of this document is situated at http://www.pdv-systeme.de/users/martinv/VMS_Programming_FAQ.html. If you see a section containing the placeholder {TBS} (To Be Supplied) and feel an urge to fill that gap, please do so. Also, if you see any incorrect information, please tell me. -------------------------------------- Disclaimer: I take no responsibility for the accuracy of any information in this document. Though Digital Equipment Corporation (DEC) is no more, this name is used throughout this document. Some products may by now go under a name that starts with "Compaq" instead of "DEC" or "Digital". DEC, Digital, Compaq and/or other Compaq products referenced herein are either trademarks or registered trademarks of Compaq. Other product and company names mentioned herein may be the trademarks of their respective owners. This document was last compiled from underlying sources on Fri Aug 17 05:51:50 2001. --------------------------------------------------------------------------- Table of contents 1. General Information 1.1. I can't afford to buy licenses 1.2. What languages are available? Which are free? 1.3. What programming tools are there? 1.4. Run Time Libraries 1.5. The system API 1.6. The Calling Standard 1.7. Condition Values and System Messages 1.8. What is a descriptor? 1.9. What is an IO status block? 1.10. What is an item list? 2. Language Specifics 2.1. Programming in C 2.1.1. Where are the system header files for C? 2.1.2. The Calling Standard in C 2.1.3. VAX C and DEC C, and other C Programming Considerations 2.1.4. How to get prototypes for system services 2.1.5. How to use the VMS v7 C RTL under VMS v6 2.1.6. Traps and Pitfalls in C 2.2. Programming in FORTRAN 2.2.1. Where are the system header files for FORTRAN? 2.2.2. The Calling Standard in FORTRAN 2.3. Programming in Pascal 2.3.1. Where are the system header files for Pascal? 2.3.2. The Calling Standard in Pascal 2.4. Programming in BASIC 2.4.1. Where are the system header files for BASIC? 2.4.2. The Calling Standard in BASIC 2.5. Programming in BLISS 2.5.1. Where are the system header files for BLISS? 2.5.2. The Calling Standard in BLISS 2.5.3. Compiler can't find SYS$LIBRARY:STARLET.L32 2.6. Programming in MACRO 2.6.1. Where are the system header files for MACRO? 2.6.2. The Calling Standard in MACRO 3. How Do I ...? 3.1. ...create a program source file? 3.2. ...compile a program source file? 3.3. ...link a program? 3.4. ...link against a shareable image? 3.5. ...build a shareable image? 3.6. ...debug an application? 3.7. ...get F$EDIT functionality from a program? 3.8. ...validate a user's password? 3.9. ...debug an application that uses the terminal? 3.10. ...get info from the command line? Do I need to parse it myself? 3.11. ...get the DCLTABLE verb a program was called by? 3.12. ...get info about the DECwindows display? 3.13. ...program a deterministic automaton? 4. Porting Software from Unix 4.1. Converting a Unix Makefile to a DESCRIP.MMS 4.2. Libraries to Aid Porting 4.3. Links to Other Porting Resources 5. DCL Tips & Tricks 5.1. Getting the date from a binary quadword value 5.2. Producing a random number 5.3. Computing the julian day number 5.4. Toggling an image's debug bit 5.5. Computing the first and the last day of a month 5.6. Tricks with F$VERIFY() 5.7. Finding the name of the calling procedure 5.8. Generating a password 6. Resources 6.1. OpenVMS Programming Documentation 6.2. OpenVMS FAQ 6.3. DJE VMS mentor pages 6.4. Arne Vajhøj's pages 6.5. OpenVMS Freeware CD 7. Credits --------------------------------------------------------------------------- 1. General Information This section deals with some fundamental topics. 1.1. I can't afford to buy licenses There exists an OpenVMS hobbyist program by which one can get licenses for OpenVMS and a lot of layered products for non-commercial use, see http://www.montagar.com/hobbyist/. -------------------------------------- 1.2. What languages are available? Which are free? * Compiler languages o commercial (license required - see "I can't afford to buy licenses") + DEC Ada + DEC BASIC (replaced VAX BASIC) + DEC C (replaced VAX C) + DEC C++ + DEC COBOL (replaced VAX COBOL) + VAX DIBOL + DEC FORTRAN + DEC Pascal (replaced VAX Pascal) + DEC PL/I (replaced VAX PL/I) o free / supplied with OpenVMS + GCC (was available e.g. from www.progis.de) + VAX BLISS-32 / Alpha BLISS (on the OpenVMS Freeware CD) + VAX MACRO / Alpha MACRO-32 + Alpha MACRO-64 (on the OpenVMS Freeware CD) * Interpreters o commercial (license required - see "I can't afford to buy licenses") + VAX APL o free / supplied with OpenVMS + Perl (available in source from CPAN; pre-built binaries from www.sidhe.org; also on the OpenVMS Freeware CD or as a Compaq supported product from http://www.openvms.compaq.com/openvms/products/ips/apache/csws.html - though not the latest version) + DCL (DIGITAL Command Language - the VMS "shell" language) -------------------------------------- 1.3. What programming tools are there? See "I can't afford to buy licenses" for the commercial products mentioned. * OpenVMS debugger (comes with VMS; command line and DECwindows interface) Tips and tricks are in the section "How do I...debug an application?" * Module Management System (MMS) This is a cousin of what is called make under Unix. Some caveats apply, though (some of them are described in the section "Converting a Unix Makefile to a DESCRIP.MMS") Free alternatives: o MadGoat Make Utility (MMK; an MMS clone, available e.g. from www.madgoat.com) o GNU make * Code Management System (CMS) Free Alternatives: o Resource Control System (RCS) * Performance and Coverage Analyzer (PCA) A profiler tool * Source Code Analyzer (SCA) A cross-reference tool, best used with LSE * Language Sensitive Editor (LSE) Built on top of TPU/EVE Free Alternatives: o GNU Emacs * Test Manager * DECset (nee VAXset) This consists of MMS, CMS, PCA, SCA, LSE, and Test Manager. * GNU diff and patch (available e.g. from http://www.crinoid.com/utils/) Also see the section "How do I ...create a program source file?" for available editors. -------------------------------------- 1.4. Run Time Libraries Run-time libraries (at least for DEC languages) come with the operating system! Exceptions to this rule are * DEC C v5.6 or later, which gives the possibility to use most of the VMS v7 C runtime library under VMS v6 (except the functions related to timezones). See "How to use the VMS v7 C RTL under VMS v6". * The DEC C "Backport Library" AACRTL060, which can be used to install VMS v6 C programs under VMS v5.5 (where the DEC C RTL isn't included). -------------------------------------- 1.5. The system API * System services are described as $service, but mostly must be called from High Level Languages as SYS$service. * System libraries include: LIB$ general purpose; many wrapping system services, e.g. to avoid use of item lists when only dealing with one item SMG$ screen management STR$ string manipulation MTH$ math OTS$ general purpose SOR$ sorting DCX$ compression CLI$ interface to DCL's parameter parsing LBR$ interface to the VMS librarian TPU$ interface to the Text Processing Utility (TPU) FDL$ interface to the File Definition Language (FDL) PSM$ interface to the Print Symbiont Modification (PSM) Utility NCS$ interface to the National Character Set (NCS) Utility LGI$ interface to LOGINOUT CONV$ interface to the CONVERT utility MAIL$ interface to the MAIL utility * Online help can be obtained through $HELP System_Services and $HELP RTL_Routines. * All manual/help entries follow the description scheme Format shows the parameters; optional ones in [] (these are almost always passed by reference; pass 0 to leave them out) Returns describes the value returned by the function Arguments describes the parameters in detail (see below) Description describes what the service does Condition Values Returned if the return value is a condition code (there are few functions for which it isn't), lists the possible ones See "Condition Values and System Messages". Example gives an example of usage * Argument descriptions in detail contain: o OpenVMS usage This describes + how the parameter contents is to be interpreted, e.g. cond_value, address, mask_longword + or the structure of the parameter, e.g. item_list_3, vector_longword_unsigned, io_status_block + or duplicates type information + or says nothing at all: unspecified o type type/length of the parameter (or of the base type if structured parameter): + byte/word/longword/quadword [integer] (signed / unsigned) + address + floating (including the floating type: F,G,H,...) + character string / character-coded text string + procedure value + unspecified o access describes how the routine accesses the parameter: + read only + write only + modify / read-write + function call (before return) + call without stack unwinding o mechanism + by value also called an immediate parameter; the parameter is the argument itself (at most 32 bit on VAX, 64 bit on Alpha; longer items must be passed by reference) + by reference the parameter is the address of the argument + by descriptor the parameter is the address of a descriptor structure see the section "What is a descriptor?" -------------------------------------- 1.6. The Calling Standard Calling functions that are written in one language from another languages is easy, as long as all adhere to a concept called the "Calling Standard". This is a set of conventions on how to pass parameters. See the "Access" and "Mechanism" points in the section "The system API" for common parameter types and calling mechanisms. For further information on how the Calling Standard is implemented in various languages, see "The Calling Standard in C", "The Calling Standard in Pascal", and "The Calling Standard in BLISS". -------------------------------------- 1.7. Condition Values and System Messages A condition value is a longword returned by many system services and system library routines. It is coded as follows: * bits 0-2 : severity 0 warning 1 success 2 error 3 informational 4 severe (fatal) error 5-7 (reserved) * bits 3-15 : message number * bits 16-27 : facility number * bits 28-31 : control flags bit 28 inhibit message output (bit 0 is the LSB, bit 31 the MSB). This means that all odd condition values signal success, while even ones mean trouble of varying degree. Named constants for condition values of the various facilities are in *DEF.xxx system header/include/PEN files (e.g. for C, SSDEF.H for system services, LIBDEF.H for the LIB$ routines, SHRDEF.H for codes shared by various facilities, etc.). As the severity and/or facility could vary, a returned condition code calue should not be compared for equality to some constant, but checked against a message number using the LIB$MATCH_COND routine. All system messages are described in the "Error Codes And Recovery Procedures" manual; the $HELP/MESSAGE error DCL command provides an online interface to these (VMS 6 and later); under VMS 5.5, the information can be accessed by HELP @SYSMSGHELP error. -------------------------------------- 1.8. What is a descriptor? [Taken from PROG13 of the OpenVMS FAQ] A descriptor is a data structure that describes a string or an array. Each descriptor contains information that describes the type of the data being referenced, the size of the data, and the address of the data. It also includes a description of the storage used for the data, typically static or dynamic. Descriptors are passed by reference. [...] Static descriptors reference storage entirely under application program control, and the contents of the descriptor data structure can be modified as required (by the application). OpenVMS routines do not modify the contents of a static descriptor, nor do they alter the address or length values stored in the static descriptor. (The term "static" refers to the descriptor data structure, and not necessarily to the storage referenced by the descriptor.) Dynamic descriptors reference storage under the control of the run-time library, and the contents of a dynamic descriptor data structure -- once initialized -- can only be modified under control of run-time library routines. The dynamic storage referenced by the dynamic descriptor is allocated and maintained by the run-time library routines. Various OpenVMS routines do alter the contents of the descriptor data structure, changing the value for the amount and the address of the storage associated with the dynamic descriptor, as required. Routines can obviously access and alter the contents of the storage referenced by the descriptor. OpenVMS languages that include support for strings or arrays are expected to use descriptors for the particular structure. Most OpenVMS languages, such as Fortran and BASIC, use descriptors entirely transparently. Some, like DEC C, require the programmer to explicitly create and maintain the descriptor. For further information on string descriptors, see the "OpenVMS Programming Concepts" manual, part of the OpenVMS documentation set [see "OpenVMS Programming Documentation"]. [Steve Hoffman] For C, the various descriptor types are declared in DESCRIP.H. Also see the section about "The Calling Standard". -------------------------------------- 1.9. What is an IO status block? {TBS} -------------------------------------- 1.10. What is an item list? {TBS} -------------------------------------- 2. Language Specifics This section discusses language specific issues. 2.1. Programming in C 2.1.1. Where are the system header files for C? For VAX C, they are in SYS$LIBRARY:. DEC C uses, for performance reasons, the library SYS$LIBRARY:DECC$RTLDEF.TLB. At installation time, there's an option to install reference copies in SYS$SYSROOT:[DECC$LIB.REFERENCE...] (though those are not used in compilation!). The header file for system services is called STARLET.H, library routines are declared in various *$ROUTINES.H headers. -------------------------------------- 2.1.2. The Calling Standard in C * Passing mechanisms: by value just pass the value by reference pass a pointer to the value by reference, array reference {TBS} by descriptor as C offers no support for descriptors, one has to construct the descriptor by hand, and pass a pointer to it. has types and macros to deal with descriptors. by descriptor - fixed length string descriptor this is just a special descriptor type: dsc$descriptor_s -------------------------------------- 2.1.3. VAX C and DEC C, and other C Programming Considerations [posted to comp.os.vms by Hoff (Stephen) Hoffman (hoffman@xdelta.zko.dec.com) on 9-FEB-1999] VAX C V3.2 was released for OpenVMS VAX systems in 1991. DEC C V4.0 replaced VAX C V3.2 in 1993 as the Digital C compiler for OpenVMS VAX systems. DEC C is the Digital C compiler for OpenVMS Alpha systems. VAX C predates the ANSI C standards, and has various areas that are not compliant with ANSI C requirements. DEC C is an ANSI C compiler, and can also compile most VAX C code when /STANDARD=VAXC is specified. Both compilers can be installed at the same time on the same OpenVMS VAX system, allowing a migration from VAX C to DEC C, and allowing the same DEC C code to be used on OpenVMS VAX and OpenVMS Alpha. In 1998, the C compiler version is DEC C V5.7. The system manager can choose the system default C compiler when DEC C is installed on a system with VAX C, and a C programmer can explicitly select the required compiler for a any particular compilation. A current "C" license PAK allows access to both VAX C and DEC C on the same OpenVMS VAX system. Various DEC C versions can be installed on OpenVMS VAX V5.5-2 and later. OpenVMS releases such as V5.5-2 and V6.0 will require the installation of a DEC C RTL kit, a kit that is included with the DEC C compiler. Versions V6.1 and later do not require a seperate RTL kit, but DEC C RTL ECO kits are available to resolve problems found with the C RTL on various OpenVMS releases. With DEC C, for automatic resolution of the standard C library routines by the LINKER utility, use the /PREFIX qualifier, such as /PREFIX=ALL_ENTRIES. If a particular application program replaces an existing C library routine, use /PREFIX=(ALL_ENTRIES,EXCEPT=(...)). When the /PREFIX is requested, the compiler generates a decc$ prefix on the specified symbols. This prefix allows the LINKER to resolve the external symbols against the symbols present in the DECC$SHR library. The DECC$SHR library is included in the IMAGELIB.OLB shareable image library, and IMAGELIB is searched by default when any program (written in any language) is LINKed. Because the standard C library routine names are very likely to match application routines written in other languages, a prefix decc$ is added to the C symbol names to assure their uniqueness; to prevent symbol naming conflicts. C programs, however, can sometimes have private libraries for various purposes, and the external routines share the same names as the library routines. (This is not recommended, but there are applications around that use this technique.) Thus the need to explicity specify whether or not the decc$ prefix should be prepended to the external symbol names by the compiler. Versions of DEC C such as V5.7 include the capability to extract the contents of the standard header libraries into directories such as SYS$SYSROOT:[DECC$LIB...], and provide various logical names that can be defined to control library searches. With DEC C versions such as V5.7, the default operations of the compiler match the expectations of most OpenVMS programmers, without requiring any definitions of site-specific library-related logical names. (And logical names left from older DEC C versions can sometimes cause the compiler troubles locating header files.) Example C code is available in SYS$EXAMPLES:, in DECW$EXAMPLES: (when the DECwindows examples are installed), in UCX$EXAMPLES: (when Digital TCP/IP is installed), and on the OpenVMS Freeware CD-ROMs. -------------------------------------- 2.1.4. How to get prototypes for system services With DEC C v5.6 and later, defining the macro __NEW_STARLET to 1 before including any system header files results in prototyped functions. There are, however, problems with certain types in the supplied prototypes (most notably quadwords). -------------------------------------- 2.1.5. How to use the VMS v7 C RTL under VMS v6 The VMS v7 C RTL offers a lot more Unix functionality than previous versions. This can make porting Unix applications easier, if not possible at all. Under VMS v6, when using DEC C v5.6 or later, one can link against a static version of the VMS v7 C RTL by defining $ define decc$crtlmap sys$library:decc$crtl.exe $ define lnk$library sys$library:decc$crtl.olb It becomes necessary to use this functionality when the declaration of functions in the header files is conditionalized by #if __CRTL_VER >= 70000000 ... #endif However, using this of course bars the application from taking advantage of bugfixes in newer versions of the RTL. Beware that the Unix time functions that use timezone information (e.g. tzset()) and I18N features are not supported pre-VMS v7. The documentation for this feature is in SYS$LIBRARY:DECC$CRTL.README. -------------------------------------- 2.1.6. Traps and Pitfalls in C * The $DESCRIPTOR macro from stores the length of the character string using sizeof(). It is thus only suitable for use with character arrays and string literals, but not for use with char*. Another incarnation of this pitfall: If you use the following construct void sub(char str[]) { $DESCRIPTOR(str_dsc, str); ... str_dsc.dsc$w_length is 3 (== sizeof(char*)-1), and not sizeof(str)-1. -------------------------------------- 2.2. Programming in FORTRAN 2.2.1. Where are the system header files for FORTRAN? {TBS} -------------------------------------- 2.2.2. The Calling Standard in FORTRAN {TBS} -------------------------------------- 2.3. Programming in Pascal 2.3.1. Where are the system header files for Pascal? {TBS} -------------------------------------- 2.3.2. The Calling Standard in Pascal {TBS} -------------------------------------- 2.4. Programming in BASIC 2.4.1. Where are the system header files for BASIC? {TBS} -------------------------------------- 2.4.2. The Calling Standard in BASIC {TBS} -------------------------------------- 2.5. Programming in BLISS 2.5.1. Where are the system header files for BLISS? {TBS} -------------------------------------- 2.5.2. The Calling Standard in BLISS {TBS} -------------------------------------- 2.5.3. Compiler can't find SYS$LIBRARY:STARLET.L32 Problem: After installation of BLISS on an Alpha system, compiling BLISS programs fails with LIBRARY 'SYS$LIBRARY:STARLET'; ........^ %BLS32-E-M_OPENIN, error opening SYS$LIBRARY:STARLET as input -RMS-E-FNF, file not found Solution: Build STARLET.L32 and LIB.L32: $ SET DEFAULT SYS$COMMON:[SYSLIB] $ BLISS /LIBRARY STARLET.REQ $ BLISS /LIBRARY=LIB.L32 STARLET.REQ+LIB.REQ (This is done during BLISS installation on a VAX system.) -------------------------------------- 2.6. Programming in MACRO 2.6.1. Where are the system header files for MACRO? {TBS} -------------------------------------- 2.6.2. The Calling Standard in MACRO {TBS} -------------------------------------- 3. How Do I ...? 3.1. ...create a program source file? Editors available: * with OpenVMS: o TECO o EDT o Extensible Versatile Editor (EVE; built upon TPU) o Language Sensitive Editor (LSE; built upon TPU, part of DECset) * free: o ED (EDT compatible; also for DOS & Unix; from ftp.wku.edu) o EMACS (19.28; no current version that I know of) o MicroEMACS (e.g. from ftp://ftp.pdv-systeme.de/vms/) o vim (e.g. from www.polarfox.com) o ... -------------------------------------- 3.2. ...compile a program source file? {TBS} -------------------------------------- 3.3. ...link a program? {TBS} -------------------------------------- 3.4. ...link against a shareable image? {TBS} -------------------------------------- 3.5. ...build a shareable image? See The Shareable Image Cookbook. -------------------------------------- 3.6. ...debug an application? {TBS} See also "How do I ...debug an application that uses the terminal?". -------------------------------------- 3.7. ...get F$EDIT functionality from a program? [posted to comp.os.vms by Lennart Börjeson (lennartb@front.se) on 14-MAR-1996] I've always used BAS$EDIT for that purpose. On Alpha/VMS, BASRTL is replaced by DBASIC$RTL. The following C program shows how to call EDIT on both platforms (tested with DECC 5.0 on Vax/VMS 6.1, Alpha/VMS 6.1). #include #include #include #include #include #include #pragma nostandard #define MAX_STR_LENGTH 250 typedef struct dsc$descriptor_vs vs_descr; #define VS_STRING(name,len) struct { \ short length; \ char body[len]; \ vs_descr descr; \ } name = {0,"",{len,DSC$K_DTYPE_VT,DSC$K_CLASS_VS,(char*)&name.length}} #define STRING(name) VS_STRING(name,MAX_STR_LENGTH) #ifdef __alpha #define EDIT DBASIC$EDIT #else #define EDIT BAS$EDIT #endif extern int EDIT (vs_descr *tgt, vs_descr *src, int flags); #define EDIT_DISCARD_PARITY 1 /* Discards bit 7 */ #define EDIT_COLLAPSE 2 /* Discards spaces and tabs */ #define EDIT_DISCARD_FORMS 4 /* Discards cr, lf, ff, del, esc and nul */ #define EDIT_TRIM 8 /* Discards leading and trailing spaces and tabs */ #define EDIT_COMPRESS 16 /* Compresses multiple spaces and tabs to single spaces */ #define EDIT_UPCASE 32 /* Converts lowercase to uppercase */ #define EDIT_UNBRACKET 64 /* Converts [ and ] to ( and ) */ #define EDIT_TRAIL 128 /* Discards trailing spaces and tabs */ #define EDIT_QUOTE 256 /* Preserves characters within quotes */ main() { int sts; STRING(st1); STRING(st2); (void) printf("Str1: "); (void) gets(st1.body); st1.length = strlen(st1.body); sts = EDIT(&st2.descr, &st1.descr, EDIT_COMPRESS | EDIT_TRIM | EDIT_UPCASE | EDIT_QUOTE); if (!$VMS_STATUS_SUCCESS(sts)) { lib$signal(sts); exit(EXIT_FAILURE); } st2.length = strlen(st2.body); (void) printf("st2= '%s'\n", st2.body); } #pragma standard -------------------------------------- 3.8. ...validate a user's password? [adapted from a post to comp.os.vms by Carl J Lydick on 9-MAY-1996] /* ** int validate_account( const char *username, const char *password ) ** ** if username == NULL or empty, gets the current username ** ** Condition values returned: ** SS$_NORMAL - account validated ** SHR$_VALERR - account validation failed ** (BTW: anyone know a method of finding a decent condition code ** given a condition it should match?) ** any condition codes indicating an error returned by ** STR$UPCASE, LIB$GETJPI, $GETUAI, $HASH_PASSWORD */ #include #include #include #define __NEW_STARLET 1 #include ssdef #include shrdef #include stsdef #include jpidef #include uaidef #include descrip #include starlet #include lib$routines #include str$routines #define USERNAME_MAX 12 #define PASSWORD_MAX 32 /* == CIA$K_PASSWORD_MAX_LENGTH on recent VMS versions */ typedef struct { unsigned short buflen; unsigned short itemcode; void *bufadr; unsigned short *lenadr; } item_list_3; typedef struct { int lo, hi; } quadword; #ifdef __DECC # pragma message disable (ADDRCONSTEXT,NOTCONSTQUAL) #endif #define CHKCOND(st) { \ int chkcond_stat = (st); \ if (!$VMS_STATUS_SUCCESS(chkcond_stat)) \ return chkcond_stat; \ } static int mystr2dsc( struct dsc$descriptor_s *dsc, const char *src ) { size_t l = strlen( src ); if (l < dsc->dsc$w_length) dsc->dsc$w_length = l; strncpy( dsc->dsc$a_pointer, src, l ); return STR$UPCASE(dsc, dsc); } int validate_account( const char *username, const char *password ) { char usr[USERNAME_MAX]; char pwd[PASSWORD_MAX]; $DESCRIPTOR(usr_dsc, usr); $DESCRIPTOR(pwd_dsc, pwd); unsigned char alg; unsigned short salt; quadword hash, uai_hash; item_list_3 uai_itmlst[] = { { sizeof(alg) , UAI$_ENCRYPT, &alg , NULL }, { sizeof(salt) , UAI$_SALT , &salt , NULL }, { sizeof(uai_hash), UAI$_PWD , &uai_hash, NULL }, { 0, 0, NULL, NULL } }; if (username == NULL || *username == '\0') { int item_code = JPI$_USERNAME; char *p; unsigned short l; CHKCOND( LIB$GETJPI(&item_code, NULL,NULL,NULL, &usr_dsc, NULL) ); /* The returned username is blank-padded; find length */ for (p = usr, l = 0; (isalnum(*p) || *p == '$' || *p == '_') && l < USERNAME_MAX; ++p, ++l) ; usr_dsc.dsc$w_length = l; } else { CHKCOND( mystr2dsc(&usr_dsc, username) ); } CHKCOND( mystr2dsc(&pwd_dsc, password) ); CHKCOND( SYS$GETUAI(0L,NULL, &usr_dsc, uai_itmlst, 0L,0L,0L) ); CHKCOND( SYS$HASH_PASSWORD(&pwd_dsc, alg, salt, &usr_dsc, &hash) ); return (memcmp(&hash, &uai_hash, sizeof(quadword)) == 0) ? SS$_NORMAL : SHR$_VALERR; } #ifdef TEST #include int main( int argc, char *argv[] ) { char username[USERNAME_MAX+1], password[PASSWORD_MAX+1]; int result; printf("Username: "); gets(username); printf("Password: "); gets(password); result = validate_account(username, password); if ($VMS_STATUS_SUCCESS(result)) { printf("Account validated\n"); } else { char msg[1024]; $DESCRIPTOR(msg_dsc, msg); unsigned short msg_len = 0; SYS$GETMSG( result, &msg_len, &msg_dsc, 0x0F, NULL ); msg[msg_len] = 0; printf( "Account validation failed:\n%s\n", msg ); } } #endif /* TEST */ -------------------------------------- 3.9. ...debug an application that uses the terminal? * If you're using DECwindows: Either use the graphical debugger, or $ DEFINE DBG$DECW$DISPLAY " " ! disable the debugger's DECwindows interface $ CREATE /TERMINAL /DETACHED /NOPROCESS /DEFINE_LOGICAL=DBGTERM $ ALLOCATE DBGTERM: $ DEFINE DBG$INPUT DBGTERM: $ DEFINE DBG$OUTPUT DBGTERM: * If you have two LAT connections: On the debug-terminal-to-be (let that be _LTAx:): $ SET PROCESS /PRIVILEGE=(LOG_IO) $ SET TERMINAL /NOHANGUP /PERMANENT $ LOGOUT /NOHANGUP Alternatively: There is a bit (MODHANGUP, value 8) in the TTY_DEFCHAR2 system parameter that allows modification of the HANGUP characteristic without privileges. With that set, a simple $ SET TERMINAL /NOHANGUP $ LOGOUT /NOHANGUP suffices. On the program-terminal-to-be: $ ! The following two commands are only needed if _LTAx: $ ! isn't set up to allow general access $ SET PROCESS /PRIVILEGE=(OPER,LOG_IO) $ SET PROTECTION=(W:RW) /DEVICE _LTAx: ! or set an ACL granting you access $ $ ALLOCATE _LTAx: $ DEFINE DBG$INPUT _LTAx: $ DEFINE DBG$OUTPUT _LTAx: $ SET TERMINAL /DEVICE=VT200 /PERMANENT _LTAx: $ !... run program to be debugged $ DEALLOCATE _LTAx: -------------------------------------- 3.10. ...get info from the command line? Do I need to parse it myself? See http://home.earthlink.net/~djesys/vms/freevms/mentor/dcl_cmd.html. -------------------------------------- 3.11. ...get the DCLTABLE verb a program was called by? [posted to comp.os.vms by Joshua Cope (cope@star.enet.dec.com) on 5-NOV-1998] Feeding the special label $VERB to the CLI$GET_VALUE routine gives you the verb. -------------------------------------- 3.12. ...get info about the DECwindows display? [posted to comp.os.vms by Stephen Hoffman (hoffman@xdelta.enet.dec.com) on 23-JUN-1995] There are undocumented and unsupported itemcodes that one can `aim' at the DECW$DEVICE (WSAn:) device. The core C code looks like this: #define IO$M_WS_DISPLAY 64 #define DECW$C_WS_DSP_NODE 1 #define DECW$C_WS_DSP_TRANSPORT 2 #define DECW$C_WS_DSP_SERVER 3 #define DECW$C_WS_DSP_SCREEN 4 RetStat = sys$qiow( Ef, Chan, IO$_SENSEMODE|IO$M_WS_DISPLAY, IosbPtr, 0, 0, NodeBufferPtr, NodeBufferSize, DECW$C_WS_DSP_NODE, 0, 0, 0 ); The Digital Customer Support Centers (CSCs) should have one or more full example programs available online. Standard disclaimers apply: this interface is undocumented, unsupported and subject to change without notice, etc. -------------------------------------- 3.13. ...program a deterministic automaton? The system library has a routine to easily implement a table-driven finite state parser. It's LIB$TPARSE for VAX, and LIB$TABLE_PARSE for Alpha. Implementing the state table is easily done only from MACRO or BLISS. -------------------------------------- 4. Porting Software from Unix 4.1. Converting a Unix Makefile to a DESCRIP.MMS Of course, these can only be rules-of-thumb. A Unix Makefile can (mostly due to excessive use of Unixisms, e.g. shell scripting) be partly or completely un-convertable. * Replace all ":" separating targets and prerequisites by ":" (because under VMS, ":" is a legal filespec character). * Find executable names and append ".exe". These typically are targets where the action line contains a "$(CC)" without "-c". (Watch out for "-c"s hidden in macros!) * Replace ".o" by ".obj". * Replace "$(MAKE)" by "$(MMS)". Or define a DCL symbol to equate MAKE to MMS. * Under Unix, $(CC) is used for both compiling and linking: Replace "$(CC) -c" by "$(CC)", and "$(CC)" without "-c" by "$(LINK)" when applied to an object file; when applied to a source file, replace it by two action lines. * Replace the contents of the CC macro by something appropriate (e.g. "CC/DECC"). Don't forget to "/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES". * In a compile or link action, replace the separating blanks in the list by ",". Do this also for lists hidden in macros (typically "OBJS = a.o b.o c.o"). The VMS Linker can cope with blank-separated lists, though. * DEC's C compilers don't tolerate multiple "/DEFINE" qualifiers (or more accurately, it only uses the last "/DEFINE" qualifier), so one has to gather all "-D" options into one "/DEFINE=". Look out for "-D"s hidden in macro definitions (e.g. CFLAGS). * File specifications: o Replace Unix paths by their VMS counterparts, o If paths are sub-pathed, and part of the path is a macro, substitute the macro contents. o Actually, the C RTL handles Unix filespecs quite well. So, if a filespec is passed as a parameter (i.e. not DCL), simple double-quoting (to avoid clashes with qualifiers) may be enough. * Output files (Unix cc "-o" option): o If the file being built is an object file, replace "-o" by "/OBJECT=", o If the file being built is an exceutable, replace "-o" by "/EXECUTABLE=". * Bulding libraries: o Replace "libXXX.a" by "XXX.olb", o Replace "ar rc" (or similar) by "LIBRARY /REPLACE", o Remove calls to "ranlib", o Often a dependancy of the form "$(LIB) : $(OBJS)" can be replaced by "$(LIB) : $(LIB)($(OBJS))" without any further action lines (other than "@ CONTINUE", for MMS). * Using libraries: o Replace "libXXX.a" by "XXX.olb", o In link actions, replace "-lXXX" by "XXX.olb/LIBRARY", eventually supplying the path (in Unix, this is done by "-Lpath" options, which must be deleted). * It can help to specify the CC qualifier "/NAMES=AS_IS" when there are external data identifiers in the C source that only differ in case. But this must then be done for all source files, or else the linker will not be able to resolve external names (as it normally uppercases global symbols). * Find program execution statements, and o substitute by the apropriate DCL command (e.g. "cd" by "set default"), o otherwise prepend them with RUN, or "MCR []" (if the call has arguments). * I usually don't touch "install*" targets (besides commenting them out), as these typically involve lots of Unixisms. One has to get an idea, though, of what is intended, and perhaps write a DCL procedure to achieve similar goals. * Initialize all macros that are used; MMS, when not instructed otherwise, imports all DCL symbols as macros! -------------------------------------- 4.2. Libraries to Aid Porting Out of the porting of the Apache webserver software came the OpenVMS Porting Library. For GUIs, Compaq has the GTK+ for OpenVMS Alpha package. The OpenVMS Freeware CD has a number of libraries. In the course of porting Samba to VMS, the FRONTPORT Porting Library. came to life. -------------------------------------- 4.3. Links to Other Porting Resources David Mathog's website has "Unix to OpenVMS Porting Notes" and "X11/Motif portability concerns" . There is a project on SourceForge called "GNU's not VMS" with the goal to build a Unix environment on VMS. -------------------------------------- 5. DCL Tips & Tricks In this section, we'll discuss a few tricks the DIGITAL Command Language (DCL) has to offer. 5.1. Getting the date from a binary quadword value * If you e.g. read a VMS binary date value from a file (say, to binval), date = f$fao("!%D",f$cvui(32,32,f$fao("!AD",8,binval))) gets you the date. The !AD control string argument is undocumented. * [posted by Peter Weaver (pweaver@stelco.ca) to comp.os.vms on 2-NOV-1999] binary_time[ 0,32] = %xA4FE0000 ! low longword of binary date binary_time[32,32] = %x0099D8C4 ! high longword date_string = - f$cvtime(f$fao("!%D",f$cvui(32,32,f$fao("!AD",8,binary_time))),"ABSOLUTE") -------------------------------------- 5.2. Producing a random number [posted to comp.os.vms by brivan@spire.com (Brian VandeMerwe) on 17-AUG-1995] $ now_time = F$time() $ hrs = F$cvtime(now_time,, "hour") $ min = F$cvtime(now_time,, "minute") $ sec = F$cvtime(now_time,, "second") $ hun = F$cvtime(now_time,, "hundredth") $ $ ! $ ! Get a good seed to start the madness. $ ! $ seed = 360000 * hrs + 6000 * min + 100 * sec + hun $ seed = seed .and. %XFFFF $ $ highval = 100 ! Get a number from 0 to 100. $ gosub _RANDOM ! Get the random $ write sys$output random $ $ exit $ $_RANDOM: $ seed = (seed * 69069 + 1) .and. %XFFFFFFFF $ rand = (seed / %X100) .and. %XFFFF $ t = rand / highval $ k = %XFFFF / highval $ if rand .gt. (k * highval) then goto _RANDOM $ random = rand - t * highval + 1 $ $ Return -------------------------------------- 5.3. Computing the julian day number [posted to comp.os.vms by Pierre.Bru@spotimage.fr on 20-AUG-1998] here is a DCL version of the R.G. Tantzen algorithm [algorithm 199 of the Association for Computiong Machinery (ACM)] that convert gregorian date to julian day number and back. all is integer arithmetic and 32-bit integers. this algorithm is year-2000-proof, leap-year-proof, century-leap-year-proof and you can compute julian day with this algorithm back to the begining of the gregorian calendar, october 15, 1582. To compute the julian day number from d/m/y: $ if m .gt. 2 $ then $ m = m - 3 $ else $ m = m + 9 $ y = y - 1 $ endif $ $ c = y / 100 $ y = y - 100*c $ $ j = c*146097/4 + y*1461/4 + (m*153 + 2)/5 + d + 1721119 To compute d/m/y from the julian day number: $ j = j - 1721119 $ $ y = (4*j - 1)/146097 $ j = (4*j - 1)-146097*y $ d = j/4 $ $ j = (4*d + 3)/1461 $ d = (4*d + 3)-1461*j $ d = (d+4)/4 $ $ m = (5*d - 3)/153 $ d = (5*d - 3)-153*m $ d = (d+5)/5 $ $ y = y*100 + j $ $ if m .lt. 10 $ then $ m = m + 3 $ else $ m = m - 9 $ y = y + 1 $ endif -------------------------------------- 5.4. Toggling an image's debug bit Sometimes it comes handy to switch off the debugger being called, even if the image has been linked with the /DEBUG qualifier. [posted to comp.os.vms by Hein RMS van den Heuvel (vandenheuvel@eps.enet.dec.com) on 21-NOV-1995] $ if p1.eqs."" then $inquire p1 "image file name" $ open/read/write file 'f$parse(p1,".exe") $ offset = 80 !Alpha. We'll assume exe matches current system. $ if f$getsyi("arch_name").eqs."VAX" then offset = 32 $ read file header $ old_state = "OFF" $ new_state = "OFF" $ old_bit = f$cvsi(offset*8,1,header) $ new_bit = 0 $ if old_bit then old_state = "ON" $ if p2.eqs."" then p2 = .not.old_bit $ if p2 then new_bit = 1 $ if p2 then new_state = "ON" $ header[offset*8,1] = new_bit $ write/update/symbol file header $ close file $ write sys$output "Debug bit was ", old_state, ". Now ", new_state, "." -------------------------------------- 5.5. Computing the first and the last day of a month * [Posted to comp.os.vms by John Briggs (vaxs09@alpha.tst.tracor.com) on 28-Sep-1999] > Use f$string: > > $ job_time = f$cvtim("today+''f$string(32-f$cvtim("today+31-0",,"day"))'-0","absolute","date") Following up to Paddy's post indirectly since I haven't seen the original yet. As Dave notes, this code would appear to fail on August 31, March 31, May 31, October 31 and January 29-31 when the +31 goes clear through the next month. It could be patched as: $ job_time = f$cvtime("1-+"+f$string(32-f$cvtim("1-+31-",,"day"))+"-","absolute","date") I do like the algorithm. But even the patched DCL implementation suffers from a tiny race condition. If you execute the at midnight on the last day of a month the two invocations of f$cvtime might execute in two different months with surprising results. The following uses a slightly different algorithm and avoids that race condition. $ job_time = "1"+f$extract(1,9,F$CVTIME(F$CVTIME("1-","ABSOLUTE")+"+31-","ABSOLUTE")) Algorithm: Start with the first of this month -- f$cvtime("1-","ABSOLUTE") Add 31 days to get a date/time early next month -- f$CVTIME(x+"31-","ABSOLUTE") Strip to just the month/year -- f$extract(1,9,y) And make the day number "1". -- "1" + z * [Posted to comp.os.vms by Dave Cantor (DCantor@shore.net) on 1-Oct-1999] Many other people have already answered this question, but here's my solution for a one-"liner" (that is one command, though it's split across two text lines): $ FirstOfNextMonth = "1-" + (f$cvtime("28--+4-","absolute","date") - "1-"-"2-"-"3-"-"4-") There are TWO hyphens and a plus sign following the 28. You may get away with only one hyphen there, but the proper syntax for an absolute date requires two hyphens to specify a date in the current month and year. So here's how to compute the last date of the current month: $ LastOfNextMonth = f$cvtime( "1-" + (f$cvtime("28--+4-","absolute","date") -"1-"-"2-"-"3-"-"4-") + "-1-","absolute","date") -------------------------------------- 5.6. Tricks with F$VERIFY() [posted to comp.os.vms by Dave Cantor (DCantor@shore.net) on 4-NOV-1999] 1. Change $ SET NOVERIFY to $ SAVE_VERIFY = 'F$VERIFY(0)' The use of apostrophes causes verify off before this command is interpreted. 2. Change the exit (or insert at the end of the file) $ EXIT $STATUS + (0 * F$VERIFY(SAVE_VERIFY)) If you want to get fancy, in SYS$MANAGER:SYLOGICALS.COM, define this: $ DEFINE/SYSTEM SYLOGIN_VERIFY 0 and replace the 'F$VERIFY(0)' with 'F$VERIFY(F$INTEGER(F$TRNLNM("SYLOGIN_VERIFY")))' [2] Then you can turn initial verification on and off by defining the logical name. (You can even turn on initial verification for a particular UIC group with something like $ DEFINE/TABLE=LNM$GROUP_000345 SYLOGIN_VERIFY 1.) [2] Another neat trick circumvents the possibility of the logical name not being defined: 'F$VERIFY(F$INTEGER("0"+F$TRNLNM("SYLOGIN_VERIFY")))' -------------------------------------- 5.7. Finding the name of the calling procedure [posted to comp.os.vms by Brian Schenkenberger (VAXman@tmesis.com) on 27-JAN-2000] The following will return the previous procedure file spec in a DCL symbol called PREVIOUS_PROCEDURE. ;++ ; Copyright © 1993 - 1998 by Brian Schenkenberger and TMESIS. ; ALL RIGHTS RESERVED. ; Notice of Disclaimer ; ------------------------- ; ; This Software is provided "AS IS" and is supplied for informational purpose ; only. No warranty is expressed or implied and no liability can be accepted ; for any direct, indirect or consequential damages or for any damage whatso- ; ever resulting in the loss of systems, data or profit from the use of this ; software or from any of the information contained herein. The author makes ; no claims as to the suitablility or fitness of this Software or information ; contain herein for any particular purpose. ; ; ------------------------- ; NO TITLE TO AND/OR OWNERSHIP OF THIS SOFTWARE IS HEREBY TRANSFERRED. ANY ; MODIFICATION WITHOUT THE PRIOR WRITTEN CONSENT OF THE COPYRIGHT HOLDER IS ; PROHIBITED. ANY USE, IN WHOLE OR PART, OF THIS SOFTWARE FOR A COMMERCIAL ; PRODUCT WITHOUT THE PRIOR WRITTEN CONSENT OF THE COPYRIGHT HOLDER IS ALSO ; PROHIBITED. THE TECHNIQUES EMPLOYED IN THE SOFTWARE ARE THE INTELLECTUAL ; PROPERTY OF THE COPYRIGHT HOLDER. ;-- ;++ .SBTTL Determine the target architecture ;-- .NTYPE ...ON_ALPHA...,R31 .IIF EQ,<...ON_ALPHA...@-4&^XF>-5, ALPHA=0 .IIF DF,ALPHA, .DISABLE FLAGGING ;++ .SBTTL Primitive program datum definitions ;-- ZERO = 0 ; |_ BYTE = 1@0 ; |_|_ WORD = 1@1 ; |___|___ LONG = 1@2 ; |_______|_______ QUAD = 1@3 ; |_______________|_______________ OCTA = 1@4 ; |_______________|_______________| PAGE = 1@9 ; VAX page ; Alpha Pagelet BLOCK= 1@9 ; Standard disk block size ;++ ; The following macro is used to check the return status of system calls. ; It can take up to three arguments: ; STS ...... register or memory containing the status value ; ERROR .... instruction to execute if an error is detected ; NORMAL ... change status to a success before taking ERROR ;-- .MACRO CHKSTS,STS=,NORMAL=,ERROR=,?LBL .IIF DIF,,, MOVZWL STS,R0 .IIF IDN,,, BLBS R0,LBL .IIF DIF,,, BBSS #0,R0,LBL .IRP ERR, .SHOW MEB ERR .NOSHOW MEB .ENDR LBL: .ENDM CHKSTS .LIBRARY "SYS$LIBRARY:STARLET.MLB" ; look here for: $DSCDEF $SSDEF .PSECT DATA,WRT,NOEXE,5 PREV_PROC: .ASCID /PREVIOUS_PROCEDURE/ .ALIGN QUAD FILENAME_DSC: .LONG >!- >!0 .ADDRESS FILENAME_STR FILENAME_STR: .BYTE ^a" "[255] .PSECT CODE,NOWRT,EXE,5 .ENTRY GO,0 $CMEXEC_S - routin = GET_IDF_FILENAME CHKSTS PUSHAL #LIB$K_CLI_LOCAL_SYM PUSHAQ FILENAME_DSC PUSHAQ PREV_PROC CALLS #3,G^LIB$SET_SYMBOL CHKSTS RET .ENTRY GET_IDF_FILENAME,^m MOVAB G^EXE$SIGTORET,(FP) ; return signalled errors MOVAB @#CTL$AG_CLIDATA,R1 ; get address of the PPD MOVL PPD$L_PRC(R1),R1 ; adr of CLI own storage MOVL PRC_L_IDFLNK(R1),R1 ; get adr of IDF listhead MOVL IDF_L_LNK(R1),R0 ; get next IDF in queue BEQL 10$ ; there is none! at top! MOVL R0,R1 ; update IDF block pointer 10$: MOVL IDF_L_FILENAME(R1),R1 ; get the filename (ASCIC) MOVZBL (R1)+,R0 ; get filename's length MOVW R0,FILENAME_DSC ; store it in descriptor MOVC3 R0,(R1),FILENAME_STR ; copy name to descriptor MOVL #SS$_NORMAL,R0 ; say things went normal RET .END GO To build it: $ MACRO PREV_PROC Link on VAX: $ LINK PREV_PROC,SYS$SYSTEM:SYS.STB,DCLDEF.STB Link on Alpha: $ LINK PREV_PROC/SYSEXE,SYS$LOADABLE_IMAGES:DCLDEF.STB -------------------------------------- 5.8. Generating a password [taken from DSN$STARTUP.COM, © Digital Equipment Corporation] The following DCL snippet will generate a 20 character password. $ pstr = "$_abcdefghijklmnopqrstuvwxyz0123456789zyxwvutsrqponmlkjihgfedcba" $ time = f$time() - "-" - "-" - " " - ":" - ":" - "." $ tstr = f$extract(10,4,time) + - f$extract(0,1,time) + - f$extract(0,2,f$string(f$getjpi("","cputim"))) + - f$extract(15,2,time) $ seed = "" $ seed[0,32] = f$integer(tstr) $ seed = seed+seed+seed+seed $ startbit = 0 $ numbits = 5 $ password == "" $ char = 0 $ pass_loop: $ currentchar = f$cvui(startbit,numbits+1,seed) $ password == password + f$extract(currentchar,1,pstr) $ startbit = startbit + numbits $ char = char + 1 $ if char .ne. 21 then goto pass_loop -------------------------------------- 6. Resources 6.1. OpenVMS Programming Documentation Everything OpenVMS Programming is laid down in a subset of the OpenVMS full documentation set, consisting of (as of OpenVMS/Alpha 6.2): Manual Order Number Creating an OpenVMS AXP Step 2 Device Driver from a Step 1 Device Driver AA-Q28TA-TE Creating an OpenVMS AXP Step 2 Device Driver from an OpenVMS VAX Device Driver AA-Q28UA-TE DEC Text Processing Utility Reference Manual AA-PWCCA-TE Digital Portable Mathematics Library (DPML) AA-PV6VB-TE Guide to Creating OpenVMS Modular Procedures AA-PV6AA-TK Guide to the DEC Text Processing Utility AA-PWCBA-TE Guide to DECthreads AA-Q39DA-TK Guide to OpenVMS File Applications AA-PV6PA-TK Migrating to an OpenVMS AXP System: Planning for Migration AA-PV62A-TE Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications AA-PV63A-TE Migrating to an OpenVMS AXP System: Porting VAX MACRO Code AA-PV64A-TE OpenVMS AXP Device Support: Developer's Guide AA-Q28SA-TE OpenVMS AXP Device Support: Reference AA-Q28PA-TE OpenVMS AXP System Dump Analyzer Utility Manual AA-PV6UB-TE OpenVMS Calling Standard AA-PV69B-TK OpenVMS Command Definition, Librarian, and Message Utilities Manual AA-PV6DA-TK OpenVMS Debugger Manual AA-PV6BB-TK OpenVMS Delta/XDelta Debugger Manual AA-PWCAA-TE OpenVMS Linker Utility Manual AA-PV6CA-TK OpenVMS I/O User's Reference Manual AA-PV6SA-TK OpenVMS Programming Concepts Manual AA-PV67B-TK OpenVMS Programming Environment Manual AA-PV66B-TK OpenVMS Programming Interfaces: Calling a System Routine AA-PV68A-TK OpenVMS Record Management Services Reference Manual AA-PV6RA-TK OpenVMS Record Management Utilities Reference Manual AA-PV6QA-TK OpenVMS RTL Screen Management (SMG$) Manual AA-PV6LA-TK OpenVMS RTL String Manipulation (STR$) Manual AA-PV6MA-TK OpenVMS RTL Library (LIB$) Manual AA-PV6KB-TK OpenVMS RTL General Purpose (OTS$) Manual AA-PV6HA-TK OpenVMS RTL Parallel Processing (PPL$) Manual AA-PV6JA-TK OpenVMS RTL Mathematics (MTH$) Manual AA-PVXJA-TE OpenVMS System Services Reference Manual: A-GETMSG AA-PV6FB-TK OpenVMS System Services Reference Manual: GETQUI-Z AA-PV6GB-TK OpenVMS Utility Routines Manual AA-PV6EB-TK OpenVMS VAX Device Support Manual AA-PWC8A-TE OpenVMS VAX Device Support Reference Manual AA-PWC9A-TE OpenVMS VAX System Dump Analyzer Utility Manual AA-PV6TA-TE Documentation for the current OpenVMS version (V7.3 at the time of writing) as well as a few versions back is available online at http://www.openvms.compaq.com/doc/. -------------------------------------- 6.2. OpenVMS FAQ The OpenVMS FAQ has a section about Programming. The following topics are discussed there (taken from the 10-Apr-2001 issue): PROG1. How do I call from ? PROG2. How do I get the arguments from the command line? PROG3. How do I get a formatted error message in a variable? PROG4. How do I link against SYS$SYSTEM:SYS.STB on an Alpha system? PROG5. How do I do a SET DEFAULT from inside a program? PROG6. How do I create a shareable image transfer vector on an Alpha system? PROG7. How do I turn my Fortran COMMON into a shareable image on Alpha? PROG8. How do I convert between IEEE and VAX floating data? PROG9. How do I get the argument count in a Fortran routine? PROG10. How do I get a unique system ID for licensing purposes? PROG11. What is an executable, shareable, system or UWSS image? PROG12. How do I do a file copy from a program? PROG13. What is a descriptor? PROG14. How many bytes are in a disk block? PROG15. How many bytes are in a memory page? PROG16. How do I create a process under another username? PROG17. Why do lib$spawn, lib$set_symbol fail in detached processes? PROG18. Where can I obtain Bliss, and the libraries and supporting files? PROG19. How can I open a file for shared access? PROG20. How can I have common sources for messages, constants? PROG21. How do I activate the OpenVMS Debugger from an application? -------------------------------------- 6.3. DJE VMS mentor pages See DJE VMS mentor pages -------------------------------------- 6.4. Arne Vajhøj's pages Arne Vajhøj has a lot of VMS programming examples at ftp://ftp.hhs.dk/pub/vms/. -------------------------------------- 6.5. OpenVMS Freeware CD Not exactly a resource for programming examples, the OpenVMS Freeware CD contains lots of packages (most of them in source) that can be helpful in the everyday use of VMS. The CD is packaged with the OpenVMS distribution; its contents is available online at www.openvms.compaq.com. -------------------------------------- 7. Credits My warmest Thank You to * all the people that keep comp.os.vms alive with their helpful posts. * DEC for a stable, well designed operating system like OpenVMS. * my employer PDV-SYSTEME for letting me get in touch with VMS. -------------------------------------- Martin Vorländer - on the web - mv@pdv-systeme.de - martin@radiogaga.harz.de