Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Programming Concepts Manual


Previous Contents Index

12.10.3 Using SYS$DELLNM to Delete Logical Names

The Delete Logical Name (SYS$DELLNM) system service deletes entries from a logical name table. When you write a call to the SYS$DELLNM system service, you can specify a single logical name to delete, or you can specify that you want to delete all logical names from a particular table. For example, the following call deletes the process logical name TERMINAL from the job logical name table:


 
#include <stdio.h> 
#include <lnmdef.h> 
#include <ssdef.h> 
#include <descrip.h> 
 
main() { 
 
        unsigned int status; 
        $DESCRIPTOR(logdesc,"DISK"); 
        $DESCRIPTOR(tabdesc,"LNM$JOB"); 
 
/* Delete the logical name */ 
        status = SYS$DELLNM(&tabdesc,   /* tabnam - logical table name */ 
                        &logdesc,       /* lognam - logical name */ 
                0);                     /* acmode - access mode */ 
        if ((status & 1) != 1) 
                LIB$SIGNAL(status); 
 
} 
 
 

For information about access modes and the deletion of logical names, see OpenVMS Programming Interfaces: Calling a System Routine.

12.10.4 Using SYS$TRNLNM to Translate Logical Names

The Translate Logical Name (SYS$TRNLNM) system service translates a logical name to its equivalence string. In addition, SYS$TRNLNM returns information about the logical name and equivalence string.

The system service call to SYS$TRNLNM specifies the tables to search for the logical name. The tabnam argument can be either the name of a logical name table or a logical name that translates to a list of one or more logical name tables.

Because logical names can have many equivalence strings, you can specify which equivalence string you want to receive.

A number of system services that require a device name accept a logical name and translate the logical name iteratively until a physical device name is found (or until the system default number of logical name translations has been performed, typically 10). These services implicitly use the logical name table name LNM$FILE_DEV. For more information about LNM$FILE_DEV, refer to Section 12.1.4.

The following system services perform iterative logical name translation automatically:

In many cases, however, a program must perform the logical name translation to obtain the equivalence name for a logical name outside the context of a device name or file specification. In that case, you must supply the name of the table or tables to be searched. The SYS$TRNLNM system service searches the user-specified logical name tables for a specified logical name and returns the equivalence name. In addition, SYS$TRNLNM returns attributes that are specified optionally for the logical name and equivalence string.

The following example shows a call to the SYS$TRNLNM system service to translate the logical name ABC:


 
 
#include <stdio.h> 
#include <lnmdef.h> 
#include <descrip.h> 
#include <ssdef.h> 
 
/* Define an item descriptor */ 
 
struct itm { 
             unsigned short buflen, item_code; 
             void *bufaddr; 
             void *retlenaddr; 
}; 
 
/* Declare an item list */ 
struct { 
         struct itm items[2]; 
         unsigned int terminator; 
}trnlst; 
 
main() { 
 
        char eqvbuf1[LNM$C_NAMLENGTH], eqvbuf2[LNM$C_NAMLENGTH]; 
        unsigned int status, trnattr=LNM$M_CASE_BLIND; 
        unsigned int eqvdesc1, eqvdesc2; 
        $DESCRIPTOR(logdesc,"ABC"); 
        $DESCRIPTOR(tabdesc,"LNM$FILE_DEV"); 
 
/* Assign values to the item list */ 
 
        trnlst.items[0].buflen = LNM$C_NAMLENGTH; 
        trnlst.items[0].item_code = LNM$_STRING; 
        trnlst.items[0].bufaddr = eqvbuf1; 
        trnlst.items[0].retlenaddr = &eqvdesc1; 
 
        trnlst.items[1].buflen = LNM$C_NAMLENGTH; 
        trnlst.items[1].item_code = LNM$_STRING; 
        trnlst.items[1].bufaddr = eqvbuf2; 
        trnlst.items[1].retlenaddr = &eqvdesc2; 
        trnlst.terminator = 0; 
 
/* Translate the logical name */ 
        status = SYS$TRNLNM(&trnattr,  /* attr - attributes */ 
                       &tabdesc,       /* tabnam - table name */ 
                       &logdesc,       /* lognam - logical name */ 
                       0,              /* acmode - access mode */ 
                       &trnlst);       /* itmlst - item list */ 
        if((status & 1) != 1) 
                LIB$SIGNAL(status); 
        
} 
 
 

This call to the SYS$TRNLNM system service results in the translation of the logical name ABC. In addition, LNM$FILE_DEV is specified in the tabnam argument as the search list that SYS$TRNLNM is to use to find the logical name ABC. The logical name ABC was assigned two equivalence strings. The LNM$_STRING item code in the itmlst argument directs SYS$TRNLNM to look for an equivalence string at the current index value. Note that the LNM$_STRING item code is invoked twice. The equivalence strings are placed in the two output buffers, EQVBUF1 and EQVBUF2, described by TRNLIST.

The attribute LNM$M_CASE_BLIND governs the translation process. The SYS$TRNLNM system service searches for the equivalence strings without regard to uppercase or lowercase letters. The SYS$TRNLNM system service matches any of the following character strings: ABC, aBC, AbC, abc, and so forth.

The output equivalence name string length is written into the first word of the character string descriptor. This descriptor can then be used as input to another system service.

12.10.5 Using SYS$CRELNM, SYS$TRNLNM, and SYS$DELLNM in a Program Example

In the following example, the Fortran program CALC.FOR creates a spawned subprocess to perform an iterative calculation. The logical name REP_NUMBER specifies the number of times that REPEAT should perform the calculation. Because the two processes are part of the same job, REP_NUMBER is placed in the job logical name table LNM$JOB. (Note that logical name table names are case sensitive. Specifically, LNM$JOB is a system-defined logical name that refers to the job logical name table; lnm$job is not.)


      PROGRAM CALC 
 
! Status variable and system routines 
 
      INCLUDE '($LNMDEF)' 
      INCLUDE '($SYSSRVNAM)' 
      INTEGER*4 STATUS 
 
      INTEGER*2 NAME_LEN, 
     2         NAME_CODE 
      INTEGER*4 NAME_ADDR, 
     2         RET_ADDR /0/, 
     2         END_LIST /0/ 
 
      COMMON /LIST/ NAME_LEN, 
     2             NAME_CODE, 
     2             NAME_ADDR, 
     2             RET_ADDR, 
     2             END_LIST 
 
      CHARACTER*3 REPETITIONS_STR 
      INTEGER REPETITIONS 
 
      EXTERNAL CLI$M_NOLOGNAM, 
     2        CLI$M_NOCLISYM, 
     2        CLI$M_NOKEYPAD, 
     2        CLI$M_NOWAIT 
 
       NAME_LEN = 3 
       NAME_CODE = (LNM$_STRING) 
       NAME_ADDR = %LOC(REPETITIONS_STR) 
       STATUS = SYS$CRELNM (,'LNM$JOB','REP_NUMBER',,NAME_LEN) 
       IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
      MASK = %LOC (CLI$M_NOLOGNAM) .OR. 
     2      %LOC (CLI$M_NOCLISYM) .OR. 
     2      %LOC (CLI$M_NOKEYPAD) .OR. 
     2      %LOC (CLI$M_NOWAIT) 
      STATUS = LIB$GET_EF (FLAG) 
      IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
      STATUS = LIB$SPAWN ('RUN REPEAT',,,MASK,,,,FLAG) 
    IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
       END 
 
      PROGRAM REPEAT 
      INTEGER STATUS, 
     2       SYS$TRNLNM,SYS$DELLNM 
      INTEGER*4   REITERATE, 
     2           REPEAT_STR_LEN 
      CHARACTER*3 REPEAT_STR 
     ! Item list for SYS$TRNLNM 
      INTEGER*2 NAME_LEN, 
     2         NAME_CODE 
      INTEGER*4 NAME_ADDR, 
     2         RET_ADDR, 
     2         END_LIST /0/ 
      COMMON /LIST/ NAME_LEN, 
     2             NAME_CODE, 
     2             NAME_ADDR, 
     2             RET_ADDR, 
     2             END_LIST 
 
      NAME_LEN = 3 
      NAME_CODE = (LNM$_STRING) 
      NAME_ADDR = %LOC(REPEAT_STR) 
      RET_ADDR = %LOC(REPEAT_STR_LEN) 
      STATUS = SYS$TRNLNM (, 
     2                    'LNM$JOB',     ! Logical name table 
     2                    'REP_NUMBER',, ! Logical name 
     2                    NAME_LEN)      ! List requesting equivalence string 
      IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
      READ (UNIT = REPEAT_STR, 
     2     FMT = '(I3)') REITERATE 
 
      DO I = 1, REITERATE 
      END DO 
 
      STATUS = SYS$DELLNM ('LNM$JOB',     ! Logical name table 
     2                    'REP_NUMBER',) ! Logical name 
      IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 
 
       END 


Chapter 13
Distributed Name Service (VAX Only)

This chapter describes the Digital Distributed Name Service (DECdns) Clerk by introducing the functions of the DECdns (SYS$DNS) system service and various run-time library routines. It is divided into the following sections:

Section 13.1 describes how to use the portable application programming interface and the operating system's system service and run-time library interface.

Section 13.2 describes how to use the SYS$DNS system service.

Section 13.3 describes how to use the DCL command DEFINE.

13.1 DECdns Clerk System Service

The DECdns Clerk (SYS$DNS) system service provides applications with a means of assigning networkwide names to system resources. Applications can use DECdns to name such resources as printers, files, disks, nodes, servers, and application databases. Once an application has named a resource using DECdns, the name is available for all users of the application.

The SYS$DNS system service supports two programming interfaces:

Portable Application Interface

Application designers should select an interface for their application based on programming language, application base, and specific requirements of their application.

The portable interface provides support for applications written in the C programming language, and it provides a high-level interface with easy-to-use methods of creating and maintaining DECdns names. Use the portable interface for applications that must be portable between VAX systems and the Compaq UNIX operating system.

The portable interface is documented in the Guide to Programming with DECdns.

VAX System Services and RTL Routines

The VAX system services and run-time library routines can be used by applications written in the high-level and midlevel languages listed in the preface of this document. However, applications that use these interfaces are limited to the VAX system environment. Use the system service when an application meets any of the following requirements:

The SYS$DNS system service is documented in the OpenVMS System Services Reference Manual. Before using this system service, familiarize yourself with the basic operating principles, terms, and definitions used by DECdns. You can gain a working knowledge of DECdns by reading about the following topics in the Guide to Programming with DECdns:

By understanding these topics, you can proceed more easily with this chapter, which provides an introduction to the DECdns system service and run-time library routines and discusses the following topics:

13.1.1 Using the DECdns System Service and Run-Time Library Routines

You can use the SYS$DNS system service and run-time library routines together to assign, maintain, and retrieve DECdns names. This section describes the capabilities of each interface.

13.1.1.1 Using the SYS$DNS System Service

DECdns provides a single system service call (SYS$DNS) to create, delete, modify, and retrieve DECdns names from a namespace. The SYS$DNS system service completes asynchronously; that is, it returns to the client immediately after making a name service call. The status returned to the client indicates whether a request was queued successfully to the name service.

The SYS$DNSW system service is the synchronous equivalent of SYS$DNS. The SYS$DNSW call is identical to SYS$DNS in every way except that SYS$DNSW returns to the caller after the operation completes.

The SYS$DNS call has two main parameters:

The system service provides the following functions:

You specify item codes as either input or output parameters in the item list. Input parameters modify functions, set context, or describe the information to be returned. Output parameters return the requested information.

You can specify the following in input item codes:

The output item codes return the following information:

13.1.1.2 Using the Run-Time Library Routines

You can use the DECdns run-time library routines to manipulate output from the SYS$DNS system service. The routines provide the following functions:

To read a single attribute value using the system service and run-time library routines, use the following routines:

You can also use the system service and run-time library routines together to add an opaque simple name to a full name by performing the following steps:

  1. Obtain a string full name from a user.
  2. Use the system service DNS$_PARSE_FULLNAME_STRING function code to convert the string name to opaque format.
  3. Use the DNS$_APPEND_SIMPLE_TO_RIGHT run-time library routine to add an opaque simple name to the end of the full name.

13.2 Using the SYS$DNS System Service Call

The following sections describe how to create and modify an object, and then how to read attributes and enumerate names and attributes in the namespace.

Each section contains a code example. These code examples are all contained in the sample program that resides on your distribution medium under the file name SYS$EXAMPLES:SYS$DNS_SAMPLE.C.

13.2.1 Creating Objects

Applications that use DECdns can create an object in the namespace for each resource used by the application. You can create objects using either the SYS$DNS or the SYS$DNSW system service.

A DECdns object consists of a name and its associated attributes. When you create the object, you must assign a class and a class version. You can modify the object to hold additional attributes, such as class-specific attributes, on an as-needed basis.

Note that applications can use objects that are created by other applications.

To create an object in the namespace with SYS$DNS:

  1. Prompt the user for a name.
    The name that an application assigns to an object should come from a user, a configuration file, a system logical name, or some other source. The application never assigns an object's name because the namespace structure is uncertain. The name the application receives from the user is in string format.
  2. Use the SYS$DNS parse function to convert the full name string into an opaque format. Specify the DNS$_NEXTCHAR_PTR item code to obtain the length of the opaque name.
  3. Optionally, reserve an event flag so you can check for completion of the service.
  4. Build an item list that contains the following elements:
  5. Optionally, provide the address of the DECdns status block to receive status information from the name service.
  6. Optionally, provide the address of the asynchronous system trap (AST) service routine. AST routines allow a program to continue execution while waiting for parts of the program to complete.
  7. Optionally, supply a parameter to pass to the AST routine.
  8. Call the create object function and provide all the parameters supplied in steps 1 through 7.

If a clerk call is not complete when timeout occurs, then the call completes with an error. The error is returned in the DECdns status block.

An application should check for errors that are returned; it is not enough to check the return of the SYS$DNS call itself. You need to check the DECdns status block to be sure no errors are returned by the DECdns server.

The following routine, written in C, shows how to create an object in the namespace with the synchronous service SYS$DNSW. The routine demonstrates how to construct an item list.


#include <dnsdef.h> 
#include <dnsmsg.h> 
/* 
 * Parameters: 
 *      class_name = address of the opaque simple name of the class 
 *                   to assign to the object 
 *      class_len  = length (in bytes) of the class opaque simple name 
 *      object_name= address of opaque full name of the object 
 *                   to create in the namespace. 
 *      object_len = length (in bytes) of the opaque full name of the 
 *                   object to create 
 */ 
 
create_object(class_name, class_len, object_name, object_len) 
unsigned char *class_name;  /*Format is a DECdns opaque simple name*\
unsigned short class_len;   
unsigned char *object_name; /*Format is a DECdns opaque simple name*\
unsigned short object_len;  
{ 
    struct $dnsitmdef createitem[4]; /* Item list used by system service */ 
    struct $dnscversdef version;     /* Version assigned to the object */ 
    struct $dnsb iosb;          /* Used to determine DECdns server status */ 
    int status;                 /* Status return from system service */ 
 
    /* 
     * Construct the item list that creates the object: 
     */ 
    createitem[0].dns$w_itm_size = class_len;   (1)
    createitem[0].dns$w_itm_code = dns$_class; 
    createitem[0].dns$a_itm_address = class_name; 
 
    createitem[1].dns$w_itm_size = object_len;   (2)
    createitem[1].dns$w_itm_code = dns$_objectname; 
    createitem[1].dns$a_itm_address = object_name; 
 
    version.dns$b_c_major = 1;   (3)
    version.dns$b_c_minor = 0; 
 
    createitem[2].dns$w_itm_size = sizeof(struct $dnscversdef);  (4)
    createitem[2].dns$w_itm_code = dns$_version; 
    createitem[2].dns$a_itm_address = &version; 
 
    *((int *)&createitem[3]) = 0;   (5)
 
    status = sys$dnsw(0, dns$_create_object, &createitem, &iosb, 0, 0); (6)
 
    if(status == SS$_NORMAL)   
    { 
        status = iosb.dns$l_dnsb_status; (7)
    } 
 
    return(status); 
} 
 

  1. The first entry in the item list is the address of the opaque simple name that represents the class of the object.
  2. The second entry is the address of the opaque full name for the object.
  3. The next step is to build a version structure, which will indicate the version of the object. In this case, the object is version 1.0.
  4. The third entry is the address of the version structure that was just built.
  5. A value of 0 terminates the item list.
  6. The next step is to call the system service to create the object.
  7. Check to see that both the system service and DECdns were able to perform the operation without error.

13.2.2 Modifying Objects and Their Attributes

After you create objects that identify resources, you can add or modify attributes that describe properties of the object. There is no limit imposed on the number of attributes an object can have.

You modify an object whenever you need to add an attribute or attribute value, change an attribute value, or delete an attribute or attribute value. When you modify an attribute, DECdns updates the timestamp contained in the DNS$UTS attribute for that attribute.

To modify an attribute or attribute value, use the DNS$_MODIFY_ATTRIBUTE function code. Specify the attribute name in the input item code along with the following required input item codes:

Use the DNS$_MODVALUE item code to specify the value of the attribute. Note that the DNS$_MODVALUE item code must be specified to add a single-valued attribute. You can specify a null value for a set-valued attribute. DECdns modifies attribute values in the following way:

To delete an attribute, use the DNS$_MODOPERATION item code.

The following is an example of how to use the DNS$_MODIFY_ATTRIBUTE function code to add a new member to a group object. To do this, you add the new member to the DNS$Members attribute of the group object. Use the following function codes:

Perform the following steps to modify an object with SYS$DNSW:

  1. Build an item list that contains the following elements:
  2. Supply any of the optional parameters described in Section 13.2.1.
  3. Call the modify attribute function, supplying the parameters established in steps 1 and 2.

The following example, written in C, shows how to add a set-valued attribute and a value to an object:


#include <dnsdef.h> 
#include <dnsmsg.h> 
/* 
 * Parameters: 
 *      obj_name = address of opaque full name of object 
 *      obj_len  = length of opaque full name of object 
 *      att_name = address of opaque simple name of attribute to create 
 *      att_len  = length of opaque simple name of attribute 
 *      att_value= value to associate with the attribute 
 *      val_len  = length of added value (in bytes) 
 */ 
 
add_attribute(obj_name, obj_len, att_name, att_len, att_value, val_len) 
unsigned char *obj_name; 
unsigned short obj_len; 
unsigned char *att_name; 
unsigned short att_len; 
unsigned char *att_value; 
unsigned short val_len; 
 
main() { 
        struct $dnsitmdef moditem[7];          /* Item list for $DNSW */ 
        unsigned char objtype = dns$k_object;  /* Using objects */ 
        unsigned char opertype = dns$k_present; /* Adding an object */ 
        unsigned char attype = dns$k_set;     /* Attribute will be type set */ 
        struct $dnsb iosb;                /* Used to determine DECdns status */ 
        int status;                       /* Status of system service */ 
 
    /* 
     * Construct the item list to add an attribute to an object. 
     */ 
    moditem[0].dns$w_itm_size = obj_len; 
    moditem[0].dns$w_itm_code = dns$_entry; 
    moditem[0].dns$a_itm_address = obj_name;   (1)
 
    moditem[1].dns$w_itm_size = sizeof(char); 
    moditem[1].dns$w_itm_code = dns$_lookingfor; 
    moditem[1].dns$a_itm_address = &objtype;   (2)
 
    moditem[2].dns$w_itm_size = sizeof(char); 
    moditem[2].dns$w_itm_code = dns$_modoperation; 
    moditem[2].dns$a_itm_address = &opertype;   (3)
 
    moditem[3].dns$w_itm_size = sizeof(char); 
    moditem[3].dns$w_itm_code = dns$_attributetype; 
    moditem[3].dns$a_itm_address = &attype;   (4)
 
    moditem[4].dns$w_itm_size = att_len; 
    moditem[4].dns$w_itm_code = dns$_attributename; 
    moditem[4].dns$a_itm_address = att_name;   (5)
 
    moditem[5].dns$w_itm_size = val_len; 
    moditem[5].dns$w_itm_code = dns$_modvalue; 
    moditem[5].dns$a_itm_address = att_value;   (6)
 
    *((int *)&moditem[6]) = 0;   (7)
 
    /* 
     * Call $DNSW to add the attribute to the object. 
     */ 
    status = sys$dnsw(0, dns$_modify_attribute, &moditem, &iosb, 0, 0);(8)
                                                          
    if(status == SS$_NORMAL) 
    { 
    status = iosb.dns$l_dnsb_status;  (9)
    } 
 
    return(status); 
} 


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5841PRO_036.HTML