Author: Tomáš Virgl <tomas@virgl.net>
Subject: Adding support for datetime information in generated FAT.

--- mkfat.orig.py	2012-03-24 10:44:37.000000000 +0100
+++ mkfat.py	2012-03-25 13:45:40.685115882 +0200
@@ -37,6 +37,8 @@
 import xstruct
 import array
 from imgutil import *
+import stat
+from datetime import datetime
 
 def subtree_size(root, cluster_size, dirent_size):
 	"Recursive directory walk and calculate size"
@@ -204,7 +206,22 @@
 	
 	return (ext + '   ').upper()[0:3]
 
-def create_dirent(name, directory, cluster, size):
+def timestampToFATdatetime(timestamp,is_ctime=False):
+	"""Converts UNIX timestamp to FAT time data"""
+	def bin_process(data, length):
+		if data.bit_length() < length:
+			return ('0'*(length-data.bit_length()))+bin(data)[2:]
+		else:		
+			return bin(data)[2:]
+	time = datetime.fromtimestamp(timestamp)
+	if is_ctime==False:
+		return (bin_process(time.second//2,5) + bin_process(time.minute,6) +bin_process(time.hour,5), bin_process(time.day,5) + bin_process(time.month,4) +bin_process(time.year-1980,7))
+	else:
+		return (bin_process(time.second//2,5) + bin_process(time.minute,6) +bin_process(time.hour,5), bin_process(time.day,5) + bin_process(time.month,4) +bin_process(time.year-1980,7), bin_process(time.microsecond//100000,4) )
+
+def create_dirent(name, directory, cluster, size, atime=0,ctime=0,mtime=0):
+	#atime, ctime, mtime are int timestamps
+
 	dir_entry = xstruct.create(DIR_ENTRY)
 	
 	dir_entry.name = mangle_fname(name).encode('ascii')
@@ -216,12 +233,28 @@
 		dir_entry.attr = 0x20
 	
 	dir_entry.lcase = 0x18
-	dir_entry.ctime_fine = 0 # FIXME
-	dir_entry.ctime = 0 # FIXME
-	dir_entry.cdate = 0 # FIXME
-	dir_entry.adate = 0 # FIXME
-	dir_entry.mtime = 0 # FIXME
-	dir_entry.mdate = 0 # FIXME
+	if ctime == 0:
+		dir_entry.ctime_fine = 0
+		dir_entry.ctime = 0
+		dir_entry.cdate = 0
+	else:
+		tmpdat = timestampToFATdatetime(ctime,True)
+		dir_entry.ctime_fine = int(tmpdat[2],2)
+		dir_entry.ctime = int(tmpdat[0],2)
+		dir_entry.cdate = int(tmpdat[1],2)
+	if atime == 0:		
+		dir_entry.adate = 0
+	else:
+		tmpdat = timestampToFATdatetime(atime,False)
+		dir_entry.adate = int(tmpdat[1],2)
+	if mtime == 0:
+		dir_entry.mtime = 0
+		dir_entry.mdate = 0
+	else:
+		tmpdat = timestampToFATdatetime(mtime,False)
+		dir_entry.mtime = int(tmpdat[0],2)
+		dir_entry.mdate = int(tmpdat[1],2)
+
 	dir_entry.cluster = cluster
 	
 	if (directory):
@@ -284,13 +317,14 @@
 	else:
 		empty_cluster = 0
 	
-	for item in listdir_items(root):		
+	for item in listdir_items(root):
+		tmp_path = item.path		
 		if item.is_file:
 			rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters)
-			directory.append(create_dirent(item.name, False, rv[0], rv[1]))
+			directory.append(create_dirent(item.name, False, rv[0], rv[1],os.stat(tmp_path)[stat.ST_ATIME],os.stat(tmp_path)[stat.ST_CTIME],os.stat(tmp_path)[stat.ST_MTIME]))
 		elif item.is_dir:
 			rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
-			directory.append(create_dirent(item.name, True, rv[0], rv[1]))
+			directory.append(create_dirent(item.name, True, rv[0], rv[1],os.stat(tmp_path)[stat.ST_ATIME],os.stat(tmp_path)[stat.ST_CTIME],os.stat(tmp_path)[stat.ST_MTIME]))
 	
 	if (head):
 		outf.seek(root_start)
