minidlna: update to 1.1.5
[tomato.git] / release / src / router / minidlna / tivo_utils.c
blob111e9b62b3c5320ec6612dd77f221ae3f2deb223
1 /* MiniDLNA media server
2 * Copyright (C) 2009 Justin Maggard
4 * This file is part of MiniDLNA.
6 * MiniDLNA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * MiniDLNA is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>.
18 #include "config.h"
19 #ifdef TIVO_SUPPORT
20 #include <stdlib.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <ctype.h>
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sqlite3.h>
28 #include "tivo_utils.h"
30 /* This function based on byRequest */
31 char *
32 decodeString(char *string, int inplace)
34 if( !string )
35 return NULL;
36 int alloc = (int)strlen(string)+1;
37 char *ns = NULL;
38 unsigned char in;
39 int strindex=0;
40 long hex;
42 if( !inplace )
44 if( !(ns = malloc(alloc)) )
45 return NULL;
48 while(--alloc > 0)
50 in = *string;
51 if((in == '%') && isxdigit(string[1]) && isxdigit(string[2]))
53 /* this is two hexadecimal digits following a '%' */
54 char hexstr[3];
55 char *ptr;
56 hexstr[0] = string[1];
57 hexstr[1] = string[2];
58 hexstr[2] = 0;
60 hex = strtol(hexstr, &ptr, 16);
62 in = (unsigned char)hex; /* this long is never bigger than 255 anyway */
63 if( inplace )
65 *string = in;
66 memmove(string+1, string+3, alloc-2);
68 else
70 string+=2;
72 alloc-=2;
74 if( !inplace )
75 ns[strindex++] = in;
76 string++;
78 if( inplace )
80 free(ns);
81 return string;
83 else
85 ns[strindex] = '\0'; /* terminate it */
86 return ns;
90 /* These next functions implement a repeatable random function with a user-provided seed */
91 static int
92 seedRandomByte(uint32_t seed)
94 unsigned char t;
96 if( !sqlite3Prng.isInit )
98 int i;
99 char k[256];
100 sqlite3Prng.j = 0;
101 sqlite3Prng.i = 0;
102 memset(&k, '\0', sizeof(k));
103 memcpy(&k, &seed, 4);
104 for(i=0; i<256; i++)
105 sqlite3Prng.s[i] = i;
106 for(i=0; i<256; i++)
108 sqlite3Prng.j += sqlite3Prng.s[i] + k[i];
109 t = sqlite3Prng.s[sqlite3Prng.j];
110 sqlite3Prng.s[sqlite3Prng.j] = sqlite3Prng.s[i];
111 sqlite3Prng.s[i] = t;
113 sqlite3Prng.isInit = 1;
115 /* Generate and return single random byte */
116 sqlite3Prng.i++;
117 t = sqlite3Prng.s[sqlite3Prng.i];
118 sqlite3Prng.j += t;
119 sqlite3Prng.s[sqlite3Prng.i] = sqlite3Prng.s[sqlite3Prng.j];
120 sqlite3Prng.s[sqlite3Prng.j] = t;
121 t += sqlite3Prng.s[sqlite3Prng.i];
123 return sqlite3Prng.s[t];
126 static void
127 seedRandomness(int n, void *pbuf, uint32_t seed)
129 unsigned char *zbuf = pbuf;
131 while( n-- )
132 *(zbuf++) = seedRandomByte(seed);
135 void
136 TiVoRandomSeedFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
138 int64_t r, seed;
140 if( argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_INTEGER )
141 return;
142 seed = sqlite3_value_int64(argv[0]);
143 seedRandomness(sizeof(r), &r, seed);
144 sqlite3_result_int64(context, r);
148 is_tivo_file(const char *path)
150 unsigned char buf[5];
151 unsigned char hdr[5] = { 'T','i','V','o','\0' };
152 int fd;
154 /* read file header */
155 fd = open(path, O_RDONLY);
156 if( fd < 0 )
157 return 0;
158 if( read(fd, buf, 5) < 5 )
159 buf[0] = 'X';
160 close(fd);
162 return !memcmp(buf, hdr, 5);
165 #endif