| 873 | } |
| 874 | |
| 875 | static void cache_hash(const char *it, char *val, int ndepth, int nlength) |
| 876 | { |
| 877 | apr_md5_ctx_t context; |
| 878 | unsigned char digest[16]; |
| 879 | char tmp[22]; |
| 880 | int i, k, d; |
| 881 | unsigned int x; |
| 882 | static const char enc_table[64] = |
| 883 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_@"; |
| 884 | |
| 885 | apr_md5_init(&context); |
| 886 | apr_md5_update(&context, (const unsigned char *) it, strlen(it)); |
| 887 | apr_md5_final(digest, &context); |
| 888 | |
| 889 | /* encode 128 bits as 22 characters, using a modified uuencoding |
| 890 | * the encoding is 3 bytes -> 4 characters* i.e. 128 bits is |
| 891 | * 5 x 3 bytes + 1 byte -> 5 * 4 characters + 2 characters |
| 892 | */ |
| 893 | for (i = 0, k = 0; i < 15; i += 3) { |
| 894 | x = (digest[i] << 16) | (digest[i + 1] << 8) | digest[i + 2]; |
| 895 | tmp[k++] = enc_table[x >> 18]; |
| 896 | tmp[k++] = enc_table[(x >> 12) & 0x3f]; |
| 897 | tmp[k++] = enc_table[(x >> 6) & 0x3f]; |
| 898 | tmp[k++] = enc_table[x & 0x3f]; |
| 899 | } |
| 900 | |
| 901 | /* one byte left */ |
| 902 | x = digest[15]; |
| 903 | tmp[k++] = enc_table[x >> 2]; /* use up 6 bits */ |
| 904 | tmp[k++] = enc_table[(x << 4) & 0x3f]; |
| 905 | |
| 906 | /* now split into directory levels */ |
| 907 | for (i = k = d = 0; d < ndepth; ++d) { |
| 908 | memcpy(&val[i], &tmp[k], nlength); |
| 909 | k += nlength; |
| 910 | val[i + nlength] = '/'; |
| 911 | i += nlength + 1; |
| 912 | } |
| 913 | memcpy(&val[i], &tmp[k], 22 - k); |
| 914 | val[i + 22 - k] = '\0'; |
| 915 | } |
| 916 | |
| 917 | CACHE_DECLARE(char *)ap_cache_generate_name(apr_pool_t *p, int dirlevels, |
| 918 | int dirlength, const char *name) |
no outgoing calls
no test coverage detected