[comp.sys.apollo] [LONG] Re: Help needed on sys calls to get user,group names

beierl_c@apollo.HP.COM (Christopher Beierl) (04/25/91)

In article <4092@risky.Convergent.COM> ssridhar@pase60.Convergent.Com (Srinivasan Sridhar) writes:
>...
>Help with the name_$read_dir_lc() call
>======================================

Since this seems to be something that a number of folks have had
problems with at one point or another, here are some sample routines
which use the name_$read_dir_lc() call from C and FORTRAN:

<read_dir_example.c>
+ /*******************************************************************/
+ /* NOTE: The include file <apollo/name.h> may have an incorrect
+ /*       prototype for name_$read_dir_lc().  If it says
+ /*       "name_$cursor_t *cursor," rather than the correct
+ /*       "name_$cursor_t cursor," you will need to change the
+ /*       fourth argument to name_$read_dir_lc() in the code below
+ /*       to "(name_$cursor_t *)index" rather than "index" (or fix
+ /*       the <apollo/name.h> header file by removing the asterisk)
+ /*******************************************************************/
+ 
+ #include <stdio.h>
+ #include <math.h>
+ #include <strings.h>
+ #include <apollo/base.h>
+ #include <apollo/error.h>
+ #include <apollo/name.h>
+ 
+ #define MAX_COUNT       6       /* Arbitrary */
+ #define DIR_LIST_SIZE   2048    /* Arbitrary buffer size */
+ 
+ #define CHECK   if (status.all) {error_$print(status); exit(1);}
+ 
+ main(int argc, char **argv)
+ {
+     char                        dir_list[DIR_LIST_SIZE];
+     name_$long_name_t           full_name;
+     unsigned short              full_len;
+     unsigned short              entlen;
+     name_$long_name_t           entname;
+     name_$canonical_dir_entry_t *entry_ptr;
+     short                       enttype;
+     int                         i, j;
+     name_$cursor_t              index;
+     name_$long_name_t           partial_name;
+     unsigned short              read_count;
+     boolean                     seek_to_bof;
+     status_$t                   status;
+ 
+     if (argc != 2) {
+         fprintf(stderr, "Syntax:  %s  directory\n", argv[0]);
+         exit(1);
+     }
+ 
+ /* Get partial directory name from command line */
+     strcpy(partial_name, argv[1]);
+     printf("\nPartial name: '%s'\n", partial_name);
+ 
+ /* Expand partial directory name to full path name */
+     name_$get_path_lc(partial_name,
+                       (unsigned short)strlen(partial_name), 
+                       (unsigned short)name_$long_pnamlen_max,
+                       full_name,
+                       &full_len,
+                       &status); CHECK;
+     full_name[full_len] = '\0';
+     printf("Full name: '%s'\n", full_name);
+ 
+ /* Read directory entries (up to MAX_COUNT at a time) */
+     seek_to_bof = true;
+     for (;;) {
+         name_$read_dir_lc(full_name,
+                           (unsigned short)strlen(full_name),
+                           &seek_to_bof,
+                           index,    /* See NOTE at top of file */
+                           (unsigned short)MAX_COUNT,
+                           (unsigned long)DIR_LIST_SIZE,
+                           dir_list,
+                           &read_count,
+                           &status); CHECK;
+         if (read_count == 0) {
+             break;
+         }
+         printf("Read_count = %u\n", read_count);
+ 
+ /* Extract data from directory entries */
+         entry_ptr = (name_$canonical_dir_entry_t *)dir_list;
+         for (i = 0; i < read_count; ++i) {
+             printf("\t  [struct ref] : (%s) '",
+                 entry_ptr->enttype == name_$file ? "file" : "link");
+ 
+             for (j = 0; j < entry_ptr->entlen; ++j) {
+                 putchar(entry_ptr->entname[j]);
+             }
+             printf("'\n");
+ 
+ /* Reset entry_ptr to point to next entry */
+             entry_ptr = (name_$canonical_dir_entry_t *)((char *)entry_ptr + entry_ptr->entnxt);
+         }
+     }
+ }

<read_dir_example.ftn>
+         program read_dir_example
+ 
+ %include '/sys/ins/base.ins.ftn'
+ %include '/sys/ins/error.ins.ftn'
+ %include '/sys/ins/name.ins.ftn'
+ %include '/sys/ins/pgm.ins.ftn'
+ 
+         integer*4       DIR_LIST_SIZE
+         parameter (
+      &      DIR_LIST_SIZE   = 2048)             { arbitrary }
+ 
+         integer*2       MAX_COUNT, MAX_LEN, MAX_ENT_LEN
+         parameter (
+      &      MAX_COUNT       = 6,                { arbitrary }
+      &      MAX_LEN         = name_$long_pnamlen_max,
+      &      MAX_ENT_LEN     = name_$long_complen_max)
+ 
+         integer         i
+         integer         entry_ptr
+         character       partial_name*1023
+         character       full_name*1023
+         integer*2       full_len
+         logical         seek_to_bof
+         character       index*300
+         character       dir_list*(DIR_LIST_SIZE)
+         integer*2       read_count
+         integer*2       entnxt
+         integer*2       enttype
+         integer*2       entlen
+         character       entname*255
+         integer*2       arg_len
+         integer*2       arg_number
+         integer*4       status
+         integer*2       buffer_len
+         character       canonical_entry*278
+ 
+         equivalence (entnxt,  canonical_entry( 1:  2))
+         equivalence (enttype, canonical_entry( 3:  4))
+         equivalence (entlen,  canonical_entry(21: 22))
+         equivalence (entname, canonical_entry(23:278))
+ 
+ C  Get partial directory name from command line */
+         arg_number = 1
+         buffer_len = 1023
+         arg_len = pgm_$get_arg(arg_number, partial_name, status,
+      &      buffer_len)
+         if (arg_len .eq. 0) then
+             print *, 'Syntax:  name_test  directory'
+             stop
+         end if
+         print *, 'Partial name: ', partial_name(1:arg_len)
+ 
+ C  Expand partial directory name to full path name */
+         call name_$get_path_lc(partial_name,
+      &                         arg_len,
+      &                         MAX_LEN,
+      &                         full_name,
+      &                         full_len,
+      &                         status)
+         if (status .ne. 0) then
+             call error_$print(status)
+             stop
+         end if
+         print *, 'Full name: ', full_name(1:full_len)
+ 
+ C  Read directory entries (up to MAX_COUNT at a time) */
+         seek_to_bof = .true.
+         do while (.true.)
+             call name_$read_dir_lc(full_name,
+      &                             full_len,
+      &                             seek_to_bof,
+      &                             index,
+      &                             MAX_COUNT,
+      &                             DIR_LIST_SIZE,
+      &                             dir_list,
+      &                             read_count,
+      &                             status)
+             if (status .ne. 0) then
+                 call error_$print(status)
+                 stop
+             end if
+             if (read_count .eq. 0) goto 999
+             print *, 'Read_count = ', read_count
+ 
+ C  Extract data from directory entries */
+             entry_ptr = 1
+             do i = 1, read_count
+                 canonical_entry = dir_list(entry_ptr : entry_ptr + 277)
+                 if (enttype .eq. name_$file) then
+                     print *, '    Directory entry: (file) ''',
+      &                  entname(1:entlen), ''''
+                 else
+                     print *, '    Directory entry: (link) ''',
+      &                  entname(1:entlen), ''''
+                 end if
+ 
+ C Reset entry_ptr to point to next entry
+                 entry_ptr = entry_ptr + entnxt
+             end do
+         end do
+ 
+ 999     continue
+         end

The following FORTRAN example makes use of name_$extract_data_lc(), but
is limited to processing one directory entry at a time.  It is much
simpler to use the previous method.

<read_dir_example2.ftn>
+         program read_dir_example2
+ 
+ %include '/sys/ins/base.ins.ftn'
+ %include '/sys/ins/error.ins.ftn'
+ %include '/sys/ins/name.ins.ftn'
+ %include '/sys/ins/pgm.ins.ftn'
+ 
+         integer*4       DIR_LIST_SIZE
+         parameter (
+      &      DIR_LIST_SIZE   = 2048)             { arbitrary }
+ 
+         integer*2       MAX_COUNT, MAX_LEN, MAX_ENT_LEN
+         parameter (
+      &      MAX_COUNT       = 1,                { MUST be 1 }
+      &      MAX_LEN         = name_$long_pnamlen_max,
+      &      MAX_ENT_LEN     = name_$long_complen_max)
+ 
+         integer         i
+         integer         entry_ptr
+         character       partial_name*1023
+         character       full_name*1023
+         integer*2       full_len
+         logical         seek_to_bof
+         character       index*300
+         character       dir_list*(DIR_LIST_SIZE)
+         integer*2       read_count
+         integer*2       enttype
+         integer*2       entlen
+         character       entname*255
+         integer*2       arg_len
+         integer*2       arg_number
+         integer*4       status
+         integer*2       buffer_len
+ 
+ C  Get partial directory name from command line */
+         arg_number = 1
+         buffer_len = 1023
+         arg_len = pgm_$get_arg(arg_number, partial_name, status,
+      &      buffer_len)
+         if (arg_len .eq. 0) then
+             print *, 'Syntax:  name_test  directory'
+             stop
+         end if
+         print *, 'Partial name: ', partial_name(1:arg_len)
+ 
+ C  Expand partial directory name to full path name */
+         call name_$get_path_lc(partial_name,
+      &                         arg_len,
+      &                         MAX_LEN,
+      &                         full_name,
+      &                         full_len,
+      &                         status)
+         if (status .ne. 0) then
+             call error_$print(status)
+             stop
+         end if
+         print *, 'Full name: ', full_name(1:full_len)
+ 
+ C  Read directory entries (up to MAX_COUNT at a time) */
+         seek_to_bof = .true.
+         do while (.true.)
+             call name_$read_dir_lc(full_name,
+      &                             full_len,
+      &                             seek_to_bof,
+      &                             index,
+      &                             MAX_COUNT,
+      &                             DIR_LIST_SIZE,
+      &                             dir_list,
+      &                             read_count,
+      &                             status)
+             if (status .ne. 0) then
+                 call error_$print(status)
+                 stop
+             end if
+             if (read_count .eq. 0) goto 999
+             print *, 'Read_count = ', read_count
+ 
+ C  Extract data from directory entry (only handles on entry) */
+             call name_$extract_data_lc(dir_list,
+      &                                 enttype,
+      &                                 entlen,
+      &                                 MAX_ENT_LEN,
+      &                                 entname,
+      &                                 status)
+             if (enttype .eq. name_$file) then
+                 print *, '    Directory entry: (file) ''',
+      &              entname(1:entlen), ''''
+             else
+                 print *, '    Directory entry: (link) ''',
+      &              entname(1:entlen), ''''
+             end if
+         end do
+ 
+ 999     continue
+         end

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Christopher T. Beierl  Internet: beierl_c@apollo.HP.COM;beierl_c@apollo.com
 Apollo Computer, Inc.      UUCP: {mit-eddie,yale,uw-beaver}!apollo!beierl_c
 A Subsidiary of Hewlett-Packard                       Phone: (508) 256-6600