HP OpenVMS Systems Documentation |
HP OpenVMS Programming Concepts Manual
Appendix F
|
#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);
}
|
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:
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);
}
|
Once an application adds its objects to the namespace and modifies the names to contain all necessary attributes, the application is ready to use the namespace. An application can request that the DECdns Clerk either read attribute information stored with an object or list all the application's objects that are stored in a particular directory. An application might also need to resolve all soft links in a name in order to identify a target.
To request information from DECdns, use the read or enumerate function codes, as follows:
The VAX Distributed File Service (DFS) uses DECdns for resource naming. This section gives an example of the DNS$_READ_ATTRIBUTE call as used by DFS. The DFS application uses DECdns to give the operating system's users the ability to use remote operating system disks as if the disks were attached to their local VAX system. The DFS application creates DECdns names for the operating system's directory structures (a directory and all of its subdirectories). Each DFS object in the namespace references a particular file access point. DFS creates each object with a class attribute of DFS$ACCESSPOINT and modifies the address attribute (DNS$Address) of each object to hold the DECnet node address where the directory structures reside. As a final step in registering its resources, DFS creates a database that maps DECdns names to the appropriate operating system directory structures.
Whenever the DFS application receives the following mount request, DFS sends a request for information to the DECdns Clerk:
|
MOUNT ACCESS_POINT dns-name vms-logical-name |
To read the address attribute of the access point object, the DFS application performs the following steps:
The DFS client and DFS server now can communicate to complete the mount
function.
F.2.3.2 Reading Attributes from DNS
When requesting information from DNS, an application always takes an object name from the user, translates the name into opaque format, and passes it in an item list to the DECdns Clerk.
Each read request returns a set of attribute values. The DNS$_READ_ATTRIBUTE service uses a context item code called DNS$_CONTEXTVARTIME to maintain context when reading the attribute values. The context item code saves the last member that is read from the set. When the next read call is issued, the item code sets the context to the next member in the set, reads it, and returns it. The context item code treats single-valued attributes as though they were a set of one.
If an enumeration call returns DNS$_MOREDATA, not all matching names or attributes have been enumerated. If you receive this message, you should make further calls, setting DNS$_CONTEXTVARTIME to the last value returned until the procedure returns SS$_NORMAL.
The following program, written in C, shows how an application reads an object attribute. The SYS$DNSW service uses an item list to return a set of objects. Then the application calls a run-time library routine to read each value in the set.
#include <dnsdef.h>
#include <dnsmsg.h>
/*
* Parameters:
* opaque_objname = address of opaque full name for the object
* containing the attribute to be read
* obj_len = length of opaque full name of the object
* opaque_attname = address of the opaque simple name of the
* attribute to be read
* attname_len = length of opaque simple name of attribute
*/
read_attribute(opaque_objname, obj_len, opaque_attname, attname_len)
unsigned char *opaque_objname;
unsigned short obj_len;
unsigned char *opaque_attname;
unsigned short attname_len;
{
struct $dnsb iosb; /* Used to determine DECdns status */
char objtype = dns$k_object; /* Using objects */
struct $dnsitmdef readitem[6]; /* Item list for system service */
struct dsc$descriptor set_dsc, value_dsc, newset_dsc, cts_dsc;
unsigned char attvalbuf[dns$k_maxattribute]; /* To hold the attribute */
/* values returned from extraction routine. */
unsigned char attsetbuf[dns$k_maxattribute]; /* To hold the set of */
/* attribute values after the return from $DNSW. */
unsigned char ctsbuf[dns$k_cts_length]; /* Needed for context of multiple reads */
int read_status; /* Status of read attribute routine */
int set_status; /* Status of remove value routine */
int xx; /* General variable used by print routine */
unsigned short setlen; /* Contains current length of set structure */
unsigned short val_len; /* Contains length of value extracted from set */
unsigned short cts_len; /* Contains length of CTS extracted from set */
/* Construct an item list to read values of the attribute. */ (1)
readitem[0].dns$w_itm_code = dns$_entry;
readitem[0].dns$w_itm_size = obj_len;
readitem[0].dns$a_itm_address = opaque_objname;
readitem[1].dns$w_itm_code = dns$_lookingfor;
readitem[1].dns$w_itm_size = sizeof(char);
readitem[1].dns$a_itm_address = &objtype;
readitem[2].dns$w_itm_code = dns$_attributename;
readitem[2].dns$a_itm_address = opaque_attname;
readitem[2].dns$w_itm_size = attname_len;
readitem[3].dns$w_itm_code = dns$_outvalset;
readitem[3].dns$a_itm_ret_length = &setlen;
readitem[3].dns$w_itm_size = dns$k_maxattribute;
readitem[3].dns$a_itm_address = attsetbuf;
*((int *)&readitem[4]) = 0;
do (2)
{
read_status = sys$dnsw(0, dns$_read_attribute, &readitem, &iosb, 0, 0);
if(read_status == SS$_NORMAL)
{
read_status = iosb.dns$l_dnsb_status;
}
if((read_status == SS$_NORMAL) || (read_status == DNS$_MOREDATA))
{
do
{
set_dsc.dsc$w_length = setlen;
set_dsc.dsc$a_pointer = attsetbuf; /* Address of set */
value_dsc.dsc$w_length = dns$k_simplenamemax;
value_dsc.dsc$a_pointer = attvalbuf; /* Buffer to hold */
/* attribute value */
cts_dsc.dsc$w_length = dns$k_cts_length;
cts_dsc.dsc$a_pointer = ctsbuf; /* Buffer to hold value's CTS*/
newset_dsc.dsc$w_length = dns$k_maxattribute;
newset_dsc.dsc$a_pointer = attsetbuf; /* Same buffer for */
/* each call */
set_status = dns$remove_first_set_value(&set_dsc, &value_dsc,
(3) &val_len, &cts_dsc,
&cts_len, &newset_dsc,
&setlen);
if(set_status == SS$_NORMAL)
{ (4)
readitem[4].dns$w_itm_code = dns$_contextvartime;
readitem[4].dns$w_itm_size = cts_len;
readitem[4].dns$a_itm_address = ctsbuf;
*((int *)&readitem[5]) = 0;
printf("\tValue: "); (5)
for(xx = 0; xx < val_len; xx++)
printf("%x ", attvalbuf[xx]);
printf("\n");
}
else if (set_status != 0)
{
printf("Error %d returned when removing value from set\n",
set_status);
exit(set_status);
}
} while(set_status == SS$_NORMAL);
}
else
{
printf("Error reading attribute = %d\n", read_status);
exit(read_status);
}
} while(read_status == DNS$_MOREDATA);
}
|
| Previous | Next | Contents | Index |