/[zanavi_public1]/navit/navit/file.c
ZANavi

Diff of /navit/navit/file.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 49 Revision 50
1/**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
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
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
1/** 20/**
2 * Navit, a modular navigation system. 21 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2011 Navit Team 22 * Copyright (C) 2005-2011 Navit Team
4 * 23 *
5 * This program is free software; you can redistribute it and/or 24 * This program is free software; you can redistribute it and/or
19 38
20#define _FILE_OFFSET_BITS 64 39#define _FILE_OFFSET_BITS 64
21#define _LARGEFILE_SOURCE 40#define _LARGEFILE_SOURCE
22#define _LARGEFILE64_SOURCE 41#define _LARGEFILE64_SOURCE
23#include "config.h" 42#include "config.h"
43
24#ifdef HAVE_UNISTD_H 44#ifdef HAVE_UNISTD_H
25#include <unistd.h> 45#include <unistd.h>
26#endif 46#endif
47
27#ifdef _MSC_VER 48#ifdef _MSC_VER
28#include <windows.h> 49#include <windows.h>
29#else 50#else
30#include <dirent.h> 51#include <dirent.h>
31#endif /* _MSC_VER */ 52#endif /* _MSC_VER */
53
32#include <string.h> 54#include <string.h>
33#include <fcntl.h> 55#include <fcntl.h>
34#include <sys/stat.h> 56#include <sys/stat.h>
35#include <sys/mman.h> 57#include <sys/mman.h>
36#include <stdio.h> 58#include <stdio.h>
43#include "file.h" 65#include "file.h"
44#include "atom.h" 66#include "atom.h"
45#include "item.h" 67#include "item.h"
46#include "util.h" 68#include "util.h"
47#include "types.h" 69#include "types.h"
70
48#ifdef HAVE_SOCKET 71#ifdef HAVE_SOCKET
49#include <sys/socket.h> 72#include <sys/socket.h>
50#include <netdb.h> 73#include <netdb.h>
51#endif 74#endif
75
76#include "navit.h"
52 77
53extern char *version; 78extern char *version;
54 79
55#ifdef HAVE_LIBCRYPTO 80#ifdef HAVE_LIBCRYPTO
56#include <openssl/sha.h> 81#include <openssl/sha.h>
79static struct cache *file_cache; 104static struct cache *file_cache;
80 105
81#ifdef _MSC_VER 106#ifdef _MSC_VER
82#pragma pack(push,1) 107#pragma pack(push,1)
83#endif /* _MSC_VER */ 108#endif /* _MSC_VER */
84struct file_cache_id { 109struct file_cache_id
110{
85 long long offset; 111 long long offset;
86 int size; 112 int size;
87 int file_name_id; 113 int file_name_id;
88 int method; 114 int method;
89#ifndef _MSC_VER 115#ifndef _MSC_VER
95 121
96#ifdef HAVE_SOCKET 122#ifdef HAVE_SOCKET
97static int 123static int
98file_socket_connect(char *host, char *service) 124file_socket_connect(char *host, char *service)
99{ 125{
100 struct addrinfo hints; 126 //dbg(0,"_enterXX %s %s\n", host, service);
101 struct addrinfo *result, *rp;
102 int fd=-1,s; 127 int fd;
103
104 memset(&hints, 0, sizeof(struct addrinfo));
105 hints.ai_family = AF_UNSPEC;
106 hints.ai_socktype = SOCK_STREAM;
107 hints.ai_flags = 0;
108 hints.ai_protocol = 0;
109 s = getaddrinfo(host, service, &hints, &result);
110 if (s != 0) {
111 dbg(0,"getaddrinfo error %s\n",gai_strerror(s));
112 return -1;
113 }
114 for (rp = result; rp != NULL; rp = rp->ai_next) {
115 fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
116 if (fd != -1) {
117 if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)
118 break;
119 close(fd);
120 fd=-1;
121 }
122 }
123 freeaddrinfo(result);
124 return fd; 128 return fd;
125} 129}
126 130
127static void 131static void
128file_http_request(struct file *file, char *method, char *host, char *path, char *header, int persistent) 132file_http_request(struct file *file, char *method, char *host, char *path, char *header, int persistent)
129{ 133{
130 char *request=g_strdup_printf("%s %s HTTP/1.0\r\nUser-Agent: navit %s\r\nHost: %s\r\n%s%s%s\r\n",method,path,version,host,persistent?"Connection: Keep-Alive\r\n":"",header?header:"",header?"\r\n":""); 134 //dbg(0,"_enterXX %s\n", path);
131 write(file->fd, request, strlen(request));
132 dbg(1,"%s\n",request);
133 file->requests++;
134} 135}
135 136
136static int 137static int
137file_request_do(struct file *file, struct attr **options, int connect) 138file_request_do(struct file *file, struct attr **options, int connect)
138{ 139{
139 struct attr *attr; 140 //dbg(0,"_enterXX %s\n", file->name);
140 char *name;
141
142 if (!options)
143 return 0;
144 attr=attr_search(options, NULL, attr_url);
145 if (!attr)
146 return 0;
147 name=attr->u.str;
148 if (!name)
149 return 0;
150 g_free(file->name);
151 file->name = g_strdup(name);
152 if (!strncmp(name,"http://",7)) {
153 char *host=g_strdup(name+7);
154 char *port=strchr(host,':');
155 char *path=strchr(name+7,'/');
156 char *method="GET";
157 char *header=NULL;
158 int persistent=0;
159 if ((attr=attr_search(options, NULL, attr_http_method)) && attr->u.str)
160 method=attr->u.str;
161 if ((attr=attr_search(options, NULL, attr_http_header)) && attr->u.str)
162 header=attr->u.str;
163 if ((attr=attr_search(options, NULL, attr_persistent)))
164 persistent=attr->u.num;
165 if (path)
166 host[path-name-7]='\0';
167 if (port)
168 *port++='\0';
169 dbg(1,"host=%s path=%s\n",host,path);
170 if (connect)
171 file->fd=file_socket_connect(host,port?port:"80");
172 file_http_request(file,method,host,path,header,persistent);
173 file->special=1;
174 g_free(host);
175 }
176 return 1; 141 return 1;
177} 142}
178#endif 143#endif
179 144
180static unsigned char * 145static unsigned char *
181file_http_header_end(unsigned char *str, int len) 146file_http_header_end(unsigned char *str, int len)
182{ 147{
183 int i; 148 //dbg(0,"_enterXX %s\n", str);
184 for (i=0; i+1<len; i+=2) {
185 if (str[i+1]=='\n') {
186 if (str[i]=='\n')
187 return str+i+2;
188 else if (str[i]=='\r' && i+3<len && str[i+2]=='\r' && str[i+3]=='\n')
189 return str+i+4;
190 --i;
191 } else if (str[i+1]=='\r') {
192 if (i+4<len && str[i+2]=='\n' && str[i+3]=='\r' && str[i+4]=='\n')
193 return str+i+5;
194 --i;
195 }
196 }
197 return NULL; 149 return NULL;
198} 150}
199 151
200int
201file_request(struct file *f, struct attr **options) 152int file_request(struct file *f, struct attr **options)
202{ 153{
203#ifdef HAVE_SOCKET 154 //dbg(0,"_enterXX %s\n", f->name);
204 return file_request_do(f, options, 0);
205#else
206 return 0; 155 return 0;
207#endif
208} 156}
209 157
210char * 158char *
211file_http_header(struct file *f, char *header) 159file_http_header(struct file *f, char *header)
212{ 160{
213 if (!f->headers) 161 //dbg(0,"_enterXX %s\n", f->name);
214 return NULL; 162 return NULL;
215 return g_hash_table_lookup(f->headers, header);
216} 163}
217 164
218struct file * 165struct file *
219file_create(char *name, struct attr **options) 166file_create(char *name, struct attr **options)
220{ 167{
168 //dbg(0,"_enterPP %s\n", name);
221 struct stat stat; 169 struct stat stat;
222 struct file *file= g_new0(struct file,1); 170 struct file *file= g_new0(struct file,1);
223 struct attr *attr; 171 struct attr *attr;
224 int open_flags=O_LARGEFILE|O_BINARY; 172 int open_flags = O_LARGEFILE | O_BINARY;
225 173
226 if (options && (attr=attr_search(options, NULL, attr_url))) { 174 if (options && (attr = attr_search(options, NULL, attr_url)))
175 {
227#ifdef HAVE_SOCKET 176#ifdef HAVE_SOCKET
177 //dbg(0,"_HAVE_SOCKET\n");
228 file_request_do(file, options, 1); 178 file_request_do(file, options, 1);
229#endif 179#endif
230 } else { 180 }
181 else
182 {
231 if (options && (attr=attr_search(options, NULL, attr_readwrite)) && attr->u.num) { 183 if (options && (attr = attr_search(options, NULL, attr_readwrite)) && attr->u.num)
184 {
232 open_flags |= O_RDWR; 185 open_flags |= O_RDWR;
233 if ((attr=attr_search(options, NULL, attr_create)) && attr->u.num) 186 if ((attr = attr_search(options, NULL, attr_create)) && attr->u.num)
187 {
234 open_flags |= O_CREAT; 188 open_flags |= O_CREAT;
189 }
190 }
235 } else 191 else
192 {
236 open_flags |= O_RDONLY; 193 open_flags |= O_RDONLY;
194 }
195
237 file->name = g_strdup(name); 196 file->name = g_strdup(name);
238 file->fd=open(name, open_flags, 0666); 197 file->fd = open(name, open_flags, 0666);
198 file->current_splitter = 0; // ORIG file opened
239 if (file->fd == -1) { 199 if (file->fd == -1)
200 {
240 g_free(file); 201 g_free(file);
241 return NULL; 202 return NULL;
242 } 203 }
243 dbg(1,"fd=%d\n", file->fd); 204 dbg(0, "_fd=%d\n", file->fd);
244 fstat(file->fd, &stat); 205
245 file->size=stat.st_size; 206 // set default value
207 file->num_splits = 0;
208 file->size = file_size(file);
209
246 dbg(1,"size="LONGLONG_FMT"\n", file->size); 210 dbg(0,"_size="LONGLONG_FMT"\n", file->size);
247 file->name_id = (long)atom(name); 211 file->name_id = (long) atom(name);
248 } 212 }
249#ifdef CACHE_SIZE 213#ifdef CACHE_SIZE
250 if (!options || !(attr=attr_search(options, NULL, attr_cache)) || attr->u.num) 214 //if (!options || !(attr=attr_search(options, NULL, attr_cache)) || attr->u.num)
215 //{
216 dbg(0,"_cache=1 for %s\n",name);
251 file->cache=1; 217 file->cache=1;
218 //}
252#endif 219#endif
253 dbg_assert(file != NULL); 220 dbg_assert(file != NULL);
254 return file; 221 return file;
255} 222}
256 223
257#if 0
258struct file *
259file_create_url(char *url)
260{
261}
262#endif
263
264#ifndef S_ISDIR 224#ifndef S_ISDIR
265#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 225#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
266#endif 226#endif
267#ifndef S_ISREG 227#ifndef S_ISREG
268#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 228#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
269#endif 229#endif
270 230
271int file_is_dir(char *name) 231int file_is_dir(char *name)
272{ 232{
233 //dbg(0,"_enterOO %s\n", name);
273 struct stat buf; 234 struct stat buf;
274 if (! stat(name, &buf)) { 235 if (!stat(name, &buf))
236 {
275 return S_ISDIR(buf.st_mode); 237 return S_ISDIR(buf.st_mode);
276 } 238 }
277 return 0; 239 return 0;
278
279} 240}
280 241
281int file_is_reg(char *name) 242int file_is_reg(char *name)
282{ 243{
244 //dbg(0,"_enterOO\n");
283 struct stat buf; 245 struct stat buf;
284 if (! stat(name, &buf)) { 246 if (!stat(name, &buf))
247 {
285 return S_ISREG(buf.st_mode); 248 return S_ISREG(buf.st_mode);
286 } 249 }
287 return 0; 250 return 0;
288} 251}
289 252
290long long
291file_size(struct file *file) 253long long file_size(struct file *file)
292{ 254{
255 dbg(0, "_enterPP %s\n", file->name);
256
257 // first get and set orig file size
258 struct stat buf2;
259 stat(file->name, &buf2);
260 file->size = buf2.st_size;
261 dbg(0,"_orig_size="LONGLONG_FMT"\n", file->size);
262
263 // use initial size
264 long long f_size = file->size;
265 file->split_size_in_bytes = 0;
266 file->last_splitter_size_in_bytes = 0;
267
268 // size of all the splitters (assume all the splitter have SAME byte size!!)
269 file->split_size_in_bytes = file->size;
270
271 int i;
272 int j = 0;
273 int finished = 0;
274 for (i = 0; i < MAX_SPLIT_FILES; i++)
275 {
276 if (finished == 0)
277 {
278 char *name = g_strdup_printf("%s.%d", file->name, (i + 1));
279 dbg(0, "_i=%d name=%s\n", (i + 1), name);
280 struct stat buf;
281 if (!stat(name, &buf))
282 {
283 dbg(0,"_st_size="LONGLONG_FMT"\n", buf.st_size);
284 f_size = f_size + buf.st_size;
285 j = i + 1;
286 if (i == 0)
287 {
288 }
289 else
290 {
291 // size of last splitter (will be most likely smaller since its the last part)
292 file->last_splitter_size_in_bytes = buf.st_size;
293 }
294 }
295 else
296 {
297 finished = 1;
298 }
299 g_free(name);
300 }
301 }
302
303 // set num. of split files
304 file->num_splits = j;
305 dbg(0, "_num_splits=%d\n", file->num_splits);
306
307 dbg(0,"_all_size="LONGLONG_FMT"\n", f_size);
308 return f_size;
293 return file->size; 309 // return file->size;
294} 310}
295 311
296int file_mkdir(char *name, int pflag) 312int file_mkdir(char *name, int pflag)
297{ 313{
314 //dbg(0,"_enterOO %s\n", name);
298 char *buffer=g_alloca(sizeof(char)*(strlen(name)+1)); 315 char *buffer = g_alloca(sizeof(char) * (strlen(name) + 1));
299 int ret; 316 int ret;
300 char *next; 317 char *next;
301 dbg(1,"enter %s %d\n",name,pflag); 318 // dbg(1, "enter %s %d\n", name, pflag);
302 if (!pflag) { 319 if (!pflag)
320 {
303 if (file_is_dir(name)) 321 if (file_is_dir(name))
322 {
304 return 0; 323 return 0;
324 }
305#if defined HAVE_API_WIN32_BASE || defined _MSC_VER 325#if defined HAVE_API_WIN32_BASE || defined _MSC_VER
306 return mkdir(name); 326 return mkdir(name);
307#else 327#else
308 return mkdir(name, 0777); 328 return mkdir(name, 0777);
309#endif 329#endif
310 } 330 }
311 strcpy(buffer, name); 331 strcpy(buffer, name);
312 next=buffer; 332 next = buffer;
313 while ((next=strchr(next, '/'))) { 333 while ((next = strchr(next, '/')))
334 {
314 *next='\0'; 335 *next = '\0';
315 if (*buffer) { 336 if (*buffer)
337 {
316 ret=file_mkdir(buffer, 0); 338 ret = file_mkdir(buffer, 0);
317 if (ret) 339 if (ret)
340 {
318 return ret; 341 return ret;
319 } 342 }
343 }
320 *next++='/'; 344 *next++ = '/';
321 } 345 }
322 if (pflag == 2) 346 if (pflag == 2)
347 {
323 return 0; 348 return 0;
349 }
324 return file_mkdir(buffer, 0); 350 return file_mkdir(buffer, 0);
325} 351}
326 352
327int
328file_mmap(struct file *file) 353int file_mmap(struct file *file)
329{ 354{
330#if 0 355 //dbg(0,"_enterP? %s\n", file->name);
331 int mmap_size=file->size+1024*1024;
332#else
333 int mmap_size=file->size; 356 int mmap_size = file->size;
334#endif 357
358 // turn off mmap!!
359 if (file->num_splits > 0)
360 {
361 file->begin = NULL;
362 return 0;
363 }
364 // turn off mmap!!
365
335#ifdef HAVE_API_WIN32_BASE 366#ifdef HAVE_API_WIN32_BASE
336 file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file ); 367 file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file );
337#else 368#else
338 file->begin=mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, file->fd, 0); 369 file->begin = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, file->fd, 0);
339 dbg_assert(file->begin != NULL); 370 dbg_assert(file->begin != NULL);
340 if (file->begin == (void *)0xffffffff) { 371 if (file->begin == (void *) 0xffffffff)
372 {
341 perror("mmap"); 373 perror("mmap");
342 return 0; 374 return 0;
343 } 375 }
344#endif 376#endif
377
345 dbg_assert(file->begin != (void *)0xffffffff); 378 dbg_assert(file->begin != (void *) 0xffffffff);
346 file->mmap_end=file->begin+mmap_size; 379 file->mmap_end = file->begin + mmap_size;
347 file->end=file->begin+file->size; 380 file->end = file->begin + file->size;
348 381
349 return 1; 382 return 1;
350} 383}
351 384
352unsigned char * 385unsigned char *
353file_data_read(struct file *file, long long offset, int size) 386file_data_read(struct file *file, long long offset, int size)
354{ 387{
388 //dbg(0,"_enterPP %s "LONGLONG_FMT" %d\n", file->name, offset, size);
355 void *ret; 389 void *ret;
356 if (file->special) 390 if (file->special)
391 {
357 return NULL; 392 return NULL;
393 }
394
395 // turn off mmap
396 if (file->num_splits == 0)
397 // turn off mmap
398 {
358 if (file->begin) 399 if (file->begin)
400 {
401 //dbg(0,"_leave:begin\n");
359 return file->begin+offset; 402 return file->begin + offset;
403 }
404 }
405
360 if (file_cache) { 406 if (file_cache)
407 {
408 //dbg(0,"_file_cache\n");
361 struct file_cache_id id={offset,size,file->name_id,0}; 409 struct file_cache_id id = { offset, size, file->name_id, 0 };
362 ret=cache_lookup(file_cache,&id); 410 ret = cache_lookup(file_cache, &id);
363 if (ret) 411 if (ret)
412 {
413 //dbg(0,"_file_cache:found\n");
364 return ret; 414 return ret;
415 }
416 //dbg(0,"_file_cache:insert\n");
365 ret=cache_insert_new(file_cache,&id,size); 417 ret = cache_insert_new(file_cache, &id, size);
418 }
366 } else 419 else
420 {
421 //dbg(0,"_g_malloc\n");
367 ret=g_malloc(size); 422 ret = g_malloc(size);
423 }
424
425 if (file->num_splits == 0)
426 {
427 //dbg(0,"_num_splits=0\n");
368 lseek(file->fd, offset, SEEK_SET); 428 lseek(file->fd, offset, SEEK_SET);
369 if (read(file->fd, ret, size) != size) { 429 if (read(file->fd, ret, size) != size)
430 {
370 file_data_free(file, ret); 431 file_data_free(file, ret);
371 ret=NULL; 432 ret = NULL;
372 } 433 }
434 }
435 else
436 {
437 //dbg(0,"_num_splits=1\n");
438
439 /* ++++++++++++++++++++++++++++++++++++++++++ */
440 /* ++++++++++++++++++++++++++++++++++++++++++ */
441 int start_splitter;
442 long long offset_split;
443 long long offset2;
444 int size2;
445 int read_size;
446 int need_more = 1;
447 char *ret2; // just define any sort of pointer, maybe this can be done better??
448
449 ret2 = ret; // copy startaddress of buffer
450 offset2 = offset;
451 size2 = size;
452
453 while (need_more == 1)
454 {
455 //dbg(0,"_X:of2="LONGLONG_FMT" split_size_in_bytes=%d\n", offset2, file->split_size_in_bytes);
456 start_splitter = (offset2 / file->split_size_in_bytes);
457 offset_split = offset2 - (file->split_size_in_bytes * start_splitter);
458 //dbg(0,"_X:sp=%d ofs="LONGLONG_FMT"\n", start_splitter, offset_split);
459
460 // open
461 if (file->current_splitter != start_splitter)
462 {
463 //dbg(0,"_X:curr=%d want=%d\n", file->current_splitter, start_splitter);
464 // close file
465 close(file->fd);
466 // open new file
467 int open_flags = O_LARGEFILE | O_BINARY;
468 open_flags |= O_RDONLY;
469 char *name;
470 if (start_splitter == 0)
471 {
472 name = g_strdup_printf("%s", file->name);
473 }
474 else
475 {
476 name = g_strdup_printf("%s.%d", file->name, start_splitter);
477 }
478 //dbg(0,"_X:open=%s\n", name);
479 file->fd = open(name, open_flags, 0666);
480 //dbg(0,"_X:isopen=%d\n", file->fd);
481 file->current_splitter = start_splitter; // set which file is currently open
482 g_free(name);
483 }
484
485 if (start_splitter == file->num_splits)
486 {
487 // in last splitter, so just read to the end
488 read_size = size2;
489 // read
490 lseek(file->fd, offset_split, SEEK_SET);
491 // ***** int result = lseek(file->fd, offset_split, SEEK_SET);
492 // dbg(0,"_1:seek="LONGLONG_FMT" read=%d result=%d\n", offset_split, read_size, result);
493 int did_read = read(file->fd, ret2, read_size);
494 if (did_read != read_size)
495 {
496 file_data_free(file, ret);
497 ret = NULL;
498 //dbg(0,"_leave:error 001 read:%d\n", did_read);
499 return ret;
500 }
501 //dbg(0,"_1:read ok:%d\n", did_read);
502 // +++
503 need_more = 0;
504 }
505 else if ((offset_split + size2) > file->split_size_in_bytes)
506 {
507 read_size = file->split_size_in_bytes - offset_split;
508 // read
509 lseek(file->fd, offset_split, SEEK_SET);
510 //dbg(0,"_2:seek="LONGLONG_FMT" read=%d\n", offset_split, read_size);
511 int did_read = read(file->fd, ret2, read_size);
512 if (did_read != read_size)
513 {
514 file_data_free(file, ret);
515 ret = NULL;
516 //dbg(0,"_leave:error 002 read:%d\n", did_read);
517 return ret;
518 }
519 //dbg(0,"_2:read ok:%d\n", did_read);
520 // +++
521 if (read_size < size2)
522 {
523 // set new values
524 offset2 = offset2 + read_size; // advance offset
525 ret2 = ret2 + read_size; // advance buffer
526 size2 = size2 - read_size; // calc new size
527 need_more = 1;
528 }
529 else
530 {
531 need_more = 0;
532 }
533 }
534 else
535 {
536 // the read size is inside 1 splitter, so just read it
537 read_size = size2;
538 // read
539 lseek(file->fd, offset_split, SEEK_SET);
540 //dbg(0,"_3:seek="LONGLONG_FMT" read=%d\n", offset_split, read_size);
541 int did_read = read(file->fd, ret2, read_size);
542 if (did_read != read_size)
543 {
544 file_data_free(file, ret);
545 ret = NULL;
546 //dbg(0,"_leave:error 003 read:%d\n", did_read);
547 return ret;
548 }
549 //dbg(0,"_3:read ok:%d\n", did_read);
550 // +++
551 need_more = 0;
552 }
553 }
554 /* ++++++++++++++++++++++++++++++++++++++++++ */
555 /* ++++++++++++++++++++++++++++++++++++++++++ */
556 }
557
558 //dbg(0,"_leave:normal\n");
373 return ret; 559 return ret;
374
375} 560}
376 561
377static void
378file_process_headers(struct file *file, unsigned char *headers) 562static void file_process_headers(struct file *file, unsigned char *headers)
379{ 563{
564 //dbg(0,"_enter %s\n", file->name);
380 char *tok; 565 char *tok;
381 char *cl; 566 char *cl;
382 if (file->headers) 567 if (file->headers)
568 {
383 g_hash_table_destroy(file->headers); 569 g_hash_table_destroy(file->headers);
570 }
384 file->headers=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); 571 file->headers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free_func, NULL);
385 while ((tok=strtok((char*)headers, "\r\n"))) { 572 while ((tok = strtok((char*) headers, "\r\n")))
573 {
386 char *sep; 574 char *sep;
387 tok=g_strdup(tok); 575 tok = g_strdup(tok);
388 sep=strchr(tok,':'); 576 sep = strchr(tok, ':');
389 if (!sep) 577 if (!sep)
578 {
390 sep=strchr(tok,'/'); 579 sep = strchr(tok, '/');
580 }
391 if (!sep) { 581 if (!sep)
582 {
392 g_free(tok); 583 g_free(tok);
393 continue; 584 continue;
394 } 585 }
395 *sep++='\0'; 586 *sep++ = '\0';
396 if (*sep == ' ') 587 if (*sep == ' ')
588 {
397 sep++; 589 sep++;
590 }
398 strtolower(tok, tok); 591 strtolower(tok, tok);
399 dbg(1,"header '%s'='%s'\n",tok,sep); 592 // dbg(1, "header '%s'='%s'\n", tok, sep);
400 g_hash_table_insert(file->headers, tok, sep); 593 g_hash_table_insert(file->headers, tok, sep);
401 headers=NULL; 594 headers = NULL;
402 } 595 }
403 cl=g_hash_table_lookup(file->headers, "content-length"); 596 cl = g_hash_table_lookup(file->headers, "content-length");
404 if (cl) 597 if (cl)
598 {
405#ifdef HAVE__ATOI64 599#ifdef HAVE__ATOI64
406 file->size=_atoi64(cl); 600 file->size=_atoi64(cl);
407#else 601#else
408 file->size=atoll(cl); 602 file->size = atoll(cl);
409#endif 603#endif
604 }
410} 605}
411 606
412static void
413file_shift_buffer(struct file *file, int amount) 607static void file_shift_buffer(struct file *file, int amount)
414{ 608{
609 //dbg(0,"_enter %s %d\n", file->name, amount);
415 memmove(file->buffer, file->buffer+amount, file->buffer_len-amount); 610 memmove(file->buffer, file->buffer + amount, file->buffer_len - amount);
416 file->buffer_len-=amount; 611 file->buffer_len -= amount;
417} 612}
418 613
419unsigned char * 614unsigned char *
420file_data_read_special(struct file *file, int size, int *size_ret) 615file_data_read_special(struct file *file, int size, int *size_ret)
421{ 616{
617 //dbg(0,"_enter %s %d\n", file->name, size);
422 unsigned char *ret,*hdr; 618 unsigned char *ret, *hdr;
423 int rets=0,rd; 619 int rets = 0, rd;
424 int buffer_size=8192; 620 int buffer_size = 8192;
425 int eof=0; 621 int eof = 0;
622
426 if (!file->special) 623 if (!file->special)
624 {
427 return NULL; 625 return NULL;
626 }
627
428 if (!file->buffer) 628 if (!file->buffer)
629 {
429 file->buffer=g_malloc(buffer_size); 630 file->buffer = g_malloc(buffer_size);
631 }
632
430 ret=g_malloc(size); 633 ret = g_malloc(size);
431 while ((size > 0 || file->requests) && (!eof || file->buffer_len)) { 634 while ((size > 0 || file->requests) && (!eof || file->buffer_len))
635 {
432 int toread=buffer_size-file->buffer_len; 636 int toread = buffer_size - file->buffer_len;
433 if (toread >= 4096 && !eof) { 637 if (toread >= 4096 && !eof)
638 {
434 if (!file->requests && toread > size) 639 if (!file->requests && toread > size)
435 toread=size; 640 toread = size;
436 rd=read(file->fd, file->buffer+file->buffer_len, toread); 641 rd = read(file->fd, file->buffer + file->buffer_len, toread);
437 if (rd > 0) { 642 if (rd > 0)
643 {
438 file->buffer_len+=rd; 644 file->buffer_len += rd;
645 }
439 } else 646 else
440 eof=1; 647 eof = 1;
441 } 648 }
442 if (file->requests) { 649 if (file->requests)
650 {
443 dbg(1,"checking header\n"); 651 // dbg(1, "checking header\n");
444 if ((hdr=file_http_header_end(file->buffer, file->buffer_len))) { 652 if ((hdr = file_http_header_end(file->buffer, file->buffer_len)))
653 {
445 hdr[-1]='\0'; 654 hdr[-1] = '\0';
446 dbg(1,"found %s (%d bytes)\n",file->buffer,sizeof(file->buffer)); 655 // dbg(1, "found %s (%d bytes)\n", file->buffer, sizeof(file->buffer));
447 file_process_headers(file, file->buffer); 656 file_process_headers(file, file->buffer);
448 file_shift_buffer(file, hdr-file->buffer); 657 file_shift_buffer(file, hdr - file->buffer);
449 file->requests--; 658 file->requests--;
450 if (file_http_header(file, "location")) 659 if (file_http_header(file, "location"))
660 {
451 break; 661 break;
452 } 662 }
453 } 663 }
664 }
454 if (!file->requests) { 665 if (!file->requests)
666 {
455 rd=file->buffer_len; 667 rd = file->buffer_len;
456 if (rd > size) 668 if (rd > size)
457 rd=size; 669 rd = size;
458 memcpy(ret+rets, file->buffer, rd); 670 memcpy(ret + rets, file->buffer, rd);
459 file_shift_buffer(file, rd); 671 file_shift_buffer(file, rd);
460 rets+=rd; 672 rets += rd;
461 size-=rd; 673 size -= rd;
462 }
463 } 674 }
675 }
464 *size_ret=rets; 676 *size_ret = rets;
465 return ret; 677 return ret;
466} 678}
467 679
468unsigned char * 680unsigned char *
469file_data_read_all(struct file *file) 681file_data_read_all(struct file *file)
470{ 682{
683 //dbg(0,"_enter %s\n", file->name);
471 return file_data_read(file, 0, file->size); 684 return file_data_read(file, 0, file->size);
472} 685}
473 686
474void
475file_data_flush(struct file *file, long long offset, int size) 687void file_data_flush(struct file *file, long long offset, int size)
476{ 688{
477 if (file_cache) { 689 //dbg(0,"_enter %s "LONGLONG_FMT" %d\n", file->name, offset, size);
478 struct file_cache_id id={offset,size,file->name_id,0};
479 cache_flush(file_cache,&id);
480 dbg(1,"Flushing "LONGLONG_FMT" %d bytes\n",offset,size);
481 }
482} 690}
483 691
484int
485file_data_write(struct file *file, long long offset, int size, unsigned char *data) 692int file_data_write(struct file *file, long long offset, int size, unsigned char *data)
486{ 693{
487 file_data_flush(file, offset, size); 694 //dbg(0,"_enter %s "LONGLONG_FMT" %d\n", file->name, offset, size);
488 lseek(file->fd, offset, SEEK_SET); 695 return 1;
489 if (write(file->fd, data, size) != size) 696}
697
698int file_get_contents(char *name, unsigned char **buffer, int *size)
699{
700 //dbg(0,"_enter %s\n", name);
701 struct file *file;
702 file = file_create(name, 0);
703 if (!file)
704 {
490 return 0; 705 return 0;
491 if (file->size < offset+size) 706 }
492 file->size=offset+size; 707 *size = file_size(file);
708 *buffer = file_data_read_all(file);
709 file_destroy(file);
493 return 1; 710 return 1;
494} 711}
495 712
496int
497file_get_contents(char *name, unsigned char **buffer, int *size)
498{
499 struct file *file;
500 file=file_create(name, 0);
501 if (!file)
502 return 0;
503 *size=file_size(file);
504 *buffer=file_data_read_all(file);
505 file_destroy(file);
506 return 1;
507}
508
509
510static int
511uncompress_int(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) 713static int uncompress_int(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
512{ 714{
715 //dbg(0,"_enter %d %d\n", sourceLen, destLen);
513 z_stream stream; 716 z_stream stream;
514 int err; 717 int err;
515 718
516 stream.next_in = (Bytef*)source; 719 stream.next_in = (Bytef*) source;
517 stream.avail_in = (uInt)sourceLen; 720 stream.avail_in = (uInt) sourceLen;
518 stream.next_out = dest; 721 stream.next_out = dest;
519 stream.avail_out = (uInt)*destLen; 722 stream.avail_out = (uInt) * destLen;
520 723
521 stream.zalloc = (alloc_func)0; 724 stream.zalloc = (alloc_func) 0;
522 stream.zfree = (free_func)0; 725 stream.zfree = (free_func) 0;
523 726
524 err = inflateInit2(&stream, -MAX_WBITS); 727 err = inflateInit2(&stream, -MAX_WBITS);
525 if (err != Z_OK) return err; 728 if (err != Z_OK)
729 {
730 return err;
731 }
526 732
527 err = inflate(&stream, Z_FINISH); 733 err = inflate(&stream, Z_FINISH);
528 if (err != Z_STREAM_END) { 734 if (err != Z_STREAM_END)
735 {
529 inflateEnd(&stream); 736 inflateEnd(&stream);
530 if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) 737 if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
738 {
531 return Z_DATA_ERROR; 739 return Z_DATA_ERROR;
740 }
532 return err; 741 return err;
533 } 742 }
743
534 *destLen = stream.total_out; 744 *destLen = stream.total_out;
535 745
536 err = inflateEnd(&stream); 746 err = inflateEnd(&stream);
537 return err; 747 return err;
538} 748}
539 749
540unsigned char * 750unsigned char *
541file_data_read_compressed(struct file *file, long long offset, int size, int size_uncomp) 751file_data_read_compressed(struct file *file, long long offset, int size, int size_uncomp)
542{ 752{
753 //dbg(0,"_enterPP %s "LONGLONG_FMT" %d\n", file->name, offset, size);
543 void *ret; 754 void *ret;
544 char *buffer = 0; 755 char *buffer = 0;
545 uLongf destLen=size_uncomp; 756 uLongf destLen = size_uncomp;
546 757
547 if (file_cache) { 758 if (file_cache)
759 {
760 //dbg(0,"_file_cache 2\n");
548 struct file_cache_id id={offset,size,file->name_id,1}; 761 struct file_cache_id id = { offset, size, file->name_id, 1 };
549 ret=cache_lookup(file_cache,&id); 762 ret = cache_lookup(file_cache, &id);
550 if (ret) 763 if (ret)
764 {
765 //dbg(0,"_file_cache found 2\n");
551 return ret; 766 return ret;
767 }
768 //dbg(0,"_file_cache create new 2\n");
552 ret=cache_insert_new(file_cache,&id,size_uncomp); 769 ret = cache_insert_new(file_cache, &id, size_uncomp);
770 }
553 } else 771 else
772 {
554 ret=g_malloc(size_uncomp); 773 ret = g_malloc(size_uncomp);
774 }
775
776 buffer = (char *) g_malloc(size);
777
778 if (file->num_splits == 0)
779 {
780 //dbg(0,"_num_splits=0\n");
555 lseek(file->fd, offset, SEEK_SET); 781 lseek(file->fd, offset, SEEK_SET);
556
557 buffer = (char *)g_malloc(size);
558 if (read(file->fd, buffer, size) != size) { 782 if (read(file->fd, buffer, size) != size)
559 g_free(ret); 783 {
560 ret=NULL;
561 } else {
562 if (uncompress_int(ret, &destLen, (Bytef *)buffer, size) != Z_OK) {
563 dbg(0,"uncompress failed\n");
564 g_free(ret); 784 g_free(ret);
565 ret=NULL; 785 ret = NULL;
786 }
787 else
788 {
789 if (uncompress_int(ret, &destLen, (Bytef *) buffer, size) != Z_OK)
790 {
791 //dbg(0, "_uncompress failed\n");
792 g_free(ret);
793 ret = NULL;
566 } 794 }
567 } 795 }
796 }
797 else
798 {
799 //dbg(0,"_num_splits=1\n");
800
801 /* ++++++++++++++++++++++++++++++++++++++++++ */
802 /* ++++++++++++++++++++++++++++++++++++++++++ */
803 int start_splitter;
804 long long offset_split;
805 long long offset2;
806 int size2;
807 int read_size;
808 int need_more = 1;
809 char *ret2 = 0; // just define any sort of pointer, maybe this can be done better??
810
811 ret2 = buffer; // copy startaddress of buffer
812 offset2 = offset;
813 size2 = size;
814
815 while (need_more == 1)
816 {
817 //dbg(0,"_X:of2="LONGLONG_FMT" split_size_in_bytes=%d\n", offset2, file->split_size_in_bytes);
818 start_splitter = (offset2 / file->split_size_in_bytes);
819 offset_split = offset2 - (file->split_size_in_bytes * start_splitter);
820 //dbg(0,"_X:sp=%d ofs="LONGLONG_FMT"\n", start_splitter, offset_split);
821
822 // open
823 if (file->current_splitter != start_splitter)
824 {
825 //dbg(0,"_X:curr=%d want=%d\n", file->current_splitter, start_splitter);
826 // close file
827 close(file->fd);
828 // open new file
829 int open_flags = O_LARGEFILE | O_BINARY;
830 open_flags |= O_RDONLY;
831 char *name;
832 if (start_splitter == 0)
833 {
834 name = g_strdup_printf("%s", file->name);
835 }
836 else
837 {
838 name = g_strdup_printf("%s.%d", file->name, start_splitter);
839 }
840 //dbg(0,"_X:open=%s\n", name);
841 file->fd = open(name, open_flags, 0666);
842 //dbg(0,"_X:isopen=%d\n", file->fd);
843 file->current_splitter = start_splitter; // set which file is currently open
844 g_free(name);
845 }
846
847 if (start_splitter == file->num_splits)
848 {
849 // in last splitter, so just read to the end
850 read_size = size2;
851 // read
852 lseek(file->fd, offset_split, SEEK_SET);
853 // *** int result = lseek(file->fd, offset_split, SEEK_SET);
854 //dbg(0,"_1:seek="LONGLONG_FMT" read=%d result=%d\n", offset_split, read_size, result);
855 int did_read = read(file->fd, ret2, read_size);
856 if (did_read != read_size)
857 {
858 g_free(buffer);
859 buffer = NULL;
860 g_free(ret);
861 ret = NULL;
862 //dbg(0,"_leave:error 001 read:%d\n", did_read);
863 return ret;
864 }
865 //dbg(0,"_1:read ok:%d\n", did_read);
866 // +++
867 need_more = 0;
868 }
869 else if ((offset_split + size2) > file->split_size_in_bytes)
870 {
871 read_size = file->split_size_in_bytes - offset_split;
872 // read
873 lseek(file->fd, offset_split, SEEK_SET);
874 //dbg(0,"_2:seek="LONGLONG_FMT" read=%d\n", offset_split, read_size);
875 int did_read = read(file->fd, ret2, read_size);
876 if (did_read != read_size)
877 {
878 g_free(buffer);
879 buffer = NULL;
880 g_free(ret);
881 ret = NULL;
882 //dbg(0,"_leave:error 002 read:%d\n", did_read);
883 return ret;
884 }
885 //dbg(0,"_2:read ok:%d\n", did_read);
886 // +++
887 if (read_size < size2)
888 {
889 // set new values
890 offset2 = offset2 + read_size; // advance offset
891 ret2 = ret2 + read_size; // advance buffer
892 size2 = size2 - read_size; // calc new size
893 need_more = 1;
894 }
895 else
896 {
897 need_more = 0;
898 }
899 }
900 else
901 {
902 // the read size is inside 1 splitter, so just read it
903 read_size = size2;
904 // read
905 lseek(file->fd, offset_split, SEEK_SET);
906 //dbg(0,"_3:seek="LONGLONG_FMT" read=%d\n", offset_split, read_size);
907 int did_read = read(file->fd, ret2, read_size);
908 if (did_read != read_size)
909 {
910 g_free(buffer);
911 buffer = NULL;
912 g_free(ret);
913 ret = NULL;
914 //dbg(0,"_leave:error 003 read:%d\n", did_read);
915 return ret;
916 }
917 //dbg(0,"_3:read ok:%d\n", did_read);
918 // +++
919 need_more = 0;
920 }
921 }
922 /* ++++++++++++++++++++++++++++++++++++++++++ */
923 /* ++++++++++++++++++++++++++++++++++++++++++ */
924
925 if (buffer != NULL)
926 {
927 if (uncompress_int(ret, &destLen, (Bytef *) buffer, size) != Z_OK)
928 {
929 //dbg(0, "_uncompress failed\n");
930 g_free(ret);
931 ret = NULL;
932 }
933 }
934
935 }
936
568 g_free(buffer); 937 g_free(buffer);
569 938
570 return ret; 939 return ret;
571} 940}
572 941
573unsigned char * 942unsigned char *
574file_data_read_encrypted(struct file *file, long long offset, int size, int size_uncomp, int compressed, char *passwd) 943file_data_read_encrypted(struct file *file, long long offset, int size, int size_uncomp, int compressed, char *passwd)
575{ 944{
945 //dbg(0,"_enter %s "LONGLONG_FMT" %d\n", file->name, offset, size);
576#ifdef HAVE_LIBCRYPTO 946#ifdef HAVE_LIBCRYPTO
577 void *ret; 947 void *ret;
578 unsigned char *buffer = 0; 948 unsigned char *buffer = 0;
579 uLongf destLen=size_uncomp; 949 uLongf destLen=size_uncomp;
580 950
581 if (file_cache) { 951 if (file_cache)
582 struct file_cache_id id={offset,size,file->name_id,1}; 952 {
953 //dbg(0,"_file_cache 3\n");
954 struct file_cache_id id =
955 { offset,size,file->name_id,1};
583 ret=cache_lookup(file_cache,&id); 956 ret=cache_lookup(file_cache,&id);
584 if (ret) 957 if (ret)
958 {
959 //dbg(0,"_file_cache found 3\n");
585 return ret; 960 return ret;
961 }
962 //dbg(0,"_file_cache create new 3\n");
586 ret=cache_insert_new(file_cache,&id,size_uncomp); 963 ret=cache_insert_new(file_cache,&id,size_uncomp);
964 }
587 } else 965 else
966 {
588 ret=g_malloc(size_uncomp); 967 ret=g_malloc(size_uncomp);
968 }
589 lseek(file->fd, offset, SEEK_SET); 969 lseek(file->fd, offset, SEEK_SET);
590 970
591 buffer = (unsigned char *)g_malloc(size); 971 buffer = (unsigned char *)g_malloc(size);
592 if (read(file->fd, buffer, size) != size) { 972 if (read(file->fd, buffer, size) != size)
973 {
593 g_free(ret); 974 g_free(ret);
594 ret=NULL; 975 ret=NULL;
595 } else { 976 }
977 else
978 {
596 unsigned char key[34], salt[8], verify[2], counter[16], xor[16], mac[10], *datap; 979 unsigned char key[34], salt[8], verify[2], counter[16], xor[16], mac[10], *datap;
597 int overhead=sizeof(salt)+sizeof(verify)+sizeof(mac); 980 int overhead=sizeof(salt)+sizeof(verify)+sizeof(mac);
598 int esize=size-overhead; 981 int esize=size-overhead;
599 PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), (unsigned char *)buffer, 8, 1000, 34, key); 982 PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), (unsigned char *)buffer, 8, 1000, 34, key);
600 if (key[32] == buffer[8] && key[33] == buffer[9] && esize >= 0) { 983 if (key[32] == buffer[8] && key[33] == buffer[9] && esize >= 0)
984 {
601 AES_KEY aeskey; 985 AES_KEY aeskey;
602 AES_set_encrypt_key(key, 128, &aeskey); 986 AES_set_encrypt_key(key, 128, &aeskey);
603 datap=buffer+sizeof(salt)+sizeof(verify); 987 datap=buffer+sizeof(salt)+sizeof(verify);
604 memset(counter, 0, sizeof(counter)); 988 memset(counter, 0, sizeof(counter));
605 while (esize > 0) { 989 while (esize > 0)
990 {
606 int i,curr_size,idx=0; 991 int i,curr_size,idx=0;
607 do { 992 do
993 {
608 counter[idx]++; 994 counter[idx]++;
609 } while (!counter[idx++]); 995 }while (!counter[idx++]);
996
610 AES_encrypt(counter, xor, &aeskey); 997 AES_encrypt(counter, xor, &aeskey);
611 curr_size=esize; 998 curr_size=esize;
612 if (curr_size > sizeof(xor)) 999 if (curr_size > sizeof(xor))
613 curr_size=sizeof(xor); 1000 curr_size=sizeof(xor);
614 for (i = 0 ; i < curr_size ; i++) 1001 for (i = 0; i < curr_size; i++)
615 *datap++^=xor[i]; 1002 *datap++^=xor[i];
616 esize-=curr_size; 1003 esize-=curr_size;
617 } 1004 }
618 size-=overhead; 1005 size-=overhead;
619 datap=buffer+sizeof(salt)+sizeof(verify); 1006 datap=buffer+sizeof(salt)+sizeof(verify);
620 if (compressed) { 1007 if (compressed)
1008 {
621 if (uncompress_int(ret, &destLen, (Bytef *)datap, size) != Z_OK) { 1009 if (uncompress_int(ret, &destLen, (Bytef *)datap, size) != Z_OK)
1010 {
622 dbg(0,"uncompress failed\n"); 1011 //dbg(0,"_uncompress failed\n");
623 g_free(ret); 1012 g_free(ret);
624 ret=NULL; 1013 ret=NULL;
625 } 1014 }
1015 }
626 } else { 1016 else
1017 {
627 if (size == destLen) 1018 if (size == destLen)
628 memcpy(ret, buffer, destLen); 1019 memcpy(ret, buffer, destLen);
629 else { 1020 else
1021 {
630 dbg(0,"memcpy failed\n"); 1022 //dbg(0,"_memcpy failed\n");
631 g_free(ret); 1023 g_free(ret);
632 ret=NULL; 1024 ret=NULL;
633 } 1025 }
634 } 1026 }
1027 }
635 } else { 1028 else
1029 {
636 g_free(ret); 1030 g_free(ret);
637 ret=NULL; 1031 ret=NULL;
638 } 1032 }
639 } 1033 }
640 g_free(buffer); 1034 g_free(buffer);
643#else 1037#else
644 return NULL; 1038 return NULL;
645#endif 1039#endif
646} 1040}
647 1041
648void
649file_data_free(struct file *file, unsigned char *data) 1042void file_data_free(struct file *file, unsigned char *data)
650{ 1043{
1044 //dbg(0,"_enter %s\n", file->name);
651 if (file->begin) { 1045 if (file->begin)
1046 {
652 if (data == file->begin) 1047 if (data == file->begin)
653 return; 1048 return;
654 if (data >= file->begin && data < file->end) 1049 if (data >= file->begin && data < file->end)
655 return; 1050 return;
656 } 1051 }
1052
657 if (file->cache && data) { 1053 if (file->cache && data)
1054 {
1055 // print statistics to DEBUG OUT
1056 //if (file_cache)
1057 //{
1058 //cache_stats(file_cache);
1059 //}
1060 // print statistics to DEBUG OUT
658 cache_entry_destroy(file_cache, data); 1061 cache_entry_destroy(file_cache, data);
1062 }
659 } else 1063 else
1064 {
660 g_free(data); 1065 g_free(data);
1066 }
1067 //dbg(0,"_leave\n");
661} 1068}
662 1069
663void
664file_data_remove(struct file *file, unsigned char *data) 1070void file_data_remove(struct file *file, unsigned char *data)
665{ 1071{
1072 //dbg(0,"_enter %s\n", file->name);
666 if (file->begin) { 1073 if (file->begin)
1074 {
667 if (data == file->begin) 1075 if (data == file->begin)
1076 {
668 return; 1077 return;
1078 }
669 if (data >= file->begin && data < file->end) 1079 if (data >= file->begin && data < file->end)
1080 {
670 return; 1081 return;
671 } 1082 }
1083 }
672 if (file->cache && data) { 1084 if (file->cache && data)
1085 {
673 cache_flush_data(file_cache, data); 1086 cache_flush_data(file_cache, data);
1087 }
674 } else 1088 else
1089 {
675 g_free(data); 1090 g_free(data);
1091 }
676} 1092}
677 1093
678int
679file_exists(char const *name) 1094int file_exists(char const *name)
680{ 1095{
1096 //dbg(0,"_enter %s\n", name);
681 struct stat buf; 1097 struct stat buf;
682 if (! stat(name, &buf)) 1098 if (!stat(name, &buf))
1099 {
683 return 1; 1100 return 1;
1101 }
684 return 0; 1102 return 0;
685} 1103}
686 1104
687void
688file_remap_readonly(struct file *f) 1105void file_remap_readonly(struct file *f)
689{ 1106{
1107 //dbg(0,"_enter %s\n", f->name);
690#if defined(_WIN32) || defined(__CEGCC__) 1108#if defined(_WIN32) || defined(__CEGCC__)
691#else 1109#else
692 void *begin; 1110 void *begin;
693 munmap(f->begin, f->size); 1111 munmap(f->begin, f->size);
694 begin=mmap(f->begin, f->size, PROT_READ, MAP_PRIVATE, f->fd, 0); 1112 begin = mmap(f->begin, f->size, PROT_READ, MAP_PRIVATE, f->fd, 0);
695 if (f->begin != begin) 1113 if (f->begin != begin)
1114 {
696 printf("remap failed\n"); 1115 printf("remap failed\n");
1116 }
697#endif 1117#endif
698} 1118}
699 1119
700void
701file_unmap(struct file *f) 1120void file_unmap(struct file *f)
702{ 1121{
1122 //dbg(0,"_enter %s\n", f->name);
703#if defined(_WIN32) || defined(__CEGCC__) 1123#if defined(_WIN32) || defined(__CEGCC__)
704 mmap_unmap_win32( f->begin, f->map_handle , f->map_file ); 1124 mmap_unmap_win32( f->begin, f->map_handle , f->map_file );
705#else 1125#else
706 munmap(f->begin, f->size); 1126 munmap(f->begin, f->size);
707#endif 1127#endif
708} 1128}
709 1129
710#ifndef _MSC_VER 1130#ifndef _MSC_VER
711void * 1131void *
712file_opendir(char *dir) 1132file_opendir(char *dir)
713{ 1133{
1134 //dbg(0,"_enter %s\n", dir);
714 return opendir(dir); 1135 return opendir(dir);
715} 1136}
716#else 1137#else
717void * 1138void *
718file_opendir(char *dir) 1139file_opendir(char *dir)
719{ 1140{
1141 //dbg(0,"_enter %s\n", dir);
720 WIN32_FIND_DATAA FindFileData; 1142 WIN32_FIND_DATAA FindFileData;
721 HANDLE hFind = INVALID_HANDLE_VALUE; 1143 HANDLE hFind = INVALID_HANDLE_VALUE;
722#undef UNICODE // we need FindFirstFileA() which takes an 8-bit c-string 1144#undef UNICODE // we need FindFirstFileA() which takes an 8-bit c-string
723 char* fname=g_alloca(sizeof(char)*(strlen(dir)+4)); 1145 char* fname=g_alloca(sizeof(char)*(strlen(dir)+4));
724 sprintf(fname,"%s\\*",dir); 1146 sprintf(fname,"%s\\*",dir);
729 1151
730#ifndef _MSC_VER 1152#ifndef _MSC_VER
731char * 1153char *
732file_readdir(void *hnd) 1154file_readdir(void *hnd)
733{ 1155{
1156 //dbg(0,"_enter\n");
734 struct dirent *ent; 1157 struct dirent *ent;
735 1158
736 ent=readdir(hnd); 1159 ent = readdir(hnd);
737 if (! ent) 1160 if (!ent)
738 return NULL; 1161 return NULL;
739 return ent->d_name; 1162 return ent->d_name;
740} 1163}
741#else 1164#else
742char * 1165char *
743file_readdir(void *hnd) 1166file_readdir(void *hnd)
744{ 1167{
1168 //dbg(0,"_enter\n");
745 WIN32_FIND_DATA FindFileData; 1169 WIN32_FIND_DATA FindFileData;
746 1170
747 if (FindNextFile(hnd, &FindFileData) ) { 1171 if (FindNextFile(hnd, &FindFileData) )
1172 {
748 return FindFileData.cFileName; 1173 return FindFileData.cFileName;
749 } else { 1174 }
1175 else
1176 {
750 return NULL; 1177 return NULL;
751 } 1178 }
752} 1179}
753#endif /* _MSC_VER */ 1180#endif /* _MSC_VER */
754 1181
755#ifndef _MSC_VER 1182#ifndef _MSC_VER
756void
757file_closedir(void *hnd) 1183void file_closedir(void *hnd)
758{ 1184{
1185 //dbg(0,"_enter\n");
759 closedir(hnd); 1186 closedir(hnd);
760} 1187}
761#else 1188#else
762void 1189void
763file_closedir(void *hnd) 1190file_closedir(void *hnd)
764{ 1191{
1192 //dbg(0,"_enter\n");
765 FindClose(hnd); 1193 FindClose(hnd);
766} 1194}
767#endif /* _MSC_VER */ 1195#endif /* _MSC_VER */
768 1196
769struct file * 1197struct file *
770file_create_caseinsensitive(char *name, struct attr **options) 1198file_create_caseinsensitive(char *name, struct attr **options)
771{ 1199{
1200 //dbg(0,"_enter %s\n", name);
772 char *dirname=g_alloca(sizeof(char)*(strlen(name)+1)); 1201 char *dirname = g_alloca(sizeof(char) * (strlen(name) + 1));
773 char *filename; 1202 char *filename;
774 char *p; 1203 char *p;
775 void *d; 1204 void *d;
776 struct file *ret; 1205 struct file *ret;
777 1206
778 ret=file_create(name, options); 1207 ret = file_create(name, options);
779 if (ret) 1208 if (ret)
1209 {
780 return ret; 1210 return ret;
1211 }
781 1212
782 strcpy(dirname, name); 1213 strcpy(dirname, name);
783 p=dirname+strlen(name); 1214 p = dirname + strlen(name);
784 while (p > dirname) { 1215 while (p > dirname)
1216 {
785 if (*p == '/') 1217 if (*p == '/')
786 break; 1218 break;
787 p--; 1219 p--;
788 } 1220 }
789 *p=0; 1221 *p = 0;
790 d=file_opendir(dirname); 1222 d = file_opendir(dirname);
791 if (d) { 1223 if (d)
1224 {
792 *p++='/'; 1225 *p++ = '/';
793 while ((filename=file_readdir(d))) { 1226 while ((filename = file_readdir(d)))
1227 {
794 if (!g_strcasecmp(filename, p)) { 1228 if (!g_strcasecmp(filename, p))
1229 {
795 strcpy(p, filename); 1230 strcpy(p, filename);
796 ret=file_create(dirname, options); 1231 ret = file_create(dirname, options);
797 if (ret) 1232 if (ret)
798 break; 1233 break;
799 } 1234 }
800 } 1235 }
801 file_closedir(d); 1236 file_closedir(d);
802 } 1237 }
803 return ret; 1238 return ret;
804} 1239}
805 1240
806void
807file_destroy(struct file *f) 1241void file_destroy(struct file *f)
808{ 1242{
1243 dbg(0, "_enter %s\n", f->name);
1244
1245 // print statistics to DEBUG OUT
1246 //if (file_cache)
1247 //{
1248 //cache_stats(file_cache);
1249 //}
1250 // print statistics to DEBUG OUT
1251
809 if (f->headers) 1252 if (f->headers)
1253 {
810 g_hash_table_destroy(f->headers); 1254 g_hash_table_destroy(f->headers);
1255 }
811 switch (f->special) { 1256 switch (f->special)
1257 {
812 case 0: 1258 case 0:
813 case 1: 1259 case 1:
814 close(f->fd); 1260 close(f->fd);
815 break; 1261 break;
816 } 1262 }
817 1263
818 if ( f->begin != NULL ) 1264 if (f->begin != NULL)
819 { 1265 {
820 file_unmap( f ); 1266 file_unmap(f);
821 } 1267 }
822 1268
823 g_free(f->buffer); 1269 g_free(f->buffer);
824 g_free(f->name); 1270 g_free(f->name);
825 g_free(f); 1271 g_free(f);
826} 1272}
827 1273
828struct file_wordexp { 1274struct file_wordexp
1275{
829 int err; 1276 int err;
1277 char *pattern;
830 wordexp_t we; 1278 wordexp_t we;
831}; 1279};
832 1280
833struct file_wordexp * 1281struct file_wordexp *
834file_wordexp_new(const char *pattern) 1282file_wordexp_new(const char *pattern)
835{ 1283{
1284 dbg(0, "_enter\n");
836 struct file_wordexp *ret=g_new0(struct file_wordexp, 1); 1285 struct file_wordexp *ret=g_new0(struct file_wordexp, 1);
1286 dbg(0, "fexp 001 p=%p\n", ret);
837 1287
1288 ret->pattern = g_strdup(pattern);
1289 dbg(0, "fexp 002 p=%p p2=%p, str1=%s, str2=%s\n", ret->pattern, pattern, ret->pattern, pattern);
838 ret->err=wordexp(pattern, &ret->we, 0); 1290 ret->err = wordexp(pattern, &ret->we, 0);
1291 dbg(0, "fexp 003\n");
839 if (ret->err) 1292 if (ret->err)
1293 {
840 dbg(0,"wordexp('%s') returned %d\n", pattern, ret->err); 1294 // dbg(0, "wordexp('%s') returned %d\n", pattern, ret->err);
1295 }
1296 dbg(0, "leave\n");
841 return ret; 1297 return ret;
842} 1298}
843 1299
844int
845file_wordexp_get_count(struct file_wordexp *wexp) 1300int file_wordexp_get_count(struct file_wordexp *wexp)
846{ 1301{
1302 //dbg(0,"_enter\n");
1303
1304 if (wexp->err)
1305 {
1306 return 1;
1307 }
847 return wexp->we.we_wordc; 1308 return wexp->we.we_wordc;
848} 1309}
849 1310
850char ** 1311char **
851file_wordexp_get_array(struct file_wordexp *wexp) 1312file_wordexp_get_array(struct file_wordexp *wexp)
852{ 1313{
1314 //dbg(0,"_enter\n");
1315
1316 if (wexp->err)
1317 {
1318 return &wexp->pattern;
1319 }
853 return wexp->we.we_wordv; 1320 return wexp->we.we_wordv;
854} 1321}
855 1322
856void
857file_wordexp_destroy(struct file_wordexp *wexp) 1323void file_wordexp_destroy(struct file_wordexp *wexp)
858{ 1324{
1325 //dbg(0,"_enter\n");
859 if (! wexp->err) 1326 if (!wexp->err)
1327 {
860 wordfree(&wexp->we); 1328 wordfree(&wexp->we);
1329 }
1330 g_free(wexp->pattern);
861 g_free(wexp); 1331 g_free(wexp);
862} 1332}
863 1333
864
865int
866file_get_param(struct file *file, struct param_list *param, int count) 1334int file_get_param(struct file *file, struct param_list *param, int count)
867{ 1335{
1336 //dbg(0,"_enter %s\n", file->name);
868 int i=count; 1337 int i = count;
869 param_add_string("Filename", file->name, &param, &count); 1338 param_add_string("Filename", file->name, &param, &count);
870 param_add_hex("Size", file->size, &param, &count); 1339 param_add_hex("Size", file->size, &param, &count);
871 return i-count; 1340 return i - count;
872} 1341}
873 1342
874int
875file_version(struct file *file, int mode) 1343int file_version(struct file *file, int mode)
876{ 1344{
1345 //dbg(0,"_enter %s\n", file->name);
877#ifndef HAVE_API_WIN32_BASE 1346#ifndef HAVE_API_WIN32_BASE
878 struct stat st; 1347 struct stat st;
879 int error; 1348 int error;
880 if (mode == 3) { 1349 if (mode == 3)
1350 {
881 long long size=lseek(file->fd, 0, SEEK_END); 1351 long long size = lseek(file->fd, 0, SEEK_END);
882 if (file->begin && file->begin+size > file->mmap_end) { 1352 if (file->begin && file->begin + size > file->mmap_end)
1353 {
883 file->version++; 1354 file->version++;
1355 }
884 } else { 1356 else
1357 {
885 file->size=size; 1358 file->size = size;
886 if (file->begin) 1359 if (file->begin)
1360 {
887 file->end=file->begin+file->size; 1361 file->end = file->begin + file->size;
888 } 1362 }
889 } else { 1363 }
1364 }
1365 else
1366 {
890 if (mode == 2) 1367 if (mode == 2)
1368 {
891 error=stat(file->name, &st); 1369 error = stat(file->name, &st);
1370 }
892 else 1371 else
1372 {
893 error=fstat(file->fd, &st); 1373 error = fstat(file->fd, &st);
1374 }
894 if (error || !file->version || file->mtime != st.st_mtime || file->ctime != st.st_ctime) { 1375 if (error || !file->version || file->mtime != st.st_mtime || file->ctime != st.st_ctime)
1376 {
895 file->mtime=st.st_mtime; 1377 file->mtime = st.st_mtime;
896 file->ctime=st.st_ctime; 1378 file->ctime = st.st_ctime;
897 file->version++; 1379 file->version++;
898 dbg(1,"%s now version %d\n", file->name, file->version); 1380 // dbg(1, "%s now version %d\n", file->name, file->version);
899 } 1381 }
900 } 1382 }
901 return file->version; 1383 return file->version;
902#else 1384#else
903 return 0; 1385 return 0;
905} 1387}
906 1388
907void * 1389void *
908file_get_os_handle(struct file *file) 1390file_get_os_handle(struct file *file)
909{ 1391{
1392 //dbg(0,"_enter %s\n", file->name);
910 return GINT_TO_POINTER(file->fd); 1393 return GINT_TO_POINTER(file->fd);
911} 1394}
912 1395
913void 1396void file_cache_init(void)
914file_init(void)
915{ 1397{
916#ifdef CACHE_SIZE 1398#ifdef CACHE_SIZE
1399 dbg(0,"enter\n");
1400 dbg(0,"_have 2 CACHE_SIZE=%d\n", CACHE_SIZE);
1401 dbg(0,"_have 2 cache_size_file=%d\n", cache_size_file);
1402 if (file_cache == NULL)
1403 {
1404 file_cache=cache_new(sizeof(struct file_cache_id), cache_size_file);
1405 dbg(0,"_file_cache created!\n");
1406 }
1407 dbg(0,"leave\n");
1408#endif
1409}
1410
1411void file_init(void)
1412{
1413#ifdef CACHE_SIZE
1414 dbg(0,"enter\n");
1415 //**// dbg(0,"_have 1 CACHE_SIZE=%d\n", CACHE_SIZE);
1416 //**// dbg(0,"_have 1 cache_size_file=%d\n", cache_size_file);
917 file_name_hash=g_hash_table_new(g_str_hash, g_str_equal); 1417 file_name_hash=g_hash_table_new(g_str_hash, g_str_equal);
918 file_cache=cache_new(sizeof(struct file_cache_id), CACHE_SIZE); 1418 // file_cache=cache_new(sizeof(struct file_cache_id), cache_size_file);
1419 file_cache = NULL; // set later!!
1420 dbg(0,"leave\n");
919#endif 1421#endif
920} 1422}
921 1423
922
923
924void file_cache_init(void)
925{
926}
927

Legend:
Removed from v.49  
changed lines
  Added in v.50

   
Visit the ZANavi Wiki