Try to give possible explanations when opening a preview fails

This commit is contained in:
Jean-Francois Dockes 2019-06-15 19:21:52 +02:00
parent e7ba872404
commit dca18bc585
12 changed files with 574 additions and 479 deletions

View File

@ -77,7 +77,8 @@ bool EXEDocFetcher::makesig(RclConfig* cnf, const Rcl::Doc& idoc, string& sig)
} }
// Lookup bckid in the config and create an appropriate fetcher. // Lookup bckid in the config and create an appropriate fetcher.
EXEDocFetcher *exeDocFetcherMake(RclConfig *config, const string& bckid) std::unique_ptr<EXEDocFetcher> exeDocFetcherMake(RclConfig *config,
const string& bckid)
{ {
// The config we only read once, not gonna change. // The config we only read once, not gonna change.
static ConfSimple *bconf; static ConfSimple *bconf;
@ -122,5 +123,5 @@ EXEDocFetcher *exeDocFetcherMake(RclConfig *config, const string& bckid)
" not found in exec path or filters dir\n"); " not found in exec path or filters dir\n");
return 0; return 0;
} }
return new EXEDocFetcher(m); return std::unique_ptr<EXEDocFetcher>(new EXEDocFetcher(m));
} }

View File

@ -17,6 +17,7 @@
#ifndef _EXEFETCHER_H_INCLUDED_ #ifndef _EXEFETCHER_H_INCLUDED_
#define _EXEFETCHER_H_INCLUDED_ #define _EXEFETCHER_H_INCLUDED_
#include <memory>
#include "fetcher.h" #include "fetcher.h"
class RclConfig; class RclConfig;
@ -35,6 +36,7 @@ class RclConfig;
* query time for previewing and opening the document. * query time for previewing and opening the document.
*/ */
class EXEDocFetcher : public DocFetcher { class EXEDocFetcher : public DocFetcher {
public:
class Internal; class Internal;
EXEDocFetcher(const Internal&); EXEDocFetcher(const Internal&);
virtual ~EXEDocFetcher() {} virtual ~EXEDocFetcher() {}
@ -42,12 +44,14 @@ class EXEDocFetcher : public DocFetcher {
virtual bool fetch(RclConfig* cnf, const Rcl::Doc& idoc, RawDoc& out); virtual bool fetch(RclConfig* cnf, const Rcl::Doc& idoc, RawDoc& out);
/** Calls stat to retrieve file signature data */ /** Calls stat to retrieve file signature data */
virtual bool makesig(RclConfig* cnf, const Rcl::Doc& idoc,std::string& sig); virtual bool makesig(RclConfig* cnf, const Rcl::Doc& idoc,std::string& sig);
friend EXEDocFetcher *exeDocFetcherMake(RclConfig *, const std::string&); friend std::unique_ptr<EXEDocFetcher>
exeDocFetcherMake(RclConfig *, const std::string&);
private: private:
Internal *m; Internal *m;
}; };
// Lookup bckid in the config and create an appropriate fetcher. // Lookup bckid in the config and create an appropriate fetcher.
EXEDocFetcher *exeDocFetcherMake(RclConfig *config, const std::string& bckid); std::unique_ptr<EXEDocFetcher> exeDocFetcherMake(RclConfig *config,
const std::string& bckid);
#endif /* _EXEFETCHER_H_INCLUDED_ */ #endif /* _EXEFETCHER_H_INCLUDED_ */

View File

@ -16,6 +16,8 @@
*/ */
#include "autoconfig.h" #include "autoconfig.h"
#include <memory>
#include "log.h" #include "log.h"
#include "rclconfig.h" #include "rclconfig.h"
#include "fetcher.h" #include "fetcher.h"
@ -23,22 +25,23 @@
#include "webqueuefetcher.h" #include "webqueuefetcher.h"
#include "exefetcher.h" #include "exefetcher.h"
DocFetcher *docFetcherMake(RclConfig *config, const Rcl::Doc& idoc) std::unique_ptr<DocFetcher> docFetcherMake(RclConfig *config,
const Rcl::Doc& idoc)
{ {
if (idoc.url.empty()) { if (idoc.url.empty()) {
LOGERR("docFetcherMakeg:: no url in doc!\n" ); LOGERR("docFetcherMakeg:: no url in doc!\n" );
return 0; return std::unique_ptr<DocFetcher>();
} }
string backend; string backend;
idoc.getmeta(Rcl::Doc::keybcknd, &backend); idoc.getmeta(Rcl::Doc::keybcknd, &backend);
if (backend.empty() || !backend.compare("FS")) { if (backend.empty() || !backend.compare("FS")) {
return new FSDocFetcher; return std::unique_ptr<DocFetcher>(new FSDocFetcher);
#ifndef DISABLE_WEB_INDEXER #ifndef DISABLE_WEB_INDEXER
} else if (!backend.compare("BGL")) { } else if (!backend.compare("BGL")) {
return new WQDocFetcher; return std::unique_ptr<DocFetcher>(new WQDocFetcher);
#endif #endif
} else { } else {
DocFetcher *f = exeDocFetcherMake(config, backend); std::unique_ptr<DocFetcher> f(exeDocFetcherMake(config, backend));
if (!f) { if (!f) {
LOGERR("DocFetcherFactory: unknown backend [" << backend << "]\n"); LOGERR("DocFetcherFactory: unknown backend [" << backend << "]\n");
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 J.F.Dockes /* Copyright (C) 2012-2019 J.F.Dockes
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -19,6 +19,7 @@
#include "safesysstat.h" #include "safesysstat.h"
#include <string> #include <string>
#include <memory>
#include "rcldoc.h" #include "rcldoc.h"
@ -73,11 +74,16 @@ public:
*/ */
virtual bool makesig(RclConfig* cnf, const Rcl::Doc& idoc, virtual bool makesig(RclConfig* cnf, const Rcl::Doc& idoc,
std::string& sig) = 0; std::string& sig) = 0;
enum Reason{FetchOk, FetchNotExist, FetchNoPerm, FetchOther};
virtual Reason testAccess(RclConfig* cnf, const Rcl::Doc& idoc) {
return FetchOther;
}
virtual ~DocFetcher() {} virtual ~DocFetcher() {}
}; };
/** Return an appropriate fetcher object given the backend string /** Return an appropriate fetcher object given the backend string
* identifier inside idoc*/ * identifier inside idoc*/
DocFetcher *docFetcherMake(RclConfig *config, const Rcl::Doc& idoc); std::unique_ptr<DocFetcher> docFetcherMake(RclConfig *config,
const Rcl::Doc& idoc);
#endif /* _FETCHER_H_INCLUDED_ */ #endif /* _FETCHER_H_INCLUDED_ */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 J.F.Dockes /* Copyright (C) 2012-2019 J.F.Dockes
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -28,30 +28,31 @@
using std::string; using std::string;
static bool urltopath(RclConfig* cnf, static DocFetcher::Reason urltopath(RclConfig* cnf, const Rcl::Doc& idoc,
const Rcl::Doc& idoc, string& fn, struct stat& st) string& fn, struct stat& st)
{ {
// The url has to be like file:// // The url has to be like file://
fn = fileurltolocalpath(idoc.url); fn = fileurltolocalpath(idoc.url);
if (fn.empty()) { if (fn.empty()) {
LOGERR("FSDocFetcher::fetch/sig: non fs url: [" << (idoc.url) << "]\n" ); LOGERR("FSDocFetcher::fetch/sig: non fs url: [" << idoc.url << "]\n");
return false; return DocFetcher::FetchOther;
} }
cnf->setKeyDir(path_getfather(fn)); cnf->setKeyDir(path_getfather(fn));
bool follow = false; bool follow = false;
cnf->getConfParam("followLinks", &follow); cnf->getConfParam("followLinks", &follow);
if (path_fileprops(fn, &st, follow) < 0) { if (path_fileprops(fn, &st, follow) < 0) {
LOGERR("FSDocFetcher::fetch: stat errno " << (errno) << " for [" << (fn) << "]\n" ); LOGERR("FSDocFetcher::fetch: stat errno " << errno << " for [" << fn
return false; << "]\n");
return DocFetcher::FetchNotExist;
} }
return true; return DocFetcher::FetchOk;
} }
bool FSDocFetcher::fetch(RclConfig* cnf, const Rcl::Doc& idoc, RawDoc& out) bool FSDocFetcher::fetch(RclConfig* cnf, const Rcl::Doc& idoc, RawDoc& out)
{ {
string fn; string fn;
if (!urltopath(cnf, idoc, fn, out.st)) if (urltopath(cnf, idoc, fn, out.st) != DocFetcher::FetchOk)
return false; return false;
out.kind = RawDoc::RDK_FILENAME; out.kind = RawDoc::RDK_FILENAME;
out.data = fn; out.data = fn;
@ -62,10 +63,24 @@ bool FSDocFetcher::makesig(RclConfig* cnf, const Rcl::Doc& idoc, string& sig)
{ {
string fn; string fn;
struct stat st; struct stat st;
if (!urltopath(cnf, idoc, fn, st)) if (urltopath(cnf, idoc, fn, st) != DocFetcher::FetchOk)
return false; return false;
FsIndexer::makesig(&st, sig); FsIndexer::makesig(&st, sig);
return true; return true;
} }
DocFetcher::Reason FSDocFetcher::testAccess(RclConfig* cnf, const Rcl::Doc& idoc)
{
string fn;
struct stat st;
DocFetcher::Reason reason = urltopath(cnf, idoc, fn, st);
if (reason != DocFetcher::FetchOk) {
return reason;
}
if (!path_readable(fn)) {
return DocFetcher::FetchNoPerm;
}
// We have no way to know if the file is fully readable without
// trying (local Windows locks), which would take too much time.
return DocFetcher::FetchOther;
}

View File

@ -28,6 +28,7 @@ class FSDocFetcher : public DocFetcher{
/** Calls stat to retrieve file signature data */ /** Calls stat to retrieve file signature data */
virtual bool makesig(RclConfig* cnf,const Rcl::Doc& idoc, std::string& sig); virtual bool makesig(RclConfig* cnf,const Rcl::Doc& idoc, std::string& sig);
virtual DocFetcher::Reason testAccess(RclConfig* cnf, const Rcl::Doc& idoc);
virtual ~FSDocFetcher() {} virtual ~FSDocFetcher() {}
}; };

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2004 J.F.Dockes /* Copyright (C) 2004-2019 J.F.Dockes
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -15,7 +15,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#ifndef TEST_INTERNFILE
#include "autoconfig.h" #include "autoconfig.h"
#include <stdio.h> #include <stdio.h>
@ -29,6 +28,7 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <memory>
using namespace std; using namespace std;
@ -331,8 +331,8 @@ FileInterner::FileInterner(const Rcl::Doc& idoc, RclConfig *cnf, int flags)
LOGDEB0("FileInterner::FileInterner(idoc)\n"); LOGDEB0("FileInterner::FileInterner(idoc)\n");
initcommon(cnf, flags); initcommon(cnf, flags);
DocFetcher *fetcher = docFetcherMake(cnf, idoc); std::unique_ptr<DocFetcher> fetcher(docFetcherMake(cnf, idoc));
if (fetcher == 0) { if (!fetcher) {
LOGERR("FileInterner:: no backend\n"); LOGERR("FileInterner:: no backend\n");
return; return;
} }
@ -361,17 +361,33 @@ FileInterner::FileInterner(const Rcl::Doc& idoc, RclConfig *cnf, int flags)
return; return;
} }
FileInterner::ErrorPossibleCause FileInterner::tryGetReason(RclConfig *cnf,
const Rcl::Doc& idoc)
{
LOGDEB0("FileInterner::tryGetReason(idoc)\n");
std::unique_ptr<DocFetcher> fetcher(docFetcherMake(cnf, idoc));
if (!fetcher) {
LOGERR("FileInterner:: no backend\n");
return FileInterner::FetchNoBackend;
}
DocFetcher::Reason fetchreason = fetcher->testAccess(cnf, idoc);
switch (fetchreason) {
case DocFetcher::FetchNotExist: return FileInterner::FetchMissing;
case DocFetcher::FetchNoPerm: return FileInterner::FetchPerm;
default: return FileInterner::InternfileOther;
}
}
bool FileInterner::makesig(RclConfig *cnf, const Rcl::Doc& idoc, string& sig) bool FileInterner::makesig(RclConfig *cnf, const Rcl::Doc& idoc, string& sig)
{ {
DocFetcher *fetcher = docFetcherMake(cnf, idoc); std::unique_ptr<DocFetcher> fetcher(docFetcherMake(cnf, idoc));
if (fetcher == 0) { if (!fetcher) {
LOGERR("FileInterner::makesig no backend for doc\n"); LOGERR("FileInterner::makesig no backend for doc\n");
return false; return false;
} }
bool ret = fetcher->makesig(cnf, idoc, sig); bool ret = fetcher->makesig(cnf, idoc, sig);
delete fetcher;
return ret; return ret;
} }
@ -897,7 +913,7 @@ FileInterner::Status FileInterner::internfile(Rcl::Doc& doc,const string& ipath)
} }
} }
} }
breakloop: breakloop:
if (m_handlers.empty()) { if (m_handlers.empty()) {
LOGDEB("FileInterner::internfile: conversion ended with no doc\n"); LOGDEB("FileInterner::internfile: conversion ended with no doc\n");
return FIError; return FIError;
@ -976,8 +992,8 @@ bool FileInterner::topdocToFile(
TempFile& otemp, const string& tofile, TempFile& otemp, const string& tofile,
RclConfig *cnf, const Rcl::Doc& idoc, bool uncompress) RclConfig *cnf, const Rcl::Doc& idoc, bool uncompress)
{ {
DocFetcher *fetcher = docFetcherMake(cnf, idoc); std::unique_ptr<DocFetcher> fetcher(docFetcherMake(cnf, idoc));
if (fetcher == 0) { if (!fetcher) {
LOGERR("FileInterner::topdocToFile no backend\n"); LOGERR("FileInterner::topdocToFile no backend\n");
return false; return false;
} }
@ -1151,117 +1167,3 @@ bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn,
} }
return true; return true;
} }
#else
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include "safesysstat.h"
using namespace std;
#include "log.h"
#include "rclinit.h"
#include "internfile.h"
#include "rclconfig.h"
#include "rcldoc.h"
static string thisprog;
static string usage =
" internfile <filename> [ipath]\n"
" \n\n"
;
static void
Usage(void)
{
cerr << thisprog << ": usage:\n" << usage;
exit(1);
}
static int op_flags;
#define OPT_q 0x1
RclConfig *config;
int main(int argc, char **argv)
{
thisprog = argv[0];
argc--; argv++;
while (argc > 0 && **argv == '-') {
(*argv)++;
if (!(**argv))
/* Cas du "adb - core" */
Usage();
while (**argv)
switch (*(*argv)++) {
default: Usage(); break;
}
argc--; argv++;
}
DebugLog::getdbl()->setloglevel(DEBDEB1);
DebugLog::setfilename("stderr");
if (argc < 1)
Usage();
string fn(*argv++);
argc--;
string ipath;
if (argc >= 1) {
ipath.append(*argv++);
argc--;
}
string reason;
config = recollinit(0, 0, 0, reason);
if (config == 0 || !config->ok()) {
string str = "Configuration problem: ";
str += reason;
fprintf(stderr, "%s\n", str.c_str());
exit(1);
}
struct stat st;
if (stat(fn.c_str(), &st)) {
perror("stat");
exit(1);
}
FileInterner interner(fn, &st, config, 0);
Rcl::Doc doc;
FileInterner::Status status = interner.internfile(doc, ipath);
switch (status) {
case FileInterner::FIDone:
case FileInterner::FIAgain:
break;
case FileInterner::FIError:
default:
fprintf(stderr, "internfile failed\n");
exit(1);
}
cout << "doc.url [[[[" << doc.url <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.ipath [[[[" << doc.ipath <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.mimetype [[[[" << doc.mimetype <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.fmtime [[[[" << doc.fmtime <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.dmtime [[[[" << doc.dmtime <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.origcharset [[[[" << doc.origcharset <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.meta[title] [[[[" << doc.meta["title"] <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.meta[keywords] [[[[" << doc.meta["keywords"] <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.meta[abstract] [[[[" << doc.meta["abstract"] <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.text [[[[" << doc.text << "]]]]\n";
}
#endif // TEST_INTERNFILE

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2004 J.F.Dockes /* Copyright (C) 2004-2019 J.F.Dockes
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -33,7 +33,7 @@ using std::set;
class RclConfig; class RclConfig;
namespace Rcl { namespace Rcl {
class Doc; class Doc;
} }
class Uncomp; class Uncomp;
@ -87,7 +87,7 @@ public:
* *
*/ */
class FileInterner { class FileInterner {
public: public:
/** Operation modifier flags */ /** Operation modifier flags */
enum Flags {FIF_none, FIF_forPreview, FIF_doUseInputMimetype}; enum Flags {FIF_none, FIF_forPreview, FIF_doUseInputMimetype};
/** Return values for internfile() */ /** Return values for internfile() */
@ -138,8 +138,7 @@ class FileInterner {
~FileInterner(); ~FileInterner();
void setMissingStore(FIMissingStore *st) void setMissingStore(FIMissingStore *st) {
{
m_missingdatap = st; m_missingdatap = st;
} }
@ -248,7 +247,14 @@ class FileInterner {
static bool maybeUncompressToTemp(TempFile& temp, const string& fn, static bool maybeUncompressToTemp(TempFile& temp, const string& fn,
RclConfig *cnf, const Rcl::Doc& doc); RclConfig *cnf, const Rcl::Doc& doc);
private: /** Try to get a top level reason after an operation failed. This
* is just for "simple" issues, like file missing, permissions,
* etc. */
enum ErrorPossibleCause{FetchMissing, FetchPerm, FetchNoBackend,
InternfileOther};
static ErrorPossibleCause tryGetReason(RclConfig *, const Rcl::Doc&);
private:
static const unsigned int MAXHANDLERS = 20; static const unsigned int MAXHANDLERS = 20;
RclConfig *m_cfg; RclConfig *m_cfg;
string m_fn; string m_fn;

View File

@ -62,6 +62,7 @@ void LoadThread::run()
} else { } else {
fdoc.mimetype = interner.getMimetype(); fdoc.mimetype = interner.getMimetype();
mst.getMissingExternal(missing); mst.getMissingExternal(missing);
explain = FileInterner::tryGetReason(&m_config, m_idoc);
status = -1; status = -1;
} }
} catch (CancelExcept) { } catch (CancelExcept) {

View File

@ -25,6 +25,7 @@
#include "pathut.h" #include "pathut.h"
#include "rclutil.h" #include "rclutil.h"
#include "rclconfig.h" #include "rclconfig.h"
#include "internfile.h"
/* /*
* A thread to perform the file reading / format conversion work for preview * A thread to perform the file reading / format conversion work for preview
@ -48,6 +49,7 @@ public:
Rcl::Doc fdoc; Rcl::Doc fdoc;
TempFile tmpimg; TempFile tmpimg;
std::string missing; std::string missing;
FileInterner::ErrorPossibleCause explain{FileInterner::InternfileOther};
private: private:
Rcl::Doc m_idoc; Rcl::Doc m_idoc;

View File

@ -643,7 +643,6 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
if (CancelCheck::instance().cancelState()) if (CancelCheck::instance().cancelState())
return false; return false;
if (lthr.status != 0) { if (lthr.status != 0) {
progress.close();
QString explain; QString explain;
if (!lthr.missing.empty()) { if (!lthr.missing.empty()) {
explain = QString::fromUtf8("<br>") + explain = QString::fromUtf8("<br>") +
@ -655,13 +654,40 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
lthr.fdoc.mimetype.c_str() + explain); lthr.fdoc.mimetype.c_str() + explain);
} else { } else {
if (progress.wasCanceled()) { if (progress.wasCanceled()) {
//QMessageBox::warning(0, "Recoll", tr("Canceled")); QMessageBox::warning(0, "Recoll", tr("Canceled"));
} else { } else {
QMessageBox::warning(0, "Recoll", progress.close();
tr("Error while loading file")); // Note that we can't easily check for a readable file
// because it's possible that only a region is locked
// (e.g. on Windows for an ost file the first block is
// readable even if Outlook is running).
QString msg;
switch (lthr.explain) {
case FileInterner::FetchMissing:
msg = tr("Error loading the document: file missing");
break;
case FileInterner::FetchPerm:
msg = tr("Error loading the document: no permission");
break;
case FileInterner::FetchNoBackend:
msg =
tr("Error loading the document: backend not configured");
break;
case FileInterner::InternfileOther:
#ifdef _WIN32
msg = tr("Error loading the document: other handler error");
#else
msg = tr("Error loading the document: "
"other handler error<br>"
"Maybe the application is locking the file ?");
#endif
break;
}
QMessageBox::warning(0, "Recoll", msg);
} }
} }
progress.close();
return false; return false;
} }
// Reset config just in case. // Reset config just in case.
@ -1016,4 +1042,3 @@ void PreviewTextEdit::print()
QTextEdit::print(&printer); QTextEdit::print(&printer);
#endif #endif
} }

View File

@ -0,0 +1,129 @@
/* Copyright (C) 2017-2019 J.F.Dockes
*
* License: GPL 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include "safesysstat.h"
using namespace std;
#include "log.h"
#include "rclinit.h"
#include "internfile.h"
#include "rclconfig.h"
#include "rcldoc.h"
static string thisprog;
static string usage =
" internfile <filename> [ipath]\n"
" \n\n"
;
static void
Usage(void)
{
cerr << thisprog << ": usage:\n" << usage;
exit(1);
}
static int op_flags;
#define OPT_q 0x1
RclConfig *config;
int main(int argc, char **argv)
{
thisprog = argv[0];
argc--; argv++;
while (argc > 0 && **argv == '-') {
(*argv)++;
if (!(**argv))
/* Cas du "adb - core" */
Usage();
while (**argv)
switch (*(*argv)++) {
default: Usage(); break;
}
argc--; argv++;
}
DebugLog::getdbl()->setloglevel(DEBDEB1);
DebugLog::setfilename("stderr");
if (argc < 1)
Usage();
string fn(*argv++);
argc--;
string ipath;
if (argc >= 1) {
ipath.append(*argv++);
argc--;
}
string reason;
config = recollinit(0, 0, 0, reason);
if (config == 0 || !config->ok()) {
string str = "Configuration problem: ";
str += reason;
fprintf(stderr, "%s\n", str.c_str());
exit(1);
}
struct stat st;
if (stat(fn.c_str(), &st)) {
perror("stat");
exit(1);
}
FileInterner interner(fn, &st, config, 0);
Rcl::Doc doc;
FileInterner::Status status = interner.internfile(doc, ipath);
switch (status) {
case FileInterner::FIDone:
case FileInterner::FIAgain:
break;
case FileInterner::FIError:
default:
fprintf(stderr, "internfile failed\n");
exit(1);
}
cout << "doc.url [[[[" << doc.url <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.ipath [[[[" << doc.ipath <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.mimetype [[[[" << doc.mimetype <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.fmtime [[[[" << doc.fmtime <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.dmtime [[[[" << doc.dmtime <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.origcharset [[[[" << doc.origcharset <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.meta[title] [[[[" << doc.meta["title"] <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.meta[keywords] [[[[" << doc.meta["keywords"] <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.meta[abstract] [[[[" << doc.meta["abstract"] <<
"]]]]\n-----------------------------------------------------\n" <<
"doc.text [[[[" << doc.text << "]]]]\n";
}