Git init
[framework/multimedia/libmedia-thumbnail.git] / md5 / media-thumb-hash.c
1 /* GLIB - Library of useful routines for C programming
2  *
3  * gconvert.c: Convert between character sets using iconv
4  * Copyright Red Hat Inc., 2000
5  * Authors: Havoc Pennington <hp@redhat.com>, Owen Taylor <otaylor@redhat.com
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* The array below is taken from gconvert.c, which is licensed by GNU Lesser General Public License
24  * Code to escape string is also taken partially from gconvert.c
25  * File name is changed to media-thumb-hash.c
26  */
27
28 #include "md5.h"
29 #include "media-thumbnail-private.h"
30 #include <string.h>
31 #include <alloca.h>
32
33
34 static const char ACCEPTABLE_URI_CHARS[96] = {
35         /*      !    "    #    $    %    &    '    (    )    *    +    ,    -    .    / */
36         0x00, 0x3F, 0x20, 0x20, 0x28, 0x00, 0x2C, 0x3F, 0x3F, 0x3F, 0x3F, 0x2A,
37             0x28, 0x3F, 0x3F, 0x1C,
38         /* 0    1    2    3    4    5    6    7    8    9    :    ;    <    =    >    ? */
39         0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x38, 0x20,
40             0x20, 0x2C, 0x20, 0x20,
41         /* @    A    B    C    D    E    F    G    H    I    J    K    L    M    N    O */
42         0x38, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
43             0x3F, 0x3F, 0x3F, 0x3F,
44         /* P    Q    R    S    T    U    V    W    X    Y    Z    [    \    ]    ^    _ */
45         0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20,
46             0x20, 0x20, 0x20, 0x3F,
47         /* `    a    b    c    d    e    f    g    h    i    j    k    l    m    n    o */
48         0x20, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
49             0x3F, 0x3F, 0x3F, 0x3F,
50         /* p    q    r    s    t    u    v    w    x    y    z    {    |    }    ~  DEL */
51         0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20,
52             0x20, 0x20, 0x3F, 0x20
53 };
54
55 char *_media_thumb_generate_hash_name(const char *file)
56 {
57         int n;
58         MD5_CTX ctx;
59         static char md5out[(2 * MD5_HASHBYTES) + 1];
60         unsigned char hash[MD5_HASHBYTES];
61         static const char hex[] = "0123456789abcdef";
62
63         char *uri;
64         char *t;
65         const unsigned char *c;
66         int length;
67
68         if (!file) {
69                 return NULL;
70         }
71
72         length = 3 * strlen(file) + 9;
73
74         memset(md5out, 0, sizeof(md5out));
75
76 #define _check_uri_char(c) \
77 ((c) >= 32 && (c) < 128 && (ACCEPTABLE_URI_CHARS[(c) - 32] & 0x08))
78
79         uri = alloca(length);
80         if (uri == NULL) {
81                 return NULL;
82         }
83
84         strncpy(uri, "file://", length);
85         uri[length - 1] = '\0';
86         t = uri + sizeof("file://") - 1;
87
88         for (c = (const unsigned char *)file; *c != '\0'; c++) {
89                 if (!_check_uri_char(*c)) {
90                         *t++ = '%';
91                         *t++ = hex[*c >> 4];
92                         *t++ = hex[*c & 15];
93                 } else {
94                         *t++ = *c;
95                 }
96         }
97         *t = '\0';
98 #undef _check_uri_char
99
100         MD5Init(&ctx);
101         MD5Update(&ctx, (unsigned char const *)uri, (unsigned)strlen(uri));
102         MD5Final(hash, &ctx);
103
104         for (n = 0; n < MD5_HASHBYTES; n++) {
105                 md5out[2 * n] = hex[hash[n] >> 4];
106                 md5out[2 * n + 1] = hex[hash[n] & 0x0f];
107         }
108         md5out[2 * n] = '\0';
109
110         return md5out;
111 }
112
113 int thumbnail_generate_hash_code(const char *origin_path, char *hash_code, int max_length)
114 {
115         char *hash = NULL;
116
117         if (max_length < ((2 * MD5_HASHBYTES) + 1)) {
118                 return MEDIA_THUMB_ERROR_INVALID_PARAMETER;
119         }
120
121         hash = _media_thumb_generate_hash_name(origin_path);
122
123         if (hash == NULL) {
124                 return MEDIA_THUMB_ERROR_HASHCODE;
125         }
126
127         strncpy(hash_code, hash, max_length);
128         hash_code[strlen(hash_code)] ='\0';
129
130         return MEDIA_THUMB_ERROR_NONE;
131 }
132