summaryrefslogtreecommitdiff
path: root/src/lib/efreet
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/efreet')
-rw-r--r--src/lib/efreet/efreet_cache.c166
-rw-r--r--src/lib/efreet/efreet_cache_private.h28
2 files changed, 186 insertions, 8 deletions
diff --git a/src/lib/efreet/efreet_cache.c b/src/lib/efreet/efreet_cache.c
index f859c630f0..2b5d0c9f5f 100644
--- a/src/lib/efreet/efreet_cache.c
+++ b/src/lib/efreet/efreet_cache.c
@@ -1,3 +1,4 @@
1
1#ifdef HAVE_CONFIG_H 2#ifdef HAVE_CONFIG_H
2# include <config.h> 3# include <config.h>
3#endif 4#endif
@@ -536,6 +537,137 @@ efreet_desktop_util_cache_file(void)
536/* 537/*
537 * Needs EAPI because of helper binaries 538 * Needs EAPI because of helper binaries
538 */ 539 */
540#define SHSH(n, v) ((((v) << (n)) & 0xffffffff) | ((v) >> (32 - (n))))
541
542static inline int
543int_to_bigendian(int in)
544{
545 static const unsigned char test[4] = { 0x11, 0x22, 0x33, 0x44 };
546 static const unsigned int *test_i = (const unsigned int *)test;
547 if (test_i[0] == 0x44332211) return eina_swap32(in);
548 return in;
549}
550
551static void
552sha1(unsigned char *data, int size, unsigned char *dst)
553{
554 unsigned int digest[5], word[80], wa, wb, wc, wd, we, t;
555 unsigned char buf[64], *d;
556 int idx, left, i;
557 const unsigned int magic[4] =
558 { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
559
560 idx = 0;
561 digest[0] = 0x67452301; digest[1] = 0xefcdab89; digest[2] = 0x98badcfe;
562 digest[3] = 0x10325476; digest[4] = 0xc3d2e1f0;
563
564 memset(buf, 0, sizeof(buf));
565 for (left = size, d = data; left > 0; left--, d++)
566 {
567 if ((idx == 0) && (left < 64))
568 {
569 memset(buf, 0, 60);
570 buf[60] = (size >> 24) & 0xff;
571 buf[61] = (size >> 16) & 0xff;
572 buf[62] = (size >> 8) & 0xff;
573 buf[63] = (size) & 0xff;
574 }
575 buf[idx] = *d;
576 idx++;
577 if ((idx == 64) || (left == 1))
578 {
579 if ((left == 1) && (idx < 64)) buf[idx] = 0x80;
580 for (i = 0; i < 16; i++)
581 {
582 word[i] = (unsigned int)buf[(i * 4) ] << 24;
583 word[i] |= (unsigned int)buf[(i * 4) + 1] << 16;
584 word[i] |= (unsigned int)buf[(i * 4) + 2] << 8;
585 word[i] |= (unsigned int)buf[(i * 4) + 3];
586 }
587 for (i = 16; i < 80; i++)
588 word[i] = SHSH(1,
589 word[i - 3 ] ^ word[i - 8 ] ^
590 word[i - 14] ^ word[i - 16]);
591 wa = digest[0]; wb = digest[1]; wc = digest[2];
592 wd = digest[3]; we = digest[4];
593 for (i = 0; i < 80; i++)
594 {
595 if (i < 20)
596 t = SHSH(5, wa) + ((wb & wc) | ((~wb) & wd)) +
597 we + word[i] + magic[0];
598 else if (i < 40)
599 t = SHSH(5, wa) + (wb ^ wc ^ wd) +
600 we + word[i] + magic[1];
601 else if (i < 60)
602 t = SHSH(5, wa) + ((wb & wc) | (wb & wd) | (wc & wd)) +
603 we + word[i] + magic[2];
604 else if (i < 80)
605 t = SHSH(5, wa) + (wb ^ wc ^ wd) +
606 we + word[i] + magic[3];
607 we = wd;
608 wd = wc;
609 wc = SHSH(30, wb);
610 wb = wa;
611 wa = t;
612 }
613 digest[0] += wa; digest[1] += wb; digest[2] += wc;
614 digest[3] += wd; digest[4] += we;
615 idx = 0;
616 }
617 }
618 t = int_to_bigendian(digest[0]); digest[0] = t;
619 t = int_to_bigendian(digest[1]); digest[1] = t;
620 t = int_to_bigendian(digest[2]); digest[2] = t;
621 t = int_to_bigendian(digest[3]); digest[3] = t;
622 t = int_to_bigendian(digest[4]); digest[4] = t;
623 memcpy(dst, digest, 5 * 4);
624}
625
626EAPI Eina_Bool
627efreet_file_cache_fill(const char *file, Efreet_Cache_Check *check)
628{
629 struct stat st;
630 ssize_t size = 0;
631 char link[PATH_MAX];
632
633 if (lstat(file, &st) != 0) return EINA_FALSE;
634 if (S_ISLNK(st.st_mode))
635 {
636 size = readlink(file, link, sizeof(link));
637 if ((size > 0) && ((size_t)size >= sizeof(link))) return EINA_FALSE;
638 if (stat(file, &st) != 0) return EINA_FALSE;
639 }
640
641 memset(check, 0, sizeof(Efreet_Cache_Check));
642 if (size > 0) sha1((unsigned char *)link, size, check->link_sha1);
643 else memset(check->link_sha1, 0, sizeof(check->link_sha1));
644 check->uid = st.st_uid;
645 check->gid = st.st_gid;
646 check->size = st.st_size;
647 check->blocks = st.st_blocks;
648 check->mtime = st.st_mtime;
649 check->chtime = st.st_ctime;
650 check->mode = st.st_mode;
651 return EINA_TRUE;
652}
653
654EAPI Eina_Bool // true if matches
655efreet_file_cache_check(const Efreet_Cache_Check *check1, const Efreet_Cache_Check *check2)
656{
657 if ((check1->mtime != check2->mtime ) ||
658 (check1->size != check2->size ) ||
659 (check1->chtime != check2->chtime ) ||
660 (check1->blocks != check2->blocks) ||
661 (check1->mode != check2->mode ) ||
662 (check1->uid != check2->uid ) ||
663 (check1->gid != check2->gid ) ||
664 (memcmp(check1->link_sha1, check2->link_sha1, 20) != 0))
665 {
666 return EINA_FALSE;
667 }
668 return EINA_TRUE; // matches
669}
670
539EAPI Eet_Data_Descriptor * 671EAPI Eet_Data_Descriptor *
540efreet_version_edd(void) 672efreet_version_edd(void)
541{ 673{
@@ -691,8 +823,22 @@ efreet_icon_directory_edd(void)
691 directory_edd = eet_data_descriptor_file_new(&eddc); 823 directory_edd = eet_data_descriptor_file_new(&eddc);
692 if (!directory_edd) return NULL; 824 if (!directory_edd) return NULL;
693 825
694 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory, 826 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
695 "modified_time", modified_time, EET_T_LONG_LONG); 827 "check.uid", check.uid, EET_T_LONG_LONG);
828 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
829 "check.gid", check.gid, EET_T_LONG_LONG);
830 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
831 "check.size", check.size, EET_T_LONG_LONG);
832 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
833 "check.blocks", check.blocks, EET_T_LONG_LONG);
834 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
835 "check.mtime", check.mtime, EET_T_LONG_LONG);
836 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
837 "check.chtime", check.chtime, EET_T_LONG_LONG);
838 EET_DATA_DESCRIPTOR_ADD_BASIC(directory_edd, Efreet_Cache_Directory,
839 "check.mode", check.mode, EET_T_INT);
840 EET_DATA_DESCRIPTOR_ADD_BASIC_ARRAY(directory_edd, Efreet_Cache_Directory,
841 "check.link_sha1", check.link_sha1, EET_T_CHAR);
696 842
697 return directory_edd; 843 return directory_edd;
698} 844}
@@ -790,7 +936,21 @@ efreet_icon_theme_edd(Eina_Bool cache)
790 if (cache) 936 if (cache)
791 { 937 {
792 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme, 938 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
793 "last_cache_check", last_cache_check, EET_T_LONG_LONG); 939 "check.uid", check.uid, EET_T_LONG_LONG);
940 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
941 "check.gid", check.gid, EET_T_LONG_LONG);
942 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
943 "check.size", check.size, EET_T_LONG_LONG);
944 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
945 "check.blocks", check.blocks, EET_T_LONG_LONG);
946 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
947 "check.mtime", check.mtime, EET_T_LONG_LONG);
948 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
949 "check.chtime", check.chtime, EET_T_LONG_LONG);
950 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
951 "check.mode", check.mode, EET_T_INT);
952 EET_DATA_DESCRIPTOR_ADD_BASIC_ARRAY(icon_theme_edd, Efreet_Cache_Icon_Theme,
953 "check.link_sha1", check.link_sha1, EET_T_CHAR);
794 954
795 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme, 955 EET_DATA_DESCRIPTOR_ADD_BASIC(icon_theme_edd, Efreet_Cache_Icon_Theme,
796 "path", path, EET_T_STRING); 956 "path", path, EET_T_STRING);
diff --git a/src/lib/efreet/efreet_cache_private.h b/src/lib/efreet/efreet_cache_private.h
index 97dbd45a1e..1edbb3b5ff 100644
--- a/src/lib/efreet/efreet_cache_private.h
+++ b/src/lib/efreet/efreet_cache_private.h
@@ -38,11 +38,20 @@
38# endif 38# endif
39#endif 39#endif
40 40
41typedef struct _Efreet_Cache_Check Efreet_Cache_Check;
42
43typedef struct _Efreet_Cache_Icon_Theme Efreet_Cache_Icon_Theme;
44typedef struct _Efreet_Cache_Directory Efreet_Cache_Directory;
45typedef struct _Efreet_Cache_Desktop Efreet_Cache_Desktop;
46
41EAPI const char *efreet_desktop_util_cache_file(void); 47EAPI const char *efreet_desktop_util_cache_file(void);
42EAPI const char *efreet_desktop_cache_file(void); 48EAPI const char *efreet_desktop_cache_file(void);
43EAPI const char *efreet_icon_cache_file(const char *theme); 49EAPI const char *efreet_icon_cache_file(const char *theme);
44EAPI const char *efreet_icon_theme_cache_file(void); 50EAPI const char *efreet_icon_theme_cache_file(void);
45 51
52EAPI Eina_Bool efreet_file_cache_fill(const char *file, Efreet_Cache_Check *check);
53EAPI Eina_Bool efreet_file_cache_check(const Efreet_Cache_Check *check1, const Efreet_Cache_Check *check2);
54
46EAPI Eet_Data_Descriptor *efreet_version_edd(void); 55EAPI Eet_Data_Descriptor *efreet_version_edd(void);
47EAPI Eet_Data_Descriptor *efreet_desktop_edd(void); 56EAPI Eet_Data_Descriptor *efreet_desktop_edd(void);
48EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void); 57EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void);
@@ -52,15 +61,23 @@ EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(Eina_Bool cache);
52EAPI Eet_Data_Descriptor *efreet_icon_edd(void); 61EAPI Eet_Data_Descriptor *efreet_icon_edd(void);
53EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd(void); 62EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd(void);
54 63
55typedef struct _Efreet_Cache_Icon_Theme Efreet_Cache_Icon_Theme; 64struct _Efreet_Cache_Check
56typedef struct _Efreet_Cache_Directory Efreet_Cache_Directory; 65{
57typedef struct _Efreet_Cache_Desktop Efreet_Cache_Desktop; 66 unsigned long long uid;
67 unsigned long long gid;
68 unsigned long long size;
69 unsigned long long blocks;
70 unsigned long long mtime;
71 unsigned long long chtime;
72 unsigned int mode;
73 unsigned char link_sha1[20];
74};
58 75
59struct _Efreet_Cache_Icon_Theme 76struct _Efreet_Cache_Icon_Theme
60{ 77{
61 Efreet_Icon_Theme theme; 78 Efreet_Icon_Theme theme;
62 79
63 long long last_cache_check; /**< Last time the cache was checked */ 80 Efreet_Cache_Check check; /**< relevant stat info from last check */
64 81
65 Eina_Hash *dirs; /**< All possible icon paths for this theme */ 82 Eina_Hash *dirs; /**< All possible icon paths for this theme */
66 83
@@ -73,13 +90,14 @@ struct _Efreet_Cache_Icon_Theme
73 90
74struct _Efreet_Cache_Directory 91struct _Efreet_Cache_Directory
75{ 92{
76 long long modified_time; 93 Efreet_Cache_Check check; /**< relevant stat info from last check */
77}; 94};
78 95
79struct _Efreet_Cache_Desktop 96struct _Efreet_Cache_Desktop
80{ 97{
81 Efreet_Desktop desktop; 98 Efreet_Desktop desktop;
82 99
100 Efreet_Cache_Check check; /**< relevant stat info from last check */
83 double check_time; /**< Last time we check for disk modification */ 101 double check_time; /**< Last time we check for disk modification */
84}; 102};
85 103