int __stdcall CompressFolder(const TCHAR* path, const TCHAR* zip_filename) { int i; int status = 1; int index = 0; TCHAR* list[0xefff]; SearchFile(path, _T("*.*"), list, &index); if (index > 0) status = zipfile(zip_filename, index, list, path); //release the memory for (i = 0; i < index; ++i) free(list[i]); return (status == 0); }
int __stdcall CompressFile(const TCHAR* filename, const TCHAR* zip_filename) { const TCHAR* filenames[] = {filename}; TCHAR path[MAX_PATH]; size_t len = 0; size_t i = 0; _sntprintf(path, MAX_PATH, _T("%s\0"), filename); for (i = _tcslen(path) - 1; i >= 0; --i) { if (path[i] == _T('\\') || path[i] == _T('/')) { path[i] = 0; break; } } zipfile(zip_filename, 1, filenames, path); return 1; }
/* Check if file meets the find's requirements*/ void KQuery::processQuery( KFileItem* file) { QRegExp *filename_match; if ( file->name() == "." || file->name() == ".." ) return; bool matched=false; for ( filename_match = m_regexps.first(); !matched && filename_match; filename_match = m_regexps.next() ) { matched |= filename_match->isEmpty() || (filename_match->exactMatch( file->url().fileName( true ) ) ); } if (!matched) return; switch( m_sizemode ) { case 1: // "at least" if ( file->size() < m_sizeboundary1 ) return; break; case 2: // "at most" if ( file->size() > m_sizeboundary1 ) return; break; case 3: // "equal" if ( file->size() != m_sizeboundary1 ) return; break; case 4: // "between" if ( (file->size() < m_sizeboundary1) || (file->size() > m_sizeboundary2) ) return; break; case 0: // "none" -> fall to default default: break; } // make sure it's in the correct date range // what about 0 times? if ( m_timeFrom && m_timeFrom > file->time(KIO::UDS_MODIFICATION_TIME) ) return; if ( m_timeTo && m_timeTo < file->time(KIO::UDS_MODIFICATION_TIME) ) return; // username / group match if ( (!m_username.isEmpty()) && (m_username != file->user()) ) return; if ( (!m_groupname.isEmpty()) && (m_groupname != file->group()) ) return; // file type switch (m_filetype) { case 0: break; case 1: // plain file if ( !S_ISREG( file->mode() ) ) return; break; case 2: if ( !file->isDir() ) return; break; case 3: if ( !file->isLink() ) return; break; case 4: if ( !S_ISCHR ( file->mode() ) && !S_ISBLK ( file->mode() ) && !S_ISFIFO( file->mode() ) && !S_ISSOCK( file->mode() ) ) return; break; case 5: // binary if ( (file->permissions() & 0111) != 0111 || file->isDir() ) return; break; case 6: // suid if ( (file->permissions() & 04000) != 04000 ) // fixme return; break; default: if (!m_mimetype.isEmpty() && !m_mimetype.contains(file->mimetype())) return; } // match datas in metainfo... if ((!m_metainfo.isEmpty()) && (!m_metainfokey.isEmpty())) { bool foundmeta=false; QString filename = file->url().path(); if(filename.startsWith("/dev/")) return; KFileMetaInfo metadatas(filename); KFileMetaInfoItem metaitem; QStringList metakeys; QString strmetakeycontent; if(metadatas.isEmpty()) return; metakeys=metadatas.supportedKeys(); for ( QStringList::Iterator it = metakeys.begin(); it != metakeys.end(); ++it ) { if (!metaKeyRx->exactMatch(*it)) continue; metaitem=metadatas.item(*it); strmetakeycontent=metaitem.string(); if(strmetakeycontent.find(m_metainfo)!=-1) { foundmeta=true; break; } } if (!foundmeta) return; } // match contents... QString matchingLine; if (!m_context.isEmpty()) { if( !m_search_binary && ignore_mimetypes.findIndex(file->mimetype()) != -1 ) { kdDebug() << "ignoring, mime type is in exclusion list: " << file->url() << endl; return; } bool found = false; bool isZippedOfficeDocument=false; int matchingLineNumber=0; // FIXME: doesn't work with non local files QString filename; QTextStream* stream=0; QFile qf; QRegExp xmlTags; QByteArray zippedXmlFileContent; // KWord's and OpenOffice.org's files are zipped... if( ooo_mimetypes.findIndex(file->mimetype()) != -1 || koffice_mimetypes.findIndex(file->mimetype()) != -1 ) { KZip zipfile(file->url().path()); KZipFileEntry *zipfileEntry; if(zipfile.open(IO_ReadOnly)) { const KArchiveDirectory *zipfileContent = zipfile.directory(); if( koffice_mimetypes.findIndex(file->mimetype()) != -1 ) zipfileEntry = (KZipFileEntry*)zipfileContent->entry("maindoc.xml"); else zipfileEntry = (KZipFileEntry*)zipfileContent->entry("content.xml"); //for OpenOffice.org if(!zipfileEntry) { kdWarning() << "Expected XML file not found in ZIP archive " << file->url() << endl; return; } zippedXmlFileContent = zipfileEntry->data(); xmlTags.setPattern("<.*>"); xmlTags.setMinimal(true); stream = new QTextStream(zippedXmlFileContent, IO_ReadOnly); stream->setEncoding(QTextStream::UnicodeUTF8); isZippedOfficeDocument = true; } else { kdWarning() << "Cannot open supposed ZIP file " << file->url() << endl; } } else if( !m_search_binary && !file->mimetype().startsWith("text/") && file->url().isLocalFile() ) { KMimeType::Format f = KMimeType::findFormatByFileContent(file->url().path()); if ( !f.text ) { kdDebug() << "ignoring, not a text file: " << file->url() << endl; return; } } if(!isZippedOfficeDocument) //any other file or non-compressed KWord { filename = file->url().path(); if(filename.startsWith("/dev/")) return; qf.setName(filename); qf.open(IO_ReadOnly); stream=new QTextStream(&qf); stream->setEncoding(QTextStream::Locale); } while ( ! stream->atEnd() ) { QString str = stream->readLine(); matchingLineNumber++; if (str.isNull()) break; if(isZippedOfficeDocument) str.replace(xmlTags, ""); if (m_regexpForContent) { if (m_regexp.search(str)>=0) { matchingLine=QString::number(matchingLineNumber)+": "+str; found = true; break; } } else { if (str.find(m_context, 0, m_casesensitive) != -1) { matchingLine=QString::number(matchingLineNumber)+": "+str; found = true; break; } } kapp->processEvents(); } delete stream; if (!found) return; } emit addFile(file,matchingLine); }
/** \brief Initialize a ZipFile object from an input file. * * This constructor opens the named zip file. If the zip "file" is * embedded in a file that contains other data, e.g. a binary * program, the offset of the zip file start and end must be * specified. * * If the file cannot be opened or the Zip directory cannot * be read, then the constructor throws an exception. * * \param[in] filename The filename of the zip file to open. * \param[in] s_off Offset relative to the start of the file, that * indicates the beginning of the zip data in the file. * \param[in] e_off Offset relative to the end of the file, that * indicates the end of the zip data in the file. * The offset is a positive number, even though the * offset is towards the beginning of the file. */ ZipFile::ZipFile(std::string const& filename, offset_t s_off, offset_t e_off) : FileCollection(filename) , m_vs(s_off, e_off) { std::ifstream zipfile(m_filename, std::ios::in | std::ios::binary); if(!zipfile) { throw IOException("Error opening Zip archive file for reading in binary mode."); } // Find and read the End of Central Directory. ZipEndOfCentralDirectory eocd; { BackBuffer bb(zipfile, m_vs); ssize_t read_p(-1); for(;;) { if(read_p < 0) { if(!bb.readChunk(read_p)) { throw FileCollectionException("Unable to find zip structure: End-of-central-directory"); } } // Note: this is pretty fast since it reads from 'bb' which // caches the buffer the readChunk() function just read. // if(eocd.read(bb, read_p)) { // found it! break; } --read_p; } } // Position read pointer to start of first entry in central dir. m_vs.vseekg(zipfile, eocd.getOffset(), std::ios::beg); // TBD -- is that ", 0" still necessary? (With VC2012 and better) // Give the second argument in the next line to keep Visual C++ quiet //m_entries.resize(eocd.totalCount(), 0); m_entries.resize(eocd.getCount()); size_t const max_entry(eocd.getCount()); for(size_t entry_num(0); entry_num < max_entry; ++entry_num) { m_entries[entry_num] = FileEntry::pointer_t(new ZipCentralDirectoryEntry); m_entries[entry_num].get()->read(zipfile); } // Consistency check #1: // The virtual seeker position is exactly the start offset of the // Central Directory plus the Central Directory size // offset_t const pos(m_vs.vtellg(zipfile)); if(static_cast<offset_t>(eocd.getOffset() + eocd.getCentralDirectorySize()) != pos) { throw FileCollectionException("Zip file consistency problem. Zip file data fields are inconsistent with zip file layout."); } // Consistency check #2: // Are local headers consistent with CD headers? // for(auto it = m_entries.begin(); it != m_entries.end(); ++it) { /** \TODO * Make sure the entry offset is properly defined by ZipCentralDirectoryEntry. * Also the isEqual() is a quite advance test here! */ m_vs.vseekg(zipfile, (*it)->getEntryOffset(), std::ios::beg); ZipLocalEntry zlh; zlh.read(zipfile); if(!zipfile || !zlh.isEqual(**it)) { throw FileCollectionException("Zip file consistency problem. Zip file data fields are inconsistent with zip file layout."); } } // we are all good! m_valid = true; }