1/* MiniDLNA media server 2 * Copyright (C) 2009 Justin Maggard 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18#include "config.h" 19#ifdef TIVO_SUPPORT 20#include <stdlib.h> 21#include <string.h> 22#include <ctype.h> 23#include <linux/types.h> // Defines __u32 24#include <sqlite3.h> 25#include "tivo_utils.h" 26 27/* This function based on byRequest */ 28char * 29decodeString(char * string, int inplace) 30{ 31 if( !string ) 32 return NULL; 33 int alloc = (int)strlen(string)+1; 34 char * ns = NULL; 35 unsigned char in; 36 int strindex=0; 37 long hex; 38 39 if( !inplace ) 40 { 41 if( !(ns = malloc(alloc)) ) 42 return NULL; 43 } 44 45 while(--alloc > 0) 46 { 47 in = *string; 48 if((in == '%') && isxdigit(string[1]) && isxdigit(string[2])) 49 { 50 /* this is two hexadecimal digits following a '%' */ 51 char hexstr[3]; 52 char *ptr; 53 hexstr[0] = string[1]; 54 hexstr[1] = string[2]; 55 hexstr[2] = 0; 56 57 hex = strtol(hexstr, &ptr, 16); 58 59 in = (unsigned char)hex; /* this long is never bigger than 255 anyway */ 60 if( inplace ) 61 { 62 *string = in; 63 memmove(string+1, string+3, alloc-2); 64 } 65 else 66 { 67 string+=2; 68 } 69 alloc-=2; 70 } 71 if( !inplace ) 72 ns[strindex++] = in; 73 string++; 74 } 75 if( inplace ) 76 { 77 return string; 78 } 79 else 80 { 81 ns[strindex] = '\0'; /* terminate it */ 82 return ns; 83 } 84} 85 86/* These next functions implement a repeatable random function with a user-provided seed */ 87static int 88seedRandomByte(__u32 seed) { 89 unsigned char t; 90 if( !sqlite3Prng.isInit ) 91 { 92 int i; 93 char k[256]; 94 sqlite3Prng.j = 0; 95 sqlite3Prng.i = 0; 96 memset(&k, 0, 256); 97 memcpy(&k, &seed, 4); 98 for(i=0; i<256; i++){ 99 sqlite3Prng.s[i] = i; 100 } 101 for(i=0; i<256; i++){ 102 sqlite3Prng.j += sqlite3Prng.s[i] + k[i]; 103 t = sqlite3Prng.s[sqlite3Prng.j]; 104 sqlite3Prng.s[sqlite3Prng.j] = sqlite3Prng.s[i]; 105 sqlite3Prng.s[i] = t; 106 } 107 sqlite3Prng.isInit = 1; 108 } 109 /* Generate and return single random byte */ 110 sqlite3Prng.i++; 111 t = sqlite3Prng.s[sqlite3Prng.i]; 112 sqlite3Prng.j += t; 113 sqlite3Prng.s[sqlite3Prng.i] = sqlite3Prng.s[sqlite3Prng.j]; 114 sqlite3Prng.s[sqlite3Prng.j] = t; 115 t += sqlite3Prng.s[sqlite3Prng.i]; 116 117 return sqlite3Prng.s[t]; 118} 119 120void 121seedRandomness(int N, void *pBuf, __u32 seed){ 122 unsigned char *zBuf = pBuf; 123 124 while( N-- ){ 125 *(zBuf++) = seedRandomByte(seed); 126 } 127} 128 129void 130TiVoRandomSeedFunc(sqlite3_context *context, int argc, sqlite3_value **argv) 131{ 132 sqlite_int64 r, seed; 133 if( argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_INTEGER ) 134 return; 135 seed = sqlite3_value_int64(argv[0]); 136 seedRandomness(sizeof(r), &r, seed); 137 sqlite3_result_int64(context, r); 138} 139#endif 140