diff --git a/xtrn/dd_upload_processor/ddup.cfg b/xtrn/dd_upload_processor/ddup.cfg
index f027306af23dfa843bdfacd4958eb260b11b4a19..fc614029c51f8040fae9802ddccd2669164cfc59 100644
--- a/xtrn/dd_upload_processor/ddup.cfg
+++ b/xtrn/dd_upload_processor/ddup.cfg
@@ -11,7 +11,11 @@
 ; into a directory and scanned.
 ;
 ; This scan command is for AVG 9; you may need to change the path for your computer.
-scanCmd="C:\Program Files\AVG\AVG9\avgscanx.exe" /SCAN=%FILESPEC%
+;scanCmd="C:\Program Files\AVG\AVG9\avgscanx.exe" /SCAN=%FILESPEC%
+
+; For Linux, if using clamav, you will need to pass the --fdpass parameter in order to
+; pass the file permission descriptor to clamav
+;scanCmd=/usr/bin/clamdscan --fdpass %FILESPEC%
 
 ; The following option sets whether or not to pause for the user to
 ; enter a key after a file is scanned.  Valid values are yes and
@@ -21,4 +25,4 @@ pauseAtEnd=no
 ; If the following setting is set to yes, then all uploads by
 ; sysops will be automatically approved.  Valid values are yes
 ; and no.
-skipScanIfSysop=no
\ No newline at end of file
+skipScanIfSysop=no
diff --git a/xtrn/dd_upload_processor/ddup.js b/xtrn/dd_upload_processor/ddup.js
index e4c2231a7df5bdc36dc523c182a0c7c63667253b..72b0c16a011b59c7c0b8ae2cd887d02d658ad799 100644
--- a/xtrn/dd_upload_processor/ddup.js
+++ b/xtrn/dd_upload_processor/ddup.js
@@ -16,6 +16,11 @@
  *                                            Initial public release
  * 2022-06-08 Eric Oulashin     Version 1.01
  *                                            Made fixes to get the scanner functionality working properly in Linux
+ * 2022-06-11 Eric Oulashin     Version 1.02
+ *                                            Improved file/dir permissions more: Set file permissions too after extracting
+ *                                            an archive so that they're all readable.
+ * 2022-06-11 Eric Oulashin     Version 1.03
+ *                                            Removed the chmod stuff, as it is actually not needed.
  */
 
 /* Command-line arguments:
@@ -24,10 +29,10 @@
 
 load("sbbsdefs.js");
 
-// Require version 3.17 or newer of Synchronet (for file_chmod())
-if (system.version_num < 31700)
+// Require version 3.14 or newer of Synchronet (for file_chmod())
+if (system.version_num < 31400)
 {
-	console.print("\1nDigital Distortion Upload Processor requires Synchronet 3.17 or newer.\r\n");
+	console.print("\1nDigital Distortion Upload Processor requires Synchronet 3.14 or newer.\r\n");
 	exit(1);
 }
 
@@ -43,8 +48,8 @@ gStartupPath = backslash(gStartupPath.replace(/[\/\\][^\/\\]*$/,''));
 load(gStartupPath + "ddup_cleanup.js");
 
 // Version information
-var gDDUPVersion = "1.01";
-var gDDUPVerDate = "2022-06-08";
+var gDDUPVersion = "1.03";
+var gDDUPVerDate = "2022-06-11";
 
 // Store whether or not this is running in Windows
 var gRunningInWindows = /^WIN/.test(system.platform.toUpperCase());
@@ -65,13 +70,13 @@ if (argv.length > 0)
 			gFileToScan = fixedArgs[0];
 		else
 		{
-			console.print("nyhError: ncBlank filename argument given.\r\np");
+			console.print("\1n\1y\1hError: \1n\1cBlank filename argument given.\r\n\1p");
 			exit(-2);
 		}
 	}
 	else
 	{
-		console.print("nyhError: ncUnknown command-line argument specified.\r\np");
+		console.print("\1n\1y\1hError: \1n\1cUnknown command-line argument specified.\r\n\1p");
 		exit(-1);
 	}
 }
@@ -99,7 +104,7 @@ if (gFileToScan.length > 0)
 // if not.
 if (gFileToScan.length == 0)
 {
-   console.print("nyhError: ncNo filename specified to process.\r\np");
+   console.print("\1n\1y\1hError: \1n\1cNo filename specified to process.\r\n\1p");
    exit(1);
 }
 
@@ -116,26 +121,26 @@ var configFileRead = ReadConfigFile(gStartupPath);
 // If the configuration files weren't read, then output an error and exit.
 if (!configFileRead)
 {
-	console.print("nyhError: ncUpload processor is unable to read its\r\n");
-	console.print("configuration files.\r\np");
+	console.print("\1n\1y\1hError: \1n\1cUpload processor is unable to read its\r\n");
+	console.print("configuration files.\r\n\1p");
 	exit(2);
 }
 // Exit if there is no scan command.
 if (gGenCfg.scanCmd.length == 0)
 {
-	console.print("nyhWarning: ncNo scan command configured for the upload processor.\r\n");
+	console.print("\1n\1y\1hWarning: \1n\1cNo scan command configured for the upload processor.\r\n");
 	exit(0);
 }
 
 // Global variables
 // Strings for the OK and failure symbols
-var gOKStr = "nkh[ng�kh]n";
+var gOKStr = "\1n\1k\1h[\1n\1g�\1k\1h]\1n";
 var gOKStrWithNewline = gOKStr + "\r\n";
-var gFailStr = "nkh[rXk]n";
+var gFailStr = "\1n\1k\1h[\1rX\1k]\1n";
 var gFailStrWithNewline = gFailStr + "\r\n";
 // Stuff for the printf formatting string for the status messages
 var gStatusTextLen = 79 - console.strlen(gOKStr); // gOKStr and gFailStr should have the same length
-var gStatusPrintfStr = "n%s%-" + gStatusTextLen + "sn"; // For a color and the status text
+var gStatusPrintfStr = "\1n%s%-" + gStatusTextLen + "s\1n"; // For a color and the status text
 
 // Now, scan the file and return the appropriate return code.
 exit(main());
@@ -149,12 +154,12 @@ exit(main());
 function main()
 {
    // Output the program name & version information
-   console.print("n\r\nchDncigital hDncistortion hUncpload hPncrocessor whvng" +
+   console.print("\1n\r\n\1c\1hD\1n\1cigital \1hD\1n\1cistortion \1hU\1n\1cpload \1hP\1n\1crocessor \1w\1hv\1n\1g" +
                  gDDUPVersion);
    // Originally I had this script output the version date, but now I'm not sure
    // if I want to do that..
-   //console.print(" wh(b" + gDDUPVerDate + "w)");
-   console.print("n");
+   //console.print(" \1w\1h(\1b" + gDDUPVerDate + "\1w)");
+   console.print("\1n");
    console.crlf();
 
    // Process the file
@@ -162,15 +167,15 @@ function main()
    // Depending on the exit code, display a success or failure message.
    console.crlf();
    if (exitCode == 0)
-      console.print(gOKStr + " nbhScan successful - The file passed.\r\n");
+      console.print(gOKStr + " \1n\1b\1hScan successful - The file passed.\r\n");
    else
-      console.print(gFailStr + " nyhScan failed!\r\n");
+      console.print(gFailStr + " \1n\1y\1hScan failed!\r\n");
 
    // If the option to pause at the end is enabled, then prompt the user for
    // a keypress.
    if (gGenCfg.pauseAtEnd)
    {
-      console.print("nwhPress any key to continue:n");
+      console.print("\1n\1w\1hPress any key to continue:\1n");
       console.getkey(K_NOECHO);
    }
 
@@ -240,14 +245,14 @@ function processFile(pFilename)
 	// Display the program header stuff - The name of the file being scanned
 	// and the status header line
 	var justFilename = getFilenameFromPath(pFilename);
-	console.print("nwhScanning b" + justFilename.substr(0, 70));
-	console.print("n\r\nb7                             File Scan Status                                  n\r\n");
+	console.print("\1n\1w\1hScanning \1b" + justFilename.substr(0, 70));
+	console.print("\1n\r\n\1b\1" + "7                             File Scan Status                                  \1n\r\n");
 
 	// If the skipScanIfSysop option is enabled and the user is a sysop,
 	// then assume the file is good.
 	if (gGenCfg.skipScanIfSysop && user.compare_ars("SYSOP"))
 	{
-		printf(gStatusPrintfStr, "gh", "Auto-approving the file (you're a sysop)");
+		printf(gStatusPrintfStr, "\1g\1h", "Auto-approving the file (you're a sysop)");
 		console.print(gOKStrWithNewline);
 		return 0;
 	}
@@ -281,11 +286,9 @@ function processFile(pFilename)
 				deltree(baseWorkDir + "/");
 				if (!mkdir(baseWorkDir))
 				{
-					console.print("nyhWarning: nwh Unable to create the work dir.n\r\n");
+					console.print("\1n\1y\1hWarning: \1n\1w\1h Unable to create the work dir.\1n\r\n");
 					retval = -1;
 				}
-				file_chmod(baseWorkDir, 0x1fd); // Octal 775, rwxrwxr-x
-				//chmodDirsRecursive(baseWorkDir, 0x1fd); // Octal 775, rwxrwxr-x
 				
 				// If all is okay, then create the directory in the temporary work dir.
 				var workDir = baseWorkDir + "/" + justFilename + "_temp";
@@ -294,7 +297,7 @@ function processFile(pFilename)
 					deltree(workDir + "/");
 					if (!mkdir(workDir))
 					{
-						console.print("nyhWarning: nwh Unable to create a dir in the temporary work dir.n\r\n");
+						console.print("\1n\1y\1hWarning: \1n\1w\1h Unable to create a dir in the temporary work dir.\1n\r\n");
 						retval = -1;
 					}
 				}
@@ -303,15 +306,12 @@ function processFile(pFilename)
 				if (retval == 0)
 				{
 					// Extract the file to the work directory
-					printf(gStatusPrintfStr, "mh", "Extracting the file...");
+					printf(gStatusPrintfStr, "\1m\1h", "Extracting the file...");
 					var errorStr = extractFileToDir(pFilename, workDir);
 					if (errorStr.length == 0)
 					{
-						// In case we're running in Linux, chmod all directories in the work dir recursively so the scanner can access their files
-						chmodDirsRecursive(workDir, 0x1fd); // Octal 775, rwxrwxr-x
-						console.print(gOKStrWithNewline);
 						// Scan the files in the work directory.
-						printf(gStatusPrintfStr, "r", "Scanning files inside the archive for viruses...");
+						printf(gStatusPrintfStr, "\1r", "Scanning files inside the archive for viruses...");
 						var retObj = scanFilesInDir(workDir);
 						retval = retObj.returnCode;
 						if (retObj.returnCode == 0)
@@ -319,7 +319,7 @@ function processFile(pFilename)
 						else
 						{
 							console.print(gFailStrWithNewline);
-							console.print("nyhVirus scan failed.(1)  Scan output:n\r\n");
+							console.print("\1n\1y\1hVirus scan failed.(1)  Scan output:\1n\r\n");
 							for (var index = 0; index < retObj.cmdOutput.length; ++index)
 							{
 								console.print(retObj.cmdOutput[index]);
@@ -331,7 +331,7 @@ function processFile(pFilename)
 					{
 						console.print(gFailStrWithNewline);
 						// Scan the files in the work directory.
-						console.print("nyhWarning: nwh Unable to extract to work dir.n\r\n");
+						console.print("\1n\1y\1hWarning: \1n\1w\1h Unable to extract to work dir.\1n\r\n");
 						retval = -2;
 					}
 				}
@@ -341,7 +341,7 @@ function processFile(pFilename)
 			else
 			{
 				// The file has no extract command, so just scan it.
-				printf(gStatusPrintfStr, "bh", "Scanning...");
+				printf(gStatusPrintfStr, "\1b\1h", "Scanning...");
 				var scanCmd = gGenCfg.scanCmd.replace("%FILESPEC%", "\"" + fixPathSlashes(pFilename) + "\"");
 				// Run the scan command and capture its output, in case the scan fails.
 				var retObj = runExternalCmdWithOutput(scanCmd);
@@ -351,7 +351,7 @@ function processFile(pFilename)
 				else
 				{
 					console.print(gFailStrWithNewline);
-					console.print("nyhVirus scan failed.(2)  Scan output:n\r\n");
+					console.print("\1n\1y\1hVirus scan failed.(2)  Scan output:\1n\r\n");
 					for (var index = 0; index < retObj.cmdOutput.length; ++index)
 					{
 						console.print(retObj.cmdOutput[index]);
@@ -366,7 +366,7 @@ function processFile(pFilename)
 	else
 	{
 		// There's nothing configured for the file's extension, so just scan it.
-		printf(gStatusPrintfStr, "r", "Scanning...");
+		printf(gStatusPrintfStr, "\1r", "Scanning...");
 		var scanCmd = gGenCfg.scanCmd.replace("%FILESPEC%", "\"" + fixPathSlashes(pFilename) + "\"");
 		var retObj = runExternalCmdWithOutput(scanCmd);
 		retval = retObj.returnCode;
@@ -375,7 +375,7 @@ function processFile(pFilename)
 		else
 		{
 			console.print(gFailStrWithNewline);
-			console.print("nyhVirus scan failed.(3)  Scan output:n\r\n");
+			console.print("\1n\1y\1hVirus scan failed.(3)  Scan output:\1n\r\n");
 			for (var index = 0; index < retObj.cmdOutput.length; ++index)
 			{
 				console.print(retObj.cmdOutput[index]);
@@ -996,7 +996,6 @@ function runExternalCmdWithOutput(pCommand)
 			scriptFile.writeln(pCommand);
 			scriptFile.close();
 			wroteScriptFile = true;
-			file_chmod(scriptFilename, 775); // rwxrwxr-x
 			retObj = execCmdWithOutput("bash " + scriptFilename);
 		}
 	}
@@ -1018,22 +1017,3 @@ function runExternalCmdWithOutput(pCommand)
 
 	return retObj;
 }
-
-// Changes the mode value of a directory and all of its subdirectories recursively
-//
-// Parameters:
-//  pBaseDir: The directory to chmod recursively (along with all of its subdirectories)
-//  pMode: The mode value (number) to apply
-function chmodDirsRecursive(pBaseDir, pMode)
-{
-	if (typeof(pBaseDir) !== "string" || !file_isdir(pBaseDir) || typeof(pMode) !== "number")
-		return;
-
-	file_chmod(pBaseDir, pMode);
-	var fileEntries = directory(backslash(pBaseDir) + "*");
-	for (var i = 0; i < fileEntries.length; ++i)
-	{
-		if (file_isdir(fileEntries[i]))
-			chmodDirsRecursive(fileEntries[i], pMode);
-	}
-}
\ No newline at end of file
diff --git a/xtrn/dd_upload_processor/readme.txt b/xtrn/dd_upload_processor/readme.txt
index cc9570a104392907ad7130dd592f63e3a361a941..f5ae1d15d107a91f8a500beb9f8976d87dcaefd9 100644
--- a/xtrn/dd_upload_processor/readme.txt
+++ b/xtrn/dd_upload_processor/readme.txt
@@ -1,6 +1,6 @@
                    Digital Distortion Upload Processor
-                              Version 1.01
-                        Release date: 2022-06-08
+                              Version 1.03
+                        Release date: 2022-06-11
 
                                   by
 
diff --git a/xtrn/dd_upload_processor/version_history.txt b/xtrn/dd_upload_processor/version_history.txt
index 75b89dbd7c65bbb4a86a0361c3199b317cd18560..25e7d79a1cba0d13c1af80bc2d01cd32c2cd3df3 100644
--- a/xtrn/dd_upload_processor/version_history.txt
+++ b/xtrn/dd_upload_processor/version_history.txt
@@ -2,5 +2,10 @@ Revision History for Digital Distortion Upload Processor
 ========================================================
 Version  Date         Description
 -------  ----         -----------
+1.03     2022-06-11   Removed the chmod updates because they're actually not
+                      needed.  Some antivirus scanners (such as ClamAV) need
+                      a command line parameter to pass the file permissions
+                      descriptor to the scanner.
+1.02     2022-06-11   More chmod updates (similar to 1.01)
 1.01     2022-06-08   Updated so that the scanning works properly in Linux
-1.00     2009-12-29   First general public release
\ No newline at end of file
+1.00     2009-12-29   First general public release