Sophie

Sophie

distrib > Mandriva > 2009.1 > i586 > media > main-release-src > by-pkgid > 4090922c88d76dcb9d3d77a391885b7d > files > 1

anacron-2.3-30mdv2009.1.src.rpm

--- anacron-2.3.orig/global.h
+++ anacron-2.3/global.h
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
 
     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
@@ -53,9 +54,11 @@
 
 struct job_rec1 {
    int period;
+   int named_period;
    int delay;
    char *ident;
    char *command;
+   char *mailto;
 
    int tab_line;
    int arg_num;
@@ -75,9 +78,10 @@
 extern pid_t primary_pid;
 extern char *program_name;
 extern char *anacrontab;
+extern char *spooldir;
 extern int old_umask;
 extern sigset_t old_sigmask;
-extern int serialize,force,update_only,now,no_daemon,quiet;
+extern int serialize,force,update_only,now,no_daemon,quiet,testing_only;
 extern int day_now;
 extern int year,month,day_of_month;
 extern int in_background;
@@ -93,6 +97,7 @@
 
 extern int running_jobs,running_mailers;
 
+extern int complaints;
 
 /* Function prototypes */
 
@@ -121,7 +126,7 @@
 #endif /* not DEBUG */
 
 /* readtab.c */
-void read_tab();
+void read_tab(int cwd);
 void arrange_jobs();
 
 /* lock.c */
--- anacron-2.3.orig/lock.c
+++ anacron-2.3/lock.c
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyirght (C) 2004  Pascal Hakim <pasc@redellipse.net>
  
     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
@@ -111,6 +112,35 @@
 	    xclose(jr->timestamp_fd);
 	    return 0;
 	}
+
+	/*
+	 * Check to see if it's a named period, in which case we need 
+	 * to figure it out.
+	 */
+	if (jr->named_period)
+	{
+	    int period = 0, bypass = 0;
+	    switch (jr->named_period)
+	    {
+		case 1:
+		    period = days_last_month ();
+		    bypass = days_this_month ();
+		    break;
+		case 2:
+		    period = days_last_year ();
+		    bypass = days_this_year ();
+		    break;
+		default:
+		    die ("Unknown named period for %s (%d)", jr->ident, jr->named_period);
+	    }
+	    printf ("Checking against %d with %d\n", day_delta, period);
+	    if (day_delta < period && day_delta != bypass)
+	    {
+		/* Job is still too young */
+		xclose (jr->timestamp_fd);
+		return 0;
+	    }
+	}
     }
 
     /* no! try to grab the lock */
--- anacron-2.3.orig/anacrontab.5
+++ anacron-2.3/anacrontab.5
@@ -1,4 +1,4 @@
-.TH ANACRONTAB 5 1998-02-02 "Itai Tzur" "Anacron Users' Manual"
+.TH ANACRONTAB 5 2004-07-11 "Pascal Hakim" "Anacron Users' Manual"
 .SH NAME
 /etc/anacrontab \- configuration file for anacron
 .SH DESCRIPTION
@@ -8,10 +8,13 @@
 three kinds:  job-description lines, environment
 assignments, or empty lines.
 .PP
-Job-description lines are of the form:
+Job-description lines are of one of these two forms:
 .PP
    period  delay  job-identifier  command
 .PP
+.PP
+   @period_name delay job-identify command
+.PP
 The
 .I period
 is specified in days, the
@@ -22,7 +25,12 @@
 the job in Anacron messages,
 and as the name for the job's timestamp file.  The
 .I command
-can be any shell command.
+can be any shell command. The fields can be seperated by blank spaces or tabs.
+The
+.I period_name
+can only be set to monthly at the present time. This will ensure jobs
+are only run once a month, no matter the number of days in this month,
+or the previous month.
 .PP
 Environment assignment lines are of the form:
 .PP
@@ -38,6 +46,8 @@
 .PP
 Empty lines are either blank lines, line containing white-space only, or
 lines with white-space followed by a '#' followed by an arbitrary comment.
+.PP
+You can continue a line onto the next line by ending it with a '\'.
 .SH "SEE ALSO"
 .B anacron(8)
 .PP
@@ -46,3 +56,5 @@
 file.
 .SH AUTHOR
 Itai Tzur <itzur@actcom.co.il>
+.PP
+Currently maintained by Pascal Hakim <pasc@(debian.org|redellipse.net)>.
--- anacron-2.3.orig/log.c
+++ anacron-2.3/log.c
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
  
     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
@@ -48,6 +49,9 @@
 static char msg[MAX_MSG + 1];
 static int log_open = 0;
 
+/* Number of complaints that we've seen */
+int complaints = 0;
+
 static void
 xopenlog()
 {
@@ -147,6 +151,8 @@
     va_start(args, fmt);
     log(COMPLAIN_LEVEL, fmt, args);
     va_end(args);
+
+    complaints += 1;
 }
 
 void
@@ -158,6 +164,8 @@
     va_start(args, fmt);
     log_e(COMPLAIN_LEVEL, fmt, args);
     va_end(args);
+
+    complaints += 1;
 }
 
 void
--- anacron-2.3.orig/anacron.apm
+++ anacron-2.3/anacron.apm
@@ -0,0 +1,19 @@
+#! /bin/sh
+
+# This script makes anacron jobs start to run when the machine is
+# plugged into AC power, or woken up.  For a laptop, these are the 
+# closest parallels to turning on a desktop.
+
+# The /etc/init.d/anacron script now normally tries to avoid running
+# anacron unless on AC power, so as to avoid running down the battery.
+# (Things like the slocate updatedb cause a lot of IO.)  Rather than
+# trying to second-guess which events reflect having or not having
+# power, we just try to run anacron every time and let it abort if
+# there's no AC.  You'll see a message on the cron syslog facility 
+# (typically /var/log/cron) if it does run.
+
+case "$1,$2" in
+change,power|resume,*)
+    /etc/init.d/anacron start >/dev/null
+    ;;
+esac
--- anacron-2.3.orig/anacron.8
+++ anacron-2.3/anacron.8
@@ -1,13 +1,15 @@
-.TH ANACRON 8 2000-06-22 "Sean 'Shaleh' Perry" "Anacron Users' Manual"
+.TH ANACRON 8 2004-07-11 "Pascal Hakim" "Anacron Users' Manual"
 .SH NAME
 anacron \- runs commands periodically
 .SH SYNOPSIS
 .B anacron \fR[\fB-s\fR] [\fB-f\fR] [\fB-n\fR] [\fB-d\fR] [\fB-q\fR]
-[\fB-t anacrontab\fR] [\fIjob\fR] ...
+[\fB-t anacrontab\fR] [\fB-S spooldir\fR] [\fIjob\fR] ...
 .br
-.B anacron -u [\fB-t anacrontab\fR] \fR[\fIjob\fR] ...
+.B anacron [\fB-S spooldir\fR] -u [\fB-t anacrontab\fR] \fR[\fIjob\fR] ...
 .br
 .B anacron \fR[\fB-V\fR|\fB-h\fR]
+.br
+.B anacron -T [\fB-t anacrontab\fR]
 .SH DESCRIPTION
 Anacron
 can be used to execute commands periodically, with a
@@ -58,7 +60,10 @@
 completely independent.
 .PP
 If a job generates any output on its standard output or standard error,
-the output is mailed to the user running Anacron (usually root).
+the output is mailed to the user running Anacron (usually root), or to
+the address contained by the MAILTO environment variable in the crontab, if such
+exists. If the LOGNAME environment variable is set, it will be used as From:
+field.
 .PP
 Informative messages about what Anacron is doing are sent to \fBsyslogd(8)\fR
 under facility \fBcron\fR, priority \fBnotice\fR.  Error messages are sent at
@@ -98,6 +103,15 @@
 .B -t anacrontab
 Use specified anacrontab, rather than the default
 .TP
+.B -T
+Anacrontab testing. The configuration file will be tested for validity. If
+there is an error in the file, an error will be shown and anacron will 
+return 1. Valid anacrontabs will return 0.
+.TP
+.B -S spooldir
+Use the specified spooldir to store timestamps in. This option is required for
+users who wish to run anacron themselves.
+.TP
 .B -V
 Print version information, and exit.
 .TP
@@ -115,6 +129,8 @@
 file.  See
 .B tzset(3)
 for more information.
+
+Timestamp files are created in the spool directory for each job in anacrontab. These are never removed automatically by anacron, and should be removed by hand if a job is no longer being scheduled.
 .SH FILES
 .TP
 .I /etc/anacrontab
@@ -144,4 +160,7 @@
 The current implementation is a complete rewrite by Itai Tzur
 <itzur@actcom.co.il>.
 .PP
-The code base is currently maintained by Sean 'Shaleh' Perry <shaleh@(debian.org|valinux.com)>.
+The code base was maintained by Sean 'Shaleh' Perry <shaleh@(debian.org|valinux.com)>.
+.PP
+Since 2004, it is maintained by Pascal Hakim <pasc@(debian.org|redellipse.net)>.
+
--- anacron-2.3.orig/TODO
+++ anacron-2.3/TODO
@@ -1,6 +1,3 @@
-anacron runs jobs twice in a 31 day month
-add hostname to emails sent to admin
-allow user anacrontabs
 make manpages match #defines automagically --> sed fu
 full ANSI / POSIX compliance
 code cleaning
--- anacron-2.3.orig/gregor.h
+++ anacron-2.3/gregor.h
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
 
     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
@@ -23,3 +24,7 @@
 
 
 int day_num(int year, int month, int day);
+int days_last_month (void);
+int days_this_month (void);
+int days_last_year (void);
+int days_this_year (void);
--- anacron-2.3.orig/gregor.c
+++ anacron-2.3/gregor.c
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
  
     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
@@ -23,6 +24,7 @@
 
 
 #include <limits.h>
+#include <time.h>
 #include "gregor.h"
 
 const static int
@@ -65,7 +67,7 @@
 {
     int dn;
     int i;
-    const int isleap; /* save three calls to leap() */
+    int isleap; /* save three calls to leap() */
 
     /* Some validity checks */
 
@@ -114,3 +116,66 @@
     /* but not by 400 */
     return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
 }
+
+int
+days_last_month (void)
+/* How many days did last month have? */
+{
+    struct tm time_record;
+    time_t current_time;
+    time (&current_time);
+    localtime_r (&current_time, &time_record);
+
+    switch (time_record.tm_mon) {
+	case 0: return days_in_month[11];
+	case 2: return days_in_month[1] + (leap (time_record.tm_year + 1900) ? 1 : 0);
+	default: return days_in_month[time_record.tm_mon - 1];
+    }
+}
+
+int
+days_this_month (void)
+/* How many days does this month have? */
+{
+    struct tm time_record;
+    time_t current_time;
+    time (&current_time);
+    localtime_r (&current_time, &time_record);
+
+    switch (time_record.tm_mon) {
+	case 1: return days_in_month[1] + (leap (time_record.tm_year + 1900) ? 1 : 0);
+	default: return days_in_month[time_record.tm_mon];
+    }
+}
+
+int
+days_last_year (void)
+/* How many days this last year have? */
+{
+    struct tm time_record;
+    time_t current_time;
+    time (&current_time);
+    localtime_r (&current_time, &time_record);
+
+    if (leap(time_record.tm_year - 1 + 1900)) {
+	return 366;
+    }
+
+    return 365;
+}
+
+int
+days_this_year (void)
+/* How many days does this year have */
+{
+     struct tm time_record;
+    time_t current_time;
+    time (&current_time);
+    localtime_r (&current_time, &time_record);
+
+    if (leap(time_record.tm_year + 1900)) {
+	return 366;
+    }
+
+    return 365;
+}
--- anacron-2.3.orig/main.c
+++ anacron-2.3/main.c
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
  
     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
@@ -39,8 +40,9 @@
 
 char *program_name;
 char *anacrontab;
+char *spooldir;
 int serialize, force, update_only, now,
-    no_daemon, quiet;                            /* command-line options */
+    no_daemon, quiet, testing_only;            /* command-line options */
 char **args;                       /* vector of "job" command-line arguments */
 int nargs;                                     /* number of these */
 char *defarg = "*";
@@ -61,17 +63,19 @@
     printf("Anacron " RELEASE "\n"
 	   "Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>\n"
 	   "Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>\n"
+	   "Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>\n"
 	   "\n"
-	   "Mail comments, suggestions and bug reports to <shaleh@debian.org>."
+	   "Mail comments, suggestions and bug reports to <pasc@redellipse.net>."
 	   "\n\n");
 }
 
 static void
 print_usage()
 {
-    printf("Usage:  anacron [-s] [-f] [-n] [-d] [-q] [-t anacrontab] [job] ...\n"
-	   "        anacron -u [job] ...\n"
+    printf("Usage:  anacron [-s] [-f] [-n] [-d] [-q] [-t anacrontab] [-S spooldir] [job] ...\n"
+	   "        anacron [-S spooldir] -u [job] ...\n"
 	   "        anacron [-V|-h]\n"
+	   "        anacron -T [-t anacrontab]\n"
 	   "\n"
 	   " -s  Serialize execution of jobs\n"
 	   " -f  Force execution of jobs, even before their time\n"
@@ -82,6 +86,8 @@
 	   " -t  Use this anacrontab\n"
 	   " -V  Print version information\n"
 	   " -h  Print this message\n"
+	   " -T  Test an anacrontab\n"
+	   " -S  Select a different spool directory\n"
 	   "\n"
 	   "See the manpage for more details.\n"
 	   "\n");
@@ -95,7 +101,7 @@
 
     quiet = no_daemon = serialize = force = update_only = now = 0;
     opterr = 0;
-    while ((opt = getopt(argc, argv, "sfundqt:Vh")) != EOF)
+    while ((opt = getopt(argc, argv, "sfundqt:TS:Vh")) != EOF)
     {
 	switch (opt)
 	{
@@ -120,6 +126,12 @@
 	case 't':
 	    anacrontab = strdup(optarg);
 	    break;
+	case 'T':
+	    testing_only = 1;
+	    break;
+	case 'S':
+	    spooldir = strdup(optarg);
+	    break;
 	case 'V':
 	    print_version();
 	    exit(0);
@@ -351,7 +363,7 @@
     day_of_month = tm_now->tm_mday;
     day_now = day_num(year, month, day_of_month);
     if (day_now == -1) die("Invalid date (this is really embarrassing)");
-    if (!update_only)
+    if (!update_only && !testing_only)
 	explain("Anacron " RELEASE " started on %04d-%02d-%02d",
 		year, month, day_of_month);
 }
@@ -414,7 +426,10 @@
 {
     int j;
 
+    int cwd;
+
     anacrontab = NULL;
+    spooldir = NULL;
 
     if((program_name = strrchr(argv[0], '/')) == NULL)
 	program_name = argv[0];
@@ -426,9 +441,16 @@
     if (anacrontab == NULL)
 	anacrontab = strdup(ANACRONTAB);
 
+    if (spooldir == NULL)
+	spooldir = strdup(SPOOLDIR);
+
+    if ((cwd = open ("./", O_RDONLY)) == -1) {
+	die_e ("Can't save current directory");
+    }
+
     in_background = 0;
 
-    if (chdir(SPOOLDIR)) die_e("Can't chdir to " SPOOLDIR);
+    if (chdir(spooldir)) die_e("Can't chdir to %s", spooldir );
 
     old_umask = umask(0);
 
@@ -437,15 +459,22 @@
     if (fclose(stdin)) die_e("Can't close stdin");
     xopen(0, "/dev/null", O_RDONLY);
 
-    if (!no_daemon)
+    if (!no_daemon && !testing_only)
 	go_background();
     else
 	primary_pid = getpid();
 
     record_start_time();
-    read_tab();
+    read_tab(cwd);
     arrange_jobs();
 
+    if (testing_only)
+    {
+	if (complaints) exit (1);
+	
+	exit (0);
+    }
+
     if (update_only)
     {
 	fake_jobs();
@@ -462,6 +491,6 @@
 	launch_job(job_array[j]);
     }
     wait_children();
-    explain("Normal exit (%d jobs run)", njobs);
+    explain("Normal exit (%d job%s run)", njobs, (njobs == 1 ? "" : "s"));
     exit(0);
 }
--- anacron-2.3.orig/ChangeLog
+++ anacron-2.3/ChangeLog
@@ -1,3 +1,8 @@
+   Changes in Anacron 2.3.1
+   ------------------------
+* documentation no longer suggests adding local directories to the PATH
+
+
    Changes in Anacron 2.3
    ----------------------
 * anacron can now read an arbitrary anacrontab file, use the -t option
--- anacron-2.3.orig/readtab.c
+++ anacron-2.3/readtab.c
@@ -2,6 +2,7 @@
     Anacron - run commands periodically
     Copyright (C) 1998  Itai Tzur <itzur@actcom.co.il>
     Copyright (C) 1999  Sean 'Shaleh' Perry <shaleh@debian.org>
+    Copyright (C) 2004  Pascal Hakim <pasc@redellipse.net>
  
     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
@@ -83,11 +84,23 @@
 Return NULL if no more lines.
  */
 {
-    int c;
+    int c, prev=0;
 
     if (feof(tab)) return NULL;
-    while ((c = getc(tab)) != EOF && c != '\n')
-	obstack_1grow(&input_o, c);
+    while (1)
+    {
+	c = getc(tab);
+	if ((c == '\n' && prev != '\\') || c == EOF)
+	{
+	    if (0 != prev) obstack_1grow(&input_o, prev);
+	    break;
+	}
+
+	if ('\\' != prev && 0 != prev && '\n' != prev) obstack_1grow(&input_o, prev);
+	else if ('\n' == prev) obstack_1grow(&input_o, ' ');
+
+	prev = c;
+    }
     if (ferror(tab)) die_e("Error reading %s", anacrontab);
     obstack_1grow(&input_o, '\0');
     return obstack_finish(&input_o);
@@ -153,6 +166,7 @@
     }
     jr = obstack_alloc(&tab_o, sizeof(job_rec));
     jr->period = period;
+    jr->named_period = 0;
     jr->delay = delay;
     jr->tab_line = line_num;
     jr->ident = obstack_alloc(&tab_o, ident_len + 1);
@@ -171,6 +185,54 @@
 }
 
 static void
+register_period_job(const char *periods, const char *delays,
+		    const char *ident, char *command)
+/* Store a job definition with a named period */
+{
+    int delay;
+    job_rec *jr;
+    int period_len, ident_len, command_len;
+
+    period_len = strlen(periods);
+    ident_len = strlen(ident);
+    command_len = strlen(command);
+    jobs_read++;
+    delay = conv2int(delays);
+    if (delay < 0)
+    {
+	complain("%s: number out of range on line %d, skipping",
+		 anacrontab, line_num);
+	return;
+    }
+
+    jr = obstack_alloc(&tab_o, sizeof(job_rec));
+    if (!strncmp ("@monthly", periods, 7)) {
+	jr->named_period = 1;
+    } else if (!strncmp("@yearly", periods, 7)) {
+	jr->named_period = 2;
+    } else {
+	complain("%s: Unknown named period on line %d, skipping",
+		 anacrontab, line_num);
+    }
+    jr->period = 0;
+    jr->delay = delay;
+    jr->tab_line = line_num;
+    jr->ident = obstack_alloc(&tab_o, ident_len + 1);
+    strcpy(jr->ident, ident);
+    jr->arg_num = job_arg_num(ident);
+    jr->command = obstack_alloc(&tab_o, command_len + 1);
+    strcpy(jr->command, command);
+    jr->job_pid = jr->mailer_pid = 0;
+    if (last_job_rec != NULL) last_job_rec->next = jr;
+    else first_job_rec = jr;
+    last_job_rec = jr;
+    jr->prev_env_rec = last_env_rec;
+    jr->next = NULL;
+    Debug(("Read job - period %d, delay=%d, ident%s, command=%s",
+	  jr->named_period, jr->delay, jr->ident, jr->command));
+}
+
+static void
 parse_tab_line(char *line)
 {
     int r;
@@ -210,6 +272,18 @@
 	register_job(periods, delays, ident, command);
 	return;
     }
+
+    /* A period job? */
+    r = match_rx("^[ \t]*(@[^ \t]+)[ \t]+([[:digit:]]+)[ \t]+"
+		 "([^ \t/]+)[ \t]+([^ \t].*)$",
+		 line, 4, &periods, &delays, &ident, &command);
+    if (r == -1) goto reg_err;
+    if (r)
+    {
+	register_period_job(periods, delays, ident, command);
+	return;
+    }
+
     complain("Invalid syntax in %s on line %d - skipping this line",
 	     anacrontab, line_num);
     return;
@@ -219,7 +293,7 @@
 }
 
 void
-read_tab()
+read_tab(int cwd)
 /* Read the anacrontab file into memory */
 {
     char *tab_line;
@@ -229,7 +303,10 @@
     jobs_read = 0;
     line_num = 0;
     /* Open the anacrontab file */
+    fchdir (cwd);
     tab = fopen(anacrontab, "r");
+    if (chdir(spooldir)) die_e("Can't chdir to %s", SPOOLDIR);
+
     if (tab == NULL) die_e("Error opening %s", anacrontab);
     /* Initialize the obstacks */
     obstack_init(&input_o);
@@ -271,7 +348,7 @@
     njobs = 0;
     while (j != NULL)
     {
-	if (j->arg_num != -1 && (update_only || consider_job(j)))
+	if (j->arg_num != -1 && (update_only || testing_only || consider_job(j)))
 	{
 	    njobs++;
 	    obstack_grow(&tab_o, &j, sizeof(j));
--- anacron-2.3.orig/runjob.c
+++ anacron-2.3/runjob.c
@@ -109,7 +109,6 @@
 run_job(const job_rec *jr)
 /* This is called to start the job, after the fork */
 {
-    setup_env(jr);
     /* setup stdout and stderr */
     xclose(1);
     xclose(2);
@@ -153,6 +152,15 @@
 launch_mailer(job_rec *jr)
 {
     pid_t pid;
+    struct stat buf;
+    int r;
+
+    /* Check that we have a way of sending mail. */
+    if(stat(SENDMAIL, &buf))
+    {
+	complain("Can't find sendmail at %s, not mailing output", SENDMAIL);
+	return;
+    }
 
     pid = xfork();
     if (pid == 0)
@@ -173,7 +181,7 @@
 	 * options, which don't seem to be appropriate here.
 	 * Hopefully, this will keep all the MTAs happy. */
 	execl(SENDMAIL, SENDMAIL, "-FAnacron", "-odi",
-	      username(), (char *)NULL);
+	      jr->mailto, (char *)NULL);
 	die_e("Can't exec " SENDMAIL);
     }
     /* parent */
@@ -207,19 +215,44 @@
 {
     pid_t pid;
     int fd;
+    char hostname[512];
+    char *mailto;
+
+    /* get hostname */
+    if (gethostname(hostname, 512)) {
+      strcpy (hostname,"unknown machine");
+    }
+
+    setup_env(jr);
+   
+    /* Get the destination email address if set, or current user otherwise */
+    mailto = getenv("MAILTO");
+
+    if (mailto)
+	    jr->mailto = mailto;
+    else
+	    jr->mailto = username ();
 
     /* create temporary file for stdout and stderr of the job */
     fd = jr->output_fd = temp_file();
     /* write mail header */
     xwrite(fd, "From: ");
+    xwrite(fd, "Anacron <");
     xwrite(fd, username());
-    xwrite(fd, " (Anacron)\n");
+    xwrite(fd, ">\n");
     xwrite(fd, "To: ");
-    xwrite(fd, username());
+    if (mailto) {
+       xwrite(fd, mailto);
+    } else {
+       xwrite(fd, username());
+    }
     xwrite(fd, "\n");
     xwrite(fd, "Subject: Anacron job '");
     xwrite(fd, jr->ident);
-    xwrite(fd, "'\n\n");
+    xwrite(fd, "' on ");
+    xwrite(fd, hostname);
+    xwrite(fd, "\n\n");
+
     jr->mail_header_size = file_size(fd);
 
     pid = xfork();