• Patch: Elm ME+ 2.5 PLalpha63 -> Elm ME+ 2.5 PLalpha64 [2/4] (5/5)

    From Kari Hurtta@21:1/5 to All on Tue Jul 2 20:52:17 2024
    [continued from previous message]

    + sys_dir,strerror(err), err));
    +
    + /* No last_read_cache, if directory
    + is not writable and executable (searchable)
    + */
    + goto fail;
    + case syscall_success /* 0 */:
    + DPRINT(Debug,10,(&Debug,
    + "last_read_enabled: %s is accessible\n",
    + sys_dir));
    + break;
    + }
    + }
    +
    + last_read = give_last_read(sys_dir,last_read_loc,res_dir,
    + may_create);
    +
    + if (last_read) {
    + if (LAST_READ_CACHE_magic != last_read->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"last_read_enabled",
    + "Bad magic type (last_read_cache)",0);
    +
    + switch (may_create) {
    + case last_read_def_existing:
    +
    + if (last_read->entries) {
    + const char * name1
    + = pathname_to_entryname(last_read,
    + cur_folder_sys,
    + curstat);
    +
    + if (name1) { /* NULL if / without absolute path */
    +
    + union sort_key key;
    + union sort_item res;
    + union sort_item_default def;
    + size_t idx = 0;
    +
    + key.str = name1;
    + def.last_read_entry = NULL;
    + res.dummy = NULL;
    +
    + if (search_sort_list_item(last_read->entries,
    + sort_list_search_normal,
    + key,def,&res,&idx,
    + NULL)) {
    +
    + if (res.last_read_entry) {
    + struct last_read_entry * entry = res.last_read_entry;
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: %s: %s found from %s idx %zu\n",
    + cur_folder_sys,name1,
    + last_read->cache_file_name ?
    + last_read->cache_file_name : "(no name)",
    + idx));
    +
    + if (LAST_READ_ENTRY_magic != entry->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"last_read_enabled",
    + "Bad magic type (last_read_entry)",0);
    +
    + ret = last_read;
    + last_read = NULL;
    +
    + /* Decrements refcount */
    + free_last_read_entry(& res.last_read_entry);
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: %s: %s found from %s idx %zu - search_sort_list_item did not set last_read_entry\n",
    + cur_folder_sys,name1,
    + last_read->cache_file_name ?
    + last_read->cache_file_name : "(no name)",
    + idx));
    + }
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: %s: %s not found from %s\n",
    + cur_folder_sys,name1,
    + last_read->cache_file_name ?
    + last_read->cache_file_name : "(no name)"));
    + }
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: %s: not valid\n",
    + cur_folder_sys));
    + }
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: %s: no entries on %s\n",
    + cur_folder_sys,
    + last_read->cache_file_name ?
    + last_read->cache_file_name : "(no name)"));
    +
    + }
    +
    + break;
    +
    + case last_read_def_create:
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: using last read cache %s",
    + last_read->cache_file_name ?
    + last_read->cache_file_name : "(no name)"));
    + if (last_read->sys_dir) {
    + DPRINT(Debug,13,(&Debug," for %s",
    + last_read->sys_dir));
    + }
    +
    + DPRINT(Debug,13,(&Debug,"\n"));
    + ret = last_read;
    + last_read = NULL;
    + break;
    + }
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled: last read cache not available, sys_dir=%s\n",
    + sys_dir));
    + }
    +
    + fail:
    + if (last_read)
    + free_last_read_cache(& last_read);
    +
    + if (sys_dir) {
    + if (free_sys_dir)
    + free(sys_dir);
    + sys_dir = NULL;
    + }
    +
    +
    + if (ret) {
    + if (LAST_READ_CACHE_magic != ret->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"last_read_enabled",
    + "Bad magic type (last_read_cache)",0);
    +
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled=%p",ret));
    + if (ret->sys_dir) {
    + DPRINT(Debug,13,(&Debug," sys_dir=%s",ret->sys_dir));
    + }
    + if (ret->cache_file_name) {
    + DPRINT(Debug,13,(&Debug," cache_file_name=%s",ret->cache_file_name));
    + }
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "last_read_enabled=NULL"));
    + }
    + DPRINT(Debug,13,(&Debug,"; cur_folder_sys=%s\n",cur_folder_sys));
    +
    + return ret;
    + }
    +
    + /* Writes cache */
    +
    + void mark_last_read(cache,
    + cur_folder_sys,
    + curstat)
    + struct last_read_cache * cache;
    + char * cur_folder_sys;
    + struct stat * curstat;
    + {
    + struct dt_flags_info * locking =
    + cache_guess_locking(cache);
    + struct last_read_open * H = NULL;
    + const char * name1 = NULL;
    +
    + enum last_read_mode read_mode = last_read_read_update;
    +
    + if (LAST_READ_CACHE_magic != cache->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mark_last_read",
    + "Bad magic type (last_read_cache)",0);
    +
    + if (cache->cache_file_name && ! cache->read) {
    + enum syscall_status r_access =
    + access(cache->cache_file_name, ACCESS_EXISTS);
    +
    + switch ( r_access) {
    + int err UNUSED_VAROK;
    + case syscall_success:
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: cache file %s exists\n",
    + cur_folder_sys,cache->cache_file_name));
    + break;
    + case syscall_error:
    + err = errno;
    +
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: cache file %s gives: %s\n",
    + cur_folder_sys,cache->cache_file_name,
    + strerror(err)));
    +
    + if (ENOENT == err) {
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: Need create %s\n",
    + cache->cache_file_name));
    + read_mode = last_read_create;
    + }
    + }
    + }
    +
    + reload_last_read_cache(cache,&H,NULL,locking,read_mode,
    + NULL /* errno_res */);
    +
    + name1 = pathname_to_entryname(cache,
    + cur_folder_sys,
    + curstat);
    +
    + if (name1) {
    +
    + union sort_key key;
    + union sort_item res;
    + union sort_item_default def;
    + size_t idx = 0;
    +
    + static struct last_read_entry_def def1 = {
    + LAST_READ_ENTRY_DEF_magic,
    + 0 /* entry_flags */
    + };
    +
    + key.str = name1;
    + def.last_read_entry = &def1;
    + res.dummy = NULL;
    +
    + if (search_sort_list_item(cache->entries,
    + sort_list_search_create,
    + key,def,&res,&idx,
    + NULL)) {
    +
    + if (res.last_read_entry) {
    + struct last_read_entry * entry = res.last_read_entry;
    +
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: %s found (or created) from %s idx %zu\n",
    + cur_folder_sys,name1,
    + cache->cache_file_name ?
    + cache->cache_file_name : "(no name)",
    + idx));
    +
    + if (LAST_READ_ENTRY_magic != entry->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "mark_last_read",
    + "Bad magic type (last_read_entry)",0);
    +
    + cache->modified = 1; /* mark need write */
    + entry->entry_flags = LAST_READ_modified;
    +
    + entry->last_read = 0;
    + entry->st_ino = 0;
    +
    + if (FILE_CHANGES_magic != cache->cache_file.magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "mark_last_read",
    + "Bad magic type (file_changes)",0);
    +
    + if (curstat && cache->cache_file.valid &&
    + cache->cache_file.dev == curstat->st_dev) {
    +
    + entry->st_ino = curstat->st_ino;
    + setit(entry->entry_flags, LAST_READ_have_st_ino);
    + }
    +
    + /* XXX is this correct? */
    + if ((time_t)-1 != time(& (entry->last_read))) {
    + setit(entry->entry_flags, LAST_READ_valid);
    + }
    +
    + /* Decrements refcount */
    + free_last_read_entry(& res.last_read_entry);
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: %s found (or created) from %s idx %zu - search_sort_list_item did not set last_read_entry\n",
    + cur_folder_sys,name1,
    + cache->cache_file_name ?
    + cache->cache_file_name : "(no name)",
    + idx));
    + }
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: %s not found (or created) from %s\n",
    + cur_folder_sys,name1,
    + cache->cache_file_name ?
    + cache->cache_file_name : "(no name)"));
    + }
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: not valid\n",
    + cur_folder_sys));
    + }
    +
    + if (H) {
    +
    + if (LAST_READ_OPEN_magic != H->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "mark_last_read",
    + "Bad magic number (last_read_open)",0);
    +
    + if (last_read_def_cache == cache) {
    + last_read_def_rewrite = ison(H->lread_open_flags,
    + LREAD_OPEN_SUGGEST_REWRITE);
    + }
    +
    + if (cache->modified || ison(H->lread_open_flags,
    + LREAD_OPEN_SUGGEST_REWRITE)) {
    +
    + if (write_last_read_cache(H,cache,locking,
    + NULL /* errno_res */,
    +
    + /* commentfile,actor,version_buff */
    + NULL,NULL,NULL
    + )) {
    +
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: cache %s updated\n",
    + cur_folder_sys,
    + cache->cache_file_name ?
    + cache->cache_file_name : "(no name)"));
    +
    + if (last_read_def_cache == cache) {
    + last_read_def_rewrite = 0;
    + }
    +
    + }
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: cache %s not modified\n",
    + cur_folder_sys,
    + cache->cache_file_name ?
    + cache->cache_file_name : "(no name)"));
    + }
    +
    + free_last_read_open(&H);
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "mark_last_read: %s: cache %s not open\n",
    + cur_folder_sys,
    + cache->cache_file_name ?
    + cache->cache_file_name : "(no name)"));
    + }
    + }
    +
    +
    + static int flag_cache_entry P_((struct sortlist * cache_entries,
    + const char * sys_dir,
    + const char * entryname,
    + const char * cache_file_name
    + ));
    + static int flag_cache_entry(cache_entries,sys_dir,entryname,cache_file_name) + struct sortlist * cache_entries;
    + const char * sys_dir;
    + const char * entryname;
    + const char * cache_file_name;
    + {
    + int ret = 0;
    + union sort_key key;
    + union sort_item res;
    + union sort_item_default def;
    + size_t idx = 0;
    +
    + key.str = entryname;
    + def.last_read_entry = NULL;
    + res.dummy = NULL;
    +
    +
    + if (search_sort_list_item(cache_entries,
    + sort_list_search_normal,
    + key,def,&res,&idx,
    + NULL)) {
    +
    + if (res.last_read_entry) {
    + struct last_read_entry * entry = res.last_read_entry;
    +
    + DPRINT(Debug,13,(&Debug,
    + "flag_cache_entry: %s: %s found from %s idx %zu\n",
    + sys_dir,entryname,
    + cache_file_name ?
    + cache_file_name : "(no name)",
    + idx));
    +
    + if (LAST_READ_ENTRY_magic != entry->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "flag_cache_entry",
    + "Bad magic type (last_read_entry)",0);
    +
    +
    + setit(entry->entry_flags,LAST_READ_flag);
    +
    + ret = 1;
    +
    + /* Decrements refcount */
    + free_last_read_entry(& res.last_read_entry);
    +
    + } else {
    + DPRINT(Debug,13,(&Debug,
    + "flag_cache_entry: %s: %s found from %s idx %zu - search_sort_list_item did not set last_read_entry\n",
    + sys_dir,entryname,
    + cache_file_name ?
    + cache_file_name : "(no name)",
    + idx));
    + }
    +
    + } else {
    + DPRINT(Debug,15,(&Debug,
    + "flag_cache_entry: %s: %s not found from %s\n",
    + sys_dir,entryname,
    + cache_file_name ?
    + cache_file_name : "(no name)"));
    + }
    +
    + return ret;
    + }
    +
    + /* Flag local entries and matching with sys_dir prefix */
    + void flag_last_read(dir_last_read,sys_dir,entryname)
    + struct last_read_cache * dir_last_read;
    + const char * sys_dir;
    + const char * entryname;
    +
    + {
    + if (LAST_READ_CACHE_magic != dir_last_read->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"flag_last_read",
    + "Bad magic type (last_read_cache)",0);
    +
    + if (sys_dir && dir_last_read->sys_dir &&
    + ! same_dir_str(sys_dir,dir_last_read->sys_dir)) {
    +
    + DPRINT(Debug,15,(&Debug,
    + "flag_last_read: dir_last_read=%p sys_dir=%s entryname=%s does dor match to cache dir %s\n",
    + dir_last_read,sys_dir,entryname,dir_last_read->sys_dir));
    + }
    +
    + if (dir_last_read->entries) {
    +
    + int r = 0;
    +
    + r += flag_cache_entry(dir_last_read->entries,
    + sys_dir,entryname,
    + dir_last_read->cache_file_name);
    +
    + if ('/' != entryname[0]) {
    + char * str = cat_dir_entry(sys_dir,entryname);
    +
    + r += flag_cache_entry(dir_last_read->entries,
    + sys_dir,str,
    + dir_last_read->cache_file_name);
    +
    + free(str);
    + }
    +
    + if (r) {
    + DPRINT(Debug,15,(&Debug,
    + "flag_last_read: dir_last_read=%p sys_dir=%s entryname=%s flagged\n",
    + dir_last_read,sys_dir,entryname));
    + }
    + }
    + }
    +
    + /* deletes not flagged local entries (and absolute path entries
    + matching with sys_dir prefix)
    + */
    + void purge_last_read(dir_last_read,sys_dir)
    + struct last_read_cache * dir_last_read;
    + const char * sys_dir;
    + {
    + if (LAST_READ_CACHE_magic != dir_last_read->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"purge_last_read",
    + "Bad magic type (last_read_cache)",0);
    +
    + if (dir_last_read->entries) {
    + size_t cache_len = sort_list_len(dir_last_read->entries);
    +
    + DPRINT(Debug,15,(&Debug,
    + "purge_last_read: dir_last_read=%p sys_dir=%s %zu items\n",
    + dir_last_read,sys_dir,cache_len));
    +
    + if (cache_len > 0) {
    + size_t i = cache_len -1;
    + size_t deleted = 0;
    + size_t valid = 0;
    + size_t flagged = 0;
    + size_t bad_prefix = 0;
    + size_t modified = 0;
    +
    + size_t sys_dir_len = strlen(sys_dir);
    +
    + if (sys_dir_len > 0 && '/' == sys_dir[sys_dir_len-1])
    + sys_dir_len--;
    +
    + while (1) {
    + union sort_item res;
    +
    + res.last_read_entry = NULL;
    +
    + /* Increments refcount */
    + get_sort_list_item(dir_last_read->entries,sort_list_get_normal,i,
    + &res);
    +
    + if (res.last_read_entry) {
    + struct last_read_entry * entry;
    +
    + int need_delete = 0;
    +
    + if (LAST_READ_ENTRY_magic != res.last_read_entry->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "purge_last_read",
    + "Bad magic type (last_read_entry)",0);
    +
    + entry = res.last_read_entry;
    +
    + if (ison(entry->entry_flags,LAST_READ_valid))
    + valid++;
    + if (ison(entry->entry_flags,LAST_READ_modified))
    + modified++;
    +
    + if (ison(entry->entry_flags,LAST_READ_flag))
    + flagged++;
    + else {
    +
    + if ('/' != entry->folder_sys[0]) {
    + need_delete = 1;
    +
    + } else if (sys_dir_len > 0 &&
    + 0 == strncmp(entry->folder_sys,
    + sys_dir,sys_dir_len) &&
    + '/' == entry->folder_sys[sys_dir_len]) {
    +
    + /* Matches prefix */
    +
    + need_delete = 1;
    +
    + } else
    + bad_prefix++;
    +
    + }
    +
    + if (isoff(entry->entry_flags,LAST_READ_valid) ||
    + (need_delete &&
    + isoff(entry->entry_flags,LAST_READ_modified))) {
    +
    + free_last_read_entry(& res.last_read_entry);
    +
    + /* Increments refcount */
    + get_sort_list_item(dir_last_read->entries,sort_list_get_remove,i,
    + &res);
    +
    + if (res.last_read_entry) {
    + struct last_read_entry * entry;
    +
    + if (LAST_READ_ENTRY_magic != res.last_read_entry->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "purge_last_read",
    + "Bad magic type (last_read_entry)",0);
    +
    + entry = res.last_read_entry;
    +
    + DPRINT(Debug,14,(&Debug,
    + "purge_last_read: dir_last_read=%p #%zu folder_sys=%s - deleted\n",
    + dir_last_read,i,entry->folder_sys));
    +
    +
    + deleted++;
    + }
    + } else
    + clearit(entry->entry_flags,LAST_READ_flag);
    +
    + if (res.last_read_entry)
    + free_last_read_entry(& res.last_read_entry);
    + }
    +
    + if (i > 0)
    + i--;
    + else
    + break;
    + }
    +
    + DPRINT(Debug,14,(&Debug,
    + "purge_last_read: dir_last_read=%p %zu valid, %zu flagged, %zu bad prefix, %zu modified - %zu deleted.\n",
    + dir_last_read,valid,flagged,bad_prefix,modified,deleted));
    + }
    +
    + }
    +
    + }
    +
    +
    +
    + /*
    + * Local Variables:
    + * mode:c
    + * c-basic-offset:4
    + * buffer-file-coding-system: iso-8859-1
    + * End:
    + */

    --
    / Kari Hurtta

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)