Author Topic: Rename files and set long name  (Read 1376 times)

Jan-Erik Lärka

  • Global Moderator
  • Full Member
  • *****
  • Thank You
  • -Given: 5
  • -Receive: 11
  • Posts: 151
    • View Profile
Rename files and set long name
« on: November 17, 2013, 09:59:08 am »
Hello,

I've searched for a function in rexx to rename files and eventually found the answer...
SysSetObjectData with the second parameter TITLE= together with the new name.
It's quite easy to rename the file/folder that way and to write a rename.cmd

CALL SysSetObjectData file_path_and_name, 'TITLE='||new_name

Recovery scripts and tools ( DFSee, JRescuer ) rely on EA's (Extended Attribute) to restore file names since JFS doesn't have the backup information about the file name within the fs itself. The functions below synchronize the file name and the EA so that such tools can help you in case of problems when you need to recover files. You do however need to run and set the EA before any problem arise that require recovery.

Please do note that I've added code that will remove unwanted characters from the actual file name that annoy me (files from the internet, other OSes etc.) , but you may want to keep those, extend them or tweak it further by altering the function "CleanString".

//Jan-Erik

Code: [Select]
setLongName: PROCEDURE
/* File/Folder name as the first and only parameter (full path) */
    file_name = FILESPEC( 'N', ARG(1) )
/* Read the EA entry for .LONGNAME from the File/Folder */
    rc = SysGetEA( ARG(1), '.LONGNAME', 'EAValue' )
/* Was it possible to read the EA entry for .LONGNAME successfully? */
    IF rc = 0 & EAValue <> '' THEN
    DO
/* Split the information up for further use */
        PARSE VAR EAValue EAType +2 EALength +2 EAValue
/* Does it contain a valid name, then set it */
        IF EAType = 'FDFF'x THEN
        DO
            longName = STRIP( EAValue, 'T', '00'x )
/* Remove unwanted charaters */
           cleanLongName = CleanString( longName )
/* Any changes between the long name and cleaned name? */
           IF cleanLongName <> longName THEN
           DO
/* Set the long name to the one of the cleaned */
               longName = cleanLongName
/* and write the information back */
               CALL SysPutEA ARG(1), '.LONGNAME', 'FDFF'x || D2C( LENGTH( longName ) ) || '00'x || longName
           END
/* If the name is different from the long name */
           IF longName <> file_name THEN
/* If the file/folder can be renamed to the long name, then set the new name */
              IF SysSetObjectData( ARG(1), 'TITLE='||longName ) THEN
                 file_name = longName
        END
        ELSE
            CALL SysPutEA ARG(1), '.LONGNAME', 'FDFF'x || D2C( LENGTH( file_name ) ) || '00'x || file_name
    END
    ELSE
        CALL SysPutEA ARG(1), '.LONGNAME', 'FDFF'x || D2C( LENGTH( file_name ) ) || '00'x || file_name
/* Above: Just write the current name to the EA if none has been set */
/* and return the file/folder with path */
RETURN FILESPEC( 'D', ARG(1) )||FILESPEC( 'P', ARG(1) )||file_name

/* String function */
CleanString: PROCEDURE
    haystack = ARG(1)
/* Clean out % and replace %20 = space, %28 = [, %29 = ] etc. */
    DO WHILE POS( '%', haystack ) > 0
        PARSE VALUE haystack WITH pre'%' +1 hex_val +2 post
        IF DATATYPE( hex_val, 'X' ) & SPACE( hex_val, 0 ) <> '' THEN
            haystack = pre||X2C( hex_val )||post
        ELSE haystack = pre||hex_val||post
    END
/* 35 = #, 36 = $, 58 = :, 91 = [, 92 = \, 93 = ], 123 = {, 125 = } etc. */
    clean = '35 36 58 91 92 93 123 125 127'
    DO i = 1 TO WORDS( clean )
        needle = D2C( SUBWORD( clean, i, 1 ) )
        DO WHILE POS( needle, haystack ) > 0
            PARSE VALUE haystack WITH pre(needle)post
            haystack = pre||post
        END
    END
RETURN haystack