Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gt_urn.c Sat Feb 20 21:18:28 2010 -0800 1.3 @@ -0,0 +1,193 @@ 1.4 +/* 1.5 + * $Id: gt_urn.c,v 1.4 2004/03/05 17:47:29 hipnod Exp $ 1.6 + * 1.7 + * Copyright (C) 2003 giFT project (gift.sourceforge.net) 1.8 + * 1.9 + * This program is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License as published by the 1.11 + * Free Software Foundation; either version 2, or (at your option) any 1.12 + * later version. 1.13 + * 1.14 + * This program is distributed in the hope that it will be useful, but 1.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + * General Public License for more details. 1.18 + */ 1.19 + 1.20 +#include "gt_gnutella.h" 1.21 +#include "gt_urn.h" 1.22 +#include "encoding/base32.h" 1.23 +#include "sha1.h" 1.24 + 1.25 +/*****************************************************************************/ 1.26 + 1.27 +#define URN_PREFIX_LEN (sizeof("urn:")-1) 1.28 +#define SHA1_PREFIX_LEN (sizeof("sha1:")-1) 1.29 +#define BITPRINT_PREFIX_LEN (sizeof("bitprint:")-1) 1.30 + 1.31 +/*****************************************************************************/ 1.32 + 1.33 +enum urn_types 1.34 +{ 1.35 + GT_URN_SHA1 = 0, 1.36 + GT_URN_BITPRINT = 1, /* for now, collapse bitprint to sha1 */ 1.37 +}; 1.38 + 1.39 +/*****************************************************************************/ 1.40 + 1.41 +static long get_urn_type (gt_urn_t *urn) 1.42 +{ 1.43 + long tmp; 1.44 + 1.45 + memcpy (&tmp, urn, sizeof(tmp)); 1.46 + return tmp; 1.47 +} 1.48 + 1.49 +static void set_urn_type (gt_urn_t *urn, enum urn_types t) 1.50 +{ 1.51 + long tmp = t; 1.52 + 1.53 + memcpy (urn, &tmp, sizeof(tmp)); 1.54 +} 1.55 + 1.56 +static unsigned char *get_urn_data (const gt_urn_t *urn) 1.57 +{ 1.58 + return (unsigned char *)urn + sizeof(long); 1.59 +} 1.60 + 1.61 +static void set_urn_data (gt_urn_t *urn, const unsigned char *data, size_t len) 1.62 +{ 1.63 + memcpy (get_urn_data (urn), data, len); 1.64 +} 1.65 + 1.66 +/*****************************************************************************/ 1.67 + 1.68 +static size_t bin_length (enum urn_types t) 1.69 +{ 1.70 + switch (t) 1.71 + { 1.72 + case GT_URN_BITPRINT: 1.73 + case GT_URN_SHA1: return SHA1_BINSIZE; 1.74 + default: return 0; 1.75 + } 1.76 +} 1.77 + 1.78 +static gt_urn_t *sha1_urn_new (const unsigned char *data) 1.79 +{ 1.80 + gt_urn_t *new_urn; 1.81 + 1.82 + if (!(new_urn = malloc (SHA1_BINSIZE + sizeof(long)))) 1.83 + return NULL; 1.84 + 1.85 + /* put the identifier at the beginning */ 1.86 + set_urn_type (new_urn, GT_URN_SHA1); 1.87 + 1.88 + /* copy the data */ 1.89 + set_urn_data (new_urn, data, SHA1_BINSIZE); 1.90 + 1.91 + return new_urn; 1.92 +} 1.93 + 1.94 +gt_urn_t *gt_urn_new (const char *urn_type, const unsigned char *data) 1.95 +{ 1.96 + if (!strcasecmp (urn_type, "urn:sha1")) 1.97 + return sha1_urn_new (data); 1.98 + 1.99 + return NULL; 1.100 +} 1.101 + 1.102 +unsigned char *gt_urn_data (const gt_urn_t *urn) 1.103 +{ 1.104 + if (!urn) 1.105 + return NULL; 1.106 + 1.107 + return get_urn_data (urn); 1.108 +} 1.109 + 1.110 +char *gt_urn_string (const gt_urn_t *urn) 1.111 +{ 1.112 + unsigned char *data; 1.113 + char *urn_str; 1.114 + const size_t prefix_len = URN_PREFIX_LEN + SHA1_PREFIX_LEN; 1.115 + 1.116 + /* 1.117 + * This is the same for bitprint and sha1 urns, because we convert 1.118 + * to sha1 anyway. 1.119 + */ 1.120 + 1.121 + if (!(data = gt_urn_data (urn))) 1.122 + return NULL; 1.123 + 1.124 + if (!(urn_str = malloc (prefix_len + SHA1_STRLEN + 1))) 1.125 + return NULL; 1.126 + 1.127 + memcpy (urn_str, "urn:sha1:", prefix_len); 1.128 + gt_base32_encode (data, SHA1_BINSIZE, urn_str + prefix_len, SHA1_STRLEN); 1.129 + 1.130 + urn_str[prefix_len + SHA1_STRLEN] = 0; 1.131 + 1.132 + return urn_str; 1.133 +} 1.134 + 1.135 +/*****************************************************************************/ 1.136 + 1.137 +static gt_urn_t *sha1_urn_parse (const char *base32) 1.138 +{ 1.139 + gt_urn_t *bin; 1.140 + 1.141 + /* make sure the hash is the right length */ 1.142 + if (!gt_base32_valid (base32, SHA1_STRLEN)) 1.143 + return NULL; 1.144 + 1.145 + if (!(bin = malloc (SHA1_BINSIZE + sizeof(long)))) 1.146 + return NULL; 1.147 + 1.148 + gt_base32_decode (base32, SHA1_STRLEN, bin + sizeof(long), SHA1_BINSIZE); 1.149 + set_urn_type (bin, GT_URN_SHA1); 1.150 + 1.151 + return bin; 1.152 +} 1.153 + 1.154 +/* 1.155 + * Bitprint urns are the format: 1.156 + * 1.157 + * urn:bitprint:[32-character SHA1].[39-character TigerTree] 1.158 + * 1.159 + * We use the sha1 parsing and truncate the tigertree for now. 1.160 + */ 1.161 +static gt_urn_t *bitprint_urn_parse (const char *base32) 1.162 +{ 1.163 + return sha1_urn_parse (base32); 1.164 +} 1.165 + 1.166 +gt_urn_t *gt_urn_parse (const char *str) 1.167 +{ 1.168 + if (strncasecmp ("urn:", str, URN_PREFIX_LEN) != 0) 1.169 + return NULL; 1.170 + 1.171 + str += URN_PREFIX_LEN; 1.172 + 1.173 + if (!strncasecmp (str, "sha1:", SHA1_PREFIX_LEN)) 1.174 + return sha1_urn_parse (str + SHA1_PREFIX_LEN); 1.175 + 1.176 + if (!strncasecmp (str, "bitprint:", BITPRINT_PREFIX_LEN)) 1.177 + return bitprint_urn_parse (str + BITPRINT_PREFIX_LEN); 1.178 + 1.179 + return NULL; 1.180 +} 1.181 + 1.182 +/*****************************************************************************/ 1.183 + 1.184 +int gt_urn_cmp (gt_urn_t *a, gt_urn_t *b) 1.185 +{ 1.186 + int ret; 1.187 + 1.188 + if (!a || !b) 1.189 + return -1; 1.190 + 1.191 + if ((ret = memcmp (a, b, 4))) 1.192 + return ret; 1.193 + 1.194 + return memcmp (a + sizeof(long), b + sizeof(long), 1.195 + bin_length (get_urn_type (a))); 1.196 +}