Lines Matching +full:file +full:- +full:entry +full:- +full:cache
2 * Copyright 1996-2003,2005,2007-2009 Alain Knaff.
3 * This file is part of mtools.
20 * Miscellaneous VFAT-related functions
27 #include "file.h"
50 tildapos = -1; in autorename()
66 seqnum = seqnum * 10 + (uint8_t)(name[dotpos] - '0'); in autorename()
69 tildapos = -1; /* sequence number interrupted */ in autorename()
71 if(tildapos == -1) { in autorename()
73 if(dotpos > limit - 2) { in autorename()
74 tildapos = limit - 2; in autorename()
86 tildapos = dotpos - 2; in autorename()
92 tildapos--; in autorename()
112 autorename(name->base, '~', ' ', short_illegals, 8, bump); in autorename_short()
117 autorename(name, '-', '\0', long_illegals, 255, bump); in autorename_long()
128 *out = in->lchar | ((in->uchar) << 8); in unicode_read()
130 if (in->uchar) in unicode_read()
133 *out = in->lchar; in unicode_read()
144 v->subentries = 0; in clear_vfat()
145 v->status = 0; in clear_vfat()
146 v->present = 0; in clear_vfat()
154 * The sum is formed by circularly right-shifting the previous sum
160 * with Microsoft Windows-95 and Microsoft Windows NT 3.5.
169 const char *name=dn->base; in sum_shortname()
181 * Return 1 if the VSEs comprise a valid long file name,
188 if (! v->subentries) { in check_vfat()
195 memcpy(dn.base, (char *)dir->name, 8); in check_vfat()
196 memcpy(dn.ext, (char *)dir->ext, 3); in check_vfat()
198 if (v->sum != sum_shortname(&dn)) in check_vfat()
201 if( (v->status & ((1<<v->subentries) - 1)) != (1<<v->subentries) - 1) in check_vfat()
204 /* zero out byte following last entry, for good measure */ in check_vfat()
205 v->name[VSE_NAMELEN * v->subentries] = 0; in check_vfat()
206 v->present = 1; in check_vfat()
210 #pragma GCC diagnostic ignored "-Wsign-conversion"
211 /* We have indeed different types for the entry slot
212 * - the higher levels have a "signed" type, in order to accomodate
213 * reserved values for "root directory" entry, "not found" entries, and
215 * - the lower levels always consider it as an index into the
220 direntry_t entry; in clear_vses() local
221 dirCache_t *cache; in clear_vses() local
224 entry.Dir = Dir; in clear_vses()
225 entry.entry = entrySlot; in clear_vses()
227 /*maximize(last, entry.entry + MAX_VFAT_SUBENTRIES);*/ in clear_vses()
228 cache = allocDirCache(Dir, last); in clear_vses()
229 if(!cache) { in clear_vses()
233 addFreeEntry(cache, entry.entry, last); in clear_vses()
234 for (; entry.entry < (signed int) last; ++entry.entry) { in clear_vses()
236 fprintf(stderr,"Clearing entry %d.\n", entry.entry); in clear_vses()
238 dir_read(&entry, &error); in clear_vses()
241 if(!entry.dir.name[0] || entry.dir.name[0] == DELMARK) in clear_vses()
243 entry.dir.name[0] = DELMARK; in clear_vses()
244 if (entry.dir.attr == 0xf) in clear_vses()
245 entry.dir.attr = '\0'; in clear_vses()
246 low_level_dir_write(&entry); in clear_vses()
258 direntry_t entry; in write_vfat() local
259 dirCache_t *cache; in write_vfat() local
271 entry.Dir = Dir; in write_vfat()
272 vse = (struct vfat_subentry *) &entry.dir; in write_vfat()
274 vse->attribute = 0x0f; in write_vfat()
275 vse->hash1 = vse->sector_l = vse->sector_u = 0; in write_vfat()
276 vse->sum = sum_shortname(shortname); in write_vfat()
279 vse->sum,shortname->base,shortname->ext); in write_vfat()
284 num_vses = (uint8_t)((wlen + VSE_NAMELEN - 1)/VSE_NAMELEN); in write_vfat()
285 for (vse_id = num_vses; vse_id; --vse_id) { in write_vfat()
288 c = wlongname + (vse_id - 1) * VSE_NAMELEN; in write_vfat()
290 c += unicode_write(c, vse->text1, VSE1SIZE, &end); in write_vfat()
291 c += unicode_write(c, vse->text2, VSE2SIZE, &end); in write_vfat()
292 c += unicode_write(c, vse->text3, VSE3SIZE, &end); in write_vfat()
294 vse->id = (vse_id == num_vses) ? (vse_id | VSE_LAST) : vse_id; in write_vfat()
297 longname, vse_id, longname + (vse_id-1) * VSE_NAMELEN, in write_vfat()
298 start + num_vses - vse_id, start + num_vses); in write_vfat()
301 entry.entry = start + num_vses - vse_id; in write_vfat()
302 low_level_dir_write(&entry); in write_vfat()
308 cache = allocDirCache(Dir, start + num_vses + 1); in write_vfat()
309 if(!cache) { in write_vfat()
313 unix_name(cp, shortname->base, shortname->ext, 0, unixyName); in write_vfat()
314 addUsedEntry(cache, start, start + num_vses + 1, wlongname, unixyName, in write_vfat()
315 &mainEntry->dir); in write_vfat()
320 void dir_write(direntry_t *entry) in dir_write() argument
323 dirCache_t *cache; in dir_write() local
325 if(entry->entry == -3) { in dir_write()
330 cache = allocDirCache(entry->Dir, entry->entry + 1); in dir_write()
331 if(!cache) { in dir_write()
335 dce = cache->entries[entry->entry]; in dir_write()
337 if(entry->dir.name[0] == DELMARK) { in dir_write()
338 addFreeEntry(cache, dce->beginSlot, dce->endSlot); in dir_write()
340 dce->dir = entry->dir; in dir_write()
343 low_level_dir_write(entry); in dir_write()
349 * data suitable for a dircache entry
351 static __inline__ void parse_vses(direntry_t *entry, in parse_vses() argument
358 vse = (struct vfat_subentry *) &entry->dir; in parse_vses()
360 id = vse->id & VSE_MASK; in parse_vses()
361 last_flag = (vse->id & VSE_LAST); in parse_vses()
364 id, entry->entry); in parse_vses()
383 if(v->sum != vse->sum) { in parse_vses()
385 v->sum = vse->sum; in parse_vses()
389 if(v->status & (1 << (id-1))) in parse_vses()
391 "parse_vses: duplicate VSE %d\n", vse->id); in parse_vses()
394 v->status |= 1 << (id-1); in parse_vses()
396 v->subentries = id; in parse_vses()
399 if (id > v->subentries) in parse_vses()
401 * the "last" entry (really the first) */ in parse_vses()
404 vse->id); in parse_vses()
407 c = &(v->name[VSE_NAMELEN * (id-1)]); in parse_vses()
408 c += unicode_read(vse->text1, c, VSE1SIZE); in parse_vses()
409 c += unicode_read(vse->text2, c, VSE2SIZE); in parse_vses()
410 c += unicode_read(vse->text3, c, VSE3SIZE); in parse_vses()
413 id,entry->entry,v->subentries,&(v->name[VSE_NAMELEN * (id-1)])); in parse_vses()
420 * Read one complete entry from directory (main name plus any VSEs
425 dirCache_t *cache, in vfat_lookup_loop_common() argument
430 unsigned int initpos = direntry->entry + 1; in vfat_lookup_loop_common()
440 ++direntry->entry; in vfat_lookup_loop_common()
446 addFreeEndEntry(cache, initpos, direntry->entry, in vfat_lookup_loop_common()
448 return addEndEntry(cache, direntry->entry); in vfat_lookup_loop_common()
451 if (endmarkSeen || direntry->dir.name[0] == ENDMARK){ in vfat_lookup_loop_common()
457 return addEndEntry(cache, direntry->entry); in vfat_lookup_loop_common()
459 if(direntry->dir.name[0] != DELMARK && in vfat_lookup_loop_common()
460 direntry->dir.attr == 0x0f) in vfat_lookup_loop_common()
463 /* the main entry */ in vfat_lookup_loop_common()
467 /* If we get here, it's a short name FAT entry, maybe erased. in vfat_lookup_loop_common()
471 /* deleted file */ in vfat_lookup_loop_common()
472 if (direntry->dir.name[0] == DELMARK) { in vfat_lookup_loop_common()
473 return addFreeEntry(cache, initpos, in vfat_lookup_loop_common()
474 direntry->entry + 1); in vfat_lookup_loop_common()
477 check_vfat(&vfat, &direntry->dir); in vfat_lookup_loop_common()
481 /* mark space between last entry and this one as free */ in vfat_lookup_loop_common()
482 addFreeEntry(cache, initpos, in vfat_lookup_loop_common()
483 direntry->entry - vfat.subentries); in vfat_lookup_loop_common()
485 if (direntry->dir.attr & 0x8){ in vfat_lookup_loop_common()
486 /* Read entry as a label */ in vfat_lookup_loop_common()
488 if (direntry->dir.name[0] == '\x05') { in vfat_lookup_loop_common()
490 ptr += dos_to_wchar(cp, direntry->dir.name+1, ptr, 7); in vfat_lookup_loop_common()
492 ptr += dos_to_wchar(cp, direntry->dir.name, ptr, 8); in vfat_lookup_loop_common()
494 ptr += dos_to_wchar(cp, direntry->dir.ext, ptr, 3); in vfat_lookup_loop_common()
498 direntry->dir.name, in vfat_lookup_loop_common()
499 direntry->dir.ext, in vfat_lookup_loop_common()
500 direntry->dir.Case, in vfat_lookup_loop_common()
508 return addUsedEntry(cache, direntry->entry - vfat.subentries, in vfat_lookup_loop_common()
509 direntry->entry + 1, longname, in vfat_lookup_loop_common()
510 newfile, &direntry->dir); in vfat_lookup_loop_common()
515 dirCache_t *cache, in vfat_lookup_loop_for_read() argument
518 int initpos = direntry->entry + 1; in vfat_lookup_loop_for_read()
522 dce = cache->entries[initpos]; in vfat_lookup_loop_for_read()
524 direntry->entry = dce->endSlot - 1; in vfat_lookup_loop_for_read()
528 direntry, cache, 0, io_error); in vfat_lookup_loop_for_read()
552 switch(dce->type) { in checkNameForMatch()
561 fprintf(stderr, "Unexpected entry type %d\n", in checkNameForMatch()
562 dce->type); in checkNameForMatch()
567 direntry->dir = dce->dir; in checkNameForMatch()
569 /* make sure the entry is of an accepted type */ in checkNameForMatch()
570 if((direntry->dir.attr & 0x8) && !(flags & ACCEPT_LABEL)) in checkNameForMatch()
574 /*---------- multiple files ----------*/ in checkNameForMatch()
576 (dce->longName && in checkNameForMatch()
577 match(dce->longName, filename, direntry->name, 0, length)) || in checkNameForMatch()
578 match(dce->shortName, filename, direntry->name, 1, length))) { in checkNameForMatch()
583 /* entry of non-requested type, has to come after name in checkNameForMatch()
588 WCHAR_TO_NATIVE(dce->shortName,tmp,13); in checkNameForMatch()
595 if(!(direntry->dir.attr & (ATTR_LABEL | ATTR_DIR)) && in checkNameForMatch()
599 WCHAR_TO_NATIVE(dce->shortName,tmp,13); in checkNameForMatch()
622 * if applicable, the file is opened and its stream is returned in File
632 dirCache_t *cache; in vfat_lookup() local
635 doscp_t *cp = GET_DOSCONVERT(direntry->Dir); in vfat_lookup()
643 if (direntry->entry == -2) in vfat_lookup()
644 return -1; in vfat_lookup()
646 cache = allocDirCache(direntry->Dir, direntry->entry+1); in vfat_lookup()
647 if(!cache) { in vfat_lookup()
653 dce = vfat_lookup_loop_for_read(cp, direntry, cache, &io_error); in vfat_lookup()
656 return -2; in vfat_lookup()
667 if(dce->longName) in vfat_lookup()
668 wchar_to_native(dce->longName, longname, in vfat_lookup()
674 wchar_to_native(dce->shortName, shortname, in vfat_lookup()
676 direntry->beginSlot = dce->beginSlot; in vfat_lookup()
677 direntry->endSlot = dce->endSlot-1; in vfat_lookup()
678 return 0; /* file found */ in vfat_lookup()
680 direntry->entry = -2; in vfat_lookup()
681 return -1; /* no file found */ in vfat_lookup()
688 dirCache_t *cache) in vfat_lookup_loop_for_insert() argument
693 dce = cache->entries[initpos]; in vfat_lookup_loop_for_insert()
694 if(dce && dce->type != DCET_END) { in vfat_lookup_loop_for_insert()
697 direntry->entry = initpos - 1; in vfat_lookup_loop_for_insert()
699 direntry, cache, 1, &io_error); in vfat_lookup_loop_for_insert()
708 return cache->entries[initpos]; in vfat_lookup_loop_for_insert()
714 if(ssp->got_slots) in accountFreeSlots()
717 if(ssp->free_end != dce->beginSlot) { in accountFreeSlots()
718 ssp->free_start = dce->beginSlot; in accountFreeSlots()
720 ssp->free_end = dce->endSlot; in accountFreeSlots()
722 if(ssp->free_end - ssp->free_start >= ssp->size_needed) { in accountFreeSlots()
723 ssp->got_slots = 1; in accountFreeSlots()
724 ssp->slot = ssp->free_start + ssp->size_needed - 1; in accountFreeSlots()
731 s->shortmatch = s->longmatch = s->slot = -1; in clear_scan()
732 s->free_end = s->got_slots = s->free_start = 0; in clear_scan()
735 s->size_needed = (unsigned) in clear_scan()
736 (1 + (wcslen(longname) + VSE_NAMELEN - 1)/VSE_NAMELEN); in clear_scan()
738 s->size_needed = 1; in clear_scan()
755 direntry_t entry; in lookupForInsert() local
758 dirCache_t *cache; in lookupForInsert() local
759 unsigned int pos; /* position _before_ the next answered entry */ in lookupForInsert()
767 ignore_match = (ignore_entry == -2 ); in lookupForInsert()
769 initializeDirentry(&entry, Dir); in lookupForInsert()
770 ssp->match_free = 0; in lookupForInsert()
775 cache = allocDirCache(Dir, 1); in lookupForInsert()
776 if(!cache) { in lookupForInsert()
782 unix_name(cp, dosname->base, dosname->ext, 0, shortName); in lookupForInsert()
784 pos = cache->nrHashed; in lookupForInsert()
786 (pos && isHashed(cache, wlongname))) { in lookupForInsert()
788 } else if(pos && !ignore_match && isHashed(cache, shortName)) { in lookupForInsert()
790 ssp->shortmatch = -2; in lookupForInsert()
794 } else if(growDirCache(cache, pos) < 0) { in lookupForInsert()
799 dce = vfat_lookup_loop_for_insert(cp, &entry, pos, cache); in lookupForInsert()
800 switch(dce->type) { in lookupForInsert()
805 if(!(dce->dir.attr & 0x8) && in lookupForInsert()
806 (signed int)dce->endSlot-1 == source_entry) in lookupForInsert()
810 * ignored entry */ in lookupForInsert()
811 if( (dce->dir.attr & 0x8) || in lookupForInsert()
812 ((signed int)dce->endSlot-1==ignore_entry)) in lookupForInsert()
816 if((dce->longName && in lookupForInsert()
817 !wcscasecmp(dce->longName, wlongname)) || in lookupForInsert()
818 (dce->shortName && in lookupForInsert()
819 !wcscasecmp(dce->shortName, wlongname))) { in lookupForInsert()
820 ssp->longmatch = dce->endSlot - 1; in lookupForInsert()
823 direntry->beginSlot = dce->beginSlot; in lookupForInsert()
824 direntry->endSlot = dce->endSlot - 1; in lookupForInsert()
831 !wcscasecmp(shortName, dce->shortName)) in lookupForInsert()
832 ssp->shortmatch = dce->endSlot - 1; in lookupForInsert()
837 pos = dce->endSlot; in lookupForInsert()
838 } while(dce->type != DCET_END); in lookupForInsert()
839 if (ssp->shortmatch > -1) in lookupForInsert()
841 ssp->max_entry = dce->beginSlot; in lookupForInsert()
842 if (ssp->got_slots) in lookupForInsert()
850 return -1; in lookupForInsert()