/* This file is part of Strigi Desktop Search * * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "jstreamsconfig.h"#include "debendanalyzer.h"#include "arinputstream.h"#include "gzipinputstream.h"#include "tarinputstream.h"#include "stringterminatedsubstream.h"#include "subinputstream.h"#include "analysisresult.h"#include "fieldtypes.h"#include <list>using namespace Strigi;using namespace jstreams;const cnstr DebEndAnalyzerFactory::nameFieldName("name");const cnstr DebEndAnalyzerFactory::versionFieldName("version");const cnstr DebEndAnalyzerFactory::summaryFieldName("summary");const cnstr DebEndAnalyzerFactory::sizeFieldName("size");const cnstr DebEndAnalyzerFactory::dependsFieldName("depends");voidDebEndAnalyzerFactory::registerFields(FieldRegister& r) { nameField = r.registerField(nameFieldName, FieldRegister::stringType, 1, 0); versionField = r.registerField(versionFieldName, FieldRegister::stringType, 1, 0); summaryField = r.registerField(summaryFieldName, FieldRegister::stringType, 1, 0); sizeField = r.registerField(sizeFieldName, FieldRegister::integerType, 1, 0); dependsField = r.registerField(dependsFieldName, FieldRegister::stringType, 0, 0);}boolDebEndAnalyzer::checkHeader(const char* header, int32_t headersize) const { return ArInputStream::checkHeader(header, headersize);}void readField(const std::string& line, const std::string& field, const Strigi::RegisteredField* reg, AnalysisResult& idx, bool multi=false){ std::string::size_type f1 = line.find(field,0); if (f1!=std::string::npos && f1<line.size()-field.size()-1) { f1+=field.size(); std::string::size_type end=line.find("\n",f1+1); if (end==std::string::npos) end=line.size()-1; do { std::string::size_type nexttoken=end; if (multi) nexttoken=line.find(", ",f1+1); if (nexttoken==std::string::npos || nexttoken>end) nexttoken=end; fprintf(stderr, "Field: %i %i %s\n", f1, nexttoken, line.substr(f1,nexttoken-f1).c_str()); idx.setField(reg, line.substr(f1,nexttoken-f1)); if (!multi) return; f1=nexttoken+2; } while (f1<end); }}charDebEndAnalyzer::analyzeControl(AnalysisResult& idx, InputStream* in) { GZipInputStream out(in); TarInputStream stream(&out); InputStream *s = stream.nextEntry(); fprintf(stderr,"IN DEB ANALYZECONTROL: str %p\n",s); if (stream.getStatus()) { fprintf(stderr, "EEerror: %s\n", stream.getError()); return -1;// exit(1); } while (s && stream.getEntryInfo().filename!="./control") { fprintf(stderr,"CTRL FILE: %s, %p\n", stream.getEntryInfo().filename.c_str(), s); s = stream.nextEntry(); } if (!s) return -1; // control const char *buf; // FIXME: get it by line int32_t nread=s->read(buf,8192, 8192); if (nread<1) return 0; fprintf(stderr,"READ %i %s\n", nread, buf); std::string line(buf, nread); readField(line,"Package: ",factory->nameField, idx); readField(line,"Description: ",factory->summaryField, idx); readField(line,"Version: ",factory->versionField, idx); readField(line,"Depends: ",factory->dependsField, idx, true); fprintf(stderr,"OK-c\n"); return 0;}charDebEndAnalyzer::analyze(AnalysisResult& idx, InputStream* in) { bool dbFound=false, ctrlFound=false, dataFound=false; fprintf(stderr,"IN DEB ANALYZE\n"); ArInputStream deb(in); InputStream *s = deb.nextEntry(); if (deb.getStatus()) { fprintf(stderr, "error: %s\n", deb.getError()); return -1;// exit(1); } while (s) { EntryInfo info=deb.getEntryInfo(); fprintf(stderr,"GOT %s\n", info.filename.c_str()); if (info.filename=="debian-binary") dbFound=true; if (info.filename=="control.tar.gz") { if (analyzeControl(idx,s)) return -1; ctrlFound=true; s->reset(0); } if (info.filename=="data.tar" || info.filename=="data.tar.gz" || info.filename=="data.tar.bz2") dataFound=true; idx.indexChild(deb.getEntryInfo().filename, deb.getEntryInfo().mtime, s); s = deb.nextEntry(); } if (deb.getStatus() == Error) { error = deb.getError(); return -1; } else { error.resize(0); } // at least one of required files not found - this is not .deb if (!ctrlFound || !dataFound || !dbFound) return -1; fprintf(stderr,"OK\n"); return 0;}/*class Factory : public AnalyzerFactoryFactory {public: list<StreamEndAnalyzerFactory*> getStreamEndAnalyzerFactories() const { list<StreamEndAnalyzerFactory*> af; af.push_back(new DebEndAnalyzerFactory()); return af; }};STRIGI_ANALYZER_FACTORY(Factory)*/