Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

sys$parse fails for long file names (length > 255)

 
SOLVED
Go to solution
madhav_poddar
Occasional Advisor

sys$parse fails for long file names (length > 255)

Hi there,

I wish to open a file (using sys$open), but that fails for files with file name length > 255 ("%RMS-F-SYN, file specification syntax error"). Hence I decided to use condensed file name instead for which I need Directory ID (DID). Now, to retrieve the DID of a file I thought of using sys$parse and sys$search, but that is also failing with the same error.  In the code, I am making sure to use NAML$L_LONG_FILENAM, etc. but it is still failing. Hence, I have the following queries:

  • Is there a way possible to directly use sys$parse on the long file name?
  • If not, is there an alternate way of retrieving the DID or converting the filename to condensed form?

 

Also, if there is any sample program which handles the opening of files with long file names, providing that would be really helpful.

 

Thanks in advance.

7 REPLIES 7
Steven Schweda
Honored Contributor

Re: sys$parse fails for long file names (length > 255)

> o Is there a way possible to directly use sys$parse on the long
> file name?

   Yes.  Sadly, I'm not very good at debugging invisible code.
Copy+paste is your friend.

> Also, if there is any sample program which handles the opening of
> files with long file names, providing that would be really helpful.

   There may be smaller examples, but have you looked at the Info-ZIP
Zip (3.0 or later) and UnZip (6.00 or later) code (typically
[.vms]vms.c in each)?  (If you get an error (RMS-F-SYN, or any other)
from either of those programs, then please let me know.)

madhav_poddar
Occasional Advisor

Re: sys$parse fails for long file names (length > 255)

Following is the code snippet :

 

	int status;
	struct FAB fab;
	struct NAM_STRUCT nam;

	char EName[NAM_MAXRSS];
	char RName[NAM_MAXRSS];

	fab = cc$rms_fab;
	nam = CC_RMS_NAM;
	fab.FAB_NAM = &nam;

#ifdef NAML$C_MAXRSS
	fab.fab$l_dna = (char *) -1;		/* Using NAML for default name. */
	fab.fab$l_fna = (char *) -1;		/* Using NAML for file name. */
#endif /* def NAML$C_MAXRSS */
	

	/* Argument file name and length. */
	FAB_OR_NAML( fab, nam ).FAB_OR_NAML_FNA = (char*)malloc( fileNameVMS.length() + 1 );
	strcpy( FAB_OR_NAML( fab, nam ).FAB_OR_NAML_FNA, fileNameVMS.c_str() );
	FAB_OR_NAML( fab, nam ).FAB_OR_NAML_FNS = fileNameVMS.length();

	// /* Default file spec and length. */
	FAB_OR_NAML( fab, nam ).FAB_OR_NAML_DNA = NULL;
	FAB_OR_NAML( fab, nam ).FAB_OR_NAML_DNS = 0;

	nam.NAM_ESA = (char*)&EName;
	nam.NAM_ESS = sizeof( EName );
	nam.NAM_RSA = (char*)&RName;
	nam.NAM_RSS = sizeof( RName );

	status = sys$parse( &fab );
	if ( ( status & 0x7fff ) != SS$_NORMAL )
	{
		// Code to display the error message.
	}

	status = sys$search( &fab );
	if ( ( status & 0x7fff ) != SS$_NORMAL )
	{
		// Code to display the error message.
	}

This works for all files except the one with long file names.

 

Steven Schweda
Honored Contributor
Solution

Re: sys$parse fails for long file names (length > 255)

 

 

> Following is the code snippet :

   A whole program would have been more helpful.  Actual file specs,
too.

   Here's my (self-contained) version (with a few changes since the
released Zip and UnZip, assuming that my copy+paste worked):

its $ type longname.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <rms.h>
#include <ssdef.h>
#include <starlet.h>

/* Define macros for use with either NAM or NAML. */

#ifdef NAML$C_MAXRSS            /* NAML is available (ODS5 support...) */

#  ifndef NAMX_MAXRSS           /* May have been defined before. */
#    define NAMX_MAXRSS NAML$C_MAXRSS
#  endif

#  define NAMX_STRUCT NAML

#  define FAB_OR_NAML(fab, nam) (nam)
#  define FAB_OR_NAML_DNA naml$l_long_defname
#  define FAB_OR_NAML_DNS naml$l_long_defname_size
#  define FAB_OR_NAML_FNA naml$l_long_filename
#  define FAB_OR_NAML_FNS naml$l_long_filename_size

#  define CC_RMS_NAMX cc$rms_naml
#  define FAB_NAMX fab$l_naml

#  define NAMX_ESA naml$l_long_expand
#  define NAMX_ESL naml$l_long_expand_size
#  define NAMX_ESS naml$l_long_expand_alloc
#  define NAMX_RSA naml$l_long_result
#  define NAMX_RSL naml$l_long_result_size
#  define NAMX_RSS naml$l_long_result_alloc
#  define NAMX_DID naml$w_did
#  define NAMX_DVI naml$t_dvi
#  define NAMX_FID naml$w_fid
#  define NAMX_FNB naml$l_fnb
#  define NAMX_NOP naml$b_nop
#  define NAMX_M_SYNCHK NAML$M_SYNCHK
#  define NAMX_B_DEV naml$l_long_dev_size
#  define NAMX_L_DEV naml$l_long_dev
#  define NAMX_B_DIR naml$l_long_dir_size
#  define NAMX_L_DIR naml$l_long_dir
#  define NAMX_B_NAME naml$l_long_name_size
#  define NAMX_L_NAME naml$l_long_name
#  define NAMX_B_TYPE naml$l_long_type_size
#  define NAMX_L_TYPE naml$l_long_type
#  define NAMX_B_VER naml$l_long_ver_size
#  define NAMX_L_VER naml$l_long_ver
#  define NAMX_DNA_FNA_SET( fab) (fab).fab$l_dna = (char *) -1; \
    (fab).fab$l_fna = (char *) -1;
                                
#else /* def NAML$C_MAXRSS */   /* NAML is not available.  Use NAM. */

#  ifndef NAMX_MAXRSS           /* May have been defined before. */
#    define NAMX_MAXRSS NAM$C_MAXRSS
#  endif

#  define NAMX_STRUCT NAM

#  define FAB_OR_NAML(fab, nam) (fab)
#  define FAB_OR_NAML_DNA fab$l_dna
#  define FAB_OR_NAML_DNS fab$b_dns
#  define FAB_OR_NAML_FNA fab$l_fna
#  define FAB_OR_NAML_FNS fab$b_fns

#  define CC_RMS_NAMX cc$rms_nam
#  define FAB_NAMX fab$l_nam
#  define NAMX_ESA nam$l_esa
#  define NAMX_ESL nam$b_esl
#  define NAMX_ESS nam$b_ess
#  define NAMX_RSA nam$l_rsa
#  define NAMX_RSL nam$b_rsl
#  define NAMX_RSS nam$b_rss
#  define NAMX_DID nam$w_did
#  define NAMX_DVI nam$t_dvi
#  define NAMX_FID nam$w_fid
#  define NAMX_FNB nam$l_fnb
#  define NAMX_NOP nam$b_nop
#  define NAMX_M_SYNCHK NAM$M_SYNCHK
#  define NAMX_B_DEV nam$b_dev
#  define NAMX_L_DEV nam$l_dev
#  define NAMX_B_DIR nam$b_dir
#  define NAMX_L_DIR nam$l_dir
#  define NAMX_B_NAME nam$b_name
#  define NAMX_L_NAME nam$l_name
#  define NAMX_B_TYPE nam$b_type
#  define NAMX_L_TYPE nam$l_type
#  define NAMX_B_VER nam$b_ver
#  define NAMX_L_VER nam$l_ver
#  define NAMX_DNA_FNA_SET( fab)

#endif /* def NAML$C_MAXRSS [else] */

int main( int argc, char **argv)
{
        int status;
        struct FAB fab;
        struct NAMX_STRUCT nam;

        char EName[NAMX_MAXRSS+ 1];
        char RName[NAMX_MAXRSS+ 1];

        char *vms_name = NULL;
        int vms_name_len = 0;

        char *short_name = "short.txt";

        char *vlong_name = "[.\
very_long_dire_name_very_long_dire_name_\
very_long_dire_name_very_long_dire_name_very_long_dire_name_]\
very_long_file_name_very_long_file_name_\
very_long_file_name_very_long_file_name_\
very_long_file_name_very_long_file_name_\
very_long_file_name_very_long_file_name_\
very_long_file_name_very_long_file_name_.txt";

        vms_name = short_name;

        if (argc > 1)
        {
                vms_name = vlong_name;
        }
        vms_name_len = strlen( vms_name);

        fprintf( stderr, " NAMX_MAXRSS = %d\n", NAMX_MAXRSS);
        fprintf( stderr, " vms_name_len = %d\n", vms_name_len);
        fprintf( stderr, " vms_name: >%s<\n", vms_name);

        fab = cc$rms_fab;
        nam = CC_RMS_NAMX;
        fab.FAB_NAMX = &nam;

        NAMX_DNA_FNA_SET( fab);
        
        /* Argument file name and length. */
        FAB_OR_NAML( fab, nam ).FAB_OR_NAML_FNA = vms_name;
        FAB_OR_NAML( fab, nam ).FAB_OR_NAML_FNS = vms_name_len;

        // /* Default file spec and length. */
        FAB_OR_NAML( fab, nam ).FAB_OR_NAML_DNA = NULL;
        FAB_OR_NAML( fab, nam ).FAB_OR_NAML_DNS = 0;

        nam.NAMX_ESA = (char*)&EName;
        nam.NAMX_ESS = sizeof( EName )- 1;
        nam.NAMX_RSA = (char*)&RName;
        nam.NAMX_RSS = sizeof( RName )- 1;

        status = sys$parse( &fab );
        if ( ( status & 0x7fff ) != SS$_NORMAL )
        {
                // Code to display the error message.
                fprintf( stderr, " sys$parse() sts = %08x\n", status);
        }
        else
        {
                fprintf( stderr, " ESL = %d\n", nam.NAMX_ESL);
                nam.NAMX_ESA[ nam.NAMX_ESL] = '\0';
                fprintf( stderr, " ESA: >%s<\n", nam.NAMX_ESA);
        }

        status = sys$search( &fab );
        if ( ( status & 0x7fff ) != SS$_NORMAL )
        {
                // Code to display the error message.
                fprintf( stderr, " sys$search() sts = %08x\n", status);
        }
        else
        {
                fprintf( stderr, " RSL = %d\n", nam.NAMX_RSL);
                nam.NAMX_RSA[ nam.NAMX_RSL] = '\0';
                fprintf( stderr, " RSA: >%s<\n", nam.NAMX_RSA);
        }

        exit( status);
}

its $ cc longname
its $ link longname

its $ mcr SYS$DISK:[]longname  
 NAMX_MAXRSS = 4095
 vms_name_len = 9
 vms_name: >short.txt<
 ESL = 29
 ESA: >ITS$DKA0:[SMS.itrc]short.txt;<
 RSL = 30
 RSA: >ITS$DKA0:[SMS.itrc]short.txt;1<

its $ mcr SYS$DISK:[]longname x
 NAMX_MAXRSS = 4095
 vms_name_len = 307
 vms_name: >[.very_long_dire_name_very_long_dire_name_very_long_dire_name_very_l
ong_dire_name_very_long_dire_name_]very_long_file_name_very_long_file_name_very_
long_file_name_very_long_file_name_very_long_file_name_very_long_file_name_very_
long_file_name_very_long_file_name_very_long_file_name_very_long_file_name_.txt<
 ESL = 325
 ESA: >ITS$DKA0:[SMS.itrc.very_long_dire_name_very_long_dire_name_very_long_dire
_name_very_long_dire_name_very_long_dire_name_]very_long_file_name_very_long_fil
e_name_very_long_file_name_very_long_file_name_very_long_file_name_very_long_fil
e_name_very_long_file_name_very_long_file_name_very_long_file_name_very_long_fil
e_name_.txt;<
 RSL = 326
 RSA: >ITS$DKA0:[SMS.itrc.very_long_dire_name_very_long_dire_name_very_long_dire
_name_very_long_dire_name_very_long_dire_name_]very_long_file_name_very_long_fil
e_name_very_long_file_name_very_long_file_name_very_long_file_name_very_long_fil
e_name_very_long_file_name_very_long_file_name_very_long_file_name_very_long_fil
e_name_.txt;1<


> This works for all files except the one with long file names.

   With my weak psychic powers, I can't see your file specs.

Arch_Muthiah
Honored Contributor

Re: sys$parse fails for long file names (length > 255)

Hi Madhav,
It may be due to OD2 and OD5 file parsing compatibility issue,
so I would suggest to check $ show dev dkannn:/full

and create a sample file with parse_style = Traditional and extended using
$ set process /parse_style = standard
$ open/write file x.x.x.x

and do test the same with $ set process/parse_style = extended
$ open/write file x.x.x.x

Dont' create extended file one ods-2 as it wont' support for some versions.

Regards
Archunan

Regards
Archie
Steven Schweda
Honored Contributor

Re: sys$parse fails for long file names (length > 255)

> It may be due to OD2 and OD5 file parsing compatibility issue, [...]

   I doubt it.  I'd expect sys$parse() not to care about the file
system.  I'd expect sys$search() to care about that.  For example, using
a slightly modified version of the program above:

ITS $ show devi /full ITS$LDA3:
[...]
  Volume Status:  ODS-2, [...]

ITS $ mcr ITS$DKA0:[SMS.itrc]longname2 x x
 NAMX_MAXRSS = 4095
 vms_name_len = 271
 vms_name: >[.dire_name_dire_name_dire_name_dire_name]very_long_file_name_very_l
ong_file_name_very_long_file_name_very_long_file_name_very_long_file_name_very_l
ong_file_name_very_long_file_name_very_long_file_name_very_long_file_name_very_l
ong_file_name_very_long_file_name_very_.txt<
 ESL = 284
 ESA: >ITS$LDA3:[SMS.DIRE_NAME_DIRE_NAME_DIRE_NAME_DIRE_NAME]very_long_file_name
_very_long_file_name_very_long_file_name_very_long_file_name_very_long_file_name
_very_long_file_name_very_long_file_name_very_long_file_name_very_long_file_name
_very_long_file_name_very_long_file_name_very_.txt;<
 sys$search() sts = 0001c02a
%RMS-E-FND, ACP file or directory lookup failed
-NONAME-W-NOMSG, Message number 00000000


   Note: No complaint from sys$parse(), only from sys$search().  (The
directory exists; the file does not.)

Arch_Muthiah
Honored Contributor

Re: sys$parse fails for long file names (length > 255)

Thanks Stewen,
I understand you must have explored lot and lot on this $parse/$search on part of your zip/unzip product, I still have have doubt on ODS compatibility too, let me go through and understand it more.


Thanks Steve,

Regards
Archie
Highlighted
Steven Schweda
Honored Contributor

Re: sys$parse fails for long file names (length > 255)

> I understand you must have explored lot and lot on this $parse/$search
> on part of your zip/unzip product, [...]

   Probably less than I should have, but more than some others, and
enough to get some things to work.

> [...] I still have have doubt on ODS compatibility too, let me go
> through and understand it more.

   How could I stop you?  In any case, you can see the program which I
used (or almost all of it, at least).  I'm always open to a good
educational experience, if you find anything interesting.