/* * The QUAFFLER library * Copyright (c) 2006 Clifford Wolf * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include "quaffler.h" int qfl_qmdf_generate(const char *filename, const char *trackeraddr, const char *attributes) { QFL_OS_FILEHDL_TYPE file_in; QFL_OS_FILEHDL_TYPE file_out; if (qfl_os_open_ro(&file_in, filename)) return -1; int filename_out_len = strlen(filename) + 6; char filename_out[filename_out_len]; snprintf(filename_out, filename_out_len, "%s.qmdf", filename); if (qfl_os_open(&file_out, filename_out)) { qfl_os_close(&file_in); return -1; } qfl_os_truncate(&file_out); unsigned long long file_size = qfl_os_getsize(&file_in); char frag_scheme = 'A'; int block_size = 1*1024*1024; if (file_size > 64*1024*1024*1024ll) { frag_scheme = 'B'; block_size = 2*1024*1024; } if (file_size > 128*1024*1024*1024ll) { frag_scheme = 'C'; block_size = 4*1024*1024; } if (file_size > 256*1024*1024*1024ll) { frag_scheme = 'D'; block_size = 8*1024*1024; } if (file_size > 512*1024*1024*1024ll) { frag_scheme = 'E'; block_size = 16*1024*1024; } int total_blocks = file_size / block_size; if (file_size % block_size) total_blocks++; int chunks_per_block = block_size / (64*1024); { unsigned int half_file_size; half_file_size = htonl((file_size & 0xffffffff00000000ll) >> 32); qfl_os_write(&file_out, 52, &half_file_size, 4); half_file_size = htonl((file_size & 0x00000000ffffffffll) >> 0); qfl_os_write(&file_out, 56, &half_file_size, 4); } qfl_os_write(&file_out, 60, &frag_scheme, 1); { unsigned char tracker_info[256]; int i; for (i=0; i<256; i++) tracker_info[i] = 0x00; if (trackeraddr) strcpy((char*)tracker_info, trackeraddr); qfl_os_write(&file_out, 61, tracker_info, 256); } { unsigned char status = 0007; qfl_os_write(&file_out, 317, &status, 1); } long long offset_idxarray; long long offset_blockdata; { int bitmap_size = total_blocks / 8; if (total_blocks % 8) bitmap_size++; unsigned char bitmap[bitmap_size]; int i; for (i=0; i