#include stdio #include string #include descrip #include stdlib #include descrip #include ssdef #include #include /* * Description: Sample program to demonstrate how to read an attribute of * a DECdns object. * * Parameters: * This program takes 3 arguments. They are: * argv[0] = name of this program * argv[1] = name of object in string (printable) format * argv[2] = an attribute of object given in argv[1] * * Returns: * Returns status from sys$dnsw, function dns$_parse_fullname_string * dns$_parse_simplename_string, or dns$_read_attribute. * Also can return status from dns$remove_first_set_value system service. */ main (int argc,char *argv[]) { struct $dnsitmdef parseitem[3]; /* Item list for parsing */ unsigned char attr_buf[dns$k_simplenamemax]; /* Opaque attribute name */ unsigned char fullname_buf[dns$k_fullnamemax]; /* Opaque object name */ int status; /* General routine status */ struct $dnsb dnsb; /* Used for nameserver status information */ unsigned short fname_len; /* Length of object name */ unsigned short attri_len; /* Length of attribute name */ /* * Make certain that you have the number of arguments you expect. */ if (argc != 3) { printf("USAGE: read_attr \n"); exit(0); } /* * Convert the object string name into opaque format. */ /* First item contains the address of the object string name */ parseitem[0].dns$w_itm_code = dns$_fromstringname; parseitem[0].dns$w_itm_size = strlen(argv[1]); parseitem[0].dns$a_itm_address = argv[1]; /* Second item contains the address of the buffer to receive the * opaque fullname of the object. */ parseitem[1].dns$w_itm_code = dns$_tofullname; parseitem[1].dns$w_itm_size = dns$k_fullnamemax; parseitem[1].dns$a_itm_address = fullname_buf; parseitem[1].dns$a_itm_ret_length = &fname_len; /* Zero terminates the itemlist to indicate no more item blocks. */ *((int *)&parseitem[2]) = 0; /* Use system service to convert object name to opaque format */ status = sys$dnsw(0, dns$_parse_fullname_string, &parseitem, &dnsb, 0, 0); /* * Must check both the return status from the service, plus the * status from the nameserver in all cases. */ if (status == SS$_NORMAL) { status = dnsb.dns$l_dnsb_status; } /* If error, print message and terminate. */ if (status != SS$_NORMAL) { printf("Error converting name %s\n", argv[1]); exit(status); } /* * Convert the attribute string name into opaque format. */ /* First item is the address of the attribute name in string format. */ parseitem[0].dns$w_itm_code = dns$_fromstringname; parseitem[0].dns$w_itm_size = strlen(argv[2]); parseitem[0].dns$a_itm_address = argv[2]; /* Second item is the address of the buffer which will contain the * opaque version of the attribute name. Size of the actual class name * will be found in attri_len. */ parseitem[1].dns$w_itm_code = dns$_tosimplename; parseitem[1].dns$w_itm_size = dns$k_simplenamemax; parseitem[1].dns$a_itm_address = attr_buf; parseitem[1].dns$a_itm_ret_length = &attri_len; /* Zero terminates the itemlist to indicate no more item blocks. */ *((int *)&parseitem[2]) = 0; /* Use system service to convert attribute name to opaque format */ status = sys$dnsw(0, dns$_parse_simplename_string, &parseitem, &dnsb, 0, 0); /* * Must check both the return status from the service, plus the * status from the nameserver in all cases. */ if (status == SS$_NORMAL) { status = dnsb.dns$l_dnsb_status; } /* If an error occurred, print out the message and terminate */ if (status != SS$_NORMAL) { printf("Error converting name %s\n", argv[2]); exit(status); } printf("Reading attribute \"%s\" of object \"%s\":\n", argv[2],argv[1]); status = read_attribute( fullname_buf, fname_len, attr_buf, attri_len); /* * Must check both the return status from the service, plus the * status from the nameserver in all cases. */ if (status == SS$_NORMAL) { status = dnsb.dns$l_dnsb_status; } /* If an error occurred, print it out and terminate */ if (status != SS$_NORMAL) { printf("Error status from read_attribute = %d\n", status); } exit(status); } /* * * Description: Function to read and display attribute of a DECdns object. * * Parameters: * opaque_objname = address of opaque full name of the object whose * attribute is to be read * obj_len = length (in bytes) of the opaque full name of the * object whose attribute is to be read * opaque_attname = address of the opaque simple name of the attribute * to be read * attname_len = length in bytes of the attribute opaque simple name * * Returns: * Returns status from sys$dnsw, function dns$_read_attribute. * Also can return status from dns$remove_first_set_value system service. */ int read_attribute( unsigned char *opaque_objname, unsigned short obj_len, unsigned char *opaque_attname, unsigned short attname_len) { struct $dnsitmdef readitem[6]; /* System service item list */ unsigned char objtype = dns$k_object; /* Defines what looking for */ struct $dnsb dnsb; /* For DECdns server status */ struct dsc$descriptor set_dsc, value_dsc, newset_dsc, cts_dsc; unsigned char /* Holds the attribute values */ attvalbuf[dns$k_maxattribute]; unsigned char /* Holds set of attribute values */ attsetbuf[dns$k_maxattribute]; unsigned char /* For context of multi reads */ ctsbuf[dns$k_uid_length]; int read_status; /* Status of read attribute routine */ int set_status; /* Status of remove value routine */ int idx; /* Index used by print routine */ unsigned short setlen; /* current length of set structure */ unsigned short val_len; /* length of value extracted from set */ unsigned short cts_len; /* length of CTS extracted from set */ /* * Construct the item list to read values for the attribute. */ /* Item identifies name you are working with */ readitem[0].dns$w_itm_size = obj_len; readitem[0].dns$w_itm_code = dns$_entry; readitem[0].dns$a_itm_address = opaque_objname; /* Item identifies previous item as an object */ readitem[1].dns$w_itm_size = sizeof(char); readitem[1].dns$w_itm_code = dns$_lookingfor; readitem[1].dns$a_itm_address = &objtype; /* Item indicates what attribute you want to read */ readitem[2].dns$w_itm_size = attname_len; readitem[2].dns$w_itm_code = dns$_attributename; readitem[2].dns$a_itm_address = opaque_attname; /* Item contains output from call */ readitem[3].dns$w_itm_size = dns$k_maxattribute; readitem[3].dns$w_itm_code = dns$_outvalset; readitem[3].dns$a_itm_address = attsetbuf; readitem[3].dns$a_itm_ret_length = &setlen; /* Zero terminates the itemlist to indicate no more item blocks. */ *((int *)&readitem[4]) = 0; do { /* Do read the attribute */ read_status = sys$dnsw(0, dns$_read_attribute, &readitem, &dnsb, 0, 0); if (read_status == SS$_NORMAL) { read_status = dnsb.dns$l_dnsb_status; } /* Must check system service and nameserver status codes */ if (!((read_status == SS$_NORMAL) || (read_status == DNS$_MOREDATA))) { /* Failed to read data */ return(read_status); } /* * Read data successfully. */ do { /* Do print out data */ set_dsc.dsc$w_length = setlen; set_dsc.dsc$a_pointer = /* address of set */ attsetbuf; value_dsc.dsc$w_length = dns$k_maxattribute; value_dsc.dsc$a_pointer = /* buffer to hold attribute */ attvalbuf; /* value. */ cts_dsc.dsc$w_length = dns$k_uid_length; cts_dsc.dsc$a_pointer = /* value's CTS */ ctsbuf; newset_dsc.dsc$w_length = dns$k_maxattribute; newset_dsc.dsc$a_pointer = /* same buffer for each call */ attsetbuf; set_status = dns$remove_first_set_value(&set_dsc, &value_dsc, &val_len, &cts_dsc, &cts_len, &newset_dsc, &setlen); if ((set_status != SS$_NORMAL) && (set_status != 0)) { /* Failed to parse data */ return (set_status); } if (set_status != 0) /* Had some data */ { /* * Parsed data successfully. Remember CTS of what you have * parsed to set the context for getting the next set member. */ readitem[4].dns$w_itm_size = cts_len; readitem[4].dns$w_itm_code = dns$_contextvartime; readitem[4].dns$a_itm_address = ctsbuf; /* Zero terminates itemlist to indicate no more item blocks. */ *((int *)&readitem[5]) = 0; printf("\tValue: "); for(idx = 0; idx < val_len; idx++) { printf("%x ", attvalbuf[idx]); } printf("\n"); } /* Had some data */ } while (set_status == SS$_NORMAL); /* Do print out data */ } while (read_status == DNS$_MOREDATA); /* Do read attribute */ return (read_status); }