uncompression+linux port

This commit is contained in:
dockes
2005-02-04 14:21:18 +00:00
parent 1f8fbc0d39
commit 74434a3b02
36 changed files with 781 additions and 32 deletions
+165
View File
@@ -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;
}
+14
View File
@@ -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_ */
+13 -1
View File
@@ -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();