Copying files from EXT3 to FAT

FatVsXFSThere are times which that is convenient to use USB disks formatted with the old FAT file system, i.e. in office environment with mixed operating system.

In my situation we have a linux server (using ext3 file system), with several SMB shared folder used by all the MAC/Linux/Windows workstation:  a very cheap backup system consist in a USB disk connected directly to the server, and a daily backup process that copy all the files from shared folders to this disk. In emergency this disk become the only way to get all files.

From here the most convenient way to use commonly a USB disk is to format it using the old FAT file system !

Yes, sure, we could use another file system, but only using FAT is possible to share a USB disk without the need to install other software (i.e. Mac cannot use natively a EXT3 file system: we would have to install additional software).

Here the big problem: the FAT and EXT3 naming convention are very different !

In this post I present a very raw php script that permit to create the described backup process, modifying file and folder name to be compatible with FAT file system, and also re-create in the USB disk a hierarchy compatible with that used in the shared folders.

I’m not a php code guru, and I’m sure then there will be several inaccuracies, but I think that this my ugly script is a good start point to help you to solve similar problems.

<?php
$sourcedir="<path to shared folder>";
$destdir="<path to USB disk>";
$errlog = "<path to log files>";
$folderlist[] = array();
function makeAll($dir, $recursive = true) {
global $destdir;
if( is_null($dir) || $dir === "" ){
return FALSE;
}
if( is_dir($dir) || $dir === "/" ){
return TRUE;
}
if( makeAll(dirname($dir), $recursive) ){
if (file_exists($dir))
{
return true;
}else
{
return mkdir($dir, 0777);
}
}
return FALSE;
}

function sanitizepath($stringtosanitize) {
$stringtosanitized = iconv("UTF-8", "UTF-8//TRANSLIT",$stringtosanitize);
$stringtosanitized = iconv("UTF-8", "ISO-8859-1//TRANSLIT",$stringtosanitize);
$stringtosanitized= strtolower(trim($stringtosanitize));
$stringtosanitized=str_replace(" ","_",$stringtosanitized);
$stringtosanitized=str_replace("$","_S_",$stringtosanitized);
$stringtosanitized=str_replace("&","_et_",$stringtosanitized);
$stringtosanitized=str_replace("..","-",$stringtosanitized);
$stringtosanitized=str_replace("*","0",$stringtosanitized);
$stringtosanitized=str_replace("?","-",$stringtosanitized);
$stringtosanitized=str_replace(":","-",$stringtosanitized);
$stringtosanitized=str_replace("~","-",$stringtosanitized);
$stringtosanitized=str_replace("[","-",$stringtosanitized);
$stringtosanitized=str_replace("]","-",$stringtosanitized);
$stringtosanitized=str_replace("'","_",$stringtosanitized);
$stringtosanitized=str_replace("<","_",$stringtosanitized);
$stringtosanitized=str_replace(">","_",$stringtosanitized);
$stringtosanitized=str_replace(":","-",$stringtosanitized);
$stringtosanitized=str_replace(";","-",$stringtosanitized);
$stringtosanitized=str_replace("(","-",$stringtosanitized);
$stringtosanitized=str_replace(")","-",$stringtosanitized);
$stringtosanitized=str_replace(",","-",$stringtosanitized);

return $stringtosanitized;
}

if (exec('find '.$sourcedir.' -type f -print', $outputarray)) {
foreach ($outputarray as $fullfilename) {
if (is_link ($fullfilename))
continue;

$dirname = dirname($fullfilename);
$filename = basename($fullfilename);
if ($filename==".")
continue;

if ($filename=="..")
continue;

if (substr($filename,0,1)=='.')
continue;

$newdirname = sanitizepath($dirname);
$newdirname = substr($newdirname, strlen($sourcedir));
$newfilename =sanitizepath($filename);
makeAll($destdir.$newdirname);
$fullfilename2=str_replace("$","\\$",$fullfilename);
$newfullfilename=$destdir.$newdirname."/".$newfilename;
shell_exec("cp -ufv "".$fullfilename2."" ".$newfullfilename." 2>>".$errlog);

#Array to check duplicate file
$folderlist[] = $newfullfilename;
$currfolder[0] =$newfullfilename;
$filtered= array_intersect ($folderlist, $currfolder);

if (count($filtered)>1)
{
shell_exec("echo ".$fullfilename." - Duplicate File >>".$errlog."\n");
}
}
}
?>