Switch to unified view

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
}