diff options
Diffstat (limited to 'src/lib/efreet')
-rw-r--r-- | src/lib/efreet/efreet_cache.c | 166 | ||||
-rw-r--r-- | src/lib/efreet/efreet_cache_private.h | 28 |
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 | |||
542 | static inline int | ||
543 | int_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 | |||
551 | static void | ||
552 | sha1(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 | |||
626 | EAPI Eina_Bool | ||
627 | efreet_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 | |||
654 | EAPI Eina_Bool // true if matches | ||
655 | efreet_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 | |||
539 | EAPI Eet_Data_Descriptor * | 671 | EAPI Eet_Data_Descriptor * |
540 | efreet_version_edd(void) | 672 | efreet_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 | ||
41 | typedef struct _Efreet_Cache_Check Efreet_Cache_Check; | ||
42 | |||
43 | typedef struct _Efreet_Cache_Icon_Theme Efreet_Cache_Icon_Theme; | ||
44 | typedef struct _Efreet_Cache_Directory Efreet_Cache_Directory; | ||
45 | typedef struct _Efreet_Cache_Desktop Efreet_Cache_Desktop; | ||
46 | |||
41 | EAPI const char *efreet_desktop_util_cache_file(void); | 47 | EAPI const char *efreet_desktop_util_cache_file(void); |
42 | EAPI const char *efreet_desktop_cache_file(void); | 48 | EAPI const char *efreet_desktop_cache_file(void); |
43 | EAPI const char *efreet_icon_cache_file(const char *theme); | 49 | EAPI const char *efreet_icon_cache_file(const char *theme); |
44 | EAPI const char *efreet_icon_theme_cache_file(void); | 50 | EAPI const char *efreet_icon_theme_cache_file(void); |
45 | 51 | ||
52 | EAPI Eina_Bool efreet_file_cache_fill(const char *file, Efreet_Cache_Check *check); | ||
53 | EAPI Eina_Bool efreet_file_cache_check(const Efreet_Cache_Check *check1, const Efreet_Cache_Check *check2); | ||
54 | |||
46 | EAPI Eet_Data_Descriptor *efreet_version_edd(void); | 55 | EAPI Eet_Data_Descriptor *efreet_version_edd(void); |
47 | EAPI Eet_Data_Descriptor *efreet_desktop_edd(void); | 56 | EAPI Eet_Data_Descriptor *efreet_desktop_edd(void); |
48 | EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void); | 57 | EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void); |
@@ -52,15 +61,23 @@ EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(Eina_Bool cache); | |||
52 | EAPI Eet_Data_Descriptor *efreet_icon_edd(void); | 61 | EAPI Eet_Data_Descriptor *efreet_icon_edd(void); |
53 | EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd(void); | 62 | EAPI Eet_Data_Descriptor *efreet_icon_fallback_edd(void); |
54 | 63 | ||
55 | typedef struct _Efreet_Cache_Icon_Theme Efreet_Cache_Icon_Theme; | 64 | struct _Efreet_Cache_Check |
56 | typedef struct _Efreet_Cache_Directory Efreet_Cache_Directory; | 65 | { |
57 | typedef 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 | ||
59 | struct _Efreet_Cache_Icon_Theme | 76 | struct _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 | ||
74 | struct _Efreet_Cache_Directory | 91 | struct _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 | ||
79 | struct _Efreet_Cache_Desktop | 96 | struct _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 | ||