|
a/src/internfile/internfile.cpp |
|
b/src/internfile/internfile.cpp |
|
... |
|
... |
378 |
if (!temp->ok()) {
|
378 |
if (!temp->ok()) {
|
379 |
LOGERR(("FileInterner::dataToTempFile: cant create tempfile: %s\n",
|
379 |
LOGERR(("FileInterner::dataToTempFile: cant create tempfile: %s\n",
|
380 |
temp->getreason().c_str()));
|
380 |
temp->getreason().c_str()));
|
381 |
return TempFile();
|
381 |
return TempFile();
|
382 |
}
|
382 |
}
|
383 |
|
383 |
string reason;
|
384 |
int fd = open(temp->filename(), O_WRONLY);
|
384 |
if (!stringtofile(dt, temp->filename(), reason)) {
|
385 |
if (fd < 0) {
|
|
|
386 |
LOGERR(("FileInterner::dataToTempFile: open(%s) failed errno %d\n",
|
385 |
LOGERR(("FileInterner::dataToTempFile: stringtofile: %s\n",
|
387 |
temp->filename(), errno));
|
386 |
reason.c_str()));
|
388 |
return TempFile();
|
387 |
return TempFile();
|
389 |
}
|
388 |
}
|
390 |
if (write(fd, dt.c_str(), dt.length()) != (int)dt.length()) {
|
|
|
391 |
close(fd);
|
|
|
392 |
LOGERR(("FileInterner::dataToTempFile: write to %s failed errno %d\n",
|
|
|
393 |
temp->filename(), errno));
|
|
|
394 |
return TempFile();
|
|
|
395 |
}
|
|
|
396 |
close(fd);
|
|
|
397 |
return temp;
|
389 |
return temp;
|
398 |
}
|
390 |
}
|
399 |
|
391 |
|
400 |
// See if the error string is formatted as a missing helper message,
|
392 |
// See if the error string is formatted as a missing helper message,
|
401 |
// accumulate helper name if it is. The format of the message is:
|
393 |
// accumulate helper name if it is. The format of the message is:
|
|
... |
|
... |
890 |
static string urltolocalpath(string url)
|
882 |
static string urltolocalpath(string url)
|
891 |
{
|
883 |
{
|
892 |
return url.substr(7, string::npos);
|
884 |
return url.substr(7, string::npos);
|
893 |
}
|
885 |
}
|
894 |
|
886 |
|
|
|
887 |
bool FileInterner::tempFileForMT(TempFile& otemp, RclConfig* cnf,
|
|
|
888 |
const string& mimetype)
|
|
|
889 |
{
|
|
|
890 |
TempFile temp(new TempFileInternal(
|
|
|
891 |
cnf->getSuffixFromMimeType(mimetype)));
|
|
|
892 |
if (!temp->ok()) {
|
|
|
893 |
LOGERR(("FileInterner::interntofile: can't create temp file\n"));
|
|
|
894 |
return false;
|
|
|
895 |
}
|
|
|
896 |
otemp = temp;
|
|
|
897 |
return true;
|
|
|
898 |
}
|
|
|
899 |
|
895 |
// Extract subdoc out of multidoc into temporary file.
|
900 |
// Extract document (typically subdoc of multidoc) into temporary file.
|
896 |
// We do the usual internfile stuff: create a temporary directory,
|
901 |
// We do the usual internfile stuff: create a temporary directory,
|
897 |
// then create an interner and call internfile. The target mtype is set to
|
902 |
// then create an interner and call internfile. The target mtype is set to
|
898 |
// the input mtype, so that no data conversion is performed.
|
903 |
// the input mtype, so that no data conversion is performed.
|
899 |
// We then write the data out of the resulting document into the output file.
|
904 |
// We then write the data out of the resulting document into the output file.
|
900 |
// There are two temporary objects:
|
905 |
// There are two temporary objects:
|
901 |
// - The internfile temporary directory gets destroyed by its destructor
|
906 |
// - The internfile temporary directory gets destroyed by its destructor
|
902 |
// - The output temporary file which is held in a reference-counted
|
907 |
// - The output temporary file which is held in a reference-counted
|
903 |
// object and will be deleted when done with.
|
908 |
// object and will be deleted when done with.
|
904 |
// This DOES NOT work with a non-internal file (because at least one conversion
|
909 |
//
|
905 |
// is always performed).
|
910 |
// If the ipath is null, maybe we're called because the file is not
|
|
|
911 |
// stored in the regular file system. We use the docfetcher to get a
|
|
|
912 |
// copy (in topdocToFile())
|
|
|
913 |
//
|
|
|
914 |
// We currently don't handle the case of an internal doc of a non-fs document.
|
|
|
915 |
|
906 |
bool FileInterner::idocToFile(TempFile& otemp, const string& tofile,
|
916 |
bool FileInterner::idocToFile(TempFile& otemp, const string& tofile,
|
907 |
RclConfig *cnf, const Rcl::Doc& idoc)
|
917 |
RclConfig *cnf, const Rcl::Doc& idoc)
|
908 |
{
|
918 |
{
|
909 |
LOGDEB(("FileInterner::idocToFile\n"));
|
919 |
LOGDEB(("FileInterner::idocToFile\n"));
|
910 |
// idoc.dump();
|
|
|
911 |
|
920 |
|
912 |
if (idoc.ipath.empty()) {
|
921 |
if (idoc.ipath.empty()) {
|
913 |
LOGDEB(("FileInterner::idocToFile: not a sub-document !\n"));
|
922 |
return topdocToFile(otemp, tofile, cnf, idoc);
|
914 |
// We could do a copy here but it's much more complicated than
|
|
|
915 |
// it seems because the source is not necessarily a simple
|
|
|
916 |
// depending on the backend. Until we fix the Internfile
|
|
|
917 |
// constructor to not do the first conversion, it's much saner
|
|
|
918 |
// to just return an error
|
|
|
919 |
return false;
|
|
|
920 |
}
|
923 |
}
|
921 |
|
924 |
|
922 |
// We set FIF_forPreview for consistency with the previous version
|
925 |
// We set FIF_forPreview for consistency with the previous version
|
923 |
// which determined this by looking at mtype!=null. Probably
|
926 |
// which determined this by looking at mtype!=null. Probably
|
924 |
// doesn't change anything in this case.
|
927 |
// doesn't change anything in this case.
|
925 |
FileInterner interner(idoc, cnf, FIF_forPreview);
|
928 |
FileInterner interner(idoc, cnf, FIF_forPreview);
|
926 |
interner.setTargetMType(idoc.mimetype);
|
929 |
interner.setTargetMType(idoc.mimetype);
|
927 |
return interner.interntofile(otemp, tofile, idoc.ipath, idoc.mimetype);
|
930 |
return interner.interntofile(otemp, tofile, idoc.ipath, idoc.mimetype);
|
|
|
931 |
}
|
|
|
932 |
|
|
|
933 |
bool FileInterner::topdocToFile(TempFile& otemp, const string& tofile,
|
|
|
934 |
RclConfig *cnf, const Rcl::Doc& idoc)
|
|
|
935 |
{
|
|
|
936 |
DocFetcher *fetcher = docFetcherMake(idoc);
|
|
|
937 |
if (fetcher == 0) {
|
|
|
938 |
LOGERR(("FileInterner::idocToFile no backend\n"));
|
|
|
939 |
return false;
|
|
|
940 |
}
|
|
|
941 |
DocFetcher::RawDoc rawdoc;
|
|
|
942 |
if (!fetcher->fetch(cnf, idoc, rawdoc)) {
|
|
|
943 |
LOGERR(("FileInterner::idocToFile fetcher failed\n"));
|
|
|
944 |
return false;
|
|
|
945 |
}
|
|
|
946 |
const char *filename = "";
|
|
|
947 |
TempFile temp;
|
|
|
948 |
if (tofile.empty()) {
|
|
|
949 |
if (!tempFileForMT(temp, cnf, idoc.mimetype)) {
|
|
|
950 |
return false;
|
|
|
951 |
}
|
|
|
952 |
filename = temp->filename();
|
|
|
953 |
} else {
|
|
|
954 |
filename = tofile.c_str();
|
|
|
955 |
}
|
|
|
956 |
string reason;
|
|
|
957 |
switch (rawdoc.kind) {
|
|
|
958 |
case DocFetcher::RawDoc::RDK_FILENAME:
|
|
|
959 |
if (!copyfile(rawdoc.data.c_str(), filename, reason)) {
|
|
|
960 |
LOGERR(("FileInterner::idocToFile: copyfile: %s\n",
|
|
|
961 |
reason.c_str()));
|
|
|
962 |
return false;
|
|
|
963 |
}
|
|
|
964 |
break;
|
|
|
965 |
case DocFetcher::RawDoc::RDK_DATA:
|
|
|
966 |
if (!stringtofile(rawdoc.data, filename, reason)) {
|
|
|
967 |
LOGERR(("FileInterner::idocToFile: stringtofile: %s\n",
|
|
|
968 |
reason.c_str()));
|
|
|
969 |
return false;
|
|
|
970 |
}
|
|
|
971 |
break;
|
|
|
972 |
default:
|
|
|
973 |
LOGERR(("FileInterner::FileInterner(idoc): bad rawdoc kind ??\n"));
|
|
|
974 |
}
|
|
|
975 |
|
|
|
976 |
if (tofile.empty())
|
|
|
977 |
otemp = temp;
|
|
|
978 |
return true;
|
928 |
}
|
979 |
}
|
929 |
|
980 |
|
930 |
bool FileInterner::interntofile(TempFile& otemp, const string& tofile,
|
981 |
bool FileInterner::interntofile(TempFile& otemp, const string& tofile,
|
931 |
const string& ipath, const string& mimetype)
|
982 |
const string& ipath, const string& mimetype)
|
932 |
{
|
983 |
{
|
|
... |
|
... |
950 |
if (!stringlowercmp("text/html", mimetype) && !get_html().empty()) {
|
1001 |
if (!stringlowercmp("text/html", mimetype) && !get_html().empty()) {
|
951 |
doc.text = get_html();
|
1002 |
doc.text = get_html();
|
952 |
doc.mimetype = "text/html";
|
1003 |
doc.mimetype = "text/html";
|
953 |
}
|
1004 |
}
|
954 |
|
1005 |
|
955 |
string filename;
|
1006 |
const char *filename;
|
956 |
TempFile temp;
|
1007 |
TempFile temp;
|
957 |
if (tofile.empty()) {
|
1008 |
if (tofile.empty()) {
|
958 |
TempFile temp1(new TempFileInternal(
|
1009 |
if (!tempFileForMT(temp, m_cfg, mimetype)) {
|
959 |
m_cfg->getSuffixFromMimeType(mimetype)));
|
|
|
960 |
temp = temp1;
|
|
|
961 |
if (!temp->ok()) {
|
|
|
962 |
LOGERR(("FileInterner::interntofile: can't create temp file\n"));
|
|
|
963 |
return false;
|
1010 |
return false;
|
964 |
}
|
1011 |
}
|
965 |
filename = temp->filename();
|
1012 |
filename = temp->filename();
|
966 |
} else {
|
1013 |
} else {
|
967 |
filename = tofile;
|
1014 |
filename = tofile.c_str();
|
968 |
}
|
1015 |
}
|
969 |
|
1016 |
string reason;
|
970 |
int fd = open(filename.c_str(), O_WRONLY|O_CREAT, 0600);
|
1017 |
if (!stringtofile(doc.text, filename, reason)) {
|
971 |
if (fd < 0) {
|
|
|
972 |
LOGERR(("FileInterner::interntofile: open(%s) failed errno %d\n",
|
1018 |
LOGERR(("FileInterner::interntofile: stringtofile : %s\n",
|
973 |
filename.c_str(), errno));
|
1019 |
reason.c_str()));
|
974 |
return false;
|
1020 |
return false;
|
975 |
}
|
1021 |
}
|
976 |
const string& dt = doc.text;
|
|
|
977 |
if (write(fd, dt.c_str(), dt.length()) != (int)dt.length()) {
|
|
|
978 |
close(fd);
|
|
|
979 |
LOGERR(("FileInterner::interntofile: write to %s failed errno %d\n",
|
|
|
980 |
filename.c_str(), errno));
|
|
|
981 |
return false;
|
|
|
982 |
}
|
|
|
983 |
close(fd);
|
|
|
984 |
|
1022 |
|
985 |
if (tofile.empty())
|
1023 |
if (tofile.empty())
|
986 |
otemp = temp;
|
1024 |
otemp = temp;
|
987 |
return true;
|
1025 |
return true;
|
988 |
}
|
1026 |
}
|