added crontab interfacing routines

This commit is contained in:
Jean-Francois Dockes 2011-12-01 16:59:59 +01:00
parent 1a22a3ddc7
commit fdfb77bf5b
5 changed files with 291 additions and 5 deletions

View File

@ -6,8 +6,8 @@ LIBS = librcl.a
all: $(LIBS)
OBJS = rclaspell.o beaglequeuecache.o cstr.o rclconfig.o rclinit.o textsplit.o unacpp.o beaglequeue.o csguess.o fsindexer.o indexer.o mimetype.o subtreelist.o htmlparse.o myhtmlparse.o mimehandler.o internfile.o mh_exec.o mh_execm.o mh_html.o mh_mail.o mh_mbox.o mh_text.o txtdcode.o docseq.o docseqdb.o docseqhist.o filtseq.o dynconf.o plaintorich.o recollq.o reslistpager.o sortseq.o wasastringtoquery.o wasatorcl.o rcldb.o rcldoc.o rclquery.o searchdata.o stemdb.o stoplist.o base64.o circache.o closefrom.o conftree.o copyfile.o debuglog.o execmd.o fstreewalk.o idfile.o fileudi.o md5.o mimeparse.o netcon.o pathut.o pxattr.o rclionice.o readfile.o smallut.o transcode.o wipedir.o x11mon.o mime-getpart.o mime-parsefull.o mime-parseonlyheader.o mime-printbody.o mime-printdoc.o mime-printheader.o mime.o convert.o iodevice.o iofactory.o
DEPS = rclaspell.dep.stamp beaglequeuecache.dep.stamp cstr.dep.stamp rclconfig.dep.stamp rclinit.dep.stamp textsplit.dep.stamp unacpp.dep.stamp beaglequeue.dep.stamp csguess.dep.stamp fsindexer.dep.stamp indexer.dep.stamp mimetype.dep.stamp subtreelist.dep.stamp htmlparse.dep.stamp myhtmlparse.dep.stamp mimehandler.dep.stamp internfile.dep.stamp mh_exec.dep.stamp mh_execm.dep.stamp mh_html.dep.stamp mh_mail.dep.stamp mh_mbox.dep.stamp mh_text.dep.stamp txtdcode.dep.stamp docseq.dep.stamp docseqdb.dep.stamp docseqhist.dep.stamp filtseq.dep.stamp dynconf.dep.stamp plaintorich.dep.stamp recollq.dep.stamp reslistpager.dep.stamp sortseq.dep.stamp wasastringtoquery.dep.stamp wasatorcl.dep.stamp rcldb.dep.stamp rcldoc.dep.stamp rclquery.dep.stamp searchdata.dep.stamp stemdb.dep.stamp stoplist.dep.stamp base64.dep.stamp circache.dep.stamp closefrom.dep.stamp conftree.dep.stamp copyfile.dep.stamp debuglog.dep.stamp execmd.dep.stamp fstreewalk.dep.stamp idfile.dep.stamp fileudi.dep.stamp md5.dep.stamp mimeparse.dep.stamp netcon.dep.stamp pathut.dep.stamp pxattr.dep.stamp rclionice.dep.stamp readfile.dep.stamp smallut.dep.stamp transcode.dep.stamp wipedir.dep.stamp x11mon.dep.stamp mime-getpart.dep.stamp mime-parsefull.dep.stamp mime-parseonlyheader.dep.stamp mime-printbody.dep.stamp mime-printdoc.dep.stamp mime-printheader.dep.stamp mime.dep.stamp convert.dep.stamp iodevice.dep.stamp iofactory.dep.stamp
OBJS = rclaspell.o beaglequeuecache.o cstr.o rclconfig.o rclinit.o textsplit.o unacpp.o beaglequeue.o csguess.o fsindexer.o indexer.o mimetype.o subtreelist.o htmlparse.o myhtmlparse.o mimehandler.o internfile.o mh_exec.o mh_execm.o mh_html.o mh_mail.o mh_mbox.o mh_text.o txtdcode.o docseq.o docseqdb.o docseqhist.o filtseq.o dynconf.o plaintorich.o recollq.o reslistpager.o sortseq.o wasastringtoquery.o wasatorcl.o rcldb.o rcldoc.o rclquery.o searchdata.o stemdb.o stoplist.o base64.o circache.o closefrom.o conftree.o copyfile.o debuglog.o ecrontab.o execmd.o fstreewalk.o idfile.o fileudi.o md5.o mimeparse.o netcon.o pathut.o pxattr.o rclionice.o readfile.o smallut.o transcode.o wipedir.o x11mon.o mime-getpart.o mime-parsefull.o mime-parseonlyheader.o mime-printbody.o mime-printdoc.o mime-printheader.o mime.o convert.o iodevice.o iofactory.o
DEPS = rclaspell.dep.stamp beaglequeuecache.dep.stamp cstr.dep.stamp rclconfig.dep.stamp rclinit.dep.stamp textsplit.dep.stamp unacpp.dep.stamp beaglequeue.dep.stamp csguess.dep.stamp fsindexer.dep.stamp indexer.dep.stamp mimetype.dep.stamp subtreelist.dep.stamp htmlparse.dep.stamp myhtmlparse.dep.stamp mimehandler.dep.stamp internfile.dep.stamp mh_exec.dep.stamp mh_execm.dep.stamp mh_html.dep.stamp mh_mail.dep.stamp mh_mbox.dep.stamp mh_text.dep.stamp txtdcode.dep.stamp docseq.dep.stamp docseqdb.dep.stamp docseqhist.dep.stamp filtseq.dep.stamp dynconf.dep.stamp plaintorich.dep.stamp recollq.dep.stamp reslistpager.dep.stamp sortseq.dep.stamp wasastringtoquery.dep.stamp wasatorcl.dep.stamp rcldb.dep.stamp rcldoc.dep.stamp rclquery.dep.stamp searchdata.dep.stamp stemdb.dep.stamp stoplist.dep.stamp base64.dep.stamp circache.dep.stamp closefrom.dep.stamp conftree.dep.stamp copyfile.dep.stamp debuglog.dep.stamp ecrontab.dep.stamp execmd.dep.stamp fstreewalk.dep.stamp idfile.dep.stamp fileudi.dep.stamp md5.dep.stamp mimeparse.dep.stamp netcon.dep.stamp pathut.dep.stamp pxattr.dep.stamp rclionice.dep.stamp readfile.dep.stamp smallut.dep.stamp transcode.dep.stamp wipedir.dep.stamp x11mon.dep.stamp mime-getpart.dep.stamp mime-parsefull.dep.stamp mime-parseonlyheader.dep.stamp mime-printbody.dep.stamp mime-printdoc.dep.stamp mime-printheader.dep.stamp mime.dep.stamp convert.dep.stamp iodevice.dep.stamp iofactory.dep.stamp
librcl.a : $(DEPS) $(OBJS) unac.o
ar ru librcl.a $(OBJS) unac.o
@ -109,6 +109,8 @@ copyfile.o : ../utils/copyfile.cpp $(depth)/mk/localdefs
$(CXX) $(ALL_CXXFLAGS) -c ../utils/copyfile.cpp
debuglog.o : ../utils/debuglog.cpp $(depth)/mk/localdefs
$(CXX) $(ALL_CXXFLAGS) -c ../utils/debuglog.cpp
ecrontab.o : ../utils/ecrontab.cpp $(depth)/mk/localdefs
$(CXX) $(ALL_CXXFLAGS) -c ../utils/ecrontab.cpp
execmd.o : ../utils/execmd.cpp $(depth)/mk/localdefs
$(CXX) $(ALL_CXXFLAGS) -c ../utils/execmd.cpp
fstreewalk.o : ../utils/fstreewalk.cpp $(depth)/mk/localdefs
@ -306,6 +308,9 @@ copyfile.dep.stamp : ../utils/copyfile.cpp $(depth)/mk/localdefs
debuglog.dep.stamp : ../utils/debuglog.cpp $(depth)/mk/localdefs
$(CXX) -M $(ALL_CXXFLAGS) ../utils/debuglog.cpp > debuglog.dep
touch debuglog.dep.stamp
ecrontab.dep.stamp : ../utils/ecrontab.cpp $(depth)/mk/localdefs
$(CXX) -M $(ALL_CXXFLAGS) ../utils/ecrontab.cpp > ecrontab.dep
touch ecrontab.dep.stamp
execmd.dep.stamp : ../utils/execmd.cpp $(depth)/mk/localdefs
$(CXX) -M $(ALL_CXXFLAGS) ../utils/execmd.cpp > execmd.dep
touch execmd.dep.stamp
@ -398,6 +403,7 @@ include closefrom.dep
include conftree.dep
include copyfile.dep
include debuglog.dep
include ecrontab.dep
include execmd.dep
include fstreewalk.dep
include idfile.dep

View File

@ -51,6 +51,7 @@ ${depth}/utils/closefrom.cpp \
${depth}/utils/conftree.cpp \
${depth}/utils/copyfile.cpp \
${depth}/utils/debuglog.cpp \
${depth}/utils/ecrontab.cpp \
${depth}/utils/execmd.cpp \
${depth}/utils/fstreewalk.cpp \
${depth}/utils/idfile.cpp \

View File

@ -1,9 +1,10 @@
depth = ..
include $(depth)/mk/sysconf
PROGS = trnetcon trcopyfile trcircache trmd5 trreadfile trfileudi \
trconftree wipedir smallut trfstreewalk trpathut transcode trbase64 \
trmimeparse trexecmd utf8iter idfile
PROGS = trecrontab
#trnetcon trcopyfile trcircache trmd5 trreadfile trfileudi \
#trconftree wipedir smallut trfstreewalk trpathut transcode trbase64 \
#trmimeparse trexecmd utf8iter idfile
all: $(PROGS) $(BIGLIB)
@ -11,6 +12,14 @@ $(BIGLIB): force
cd $(depth)/lib;$(MAKE)
force:
ECRONTAB_OBJS= trecrontab.o $(BIGLIB)
trecrontab : $(ECRONTAB_OBJS)
$(CXX) -o trecrontab $(ECRONTAB_OBJS) $(LIBICONV) \
$(LIBSYS)
trecrontab.o : ecrontab.cpp ecrontab.h
$(CXX) -o trecrontab.o -c $(ALL_CXXFLAGS) \
-DTEST_ECRONTAB ecrontab.cpp
FSTREEWALK_OBJS= trfstreewalk.o $(BIGLIB)
trfstreewalk : $(FSTREEWALK_OBJS)
$(CXX) -o trfstreewalk $(FSTREEWALK_OBJS) $(LIBICONV) \

205
src/utils/ecrontab.cpp Normal file
View File

@ -0,0 +1,205 @@
/* Copyright (C) 2004 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef TEST_ECRONTAB
#include "autoconfig.h"
#include "ecrontab.h"
#include "execmd.h"
#include "smallut.h"
bool editCrontab(const string& marker, const string& id,
const string& sched, const string& cmd, string& reason)
{
string crontab;
ExecCmd croncmd;
list<string> args;
int status;
// Retrieve current crontab contents. An error here means that no
// crontab exists, and is not fatal (just use empty string)
args.push_back("-l");
if ((status = croncmd.doexec("crontab", args, 0, &crontab))) {
// Special case: cmd is empty, no crontab, don't create one
if (cmd.empty())
return true;
}
// Split crontab into lines
vector<string> lines;
stringToTokens(crontab, lines, "\n");
// Remove old copy if any
for (vector<string>::iterator it = lines.begin();
it != lines.end(); it++) {
if (it->find(marker) != string::npos &&
it->find(id) != string::npos) {
lines.erase(it);
break;
}
}
if (!cmd.empty()) {
string nline = sched + " " + marker + " " + id + " " + cmd;
lines.push_back(nline);
}
// Rebuild new crontab and install it
crontab.clear();
for (vector<string>::iterator it = lines.begin();
it != lines.end(); it++) {
crontab += *it + "\n";
}
args.clear();
args.push_back("-");
if ((status = croncmd.doexec("crontab", args, &crontab, 0))) {
char nbuf[30];
sprintf(nbuf, "0x%x", status);
reason = string("Exec crontab -l failed: status: ") + nbuf;
}
return true;
}
bool checkCrontabUnmanaged(const string& marker, const string& data)
{
string crontab;
ExecCmd croncmd;
list<string> args;
int status;
// Retrieve current crontab contents. An error here means that no
// crontab exists.
args.push_back("-l");
if ((status = croncmd.doexec("crontab", args, 0, &crontab))) {
return false;
}
// Split crontab into lines
vector<string> lines;
stringToTokens(crontab, lines, "\n");
// Scan crontab
for (vector<string>::iterator it = lines.begin();
it != lines.end(); it++) {
if (it->find(marker) == string::npos &&
it->find(data) != string::npos) {
return true;
}
}
return false;
}
#else // TEST ->
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
#include "ecrontab.h"
static char *thisprog;
static char usage [] =
" -a add or replace crontab line \n"
" -a delete crontab line \n"
" -c <string> check for unmanaged lines for string\n"
;
static void
Usage(void)
{
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
exit(1);
}
static int op_flags;
#define OPT_MOINS 0x1
#define OPT_a 0x2
#define OPT_d 0x4
#define OPT_w 0x8
#define OPT_c 0x10
const string& marker("RCLCRON_RCLINDEX=");
// Note of course the -w does not make sense for a cron entry
const string& cmd0("recollindex -w ");
const string& id("RECOLL_CONFDIR=/home/dockes/.recoll");
const string& sched("30 8 * * *");
int main(int argc, char **argv)
{
thisprog = argv[0];
argc--; argv++;
string wt = "10";
string cmd;
while (argc > 0 && **argv == '-') {
(*argv)++;
if (!(**argv))
/* Cas du "adb - core" */
Usage();
while (**argv)
switch (*(*argv)++) {
case 'a': op_flags |= OPT_a; break;
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
cmd = *(++argv); argc--;
goto b1;
case 'd': op_flags |= OPT_d; break;
case 'w': op_flags |= OPT_w; if (argc < 2) Usage();
wt = *(++argv); argc--;
goto b1;
default: Usage(); break;
}
b1: argc--; argv++;
}
if (argc != 0)
Usage();
string reason;
bool status = false;
if (op_flags & OPT_a) {
cmd = cmd0 + wt;
status = editCrontab(marker, id, sched, cmd, reason);
} else if (op_flags & OPT_d) {
status = editCrontab(marker, id, sched, "", reason);
} else if (op_flags & OPT_c) {
if ((status = checkCrontabUnmanaged(marker, cmd))) {
cerr << "crontab has unmanaged lines for " << cmd << endl;
exit(1);
}
exit(0);
} else {
Usage();
}
if (!status) {
cerr << "editCrontab failed: " << reason << endl;
exit(1);
}
exit(0);
}
#endif // TEST

65
src/utils/ecrontab.h Normal file
View File

@ -0,0 +1,65 @@
/* Copyright (C) 2004 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ECRONTAB_H_INCLUDED_
#define _ECRONTAB_H_INCLUDED_
/** Utility function to manage lines inside a user crontab
*
* Lines managed by this routine are marked with a hopefuly unique marker
* and discriminated by a selector, both environment variable settings.
* Example:
* 30 8 * * * RCLCRONTAB_RCLINDEX= RECOLL_CONFDIR=/path/to/dir recollindex ...
* RCLCRONTAB_RCLINDEX is the line marker, and the RECOLL_CONFDIR value
* allows selecting the affected line.
*
* This approach allows leaving alone lines which do have a
* RECOLL_CONFDIR value but not managed by us. The marker and selector
* values are chosen by the caller, which should apply some thought to
* chosing sane values.
*/
#include <string>
using std::string;
/** Add, replace or delete a command inside a crontab file
*
* @param marker selects lines managed by this module and should take the form
* of a (possibly empty) environment variable assignement.
* @param id selects the appropriate line to affect and will usually be an
* actual variable assignment (see above)
* @param sched is a standard cron schedule spec (ie: 30 8 * * *)
* @param cmd is the command to execute (the last part of the line).
* Set it to an empty string to delete the line from the crontab
* @param reason error message
*
* "marker" and "id" should look like reasonable env variable assignements.
* Only ascii capital letters, numbers and _ before the '='
*/
bool editCrontab(const string& marker, const string& id,
const string& sched, const string& cmd,
string& reason
);
/**
* check crontab for unmanaged lines
* @param marker same as above, typically RCLCRONTAB_RCLINDEX=
* @param data string to look for on lines NOT marked, typically "recollindex"
* @return true if unmanaged lines exist, false else.
*/
bool checkCrontabUnmanaged(const string& marker, const string& data);
#endif /* _ECRONTAB_H_INCLUDED_ */