Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
comparison src/gt_urn.c @ 0:d39e1d0d75b6
initial add
author | paulo@hit-nxdomain.opendns.com |
---|---|
date | Sat, 20 Feb 2010 21:18:28 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e501efabb384 |
---|---|
1 /* | |
2 * $Id: gt_urn.c,v 1.4 2004/03/05 17:47:29 hipnod Exp $ | |
3 * | |
4 * Copyright (C) 2003 giFT project (gift.sourceforge.net) | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License as published by the | |
8 * Free Software Foundation; either version 2, or (at your option) any | |
9 * later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 */ | |
16 | |
17 #include "gt_gnutella.h" | |
18 #include "gt_urn.h" | |
19 #include "encoding/base32.h" | |
20 #include "sha1.h" | |
21 | |
22 /*****************************************************************************/ | |
23 | |
24 #define URN_PREFIX_LEN (sizeof("urn:")-1) | |
25 #define SHA1_PREFIX_LEN (sizeof("sha1:")-1) | |
26 #define BITPRINT_PREFIX_LEN (sizeof("bitprint:")-1) | |
27 | |
28 /*****************************************************************************/ | |
29 | |
30 enum urn_types | |
31 { | |
32 GT_URN_SHA1 = 0, | |
33 GT_URN_BITPRINT = 1, /* for now, collapse bitprint to sha1 */ | |
34 }; | |
35 | |
36 /*****************************************************************************/ | |
37 | |
38 static long get_urn_type (gt_urn_t *urn) | |
39 { | |
40 long tmp; | |
41 | |
42 memcpy (&tmp, urn, sizeof(tmp)); | |
43 return tmp; | |
44 } | |
45 | |
46 static void set_urn_type (gt_urn_t *urn, enum urn_types t) | |
47 { | |
48 long tmp = t; | |
49 | |
50 memcpy (urn, &tmp, sizeof(tmp)); | |
51 } | |
52 | |
53 static unsigned char *get_urn_data (const gt_urn_t *urn) | |
54 { | |
55 return (unsigned char *)urn + sizeof(long); | |
56 } | |
57 | |
58 static void set_urn_data (gt_urn_t *urn, const unsigned char *data, size_t len) | |
59 { | |
60 memcpy (get_urn_data (urn), data, len); | |
61 } | |
62 | |
63 /*****************************************************************************/ | |
64 | |
65 static size_t bin_length (enum urn_types t) | |
66 { | |
67 switch (t) | |
68 { | |
69 case GT_URN_BITPRINT: | |
70 case GT_URN_SHA1: return SHA1_BINSIZE; | |
71 default: return 0; | |
72 } | |
73 } | |
74 | |
75 static gt_urn_t *sha1_urn_new (const unsigned char *data) | |
76 { | |
77 gt_urn_t *new_urn; | |
78 | |
79 if (!(new_urn = malloc (SHA1_BINSIZE + sizeof(long)))) | |
80 return NULL; | |
81 | |
82 /* put the identifier at the beginning */ | |
83 set_urn_type (new_urn, GT_URN_SHA1); | |
84 | |
85 /* copy the data */ | |
86 set_urn_data (new_urn, data, SHA1_BINSIZE); | |
87 | |
88 return new_urn; | |
89 } | |
90 | |
91 gt_urn_t *gt_urn_new (const char *urn_type, const unsigned char *data) | |
92 { | |
93 if (!strcasecmp (urn_type, "urn:sha1")) | |
94 return sha1_urn_new (data); | |
95 | |
96 return NULL; | |
97 } | |
98 | |
99 unsigned char *gt_urn_data (const gt_urn_t *urn) | |
100 { | |
101 if (!urn) | |
102 return NULL; | |
103 | |
104 return get_urn_data (urn); | |
105 } | |
106 | |
107 char *gt_urn_string (const gt_urn_t *urn) | |
108 { | |
109 unsigned char *data; | |
110 char *urn_str; | |
111 const size_t prefix_len = URN_PREFIX_LEN + SHA1_PREFIX_LEN; | |
112 | |
113 /* | |
114 * This is the same for bitprint and sha1 urns, because we convert | |
115 * to sha1 anyway. | |
116 */ | |
117 | |
118 if (!(data = gt_urn_data (urn))) | |
119 return NULL; | |
120 | |
121 if (!(urn_str = malloc (prefix_len + SHA1_STRLEN + 1))) | |
122 return NULL; | |
123 | |
124 memcpy (urn_str, "urn:sha1:", prefix_len); | |
125 gt_base32_encode (data, SHA1_BINSIZE, urn_str + prefix_len, SHA1_STRLEN); | |
126 | |
127 urn_str[prefix_len + SHA1_STRLEN] = 0; | |
128 | |
129 return urn_str; | |
130 } | |
131 | |
132 /*****************************************************************************/ | |
133 | |
134 static gt_urn_t *sha1_urn_parse (const char *base32) | |
135 { | |
136 gt_urn_t *bin; | |
137 | |
138 /* make sure the hash is the right length */ | |
139 if (!gt_base32_valid (base32, SHA1_STRLEN)) | |
140 return NULL; | |
141 | |
142 if (!(bin = malloc (SHA1_BINSIZE + sizeof(long)))) | |
143 return NULL; | |
144 | |
145 gt_base32_decode (base32, SHA1_STRLEN, bin + sizeof(long), SHA1_BINSIZE); | |
146 set_urn_type (bin, GT_URN_SHA1); | |
147 | |
148 return bin; | |
149 } | |
150 | |
151 /* | |
152 * Bitprint urns are the format: | |
153 * | |
154 * urn:bitprint:[32-character SHA1].[39-character TigerTree] | |
155 * | |
156 * We use the sha1 parsing and truncate the tigertree for now. | |
157 */ | |
158 static gt_urn_t *bitprint_urn_parse (const char *base32) | |
159 { | |
160 return sha1_urn_parse (base32); | |
161 } | |
162 | |
163 gt_urn_t *gt_urn_parse (const char *str) | |
164 { | |
165 if (strncasecmp ("urn:", str, URN_PREFIX_LEN) != 0) | |
166 return NULL; | |
167 | |
168 str += URN_PREFIX_LEN; | |
169 | |
170 if (!strncasecmp (str, "sha1:", SHA1_PREFIX_LEN)) | |
171 return sha1_urn_parse (str + SHA1_PREFIX_LEN); | |
172 | |
173 if (!strncasecmp (str, "bitprint:", BITPRINT_PREFIX_LEN)) | |
174 return bitprint_urn_parse (str + BITPRINT_PREFIX_LEN); | |
175 | |
176 return NULL; | |
177 } | |
178 | |
179 /*****************************************************************************/ | |
180 | |
181 int gt_urn_cmp (gt_urn_t *a, gt_urn_t *b) | |
182 { | |
183 int ret; | |
184 | |
185 if (!a || !b) | |
186 return -1; | |
187 | |
188 if ((ret = memcmp (a, b, 4))) | |
189 return ret; | |
190 | |
191 return memcmp (a + sizeof(long), b + sizeof(long), | |
192 bin_length (get_urn_type (a))); | |
193 } |