function Add_File_Header($bin, $file, $status, $meth, $volatile = true, $crc = 0, $zlen = 0, $len = 0, $extra = array())
 {
     // Strip leading slashes from file name (fixes bug in windows archive viewer)
     $file = preg_replace('/^[\\/\\\\]+/', '', $file);
     if ($bin === false) {
         $bin = '';
     } else {
         if ($bin === WPONLINEBACKUP_BIN_DATABASE) {
             $bin = _x('Database', 'Full backup folder name in downloadable ZIP file', 'wponlinebackup') . '/';
             if (!$this->bin_database) {
                 $binstatus = array('mod_time' => time());
                 // Add the Database folder
                 if (true !== $this->Add_File_Header($bin, '', $binstatus, 0x0, false)) {
                     return $ret;
                 }
                 $this->bin_database = true;
             }
         } else {
             if ($bin === WPONLINEBACKUP_BIN_FILESYSTEM) {
                 $bin = _x('FileSystem', 'Full backup folder name in downloadable ZIP file', 'wponlinebackup') . '/';
                 if (!$this->bin_filesystem) {
                     $binstatus = array('mod_time' => time());
                     // Add the Database folder
                     if (true !== $this->Add_File_Header($bin, '', $binstatus, 0x0, false)) {
                         return $ret;
                     }
                     $this->bin_filesystem = true;
                 }
             }
         }
     }
     $file = $bin . $file;
     // Create dos timestamp
     $dts = WPOnlineBackup_Functions::DOS_Time($status['mod_time']);
     // Why don't we use general purpose bit flag bit 3 to make a streamable ZIP file?
     // So that we can write CRC/ZLEN/LEN after the file data and not need to seek back and rewrite?
     // Because Mac OS X Archive Utility doesn't work with them :-(
     // Run this and try it: zip -X - smallfile.txt - | cat > test.zip
     // Give it lots of data
     // Then CTRL+D to end STIN and try to extract the test.zip - you'll get an error
     // Using Windows or unzip command line will work
     $genpurp = 0x0;
     // Calculate extra data
     $extraloc = '';
     $extracdr = '';
     if (in_array('rjct', $extra)) {
         // The rejection header we will hide inside an extra field
         $rjct = $this->disk->Get_Header();
         // The extra field
         $fields = array(array('v', 0x4400), array('v', strlen($rjct)));
         // Pack extra field and rejection header
         $extraloc .= WPOnlineBackup_Functions::Pack_Fields($fields) . $rjct;
     }
     if ($this->config['backwards_compat']) {
         // Store the UTF-8 filename in an extra field
         $fields = array(array('v', 0x7075), array('v', 5 + strlen($file)), array('C', 1), array('V', crc32($file)));
         $fields = WPOnlineBackup_Functions::Pack_Fields($fields) . $file;
         $extraloc .= $fields;
         $extracdr .= $fields;
         // ASCII filename
         // We will assume valid UTF-8 was passed in, which currently it should be
         // It would be a bug if we didn't - UTF8_To_ASCII only works properly with valid UTF-8 since it only modifyes UTF-8 chars
         $fileloc = WPOnlineBackup_Functions::UTF8_To_ASCII($file);
     } else {
         // Just store UTF-8 in the local header, but user gen purpose bit flag 11
         $fileloc = $file;
         $genpurp |= 0x800;
     }
     $elenloc = strlen($extraloc);
     $elencdr = strlen($extracdr);
     $nlen = strlen($fileloc);
     // Build file header
     $fields = array(array('V', 0x4034b50), array('C', 20), array('C', 0), array('v', $genpurp), array('v', $meth), array('V', $dts), array('V', $crc), array('V', $zlen), array('V', $len), array('v', $nlen), array('v', $elenloc));
     // Pack fields and calculate "total" length
     $fields = WPOnlineBackup_Functions::Pack_Fields($fields) . $fileloc . $extraloc;
     $record_len = strlen($fields) + $zlen;
     // Write the header and filename
     if ($volatile) {
         // Write volatile so we can seek back and modify the CRC/ZLEN/LEN
         if (true !== ($ret = $this->writer->Start_Volatile())) {
             return $ret;
         }
         if (!is_int($pos = $this->writer->Volatile_Write($fields))) {
             return $pos;
         }
     } else {
         // No need for pos, we don't need to seek back
         $pos = false;
         if (true !== ($ret = $this->writer->Write($fields))) {
             return $ret;
         }
     }
     // Add to central directory record and increment offset
     $record = compact('pos', 'fileloc', 'nlen', 'genpurp', 'meth', 'dts', 'crc', 'zlen', 'len', 'elencdr', 'extracdr');
     // Store offset of this entry
     $record['ofs'] = $this->ofs;
     $this->file_count++;
     // If we have a CDR already stored, write it to the CDR buffer, creating one if necessary
     if ($this->last_cdr !== false) {
         if ($this->cdr === false) {
             if (($ret = $this->writer->Branch($this->cdr)) !== true) {
                 return $ret;
             }
             if (($ret = $this->cdr->Open('cdrbuffer')) !== true) {
                 return $ret;
             }
         }
         if (($ret = $this->Add_CDR_File($this->cdr, $this->last_cdr)) !== true) {
             return $ret;
         }
     }
     // Store this CDR - if we only end up with a single CDR, we don't bother creating the CDR buffer then
     $this->last_cdr = $record;
     // Increase offset to be used for next entry
     $this->ofs += $record_len;
     return true;
 }