Switch to unified view

a/src/internfile/internfile.cpp b/src/internfile/internfile.cpp
...
...
149
    } else {
149
    } else {
150
    return ipath;
150
    return ipath;
151
    }
151
    }
152
}
152
}
153
153
154
// Uncompress input file into a temporary one, by executing the appropriate
155
// script.
156
static bool uncompressfile(RclConfig *conf, const string& ifn, 
157
             const vector<string>& cmdv, TempDir& tdir, 
158
             string& tfile)
159
{
160
    // Make sure tmp dir is empty. we guarantee this to filters
161
    if (!tdir.ok() || !tdir.wipe()) {
162
  LOGERR(("uncompressfile: can't clear temp dir %s\n", tdir.dirname()));
163
  return false;
164
    }
165
    string cmd = cmdv.front();
166
167
    // Substitute file name and temp dir in command elements
168
    vector<string>::const_iterator it = cmdv.begin();
169
    ++it;
170
    vector<string> args;
171
    map<char, string> subs;
172
    subs['f'] = ifn;
173
    subs['t'] = tdir.dirname();
174
    for (; it != cmdv.end(); it++) {
175
  string ns;
176
  pcSubst(*it, ns, subs);
177
  args.push_back(ns);
178
    }
179
180
    // Execute command and retrieve output file name, check that it exists
181
    ExecCmd ex;
182
    int status = ex.doexec(cmd, args, 0, &tfile);
183
    if (status || tfile.empty()) {
184
  LOGERR(("uncompressfile: doexec: failed for [%s] status 0x%x\n", 
185
      ifn.c_str(), status));
186
  if (!tdir.wipe()) {
187
      LOGERR(("uncompressfile: wipedir failed\n"));
188
  }
189
  return false;
190
    }
191
    if (tfile[tfile.length() - 1] == '\n')
192
  tfile.erase(tfile.length() - 1, 1);
193
    return true;
194
}
195
196
// Delete temporary uncompressed file
197
void FileInterner::tmpcleanup()
198
{
199
    if (m_tfile.empty())
200
  return;
201
    if (unlink(m_tfile.c_str()) < 0) {
202
  LOGERR(("FileInterner::tmpcleanup: unlink(%s) errno %d\n", 
203
      m_tfile.c_str(), errno));
204
  return;
205
    }
206
}
207
208
// Constructor: identify the input file, possibly create an
154
// Constructor: identify the input file, possibly create an
209
// uncompressed temporary copy, and create the top filter for the
155
// uncompressed temporary copy, and create the top filter for the
210
// uncompressed file type.
156
// uncompressed file type.
211
//
157
//
212
// Empty handler on return says that we're in error, this will be
158
// Empty handler on return says that we're in error, this will be
213
// processed by the first call to internfile().
159
// processed by the first call to internfile().
214
// Split into "constructor calls init()" to allow use from other constructor
160
// Split into "constructor calls init()" to allow use from other constructor
215
FileInterner::FileInterner(const string &fn, const struct stat *stp,
161
FileInterner::FileInterner(const string &fn, const struct stat *stp,
216
             RclConfig *cnf, 
217
               TempDir& td, int flags, const string *imime)
162
               RclConfig *cnf, int flags, const string *imime)
218
    : m_tdir(td), m_ok(false), m_missingdatap(0)
163
    : m_ok(false), m_missingdatap(0), m_uncomp((flags & FIF_forPreview) != 0)
219
{
164
{
220
    LOGDEB0(("FileInterner::FileInterner(fn=%s)\n", fn.c_str()));
165
    LOGDEB0(("FileInterner::FileInterner(fn=%s)\n", fn.c_str()));
221
    if (fn.empty()) {
166
    if (fn.empty()) {
222
    LOGERR(("FileInterner::FileInterner: empty file name!\n"));
167
    LOGERR(("FileInterner::FileInterner: empty file name!\n"));
223
    return;
168
    return;
...
...
283
    if (m_cfg->getUncompressor(l_mime, ucmd)) {
228
    if (m_cfg->getUncompressor(l_mime, ucmd)) {
284
        // Check for compressed size limit
229
        // Check for compressed size limit
285
        int maxkbs = -1;
230
        int maxkbs = -1;
286
        if (!m_cfg->getConfParam("compressedfilemaxkbs", &maxkbs) ||
231
        if (!m_cfg->getConfParam("compressedfilemaxkbs", &maxkbs) ||
287
        maxkbs < 0 || !stp || int(stp->st_size / 1024) < maxkbs) {
232
        maxkbs < 0 || !stp || int(stp->st_size / 1024) < maxkbs) {
288
        if (!uncompressfile(m_cfg, m_fn, ucmd, m_tdir, m_tfile)) {
233
        if (!m_uncomp.uncompressfile(m_fn, ucmd, m_tfile)) {
289
            return;
234
            return;
290
        }
235
        }
291
        LOGDEB1(("FileInterner:: after ucomp: m_tdir %s, tfile %s\n", 
236
        LOGDEB1(("FileInterner:: after ucomp: tfile %s\n", 
292
           m_tdir.dirname(), m_tfile.c_str()));
237
           m_tfile.c_str()));
293
        m_fn = m_tfile;
238
        m_fn = m_tfile;
294
        // Stat the uncompressed file, mainly to get the size
239
        // Stat the uncompressed file, mainly to get the size
295
        struct stat ucstat;
240
        struct stat ucstat;
296
        if (stat(m_fn.c_str(), &ucstat) != 0) {
241
        if (stat(m_fn.c_str(), &ucstat) != 0) {
297
            LOGERR(("FileInterner: can't stat the uncompressed file"
242
            LOGERR(("FileInterner: can't stat the uncompressed file"
...
...
350
    m_ok = true;
295
    m_ok = true;
351
}
296
}
352
297
353
// Setup from memory data (ie: out of the web cache). imime needs to be set.
298
// Setup from memory data (ie: out of the web cache). imime needs to be set.
354
FileInterner::FileInterner(const string &data, RclConfig *cnf, 
299
FileInterner::FileInterner(const string &data, RclConfig *cnf, 
355
                           TempDir& td, int flags, const string& imime)
300
                           int flags, const string& imime)
356
    : m_tdir(td), m_ok(false), m_missingdatap(0)
301
    : m_ok(false), m_missingdatap(0), m_uncomp((flags & FIF_forPreview) != 0)
357
{
302
{
358
    LOGDEB0(("FileInterner::FileInterner(data)\n"));
303
    LOGDEB0(("FileInterner::FileInterner(data)\n"));
359
    initcommon(cnf, flags);
304
    initcommon(cnf, flags);
360
    init(data, cnf, flags, imime);
305
    init(data, cnf, flags, imime);
361
}
306
}
...
...
414
    for (unsigned int i = 0; i < MAXHANDLERS; i++)
359
    for (unsigned int i = 0; i < MAXHANDLERS; i++)
415
    m_tmpflgs[i] = false;
360
    m_tmpflgs[i] = false;
416
    m_targetMType = cstr_textplain;
361
    m_targetMType = cstr_textplain;
417
}
362
}
418
363
419
FileInterner::FileInterner(const Rcl::Doc& idoc, RclConfig *cnf, 
364
FileInterner::FileInterner(const Rcl::Doc& idoc, RclConfig *cnf, int flags)
420
                           TempDir& td, int flags)
365
    : m_ok(false), m_missingdatap(0), m_uncomp(((flags & FIF_forPreview) != 0))
421
    : m_tdir(td), m_ok(false), m_missingdatap(0)
422
{
366
{
423
    LOGDEB0(("FileInterner::FileInterner(idoc)\n"));
367
    LOGDEB0(("FileInterner::FileInterner(idoc)\n"));
424
    initcommon(cnf, flags);
368
    initcommon(cnf, flags);
425
369
426
    DocFetcher *fetcher = docFetcherMake(idoc);
370
    DocFetcher *fetcher = docFetcherMake(idoc);
...
...
460
    return ret;
404
    return ret;
461
}
405
}
462
406
463
FileInterner::~FileInterner()
407
FileInterner::~FileInterner()
464
{
408
{
465
    tmpcleanup();
466
    for (vector<Dijon::Filter*>::iterator it = m_handlers.begin();
409
    for (vector<Dijon::Filter*>::iterator it = m_handlers.begin();
467
     it != m_handlers.end(); it++) {
410
     it != m_handlers.end(); it++) {
468
        returnMimeHandler(*it);
411
        returnMimeHandler(*it);
469
    }
412
    }
470
    // m_tempfiles will take care of itself
413
    // m_tempfiles will take care of itself
...
...
1010
                  RclConfig *cnf, const Rcl::Doc& idoc)
953
                  RclConfig *cnf, const Rcl::Doc& idoc)
1011
{
954
{
1012
    LOGDEB(("FileInterner::idocToFile\n"));
955
    LOGDEB(("FileInterner::idocToFile\n"));
1013
    idoc.dump();
956
    idoc.dump();
1014
957
1015
    TempDir tmpdir;
1016
1017
    // We set FIF_forPreview for consistency with the previous version
958
    // We set FIF_forPreview for consistency with the previous version
1018
    // which determined this by looking at mtype!=null. Probably
959
    // which determined this by looking at mtype!=null. Probably
1019
    // doesn't change anything in this case.
960
    // doesn't change anything in this case.
1020
    FileInterner interner(idoc, cnf, tmpdir, FIF_forPreview);
961
    FileInterner interner(idoc, cnf, FIF_forPreview);
1021
    interner.setTargetMType(idoc.mimetype);
962
    interner.setTargetMType(idoc.mimetype);
1022
    return interner.interntofile(otemp, tofile, idoc.ipath, idoc.mimetype);
963
    return interner.interntofile(otemp, tofile, idoc.ipath, idoc.mimetype);
1023
}
964
}
1024
965
1025
bool FileInterner::interntofile(TempFile& otemp, const string& tofile,
966
bool FileInterner::interntofile(TempFile& otemp, const string& tofile,
...
...
1100
        return true;
1041
        return true;
1101
    }
1042
    }
1102
    return false;
1043
    return false;
1103
}
1044
}
1104
1045
1046
// Static.
1105
bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn, 
1047
bool FileInterner::maybeUncompressToTemp(TempFile& temp, const string& fn, 
1106
                                         RclConfig *cnf, const Rcl::Doc& doc)
1048
                                         RclConfig *cnf, const Rcl::Doc& doc)
1107
{
1049
{
1108
    LOGDEB(("FileInterner::maybeUncompressToTemp: [%s]\n", fn.c_str()));
1050
    LOGDEB(("FileInterner::maybeUncompressToTemp: [%s]\n", fn.c_str()));
1109
    struct stat st;
1051
    struct stat st;
...
...
1129
        maxkbs >= 0 && int(st.st_size / 1024) > maxkbs) {
1071
        maxkbs >= 0 && int(st.st_size / 1024) > maxkbs) {
1130
        LOGINFO(("FileInterner:: %s over size limit %d kbs\n",
1072
        LOGINFO(("FileInterner:: %s over size limit %d kbs\n",
1131
                 fn.c_str(), maxkbs));
1073
                 fn.c_str(), maxkbs));
1132
        return false;
1074
        return false;
1133
    }
1075
    }
1134
    TempDir tmpdir;
1135
    temp = 
1076
    temp = 
1136
      TempFile(new TempFileInternal(cnf->getSuffixFromMimeType(doc.mimetype)));
1077
      TempFile(new TempFileInternal(cnf->getSuffixFromMimeType(doc.mimetype)));
1137
    if (!tmpdir.ok() || !temp->ok()) {
1078
    if (!temp->ok()) {
1138
        LOGERR(("FileInterner: cant create temporary file/dir"));
1079
        LOGERR(("FileInterner: cant create temporary file"));
1139
        return false;
1080
        return false;
1140
    }
1081
    }
1141
1082
1083
    Uncomp uncomp;
1142
    string uncomped;
1084
    string uncomped;
1143
    if (!uncompressfile(cnf, fn, ucmd, tmpdir, uncomped)) {
1085
    if (!uncomp.uncompressfile(fn, ucmd, uncomped)) {
1144
        return false;
1086
        return false;
1145
    }
1087
    }
1146
1088
1147
    // uncompressfile choses the output file name, there is good
1089
    // uncompressfile choses the output file name, there is good
1148
    // reason for this, but it's not nice here. Have to move, the
1090
    // reason for this, but it's not nice here. Have to move, the
...
...
1231
    struct stat st;
1173
    struct stat st;
1232
    if (stat(fn.c_str(), &st)) {
1174
    if (stat(fn.c_str(), &st)) {
1233
    perror("stat");
1175
    perror("stat");
1234
    exit(1);
1176
    exit(1);
1235
    }
1177
    }
1236
    TempDir tmp;
1237
    FileInterner interner(fn, &st, config, tmp, 0);
1178
    FileInterner interner(fn, &st, config, 0);
1238
    Rcl::Doc doc;
1179
    Rcl::Doc doc;
1239
    FileInterner::Status status = interner.internfile(doc, ipath);
1180
    FileInterner::Status status = interner.internfile(doc, ipath);
1240
    switch (status) {
1181
    switch (status) {
1241
    case FileInterner::FIDone:
1182
    case FileInterner::FIDone:
1242
    case FileInterner::FIAgain:
1183
    case FileInterner::FIAgain: