* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: allow.c,v 1.8 2001-06-12 06:40:54 thib Exp $ */
+ /* $Id: allow.c,v 1.9 2001-06-22 21:10:30 thib Exp $ */
#include "fcrontab.h"
#include "allow.h"
return 0;
/* check if user is in fcron.allow and/or in fcron.deny files */
- allow = in_file(user, ETC "/" FCRON_ALLOW);
- deny = in_file(user, ETC "/" FCRON_DENY);
+ allow = in_file(user, fcronallow);
+ deny = in_file(user, fcrondeny);
if ( allow == -1 && deny == -1 )
/* neither fcron.allow nor fcron.deny exist :
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: conf.c,v 1.45 2001-05-28 18:48:54 thib Exp $ */
+ /* $Id: conf.c,v 1.46 2001-06-22 21:09:00 thib Exp $ */
#include "fcron.h"
#include "conf.h"
struct dirent *den;
if ( strcmp(dir_name, ".") == 0 )
- explain("updating configuration from " FCRONTABS );
+ explain("updating configuration from %s", fcrontabs);
else
explain("updating configuration from %s", dir_name);
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: config.h.in,v 1.31 2001-06-05 10:18:16 thib Exp $ */
+ /* $Id: config.h.in,v 1.32 2001-06-22 21:09:30 thib Exp $ */
/* *********************************************************** */
/* beginning of configurable stuff ********************************** */
-/* fcron allow and deny file are located in directory ETC (see below) */
+/* fcron allow, deny and conf files are located in directory ETC (see below) */
#define FCRON_ALLOW "fcron.allow"
-
#define FCRON_DENY "fcron.deny"
+#define FCRON_CONF "fcron.conf"
#define SENDMAIL_ARGS "-Ffcron", "-odi" /* args of mail command */
+/* *** time *** */
+#define FIRST_SLEEP 20 /* fcron sleep at least this time after startup
+ * before executing a job, to avoid to run jobs
+ * during system boot */
+
+#define LAVG_SLEEP 30 /* the time we sleep when some jobs are in lavg queue */
+
+#define SAVE 1800 /* save every n seconds */
+
+/* *** behavior *** */
+#define SERIAL_ONCE 0 /* can a job be several times in the serial queue at
+ * the same moment ? */
+
+#define LAVG_ONCE 1 /* can a job be several times in the lavg queue at
+ * the same moment ? */
+
+#define MAXYEAR_SCHEDULE_TIME 10 /* a job can't be scheduled further than
+ * now + MAXYEAR_SCHEDULE years. This is used
+ * to prevent infinite loop on corrupted lines */
+
/* *** memory *** */
#define EXE_INITIAL_SIZE 6 /* initial number of possible running job
* if more jobs have to be run simultaneously,
#define MAX_MSG 150 /* max length of a log message */
-/* *** time *** */
-#define FIRST_SLEEP 20 /* fcron sleep at least this time after startup
- * before executing a job, to avoid to run jobs
- * during system boot */
-
-#define LAVG_SLEEP 30 /* the time we sleep when some jobs are in lavg queue */
-
-#define SAVE 1800 /* save every n seconds */
-
-/* *** behavior *** */
-#define SERIAL_ONCE 0 /* can a job be several times in the serial queue at
- * the same moment ? */
-
-#define LAVG_ONCE 1 /* can a job be several times in the lavg queue at
- * the same moment ? */
-
-#define MAXYEAR_SCHEDULE_TIME 10 /* a job can't be scheduled further than
- * now + MAXYEAR_SCHEDULE years. This is used
- * to prevent infinite loop on corrupted lines */
-
/* *** system dependent *** */
#define EXIT_ERR 1 /* code returned by fcron/fcrontab on error */
#define EXIT_OK 0 /* code returned on normal exit */
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: fcron.c,v 1.48 2001-06-05 10:17:56 thib Exp $ */
+ /* $Id: fcron.c,v 1.49 2001-06-22 21:08:03 thib Exp $ */
#include "fcron.h"
-char rcs_info[] = "$Id: fcron.c,v 1.48 2001-06-05 10:17:56 thib Exp $";
+char rcs_info[] = "$Id: fcron.c,v 1.49 2001-06-22 21:08:03 thib Exp $";
void main_loop(void);
void check_signal(void);
f = file_base;
}
- remove(PIDFILE);
+ remove(pidfile);
explain("Exiting with code %d", exit_value);
exit (exit_value);
if ( ! daemon_lockfp ) {
int fd;
- if (((fd = open(PIDFILE, O_RDWR|O_CREAT, 0644)) == -1 )
+ if (((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1 )
|| ((daemon_lockfp = fdopen(fd, "r+"))) == NULL)
- die_e("can't open or create " PIDFILE);
+ die_e("can't open or create %s", pidfile);
#ifdef HAVE_FLOCK
/* flock() seems to keep the lock over a fork() (contrary to lockf() ):
* we only need to lock the file once */
if ( flock(fd, LOCK_EX|LOCK_NB) != 0 ) {
fscanf(daemon_lockfp, "%d", &otherpid);
- die("can't lock " PIDFILE ", running daemon's pid may be %d",
- otherpid);
+ die("can't lock %s, running daemon's pid may be %d",
+ pidfile, otherpid);
}
#endif /* HAVE_FLOCK */
#ifndef HAVE_FLOCK
if ( lockf(fileno(daemon_lockfp), F_TLOCK, 0) != 0 ) {
fscanf(daemon_lockfp, "%d", &otherpid);
- die("can't lock " PIDFILE ", running daemon's pid may be %d",
- otherpid);
+ die("can't lock %s, running daemon's pid may be %d",
+ pidfile, otherpid);
}
#endif /* ! HAVE_FLOCK */
{"version", 0, NULL, 'V'},
{"savetime", 1, NULL, 's'},
{"maxserial", 1, NULL, 'm'},
+ {"configfile", 1, NULL, 'c'},
{0,0,0,0}
};
#endif /* HAVE_GETOPT_H */
while(1) {
#ifdef HAVE_GETOPT_H
- c = getopt_long(argc, argv, "dfbhVs:m:", opt, NULL);
+ c = getopt_long(argc, argv, "dfbhVs:m:c:", opt, NULL);
#else
- c = getopt(argc, argv, "dfbhVs:m:");
+ c = getopt(argc, argv, "dfbhVs:m:c:");
#endif /* HAVE_GETOPT_H */
if (c == EOF) break;
switch (c) {
die("Max running can only be set between 1 and %d.",SHRT_MAX);
break;
+ case 'c':
+ Set(fcronconf, optarg);
+ break;
+
case ':':
error("(parseopt) Missing parameter");
usage();
main(int argc, char **argv)
{
- /* we set it to 022 in order to get a PIDFILE readable by fcrontab
+ /* we set it to 022 in order to get a pidfile readable by fcrontab
* (will be set to 066 later) */
saved_umask = umask(022);
parseopt(argc, argv);
+ /* read fcron.conf and update global parameters */
+ read_conf();
+
/* change directory */
- if (chdir(FCRONTABS) != 0)
- die_e("Could not change dir to " FCRONTABS);
+ if (chdir(fcrontabs) != 0)
+ die_e("Could not change dir to %s", fcrontabs);
if (foreground == 0) {
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: fcrontab.c,v 1.38 2001-06-03 10:54:22 thib Exp $ */
+ /* $Id: fcrontab.c,v 1.39 2001-06-22 21:06:37 thib Exp $ */
/*
* The goal of this program is simple : giving a user interface to fcron
#include "fcrontab.h"
-char rcs_info[] = "$Id: fcrontab.c,v 1.38 2001-06-03 10:54:22 thib Exp $";
+char rcs_info[] = "$Id: fcrontab.c,v 1.39 2001-06-22 21:06:37 thib Exp $";
void info(void);
void usage(void);
FILE *fp = NULL;
pid_t pid = 0;
- if ((fp = fopen(PIDFILE, "r")) != NULL) {
+ if ((fp = fopen(pidfile, "r")) != NULL) {
fscanf(fp, "%d", (int *) &pid);
fclose(fp);
}
FILE *fp = NULL;
int fd = 0;
struct tm *tm = NULL;
-
+ char sigfile[PATH_LEN];
t = time(NULL);
tm = localtime(&t);
fprintf(stderr, "Modifications will be taken into account"
" at %s.\n", buf);
+ snprintf(sigfile, sizeof(sigfile), "%s/fcrontab.sig", fcrontabs);
#if defined(HAVE_SETREGID) && defined(HAVE_SETREUID)
if (seteuid(fcrontab_uid) != 0)
switch ( fork() ) {
case -1:
- remove(FCRONTABS "/fcrontab.sig");
+ remove(sigfile);
die_e("could not fork : daemon has not been signaled");
break;
case 0:
foreground = 0;
/* try to create a lock file */
- if ((fd = open(FCRONTABS "/fcrontab.sig", O_RDWR|O_CREAT, 0644)) == -1
+ if ((fd = open(sigfile, O_RDWR|O_CREAT, 0644)) == -1
|| ((fp = fdopen(fd, "r+")) == NULL) )
- die_e("can't open or create " FCRONTABS "/fcrontab.sig");
+ die_e("can't open or create %s", sigfile);
#ifdef HAVE_FLOCK
if ( flock(fd, LOCK_EX|LOCK_NB) != 0 ) {
fclose(fp);
close(fd);
- remove(FCRONTABS "/fcrontab.sig");
+ remove(sigfile);
}
else
fprintf(stderr, "Modifications will be taken into account"
return_val = ERR;
}
- /* copy original file to FCRONTABS dir */
+ /* copy original file to fcrontabs dir */
snprintf(buf, sizeof(buf), "%s.orig", user);
if ( copy(file, buf) == ERR )
return_val = ERR;
/* copy file to a temp file, edit that file, and install it
if necessary */
{
- char *editor = NULL;
+ char *cureditor = NULL;
pid_t pid;
int status;
struct stat st;
char correction = 0;
short return_val = EXIT_OK;
- explain("fcrontabs : editing %s's fcrontab", user);
+ explain("fcrontab : editing %s's fcrontab", user);
- if ( (editor = getenv("VISUAL")) == NULL || strcmp(editor, "\0") == 0 )
- if( (editor = getenv("EDITOR")) == NULL || strcmp(editor, "\0") == 0 )
- editor = EDITOR;
+ if ((cureditor=getenv("VISUAL")) == NULL || strcmp(cureditor, "\0") == 0 )
+ if((cureditor=getenv("EDITOR"))==NULL || strcmp(cureditor, "\0") == 0 )
+ cureditor = editor;
file = temp_file(&tmp_str);
if ( (fi = fdopen(file, "w")) == NULL ) {
goto exiterr;
}
#endif
- execlp(editor, editor, tmp_str, NULL);
- error_e("Error while running \"%s\"", editor);
+ execlp(cureditor, cureditor, tmp_str, NULL);
+ error_e("Error while running \"%s\"", cureditor);
goto exiterr;
case -1:
/* constants and variables defined by command line */
while(1) {
- c = getopt(argc, argv, "u:lrezdnhV");
+ c = getopt(argc, argv, "u:lrezdnhVc:");
if (c == EOF) break;
switch (c) {
ignore_prev = 1;
break;
+ case 'c':
+ Set(fcronconf, optarg);
+ break;
+
case ':':
fprintf(stderr, "(setopt) Missing parameter");
usage();
}
}
+ /* read fcron.conf and update global parameters */
+ read_conf();
+
/* read the file name and/or user and check validity of the arguments */
if (argc - optind > 2)
usage();
if (seteuid(fcrontab_uid) != 0)
die_e("Could not change uid to fcrontab_uid[%d]",fcrontab_uid);
/* change directory */
- if (chdir(FCRONTABS) != 0) {
- error_e("Could not chdir to " FCRONTABS );
+ if (chdir(fcrontabs) != 0) {
+ error_e("Could not chdir to %s", fcrontabs);
xexit (EXIT_ERR);
}
/* get user's permissions */
if (setgid(0) != 0)
die_e("Could not change gid to 0");
/* change directory */
- if (chdir(FCRONTABS) != 0) {
- error_e("Could not chdir to " FCRONTABS );
+ if (chdir(fcrontabs) != 0) {
+ error_e("Could not chdir to %s", fcrontabs);
xexit (EXIT_ERR);
}
#endif
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: job.c,v 1.38 2001-05-15 00:37:54 thib Exp $ */
+ /* $Id: job.c,v 1.39 2001-06-22 21:06:05 thib Exp $ */
#include "fcron.h"
#include "job.h"
case 0:
/* child */
{
- char *shell;
+ char *curshell;
char *home;
env_t *env;
int mailfd = 0;
die_e("Could not chdir to HOME dir /");
}
- if ( (shell = getenv("SHELL")) == NULL )
- shell = SHELL;
- else if ( access(shell, X_OK) != 0 ) {
+ if ( (curshell = getenv("SHELL")) == NULL )
+ curshell = shell;
+ else if ( access(curshell, X_OK) != 0 ) {
if (errno == ENOENT)
- error("shell \"%s\" : no file or directory. SHELL set to "
- SHELL, shell);
+ error("shell \"%s\" : no file or directory. SHELL set to %s",
+ curshell, shell);
else
- error_e("shell \"%s\" not valid : SHELL set to " SHELL, shell);
- shell = SHELL;
+ error_e("shell \"%s\" not valid : SHELL set to %s",
+ curshell, shell);
+ curshell = shell;
}
#ifdef CHECKJOBS
/* this will force to mail a message containing at least the exact
* and complete command executed for each execution of all jobs */
- debug("Execing \"%s -c %s\"", shell, line->cl_shell);
+ debug("Execing \"%s -c %s\"", curshell, line->cl_shell);
#endif /* CHECKJOBS */
- execl(shell, shell, "-c", line->cl_shell, NULL);
+ execl(curshell, curshell, "-c", line->cl_shell, NULL);
/* execl returns only on error */
- error_e("Can't find \"%s\". Trying a execlp(\"sh\", ...)", shell);
+ error_e("Can't find \"%s\". Trying a execlp(\"sh\",...)",curshell);
execlp("sh", "sh", "-c", line->cl_shell, NULL);
- die_e("execl() \"%s -c %s\" error", shell, line->cl_shell);
+ die_e("execl() \"%s -c %s\" error", curshell, line->cl_shell);
/* execution never gets here */
xcloselog();
/* run sendmail with mail file as standard input */
- execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, line->cl_mailto, NULL);
- error_e("Can't find \""SENDMAIL"\". Trying a execlp(\"sendmail\")");
+ execl(sendmail, sendmail, SENDMAIL_ARGS, line->cl_mailto, NULL);
+ error_e("Can't find \"%s\". Trying a execlp(\"sendmail\")", sendmail);
execlp("sendmail", "sendmail", SENDMAIL_ARGS, line->cl_mailto, NULL);
die_e("Can't exec " SENDMAIL);
#else /* defined(SENDMAIL) */
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: subs.c,v 1.9 2001-06-12 06:40:33 thib Exp $ */
+ /* $Id: subs.c,v 1.10 2001-06-22 21:10:18 thib Exp $ */
#include "global.h"
#include "subs.h"
+void init_conf(void);
+
extern char *tmp_path;
+extern char debug_opt;
+
+/* fcron.conf parameters */
+char *fcronconf = NULL;
+char *fcronallow = NULL;
+char *fcrondeny = NULL;
+char *fcrontabs = NULL;
+char *pidfile = NULL;
+char *editor = NULL;
+char *shell = NULL;
+char *sendmail = NULL;
int
remove_blanks(char *str)
}
+void
+init_conf(void)
+/* initialises config with compiled in constants */
+{
+ /* set fcronconf if cmd line option -c has not been used */
+ if (fcronconf == NULL)
+ fcronconf = strdup2(ETC "/" FCRON_CONF);
+ fcronallow = strdup2(ETC "/" FCRON_ALLOW);
+ fcrondeny = strdup2(ETC "/" FCRON_DENY);
+ fcrontabs = strdup2(FCRONTABS);
+ pidfile = strdup2(PIDFILE);
+ editor = strdup2(EDITOR);
+ shell = strdup2(SHELL);
+ sendmail = strdup2(SENDMAIL);
+}
+
+
+void
+read_conf(void)
+/* reads in a config file and updates the necessary global variables */
+{
+ FILE *f = NULL;
+ struct stat st;
+ char buf[LINE_LEN];
+ char *ptr1 = NULL, *ptr2 = NULL;
+ short namesize = 0;
+ char err_on_enoent = 0;
+
+ if (fcronconf != NULL)
+ /* fcronconf has been set by -c option : file must exist */
+ err_on_enoent = 1;
+
+ init_conf();
+
+ if ( (f = fopen(fcronconf, "r")) == NULL ) {
+ if ( errno == ENOENT ) {
+ if ( err_on_enoent )
+ die_e("Could not read %s", fcronconf);
+ else
+ /* file does not exist, it is not an error */
+ return;
+ }
+ else {
+ error_e("Could not read %s : config file ignored", fcronconf);
+ return;
+ }
+ }
+
+ /* check if the file is secure : owned and writable only by root */
+ if ( fstat(fileno(f), &st) != 0 || st.st_uid != 0
+ || st.st_mode & S_IWGRP || st.st_mode & S_IWOTH ) {
+ error("Conf file (%s) must be owned by root and (no more than) 644 : "
+ "ignored", fcronconf);
+ fclose(f);
+ return;
+ }
+
+ while ( (ptr1 = fgets(buf, sizeof(buf), f)) != NULL ) {
+
+ Skip_blanks(ptr1); /* at the beginning of the line */
+
+ /* ignore comments and blank lines */
+ if ( *ptr1 == '#' || *ptr1 == '\n' || *ptr1 == '\0')
+ continue;
+
+ remove_blanks(ptr1); /* at the end of the line */
+
+ ptr2 = ptr1;
+
+ /* get the name of the var */
+ while ( (isalnum( (int) *ptr2) || *ptr2 == '_')
+ && *ptr2 != '=' && ! isspace( (int) *ptr2) )
+ ptr2++;
+
+ if ( (namesize = ptr2 - ptr1) == 0 )
+ /* name is zero-length */
+ error("Zero-length var name at line %s : line ignored", buf);
+
+ /* skip the blanks and the "=" and go to the value */
+ while ( isspace( (int) *ptr2 ) ) ptr2++;
+ if ( *ptr2 == '=' ) ptr2++;
+ while ( isspace( (int) *ptr2 ) ) ptr2++;
+
+ /* find which var the line refers to and update it */
+ if ( strncmp(ptr1, "fcronallow", 10) == 0 )
+ fcronallow = strdup2(ptr2);
+ else if ( strncmp(ptr1, "fcrondeny", 9) == 0 )
+ fcrondeny = strdup2(ptr2);
+ else if ( strncmp(ptr1, "fcrontabs", 9) == 0 )
+ fcrontabs = strdup2(ptr2);
+ else if ( strncmp(ptr1, "pidfile", 7) == 0 )
+ pidfile = strdup2(ptr2);
+ else if ( strncmp(ptr1, "editor", 6) == 0 )
+ editor = strdup2(ptr2);
+ else if ( strncmp(ptr1, "shell", 5) == 0 )
+ shell = strdup2(ptr2);
+ else if ( strncmp(ptr1, "sendmail", 8) == 0 )
+ sendmail = strdup2(ptr2);
+ else
+ error("Unknown var name at line %s : line ignored", buf);
+
+ }
+
+ if (debug_opt) {
+ debug("fcronconf=%s", fcronconf);
+ debug("fcronallow=%s", fcronallow);
+ debug("fcrondeny=%s", fcrondeny);
+ debug("fcrontabs=%s", fcrontabs);
+ debug("pidfile=%s", pidfile);
+ debug("editor=%s", editor);
+ debug("shell=%s", shell);
+ debug("sendmail=%s", sendmail);
+ }
+
+ fclose(f);
+
+}
+
+
int
save_type(FILE *f, short int type)
/* save a single type (with no data attached) in a binary fcrontab file */
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: subs.h,v 1.2 2001-05-15 00:51:17 thib Exp $ */
+ /* $Id: subs.h,v 1.3 2001-06-22 21:10:27 thib Exp $ */
#ifndef __SUBS_H__
#define __SUBS_H__
+
+/* global variables */
+
+/* fcron.conf parameters */
+extern char *fcronconf;
+extern char *fcronallow;
+extern char *fcrondeny;
+extern char *fcrontabs;
+extern char *pidfile;
+extern char *editor;
+extern char *shell;
+extern char *sendmail;
+/* end of global variables */
+
/* functions prototypes */
extern int remove_blanks(char *str);
extern char *strdup2(const char *);
extern int temp_file(char **name);
+extern void read_conf(void);
extern int save_type(FILE *f, short int type);
extern int save_str(FILE *f, short int type, char *str);
extern int save_strn(FILE *f, short int type, char *str, short int size);