Changes in tools/mkfat.py [87608a5:cc1a727] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • tools/mkfat.py

    r87608a5 rcc1a727  
    168168"""
    169169
    170 LFN_DIR_ENTRY = """little:
    171         uint8_t seq                /* sequence number */
    172         char name1[10]             /* first part of the name */
    173         uint8_t attr               /* attributes */
    174         uint8_t rec_type           /* LFN record type */
    175         uint8_t checksum           /* LFN checksum */
    176         char name2[12]             /* second part of the name */
    177         uint16_t cluster           /* cluster */
    178         char name3[4]              /* third part of the name */
    179 """
    180 
    181 lchars = set(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
    182               'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
    183               'U', 'V', 'W', 'X', 'Y', 'Z',
    184               '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    185               '!', '#', '$', '%', '&', '\'', '(', ')', '-', '@',
    186               '^', '_', '`', '{', '}', '~', '.'])
    187 
    188 def fat_lchars(name):
    189         "Filter FAT legal characters"
    190        
    191         filtered_name = ''
    192         filtered = False
    193        
    194         for char in name.encode('ascii', 'replace').upper():
    195                 if char in lchars:
    196                         filtered_name += char
    197                 else:
    198                         filtered_name += b'_'
    199                         filtered = True
    200        
    201         return (filtered_name, filtered)
    202 
    203 def fat_name83(name, name83_list):
    204         "Create a 8.3 name for the given name"
    205        
    206         ascii_name, lfn = fat_lchars(name)
    207         ascii_parts = ascii_name.split('.')
    208        
    209         short_name = ''
    210         short_ext = ''
    211        
    212         if len(ascii_name) > 11:
    213                 lfn = True
    214        
    215         if len(ascii_parts) > 0:
    216                 short_name = ascii_parts[0]
    217                 if len(short_name) > 8:
    218                         lfn = True
    219        
    220         if len(ascii_parts) > 1:
    221                 short_ext = ascii_parts[-1]
    222                 if len(short_ext) > 3:
    223                         lfn = True
    224        
    225         if len(ascii_parts) > 2:
    226                 lfn = True
    227        
    228         if lfn == False:
    229                 name83_list.append(short_name + '.' + short_ext)
    230                 return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], False)
    231        
    232         # For filenames with multiple extensions, we treat the last one
    233         # as the actual extension. The rest of the filename is stripped
    234         # of dots and concatenated to form the short name
    235         for part in ascii_parts[1:-1]:
    236                 short_name += part
    237        
    238         for number in range(1, 999999):
    239                 number_str = ('~' + str(number)).upper()
    240                
    241                 if len(short_name) + len(number_str) > 8:
    242                         short_name = short_name[0:8 - len(number_str)]
    243                
    244                 short_name += number_str;
    245                
    246                 if not (short_name + '.' + short_ext) in name83_list:
    247                         break
    248        
    249         name83_list.append(short_name + '.' + short_ext)
    250         return (short_name.ljust(8)[0:8], short_ext.ljust(3)[0:3], True)
    251 
    252 def create_lfn_dirent(name, seq, checksum):
    253         "Create LFN directory entry"
    254        
    255         entry = xstruct.create(LFN_DIR_ENTRY)
    256         name_rest = name[26:]
    257        
    258         if len(name_rest) > 0:
    259                 entry.seq = seq
    260         else:
    261                 entry.seq = seq | 0x40
    262        
    263         entry.name1 = name[0:10]
    264         entry.name2 = name[10:22]
    265         entry.name3 = name[22:26]
    266        
    267         entry.attr = 0x0F
    268         entry.rec_type = 0
    269         entry.checksum = checksum
    270         entry.cluster = 0
    271        
    272         return (entry, name_rest)
    273 
    274 def lfn_checksum(name):
    275         "Calculate LFN checksum"
    276        
    277         checksum = 0
    278         for i in range(0, 11):
    279                 checksum = (((checksum & 1) << 7) + (checksum >> 1) + ord(name[i])) & 0xFF
    280        
    281         return checksum
    282 
    283 def create_dirent(name, name83_list, directory, cluster, size):
    284         short_name, short_ext, lfn = fat_name83(name, name83_list)
    285        
     170def mangle_fname(name):
     171        # FIXME: filter illegal characters
     172        parts = name.split('.')
     173       
     174        if len(parts) > 0:
     175                fname = parts[0]
     176        else:
     177                fname = ''
     178       
     179        if len(fname) > 8:
     180                sys.stdout.write("mkfat.py: error: Directory entry " + name +
     181                    " base name is longer than 8 characters\n")
     182                sys.exit(1);
     183       
     184        return (fname + '          ').upper()[0:8]
     185
     186def mangle_ext(name):
     187        # FIXME: filter illegal characters
     188        parts = name.split('.')
     189       
     190        if len(parts) > 1:
     191                ext = parts[1]
     192        else:
     193                ext = ''
     194       
     195        if len(parts) > 2:
     196                sys.stdout.write("mkfat.py: error: Directory entry " + name +
     197                    " has more than one extension\n")
     198                sys.exit(1);
     199       
     200        if len(ext) > 3:
     201                sys.stdout.write("mkfat.py: error: Directory entry " + name +
     202                    " extension is longer than 3 characters\n")
     203                sys.exit(1);
     204       
     205        return (ext + '   ').upper()[0:3]
     206
     207def create_dirent(name, directory, cluster, size):
    286208        dir_entry = xstruct.create(DIR_ENTRY)
    287209       
    288         dir_entry.name = short_name
    289         dir_entry.ext = short_ext
     210        dir_entry.name = mangle_fname(name).encode('ascii')
     211        dir_entry.ext = mangle_ext(name).encode('ascii')
    290212       
    291213        if (directory):
     
    308230                dir_entry.size = size
    309231       
    310         if not lfn:
    311                 return [dir_entry]
    312        
    313         long_name = name.encode('utf_16_le')
    314         entries = [dir_entry]
    315        
    316         seq = 1
    317         checksum = lfn_checksum(dir_entry.name + dir_entry.ext)
    318        
    319         while len(long_name) > 0:
    320                 long_entry, long_name = create_lfn_dirent(long_name, seq, checksum)
    321                 entries.append(long_entry)
    322                 seq += 1
    323        
    324         entries.reverse()
    325         return entries
     232        return dir_entry
    326233
    327234def create_dot_dirent(empty_cluster):
     
    367274       
    368275        directory = []
    369         name83_list = []
    370        
    371         if not head:
     276       
     277        if (not head):
    372278                # Directory cluster preallocation
    373279                empty_cluster = fat.index(0)
    374                 fat[empty_cluster] = 0xFFFF
     280                fat[empty_cluster] = 0xffff
    375281               
    376282                directory.append(create_dot_dirent(empty_cluster))
     
    379285                empty_cluster = 0
    380286       
    381         for item in listdir_items(root):
     287        for item in listdir_items(root):               
    382288                if item.is_file:
    383289                        rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters)
    384                         directory.extend(create_dirent(item.name, name83_list, False, rv[0], rv[1]))
     290                        directory.append(create_dirent(item.name, False, rv[0], rv[1]))
    385291                elif item.is_dir:
    386292                        rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster)
    387                         directory.extend(create_dirent(item.name, name83_list, True, rv[0], rv[1]))
    388        
    389         if head:
     293                        directory.append(create_dirent(item.name, True, rv[0], rv[1]))
     294       
     295        if (head):
    390296                outf.seek(root_start)
    391297                for dir_entry in directory:
     
    444350        extra_bytes = int(sys.argv[1])
    445351       
    446         path = os.path.abspath(sys.argv[2].decode())
     352        path = os.path.abspath(sys.argv[2])
    447353        if (not os.path.isdir(path)):
    448354                print("<PATH> must be a directory")
     
    542448       
    543449        outf.close()
    544 
     450       
    545451if __name__ == '__main__':
    546452        main()
Note: See TracChangeset for help on using the changeset viewer.