--- a/src/utils/circache.cpp
+++ b/src/utils/circache.cpp
@@ -30,6 +30,8 @@
#include <zlib.h>
#include "chrono.h"
+#include MEMORY_INCLUDE
+
#ifndef _WIN32
#include <sys/uio.h>
@@ -857,7 +859,7 @@
};
// instance == -1 means get latest. Otherwise specify from 1+
-bool CirCache::get(const string& udi, string& dic, string& data, int instance)
+bool CirCache::get(const string& udi, string& dic, string *data, int instance)
{
Chrono chron;
if (m_d->m_fd < 0) {
@@ -900,7 +902,7 @@
}
// Did we read an appropriate entry ?
if (o_good != 0 && (instance == -1 || instance == finst)) {
- bool ret = m_d->readDicData(o_good, d_good, dic, &data);
+ bool ret = m_d->readDicData(o_good, d_good, dic, data);
LOGDEB0(("Circache::get: hfound, %d mS\n",
chron.millis()));
return ret;
@@ -920,8 +922,7 @@
} else if (ret != CCScanHook::Stop) {
return false;
}
- bool bret =
- m_d->readDicData(getter.m_offs, getter.m_hd, dic, &data);
+ bool bret = m_d->readDicData(getter.m_offs, getter.m_hd, dic, data);
LOGDEB0(("Circache::get: scanfound, %d mS\n", chron.millis()));
return bret;
@@ -943,8 +944,8 @@
// If the mem cache is not up to date, update it, we're too lazy
// to do a scan
if (!m_d->m_ofskhcplt) {
- string dic, data;
- get("nosuchudi probably exists", dic, data);
+ string dic;
+ get("nosuchudi probably exists", dic);
if (!m_d->m_ofskhcplt) {
LOGERR(("CirCache::erase : cache not updated after get\n"));
return false;
@@ -1265,13 +1266,13 @@
return true;
}
-bool CirCache::getCurrent(string& udi, string& dic, string& data)
+bool CirCache::getCurrent(string& udi, string& dic, string *data)
{
if (m_d == 0) {
LOGERR(("CirCache::getCurrent: null data\n"));
return false;
}
- if (!m_d->readDicData(m_d->m_itoffs, m_d->m_ithd, dic, &data)) {
+ if (!m_d->readDicData(m_d->m_itoffs, m_d->m_ithd, dic, data)) {
return false;
}
@@ -1367,6 +1368,85 @@
return true;
}
+// Copy all entries from occ to ncc. Both are already open.
+static bool copyall(STD_SHARED_PTR<CirCache> occ,
+ STD_SHARED_PTR<CirCache> ncc, int& nentries,
+ ostringstream& msg)
+{
+ bool eof = false;
+ if (!occ->rewind(eof)) {
+ if (!eof) {
+ msg << "Initial rewind failed" << endl;
+ return false;
+ }
+ }
+ nentries = 0;
+ while (!eof) {
+ string udi, sdic, data;
+ if (!occ->getCurrent(udi, sdic, &data)) {
+ msg << "getCurrent failed: " << occ->getReason() << endl;
+ return false;
+ }
+ // Shouldn't getcurrent deal with this ?
+ if (sdic.size() == 0) {
+ //cerr << "Skip empty entry" << endl;
+ occ->next(eof);
+ continue;
+ }
+ ConfSimple dic(sdic);
+ if (!dic.ok()) {
+ msg << "Could not parse entry attributes dic" << endl;
+ return false;
+ }
+ //cerr << "UDI: " << udi << endl;
+ if (!ncc->put(udi, &dic, data)) {
+ msg << "put failed: " << ncc->getReason() << " sdic [" << sdic <<
+ "]" << endl;
+ return false;
+ }
+ nentries++;
+ occ->next(eof);
+ }
+ return true;
+}
+
+// Append all entries from sdir to ddir
+int CirCache::append(const string ddir, const string& sdir, string *reason)
+{
+ ostringstream msg;
+ // Open source file
+ STD_SHARED_PTR<CirCache> occ(new CirCache(sdir));
+ if (!occ->open(CirCache::CC_OPREAD)) {
+ if (reason) {
+ msg << "Open failed in " << sdir << " : " <<
+ occ->getReason() << endl;
+ *reason = msg.str();
+ }
+ return -1;
+ }
+ // Open dest file
+ STD_SHARED_PTR<CirCache> ncc(new CirCache(ddir));
+ if (!ncc->open(CirCache::CC_OPWRITE)) {
+ if (reason) {
+ msg << "Open failed in " << ddir << " : " <<
+ ncc->getReason() << endl;
+ *reason = msg.str();
+ }
+ return -1;
+ }
+
+ int nentries;
+ if (!copyall(occ, ncc, nentries, msg)) {
+ if (reason) {
+ *reason = msg.str();
+ }
+ return -1;
+ }
+
+ return nentries;
+}
+
+
#else // TEST ->
#include "autoconfig.h"
@@ -1380,162 +1460,16 @@
#include <string>
#include <iostream>
+#include MEMORY_INCLUDE
#include "circache.h"
#include "fileudi.h"
#include "conftree.h"
#include "readfile.h"
#include "debuglog.h"
+#include "smallut.h"
using namespace std;
-
-// Copy all entries from occ to ncc. Both are already open.
-bool copyall(STD_SHARED_PTR<CirCache> occ,
- STD_SHARED_PTR<CirCache> ncc, int& nentries)
-{
- bool eof = false;
- if (!occ->rewind(eof)) {
- if (!eof) {
- cerr << "Initial rewind failed" << endl;
- return false;
- }
- }
- nentries = 0;
- while (!eof) {
- string udi, sdic, data;
- if (!occ->getCurrent(udi, sdic, data)) {
- cerr << "getCurrent failed: " << occ->getReason() << endl;
- return false;
- }
- // Shouldn't getcurrent deal with this ?
- if (sdic.size() == 0) {
- //cerr << "Skip empty entry" << endl;
- occ->next(eof);
- continue;
- }
- ConfSimple dic(sdic);
- if (!dic.ok()) {
- cerr << "Could not parse entry attributes dic" << endl;
- return false;
- }
- //cerr << "UDI: " << udi << endl;
- if (!ncc->put(udi, &dic, data)) {
- cerr << "put failed: " << ncc->getReason() << " sdic [" << sdic <<
- "]" << endl;
- return false;
- }
- nentries++;
- occ->next(eof);
- }
- return true;
-}
-
-#warning resizecc is not useful, create(newsize) works !
-
-// Wrote the following at a point where I thought that simple resizing
-// did not work. Upon further study (or updates?), it appears it does
-// ! So the following code is not useful actually
-
-// Resize circache. This can't be done easily if the write point is
-// inside the file (we already reached the old max size). We create a
-// new file with the new size and copy the old entries into it. The
-// old file is then renamed into a backup and the new file renamed in
-// place.
-bool resizecc(const string& dir, int newmbs)
-{
- // Create object for existing file and get the file name
- STD_SHARED_PTR<CirCache> occ(new CirCache(dir));
- string ofn = occ->getpath();
-
- // Check for previous backup
- string backupfn = ofn + ".orig";
- if (access(backupfn.c_str(), 0) >= 0) {
- cerr << "Backup file " << backupfn <<
- " exists, please move it out of the way" << endl;
- return false;
- }
-
- if (!occ->open(CirCache::CC_OPREAD)) {
- cerr << "Open failed in " << dir << " : " << occ->getReason() << endl;
- return false;
- }
-
- // Create the new empty file in a temporary directory
- string tmpdir = path_cat(dir, "tmp");
- if (access(tmpdir.c_str(), 0) < 0) {
- if (mkdir(tmpdir.c_str(), 0700) < 0) {
- cerr << "Cant create temporary directory " << tmpdir << " ";
- perror("mkdir");
- return false;
- }
- }
- STD_SHARED_PTR<CirCache> ncc(new CirCache(tmpdir));
- string nfn = ncc->getpath();
- if (!ncc->create(off_t(newmbs) * 1000 * 1024,
- CirCache::CC_CRUNIQUE | CirCache::CC_CRTRUNCATE)) {
- cerr << "Cant create new file in " << tmpdir << " : " <<
- ncc->getReason() << endl;
- return false;
- }
-
- int nentries;
- if (!copyall(occ, ncc, nentries)) {
- cerr << "Copy failed\n";
- return false;
- }
-
- // Done with our objects here, there is no close() method, so
- // delete them
- occ.reset();
- ncc.reset();
-
- // Create backup by renaming the old file
- if (rename(ofn.c_str(), backupfn.c_str()) < 0) {
- cerr << "Could not create backup " << backupfn << " : ";
- perror("rename");
- return false;
- }
- cout << "Created backup file " << backupfn << endl;
-
- // Move the new file in place.
- if (rename(nfn.c_str(), ofn.c_str()) < 0) {
- cerr << "Could not rename new file from " << nfn << " to " <<
- ofn << " : ";
- perror("rename");
- return false;
- }
- cout << "Resize done, copied " << nentries << " entries " << endl;
- return true;
-}
-
-// Append all entries from sdir to ddir
-bool appendcc(const string ddir, const string& sdir)
-{
- // Open source file
- STD_SHARED_PTR<CirCache> occ(new CirCache(sdir));
- if (!occ->open(CirCache::CC_OPREAD)) {
- cerr << "Open failed in " << sdir << " : " << occ->getReason() << endl;
- return false;
- }
- // Open dest file
- STD_SHARED_PTR<CirCache> ncc(new CirCache(ddir));
- if (!ncc->open(CirCache::CC_OPWRITE)) {
- cerr << "Open failed in " << ddir << " : " << ncc->getReason() << endl;
- return false;
- }
-
- int nentries;
- if (!copyall(occ, ncc, nentries)) {
- cerr << "Copy failed\n";
- return false;
- }
-
- occ.reset();
- ncc.reset();
-
- cout << "Copy done, copied " << nentries << " entries " << endl;
- return true;
-}
static char *thisprog;
@@ -1546,7 +1480,6 @@
" -g [-i instance] [-D] <dirname> <udi>: get\n"
" -D: also dump data\n"
" -e <dirname> <udi> : erase\n"
- " -s <dirname> <newmbs> : resize\n"
" -a <targetdir> <dir> [<dir> ...]: append old content to target\n"
" The target should be first resized to hold all the data, else only\n"
" as many entries as capacity permit will be retained\n"
@@ -1569,7 +1502,6 @@
#define OPT_D 0x80
#define OPT_u 0x100
#define OPT_e 0x200
-#define OPT_s 0x400
#define OPT_a 0x800
int main(int argc, char **argv)
@@ -1620,9 +1552,6 @@
case 'p':
op_flags |= OPT_p;
break;
- case 's':
- op_flags |= OPT_s;
- break;
case 'u':
op_flags |= OPT_u;
break;
@@ -1660,21 +1589,14 @@
cerr << "Create failed:" << cc.getReason() << endl;
exit(1);
}
- } else if (op_flags & OPT_s) {
- if (argc != 1) {
- Usage();
- }
- int newmbs = atoi(*argv++);
- argc--;
- if (!resizecc(dir, newmbs)) {
- exit(1);
- }
} else if (op_flags & OPT_a) {
if (argc < 1) {
Usage();
}
while (argc) {
- if (!appendcc(dir, *argv++)) {
+ string reason;
+ if (CirCache::append(dir, *argv++, &reason) < 0) {
+ cerr << reason << endl;
return 1;
}
argc--;
@@ -1698,11 +1620,24 @@
}
string udi;
make_udi(fn, "", udi);
- sprintf(dic, "#whatever...\nmimetype = text/plain\nudi=%s\n",
- udi.c_str());
- string sdic;
- sdic.assign(dic, strlen(dic));
- ConfSimple conf(sdic);
+ string cmd("xdg-mime query filetype ");
+ // Should do more quoting here...
+ cmd += "'" + fn + "'";
+ FILE *fp = popen(cmd.c_str(), "r");
+ char* buf=0;
+ size_t sz = 0;
+ ::getline(&buf, &sz, fp);
+ pclose(fp);
+ string mimetype(buf);
+ free(buf);
+ trimstring(mimetype, "\n\r");
+ cout << "Got [" << mimetype << "]\n";
+
+ string s;
+ ConfSimple conf(s);
+ conf.set("udi", udi);
+ conf.set("mimetype", mimetype);
+ //ostringstream str; conf.write(str); cout << str.str() << endl;
if (!cc.put(udi, &conf, data, 0)) {
cerr << "Put failed: " << cc.getReason() << endl;
@@ -1722,7 +1657,7 @@
string udi = *argv++;
argc--;
string dic, data;
- if (!cc.get(udi, dic, data, instance)) {
+ if (!cc.get(udi, dic, &data, instance)) {
cerr << "Get failed: " << cc.getReason() << endl;
exit(1);
}