uncompression+linux port
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: internfile.cpp,v 1.1 2005-02-04 14:21:17 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "internfile.h"
|
||||
#include "mimetype.h"
|
||||
#include "debuglog.h"
|
||||
#include "mimehandler.h"
|
||||
#include "execmd.h"
|
||||
#include "pathut.h"
|
||||
|
||||
static bool uncompressfile(RclConfig *conf, const string& ifn,
|
||||
const list<string>& cmdv, string& tdir,
|
||||
string& tfile)
|
||||
{
|
||||
const char *tmpdir = getenv("RECOLL_TMPDIR");
|
||||
if (!tmpdir)
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (!tmpdir)
|
||||
tmpdir = "/tmp";
|
||||
tdir = tmpdir;
|
||||
path_cat(tdir, "rcltmpXXXXXX");
|
||||
{
|
||||
char *cp = strdup(tdir.c_str());
|
||||
if (!cp) {
|
||||
LOGERR(("uncompressfile: out of memory (for file name !)\n"));
|
||||
return false;
|
||||
}
|
||||
if (!mktemp(cp)) {
|
||||
free(cp);
|
||||
LOGERR(("uncompressfile: mktemp failed\n"));
|
||||
return false;
|
||||
}
|
||||
tdir = cp;
|
||||
free(cp);
|
||||
}
|
||||
|
||||
if (mkdir(tdir.c_str(), 0700) < 0) {
|
||||
LOGERR(("uncompressfile: mkdir %s failed\n", tdir.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
string cmd = find_filter(conf, cmdv.front());
|
||||
|
||||
// Substitute file name and temp dir in command elements
|
||||
list<string>::const_iterator it = cmdv.begin();
|
||||
++it;
|
||||
list<string> args;
|
||||
for (; it != cmdv.end(); it++) {
|
||||
string s = *it;
|
||||
string ns;
|
||||
string::const_iterator it1;
|
||||
for (it1 = s.begin(); it1 != s.end();it1++) {
|
||||
if (*it1 == '%') {
|
||||
if (++it1 == s.end()) {
|
||||
ns += '%';
|
||||
break;
|
||||
}
|
||||
if (*it1 == '%')
|
||||
ns += '%';
|
||||
if (*it1 == 'f')
|
||||
ns += ifn;
|
||||
if (*it1 == 't')
|
||||
ns += tdir;
|
||||
} else {
|
||||
ns += *it1;
|
||||
}
|
||||
}
|
||||
args.push_back(ns);
|
||||
}
|
||||
|
||||
// Execute command and retrieve output file name, check that it exists
|
||||
ExecCmd ex;
|
||||
int status = ex.doexec(cmd, args, 0, &tfile);
|
||||
if (status) {
|
||||
LOGERR(("uncompressfile: doexec: status 0x%x\n", status));
|
||||
rmdir(tdir.c_str());
|
||||
return false;
|
||||
}
|
||||
if (!tfile.empty() && tfile[tfile.length() - 1] == '\n')
|
||||
tfile.erase(tfile.length() - 1, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tmpcleanup(const string& tdir, const string& tfile)
|
||||
{
|
||||
if (tdir.empty())
|
||||
return;
|
||||
if (!tfile.empty()) {
|
||||
if (unlink(tfile.c_str()) < 0) {
|
||||
LOGERR(("tmpcleanup: unlink(%s) errno %d\n", tfile.c_str(),
|
||||
errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (rmdir(tdir.c_str()) < 0) {
|
||||
LOGERR(("tmpcleanup: rmdir(%s) errno %d\n", tdir.c_str(), errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool internfile(const std::string &ifn, RclConfig *config, Rcl::Doc& doc)
|
||||
{
|
||||
string fn = ifn;
|
||||
string tdir;
|
||||
string tfile;
|
||||
MimeHandler *handler = 0;
|
||||
bool ret = false;
|
||||
|
||||
string mime = mimetype(fn, config->getMimeMap());
|
||||
if (mime.empty()) {
|
||||
// No mime type ?? pass on.
|
||||
LOGDEB(("internfile: (no mime) [%s]\n", fn.c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// First check for a compressed file
|
||||
list<string>ucmd;
|
||||
if (getUncompressor(mime, config->getMimeConf(), ucmd)) {
|
||||
if (!uncompressfile(config, fn, ucmd, tdir, tfile))
|
||||
return false;
|
||||
LOGDEB(("internfile: after ucomp: tdir %s, tfile %s\n",
|
||||
tdir.c_str(), tfile.c_str()));
|
||||
fn = tfile;
|
||||
mime = mimetype(fn, config->getMimeMap());
|
||||
if (mime.empty()) {
|
||||
// No mime type ?? pass on.
|
||||
LOGDEB(("internfile: (no mime) [%s]\n", fn.c_str()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Look for appropriate handler
|
||||
handler = getMimeHandler(mime, config->getMimeConf());
|
||||
if (!handler) {
|
||||
// No handler for this type, for now :(
|
||||
LOGDEB(("internfile: %s : no handler\n", mime.c_str()));
|
||||
goto out;
|
||||
}
|
||||
|
||||
LOGDEB(("internfile: %s [%s]\n", mime.c_str(), fn.c_str()));
|
||||
|
||||
// Turn file into a document. The document has fields for title, body
|
||||
// etc., all text converted to utf8
|
||||
if (!handler->worker(config, fn, mime, doc)) {
|
||||
goto out;
|
||||
}
|
||||
doc.mimetype = mime;
|
||||
|
||||
// Clean up. We delete the temp file and its father directory
|
||||
ret = true;
|
||||
out:
|
||||
delete handler;
|
||||
tmpcleanup(tdir, tfile);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef _INTERNFILE_H_INCLUDED_
|
||||
#define _INTERNFILE_H_INCLUDED_
|
||||
/* @(#$Id: internfile.h,v 1.1 2005-02-04 14:21:17 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "rclconfig.h"
|
||||
#include "rcldb.h"
|
||||
|
||||
/// Turn external file into internal representation, according to mime type etc
|
||||
extern bool internfile(const std::string &fn, RclConfig *config,
|
||||
Rcl::Doc& doc);
|
||||
|
||||
#endif /* _INTERNFILE_H_INCLUDED_ */
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: mimehandler.cpp,v 1.7 2005-02-04 09:39:44 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: mimehandler.cpp,v 1.8 2005-02-04 14:21:17 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@@ -71,6 +71,12 @@ class MimeHandlerExec : public MimeHandler {
|
||||
bool MimeHandlerExec::worker(RclConfig *conf, const string &fn,
|
||||
const string &mtype, Rcl::Doc &docout)
|
||||
{
|
||||
if (params.empty()) {
|
||||
// Hu ho
|
||||
LOGERR(("MimeHandlerExec::worker: empty params for mime %s\n",
|
||||
mtype.c_str()));
|
||||
return false;
|
||||
}
|
||||
// Command name
|
||||
string cmd = find_filter(conf, params.front());
|
||||
|
||||
@@ -163,8 +169,14 @@ bool getUncompressor(const std::string &mtype, ConfTree *mhandlers,
|
||||
string hs;
|
||||
|
||||
mhandlers->get(mtype, hs, "");
|
||||
if (hs.empty())
|
||||
return false;
|
||||
list<string> tokens;
|
||||
ConfTree::stringToStrings(hs, tokens);
|
||||
if (tokens.empty()) {
|
||||
LOGERR(("getUncompressor: empty spec for mtype %s\n", mtype.c_str()));
|
||||
return false;
|
||||
}
|
||||
if (stringlowercmp("uncompress", tokens.front()))
|
||||
return false;
|
||||
list<string>::iterator it = tokens.begin();
|
||||
|
||||
Reference in New Issue
Block a user