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