//////////////////////////////////////////////////////////////////////////////// // // Task: MACNSFIX.TSK // (Search for and rename Macintosh entries with invalid characters) // Author: Avanti Technology, Inc. // http://www.avanti-tech.com // Version: 1.0 - Initial Release // // Description: // ============ // Search for Macintosh entries with invalid characters (leading spaces, // ampersands, asterisks, double quotes, and/or question marks used in the // Mac NS name). If found, attempt to rename them substituting valid // characters for the invalid characters and log the results. // // Objective: // ========== // Fix Macintosh entries which have names that TaskMaster cannot support // (due to NetWare CLIB API limitations). // // Usage: // ====== // Script can be manually executed using the TaskMaster TMRUN command // at the TMConsole (Shell) Screen: // // Example: TMRUN [vol:path\]MACNSFIX.TSK // // Note: [vol:path\] is not required if the task resides either // in SYS:SYSTEM or the TaskMaster NLM load directory. // // Script can be scheduled for automatic execution using Client interface or // using the TaskMaster TMSCHEDULE command at the TMConsole (Shell) Screen: // // Examples: TMSCHEDULE ADD MACNSFIX.TSK 01 02:00 // (Executes the 1st of each month at 2:00am) // // TMSCHEDULE ADD MACNSFIX.TSK YNNNNNN 02:00 // (Executes every Sunday [SMTWTFS] at 2:00am) // // Note: Scheduled tasks must reside either in SYS:SYSTEM or the // TaskMaster NLM load directory for security reasons. // // Compatibility: // ============== // This task has been tested on the following platforms without demonstrating // any compatibility issues or any other reported/confirmed conflicts: // TaskMaster v4.10 (or later) // NetWare v4.1x / v5.x / v6.x // // Warning: // ======== // AS WITH ANY NEW SOFTWARE PROGRAM, BATCH SCRIPT, OR AUTOMATED PROCESSING // PROCEDURE, CAUTION SHOULD BE EXERCISED AND DUE DILIGENCE OBSERVED DURING // INITIAL IMPLEMENTATION. WHERE POSSIBLE, TESTING SHOULD BE PERFORMED ON // NON-PRODUCTION SYSTEMS PRIOR TO FULL IMPLEMENTATION. // //////////////////////////////////////////////////////////////////////////////// // DEBUG: IMPORTANT OPTION FOR TESTING PURPOSES // ========================================================================== // For DEBUG mode (i.e., full processing EXCLUDING renaming of the entries), // remove the comment characters (//) preceding the following DEFINE command: // // DEFINE %0 DEBUG // // Note: Enabling DEBUG mode will find and log all offending entries WITHOUT // attempting to rename them using valid characters. // ========================================================================== // DEBUG: IMPORTANT OPTION FOR TESTING PURPOSES // Check for compatible version of TaskMaster NLM IF "%TM_VERSION%.%TM_SUBVERSION%%TM_REVISION%"<"4.10" // Report the status ECHO. ECHO Error: Incompatible TaskMaster release (requires v4.10 or later)! ECHO. ABORT ENDIF // Create/Overwrite log file (same VOL:\PATH\FILENAME as .TSK with .LOG ext) OPEN WRITE %TASK_PATH%\%TASK_FILE%.LOG TRUNCATE // Check for ERRORLEVEL and process accordingly IF ERRORLEVEL // Report the status ECHO. ECHO Error: Unable to create/truncate log file (%TASK_PATH%\%TASK_FILE%.LOG) ECHO. ABORT ENDIF // Replace [base_dir] with directory tree VOL:PATH to traverse. // CHDIR [base_dir] will set the Current Working Directory (CWD) to // the [base_dir] specified VOL:PATH. CHDIR [base_dir] // Check for ERRORLEVEL and process accordingly IF ERRORLEVEL // Report the status ECHO. ECHO Error: Unable to set Current Working Directory (CWD) to specification ECHO. ABORT ENDIF // Alias some Defined Variables for easier code documentation / use VARALIAS %VAR10% %SUB% VARALIAS %VAR11% %ENTRY% VARALIAS %VAR12% %MAC_NAME% VARALIAS %VAR13% %NEW_NAME% VARALIAS %VAR14% %OLD_NAME% VARALIAS %VAR15% %POS% // Pre-Format Alias Variable %POS% to 3 digit numeric value & set to zero (000) DEFINE %POS% 000 // WHILE / LOOP starts in [base_dir] then traverses directory tree one // subdirectory each LOOP by issuing %DIR_TREE_% using the CWD (%CWD%) // for the first pass and no specification for subsequent passes. // At bottom of directory tree, %DIR_TREE_% will return a null (""). WHILE // Set Alias Variable %ENTRY% to null ("") for next WHILE / LOOP DEFINE %ENTRY% // This nested WHILE / LOOP proceses any subdirectories within // the current %DIR_TREE_% traversed directory tree level (CWD). // It issues a %DIR_SUB_% using the CWD (%CWD%) for the first // pass and no specification for subsequent passes. // At bottom of directory tree, %DIR_SUB_% will return a null (""). WHILE // If %ENTRY% is null (""), it is first WHILE / LOOP so include // Current Working Directory (%CWD% in %DIR_SUB_[%CWD%\*.*]%) to // specify directory to search. Subsequent (next) usage does // not require a spec. // Get first (%CWD%\*.*) / next (no spec) subdirectory in CWD. IF "%ENTRY%"=="" DEFINE %ENTRY% %CWD%\*.* DEFINE %ENTRY% %DIR_SUB_%ENTRY%% ELSE DEFINE %ENTRY% %DIR_SUB_% ENDIF // Check %ENTRY% and break if null IF "%ENTRY%"=="" THEN BREAK // Get Macintosh Name Space name for %ENTRY% DEFINE %MAC_NAME% %FILE_NAME_MAC_%ENTRY%% // Check %MAC_NAME% and continue (resume at WHILE) if null IF "%MAC_NAME%"=="" THEN CONTINUE // Get position of last path separator in %MAC_NAME% FINDCHR %POS% ":" "%MAC_NAME%" LAST // Increment %POS% to point to first character in %MAC_NAME% entry name DEFINE %POS% %POS%+=1 // Parse %MAC_NAME% entry name into %NEW_NAME% then copy to %OLDNAME% PARSE %NEW_NAME% %MAC_NAME% %POS%-256 PACK DEFINE %OLD_NAME% %NEW_NAME% // Check if Macintosh Name Space name has non-standard characters // Find / replace double quote(s) with single quote(s) // Note: Must be first check (script will fail if double qoutes in name) REPLACE %NEW_NAME% ""'" // Check if Mac Name Space name has leading space(s) FINDCHR %POS% " " "%NEW_NAME%" // %POS% == 001 if there is a leading space in %NEW_NAME% WHILE "%POS%"=="001" // Parse %NEW_NAME% into itself excluding leading space PARSE %NEW_NAME% %NEW_NAME% 2-256 PACK // Re-Check parsed %NEW_NAME% for leading space(s) FINDCHR %POS% " " "%NEW_NAME%" LOOP // Find / replace ampersand(s) with dollar sign(s) REPLACE %NEW_NAME% "&$" // Find / replace question mark(s) with exclamation point(s) REPLACE %NEW_NAME% "?!" // Find / replace asterisk(s) with at sign(s) REPLACE %NEW_NAME% "*@" // Check if any invalid characters found / replaced IF NOT "%NEW_NAME%"=="%OLD_NAME%" // Log original Mac NS name and new Mac NS name attempted to rename WRITE %MAC_NAME% WRITE [DIR] --> %NEW_NAME% // Attempt to rename original Mac NS entry to new Mac NS name IF NOT "%0"=="DEBUG" THEN RENDIR %ENTRY% %NEW_NAME% /M // Log result of the rename IF "%0"=="DEBUG" WRITE [DEBUG] ELSEIF ERRORLEVEL WRITE ERROR ELSE WRITE SUCCESS ENDIF WRITE ENDIF LOOP // Set Alias Variable %ENTRY% to null ("") for next WHILE / LOOP DEFINE %ENTRY% // This nested WHILE / LOOP proceses any files within // the current %DIR_TREE_% traversed directory tree level (CWD). // It issues a %DIR_FILE_% using the CWD (%CWD%) for the first // pass and no specification for subsequent passes. // At bottom of directory tree, %DIR_FILE_% will return a null (""). WHILE // If %ENTRY% is null (""), it is first WHILE / LOOP so include // Current Working Directory (%CWD% in %DIR_FILE_[%CWD%\*.*]%) to // specify directory to search. Subsequent (next) usage does // not require a spec. // Get first (%CWD%\*.*) / next (no spec) subdirectory in CWD. IF "%ENTRY%"=="" DEFINE %ENTRY% %CWD%\*.* DEFINE %ENTRY% %DIR_FILE_%ENTRY%% ELSE DEFINE %ENTRY% %DIR_FILE_% ENDIF // Check %ENTRY% and break if null IF "%ENTRY%"=="" THEN BREAK // Get Macintosh Name Space name for %ENTRY% DEFINE %MAC_NAME% %FILE_NAME_MAC_%ENTRY%% // Check %MAC_NAME% and continue (resume at WHILE) if null IF "%MAC_NAME%"=="" THEN CONTINUE // Get position of last path separator in %MAC_NAME% FINDCHR %POS% ":" "%MAC_NAME%" LAST // Increment %POS% to point to first character in %MAC_NAME% entry name DEFINE %POS% %POS%+=1 // Parse %MAC_NAME% entry name into %NEW_NAME% then copy to %OLDNAME% PARSE %NEW_NAME% %MAC_NAME% %POS%-256 PACK DEFINE %OLD_NAME% %NEW_NAME% // Check if Macintosh Name Space name has non-standard characters // Find / replace double quote(s) with single quote(s) // Note: Must be first check (script will fail if double qoutes in name) REPLACE %NEW_NAME% ""'" // Check if Mac Name Space name has leading space(s) FINDCHR %POS% " " "%NEW_NAME%" // %POS% == 001 if there is a leading space in %NEW_NAME% WHILE "%POS%"=="001" // Parse %NEW_NAME% into itself excluding leading space PARSE %NEW_NAME% %NEW_NAME% 2-256 PACK // Re-Check parsed %NEW_NAME% for leading space(s) FINDCHR %POS% " " "%NEW_NAME%" LOOP // Find / replace ampersand(s) with dollar sign(s) REPLACE %NEW_NAME% "&$" // Find / replace question mark(s) with exclamation point(s) REPLACE %NEW_NAME% "?!" // Find / replace asterisk(s) with at sign(s) REPLACE %NEW_NAME% "*@" // Check if any invalid characters found / replaced IF NOT "%NEW_NAME%"=="%OLD_NAME%" // Log original Mac NS name and new Mac NS name attempted to rename WRITE %MAC_NAME% WRITE [File] -> %NEW_NAME% // Attempt to rename original Mac NS entry to new Mac NS name IF NOT "%0"=="DEBUG" THEN RENAME %ENTRY% %NEW_NAME% /M // Log result of the rename IF "%0"=="DEBUG" WRITE [DEBUG] ELSEIF ERRORLEVEL WRITE ERROR ELSE WRITE SUCCESS ENDIF WRITE ENDIF LOOP // If %SUB% is null (""), it is first WHILE / LOOP so include Current // Working Directory (%CWD% in %DIR_TREE_%CWD%%) to specify directory // tree to walk. Subsequent (next) usage does not require a spec. // Get first (%CWD%) / next (no spec) subdirectory in directory tree. IF "%SUB%"=="" DEFINE %SUB% %DIR_TREE_%CWD%% ELSE DEFINE %SUB% %DIR_TREE_% ENDIF // Check %SUB% and break if null else LOOP to WHILE IF "%SUB%"=="" THEN BREAK LOOP // Close log file before exiting (good cleanup of resources) CLOSE