# @configure_input@
-
# The following should not be edited manually (use configure options)
# If you must do it, BEWARE : some of the following is also defined
# in config.h, so you must modify config.h AND Makefile in order
# to set the same values in the two files.
-FCRON_ALLOW = fcron.allow
-FCRON_DENY = fcron.deny
-FCRON_CONF = fcron.conf
+# Please, keep assignments aligned with spaces.
+FCRON_ALLOW = fcron.allow
+FCRON_DENY = fcron.deny
+FCRON_CONF = fcron.conf
-SRCDIR := @srcdir@
+SRCDIR := @srcdir@
# Useful to build packages
# you may want to use this var with a : 'make DESTDIR=dir install'
-DESTDIR :=
+DESTDIR :=
# Where should we install it ?
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-DESTSBIN = @sbindir@
-DESTBIN = @bindir@
-ETC = @sysconfdir@
-FCRONTABS = @FCRONTABS@
-PIDDIR = @PIDDIR@
-FIFODIR = @FIFODIR@
-PIDFILE = @PIDFILE@
-REBOOT_LOCK = @REBOOT_LOCK@
-SUSPEND_FILE = @SUSPEND_FILE@
-FIFOFILE = @FIFOFILE@
-FCRON_SHELL = @FCRON_SHELL@
-SENDMAIL = @SENDMAIL@
-FCRON_EDITOR = @FCRON_EDITOR@
-OPTIM := @CFLAGS@
-LDFLAGS := @LDFLAGS@
-CPPFLAGS := @CPPFLAGS@ -I. -I${SRCDIR}
-LIBS := @LIBS@
-LIBOBJS := @LIBOBJS@
-DEFS := @DEFS@
-CC := @CC@
-INSTALL := @INSTALL@
-STRIP := @STRIP@
-ROOTNAME := @ROOTNAME@
-ROOTGROUP := @ROOTGROUP@
-USERNAME := @USERNAME@
-GROUPNAME := @GROUPNAME@
-SYSFCRONTAB := @SYSFCRONTAB@
-DEBUG := @DEBUG@
-BOOTINSTALL := @BOOTINSTALL@
-ANSWERALL := @ANSWERALL@
-USEPAM := @USEPAM@
-FCRONDYN := @FCRONDYN@
-SYSTEMD_DIR := @SYSTEMD_DIR@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+DESTSBIN = @sbindir@
+DESTBIN = @bindir@
+ETC = @sysconfdir@
+FCRONTABS = @FCRONTABS@
+PIDDIR = @PIDDIR@
+FIFODIR = @FIFODIR@
+PIDFILE = @PIDFILE@
+REBOOT_LOCK = @REBOOT_LOCK@
+SUSPEND_FILE = @SUSPEND_FILE@
+FIFOFILE = @FIFOFILE@
+FCRON_SHELL = @FCRON_SHELL@
+SENDMAIL = @SENDMAIL@
+FCRON_EDITOR = @FCRON_EDITOR@
+OPTIM := @CFLAGS@
+LDFLAGS := @LDFLAGS@
+CPPFLAGS := @CPPFLAGS@ -I. -I${SRCDIR}
+LIBS := @LIBS@
+LIBOBJS := @LIBOBJS@
+DEFS := @DEFS@
+CC := @CC@
+INSTALL := @INSTALL@
+STRIP := @STRIP@
+ROOTNAME := @ROOTNAME@
+ROOTGROUP := @ROOTGROUP@
+USERNAME := @USERNAME@
+GROUPNAME := @GROUPNAME@
+SYSFCRONTAB := @SYSFCRONTAB@
+DEBUG := @DEBUG@
+BOOTINSTALL := @BOOTINSTALL@
+ANSWERALL := @ANSWERALL@
+USEPAM := @USEPAM@
+FCRONDYN := @FCRONDYN@
+SYSTEMD_DIR := @SYSTEMD_DIR@
+DISPLAYNAME := @DISPLAYNAME@
# Options
-# -DDEBUG even more verbose
-# -DCHECKJOBS send a mail containing the exact shell command
-# for each execution of each job.
-# -DFOREGROUND=[0|1] default run in foreground ?
-#OPTION= -DCHECKJOBS
-#OPTION= -O3 -mcpu=i686
-OPTION :=
+# -DDEBUG even more verbose
+# -DCHECKJOBS send a mail containing the exact shell command
+# for each execution of each job.
+# -DFOREGROUND=[0|1] default run in foreground ?
+#OPTION = -DCHECKJOBS
+#OPTION = -O3 -mcpu=i686
+OPTION :=
####################################
# Should not be changed under this #
####################################
-VERSION := @VERSION@
-CFLAGS += $(OPTIM) $(OPTION) $(DEFS) $(CPPFLAGS) $(LDFLAGS)
+VERSION := @VERSION@
+CFLAGS += $(OPTIM) $(OPTION) $(DEFS) $(CPPFLAGS) $(LDFLAGS)
ifeq ($(FCRONDYN), 1)
-LIBOBJS := $(LIBOBJS)
+ LIBOBJS := $(LIBOBJS)
endif
-OBJSD := fcron.o cl.o subs.o mem.o save.o temp_file.o log.o database.o job.o conf.o u_list.o exe_list.o lavg_list.o env_list.o fcronconf.o filesubs.o select.o fcrondyn_svr.o suspend.o $(LIBOBJS)
-OBJSTAB := fcrontab.o cl.o subs.o mem.o save.o temp_file.o log.o fileconf.o allow.o read_string.o u_list.o env_list.o fcronconf.o filesubs.o
-OBJSDYN := fcrondyn.o subs.o mem.o log.o allow.o read_string.o fcronconf.o filesubs.o
-OBJCONV := convert-fcrontab.o cl.o subs.o mem.o save.o log.o u_list.o env_list.o fcronconf.o filesubs.o
-OBJSIG := fcronsighup.o subs.o mem.o log.o allow.o fcronconf.o filesubs.o
-HEADERSALL := config.h $(SRCDIR)/global.h $(SRCDIR)/cl.h $(SRCDIR)/log.h $(SRCDIR)/subs.h $(SRCDIR)/mem.h $(SRCDIR)/save.h $(SRCDIR)/option.h $(SRCDIR)/dyncom.h
+OBJSD := fcron.o cl.o subs.o mem.o save.o temp_file.o log.o database.o job.o conf.o u_list.o exe_list.o lavg_list.o env_list.o fcronconf.o filesubs.o select.o fcrondyn_svr.o suspend.o $(LIBOBJS)
+OBJSTAB := fcrontab.o cl.o subs.o mem.o save.o temp_file.o log.o fileconf.o allow.o read_string.o u_list.o env_list.o fcronconf.o filesubs.o
+OBJSDYN := fcrondyn.o subs.o mem.o log.o allow.o read_string.o fcronconf.o filesubs.o
+OBJCONV := convert-fcrontab.o cl.o subs.o mem.o save.o log.o u_list.o env_list.o fcronconf.o filesubs.o
+OBJSIG := fcronsighup.o subs.o mem.o log.o allow.o fcronconf.o filesubs.o
+HEADERSALL := config.h $(SRCDIR)/global.h $(SRCDIR)/cl.h $(SRCDIR)/log.h $(SRCDIR)/subs.h $(SRCDIR)/mem.h $(SRCDIR)/save.h $(SRCDIR)/option.h $(SRCDIR)/dyncom.h
# this is a regular expression :
# do not ci automaticaly generated files and doc (done by doc's Makefile)
-RCSNOCI:=.*\(.html\|VERSION\|MANIFEST\|configure\|install.sh\|config.log\|config.status\|config.h\|config.cache\|Makefile\|doc.*\|CVS.*\|.git.*\)
+RCSNOCI := .*\(.html\|VERSION\|MANIFEST\|configure\|install.sh\|config.log\|config.status\|config.h\|config.cache\|Makefile\|doc.*\|CVS.*\|.git.*\)
RUN_NON_PRIVILEGED := @RUN_NON_PRIVILEGED@
ifeq ($(RUN_NON_PRIVILEGED), 1)
- BINMODE:=711
- BINMODESIGHUP:=711
+ BINMODE := 711
+ BINMODESIGHUP := 711
else
- BINMODE:=6711
- BINMODESIGHUP:=4710
+ BINMODE := 6711
+ BINMODESIGHUP := 4710
endif
ifeq ($(FCRONDYN), 1)
-DFCRONTABS="\"${FCRONTABS}\"" \
-DFCRON_ALLOW="\"${FCRON_ALLOW}\"" -DFCRON_DENY="\"${FCRON_DENY}\"" \
-DFCRON_SHELL="\"${FCRON_SHELL}\"" -DSENDMAIL="\"${SENDMAIL}\"" \
- -DFCRON_EDITOR="\"${FCRON_EDITOR}\"" -DBINDIREX="\"${DESTBIN}\"" \
+ -DFCRON_EDITOR="\"${FCRON_EDITOR}\"" \-DDISPLAYNAME="\"${DISPLAYNAME}\"" -DBINDIREX="\"${DESTBIN}\"" \
-c $<
initscripts:
documentation:
$(MAKE) -C doc doc-if-none
-install: install-staged strip perms
+.PHONY: test
+test:
+ $(MAKE) -C test tests
+
+
+install: install-staged strip perms
ifeq ($(BOOTINSTALL), 1)
$(SRCDIR)/script/boot-install "$(INSTALL) -o $(ROOTNAME)" $(DESTSBIN) $(DEBUG) $(FCRONTABS) $(ANSWERALL) $(SRCDIR)
endif
perms: install-staged strip
# Note : we don't use "chown user:group file" because some systems use ":"
# and others "." as separator.
- chown $(ROOTNAME) $(DESTDIR)$(DESTSBIN)
- chgrp $(ROOTGROUP) $(DESTDIR)$(DESTSBIN)
- chown $(ROOTNAME) $(DESTDIR)$(DESTBIN)
- chgrp $(ROOTGROUP) $(DESTDIR)$(DESTBIN)
- chown $(ROOTNAME) $(DESTDIR)$(ETC)
- chgrp $(ROOTGROUP) $(DESTDIR)$(ETC)
- chown $(ROOTNAME) $(DESTDIR)$(FIFODIR)
- chgrp $(ROOTGROUP) $(DESTDIR)$(FIFODIR)
- chown $(ROOTNAME) $(DESTDIR)$(PIDDIR)
- chgrp $(ROOTGROUP) $(DESTDIR)$(PIDDIR)
+ chown $(ROOTNAME) $(DESTDIR)$(DESTSBIN)
+ chgrp $(ROOTGROUP) $(DESTDIR)$(DESTSBIN)
+ chown $(ROOTNAME) $(DESTDIR)$(DESTBIN)
+ chgrp $(ROOTGROUP) $(DESTDIR)$(DESTBIN)
+ chown $(ROOTNAME) $(DESTDIR)$(ETC)
+ chgrp $(ROOTGROUP) $(DESTDIR)$(ETC)
+ chown $(ROOTNAME) $(DESTDIR)$(FIFODIR)
+ chgrp $(ROOTGROUP) $(DESTDIR)$(FIFODIR)
+ chown $(ROOTNAME) $(DESTDIR)$(PIDDIR)
+ chgrp $(ROOTGROUP) $(DESTDIR)$(PIDDIR)
# change spool dir mode
chown $(USERNAME) $(DESTDIR)$(FCRONTABS)
endif
endif
-install-boot: install
+install-boot: install
$(SRCDIR)/script/boot-install "$(INSTALL) -o $(ROOTNAME)" $(DESTSBIN) $(DEBUG) $(FCRONTABS) $(ANSWERALL) $(SRCDIR)
install-restart: install
rm -f *.o core
rm -f fcron fcrontab fcrondyn fcronsighup convert-fcrontab files/fcron.conf
$(MAKE) -C doc clean
+ $(MAKE) -C test clean
ciclean: clean
find ./ -name "*~" -exec rm -f {} \;
files/fcron.conf script/fcron.init.suse script/fcron.init.systemd script/fcron.init.systemd.reboot \
script/fcron.sh script/sysVinit-launcher
$(MAKE) -C doc clean
+ $(MAKE) -C test clean
files/fcron.conf: $(SRCDIR)/files/fcron.conf.in config.h
--dont-cuddle-else *.c *.h
configure: configure.in
-# update configure script, then Makefile and config.h, and finally
+# update configure script, then Makefile and config.h, and finally
# run make tar using the new Makefile (needed because the version
# is set in the configure.in file)
autoconf
if test $getloadavg -eq 1; then
dnl Nothing to do ...
AC_FUNC_GETLOADAVG
- AC_MSG_CHECKING(function to use for lavg* options)
+ AC_MSG_CHECKING(function to use for lavg* options)
AC_MSG_RESULT(getloadavg())
elif test $kstat -eq 1; then
- AC_MSG_CHECKING(function to use for lavg* options)
+ AC_MSG_CHECKING(function to use for lavg* options)
LIBS="$LIBS -lkstat"
AC_LIBOBJ([getloadavg])
AC_DEFINE_UNQUOTED(HAVE_KSTAT, 1)
else
dnl Try to use the /proc/loadavg file ...
AC_FUNC_GETLOADAVG
- AC_MSG_CHECKING(function to use for lavg* options)
+ AC_MSG_CHECKING(function to use for lavg* options)
AC_MSG_RESULT(/proc/loadavg)
fi
AC_CHECK_FUNCS(getcwd gettimeofday mktime putenv strerror setenv unsetenv gethostname)
fcron_enable_checks=yes
AC_ARG_ENABLE(checks,
[ --disable-checks Don't verify that programs exist on the host ], dnl '
-[ case "$enableval" in
+[ case "$enableval" in
no)
fcron_enable_checks=no
;;
;;
esac
])
-
+
+DISPLAYNAME=
+AC_MSG_RESULT([$DISPLAYNAME])
+AC_SUBST([DISPLAYNAME])
+
dnl ---------------------------------------------------------------------
dnl Programs ...
AC_MSG_RESULT([$FCRON_EDITOR])
AC_SUBST([FCRON_EDITOR])
+
dnl ---------------------------------------------------------------------
dnl Paths ...
[ case "$withval" in
no)
AC_MSG_WARN([
-Without proc, you won't be able to use the lavg* options
+Without proc, you won't be able to use the lavg* options
])
AC_DEFINE(NOLOADAVG)
;;
AC_MSG_WARN([
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-WARNING :
+WARNING :
This option allows a non privileged user to run fcron. When used,
fcron does not change its rights before running a job (i.e.,
if joe runs fcron, every job will run as joe).
*)
rootname=$withval
;;
- esac
+ esac
])
if test $fcron_enable_checks = 'yes'; then
AC_MSG_ERROR(Must be set to either "yes" or "no".)
;;
esac ],
- if test "$usepam" = "1"; then
+ if test "$usepam" = "1"; then
AC_MSG_RESULT(yes)
AC_CHECK_LIB(pam, pam_acct_mgmt)
else
usepam=0
AC_MSG_RESULT(no)
- fi
+ fi
)
if test "$usepam" != "0" && echo "$LIBS" | grep -- "-lpam" > /dev/null ; then
usepam=1
else
AC_MSG_RESULT(not available)
AC_MSG_ERROR([
- You requested the use of SELinux, but SELinux is considered
+ You requested the use of SELinux, but SELinux is considered
as not available by configure script.
])
fi
AC_ARG_WITH(db2man,
[ --with-db2man=PATH(or 'no') set PATH to a docbook2man converter.],
[ case "$withval" in
- no)
+ no)
DB2MAN=""
AC_MSG_RESULT(none)
;;
[ --with-db2man-spec=PATH set the PATH to docbook2man-spec file
(needed if no db2man converter is set).],
[ case "$withval" in
- no)
+ no)
DB2MAN_SPEC=""
AC_MSG_RESULT(none)
;;
AC_ARG_WITH(dsssl-dir,
[ --with-dsssl-dir=DIR change the default location of DSSSL stylesheets.],
[ case "$withval" in
- no)
+ no)
DSSSL_DIR=""
AC_MSG_RESULT(none)
;;
dnl ---------------------------------------------------------------------
-AC_OUTPUT(Makefile doc/Makefile doc/stylesheets/fcron-doc.dsl)
+AC_OUTPUT(Makefile doc/Makefile test/Makefile doc/stylesheets/fcron-doc.dsl)
dnl ---------------------------------------------------------------------
echo "spool dir: $sp"
echo "etc dir: $sysconfdir"
echo "doc dir: $docdir"
-echo "man dir: $mandir "
-
+echo "man dir: $mandir"
echo
echo "You can now run '$MAKE' to compile"
-<!--
+<!--
Fcron documentation
Copyright 2000-2021 Thibault Godouet <fcron@free.fr>
Permission is granted to copy, distribute and/or modify this
<refentry id="fcron.conf.5">
- <refmeta>
- <refentrytitle>fcron.conf</refentrytitle>
- <manvolnum>5</manvolnum>
- <refmiscinfo>Fcron &version; <![%devrelease; [
-(<emphasis>development</emphasis> release)]]></refmiscinfo>
- <refmiscinfo>&date;</refmiscinfo>
- </refmeta>
- <refnamediv>
- <refname>fcron.conf</refname>
- <refpurpose>configuration file for fcron and fcrontab</refpurpose>
- </refnamediv>
+ <refmeta>
+ <refentrytitle>fcron.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo>Fcron &version;
+ <![%devrelease; [(<emphasis>development</emphasis> release)]]>
+ </refmiscinfo>
+ <refmiscinfo>&date;</refmiscinfo>
+ </refmeta>
+ <refnamediv>
+ <refname>fcron.conf</refname>
+ <refpurpose>configuration file for fcron and fcrontab</refpurpose>
+ </refnamediv>
- <refsect1>
- <title>Description</title>
- <abstract>
- <para>This page describes the syntax used for the configuration file
-of <link linkend="fcrontab.1">&fcrontab;</link>(1), <link
-linkend="fcrondyn.1">&fcrondyn;</link>(1) and <link
-linkend="fcron.8">&fcron;</link>(8).</para>
- </abstract>
- <para>Blank lines, line beginning by a hash sign (#) (which are
-considered comments), leading blanks and tabs are ignored. Each line in a
-&fcron.conf; file is of the form
- <blockquote>
- <para>name = value</para>
- </blockquote> where the blanks around equal-sign (=) are ignored and
-optional. Trailing blanks are also ignored.
-</para>
- <para>The following names are recognized (default value in parentheses):
-<variablelist>
- <title>Valid variables in a fcron.conf file</title>
- <varlistentry>
- <term><varname>fcrontabs</varname>=<replaceable>directory</replaceable>
-(<filename>&fcrontabsdir;</filename>)</term>
- <listitem>
- <para>&Fcron; spool directory.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>pidfile</varname>=<replaceable>file-path</replaceable>
-(<filename>&fcron.pid;</filename>)</term>
- <listitem>
- <para>Location of &fcron; pid file (needed by &fcrontab;
-to work properly).</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>suspendfile</varname>=<replaceable>file-path</replaceable>
-(<filename>&suspendfile;</filename>)</term>
- <listitem>
- <para>Location of &fcron; suspend file. On non-Linux systems, this should be used to let fcron know how long the system was suspended (to memory or disk), so as task schedules can be updated accordingly.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>fifofile</varname>=<replaceable>file-path</replaceable>
-(<filename>&fcron.fifo;</filename>)</term>
- <listitem>
- <para>Location of &fcron; fifo file (needed by
-&fcrondyn; to communicate with &fcron;).</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>fcronallow</varname>=<replaceable>file-path</replaceable>
-(<filename>&etc;/&fcron.allow;</filename>)</term>
- <listitem>
- <para>Location of fcron.allow file.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>fcrondeny</varname>=<replaceable>file-path</replaceable>
-(<filename>&etc;/&fcron.deny;</filename>)</term>
- <listitem>
- <para>Location of fcron.deny file.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>shell</varname>=<replaceable>file-path</replaceable>
-(<filename>&shell;</filename>)</term>
- <listitem>
- <para>Location of default shell called by &fcron; when
-running a job. When &fcron; runs a job, &fcron; uses the value of <envar>SHELL</envar> from the fcrontab if any, otherwise it uses the value from <filename>fcron.conf</filename> if any, or in last resort the value from <filename>/etc/passwd</filename>.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>sendmail</varname>=<replaceable>file-path</replaceable>
-(<filename>&sendmail;</filename>)</term>
- <listitem>
- <para>Location of mailer program called by &fcron; to
-send job output.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>editor</varname>=<replaceable>file-path</replaceable>
-(<filename>&editor;</filename>)</term>
- <listitem>
- <para>Location of default editor used when invoking
-"fcrontab -e".</para>
- </listitem>
- </varlistentry>
- </variablelist> File-paths and directories are complete and absolute
-(i.e. beginning by a "/").</para>
- <para>To run several instances of &fcron; simultaneously on the same
-system, you must use a different configuration file for each instance. Each
-instance must have a different <varname>fcrontabs</varname>,
-<varname>pidfile</varname> and <varname>fifofile</varname>. Then, use <link
-linkend="fcron.8">&fcron;</link>(8)'s command line option
-<parameter>-c</parameter> to select which config file (so which instance) you
-refer to.</para>
- </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <abstract>
+ <para>
+ This page describes the syntax used for the configuration file
+ of <link linkend="fcrontab.1">&fcrontab;</link>(1),
+ <link linkend="fcrondyn.1">&fcrondyn;</link>(1) and
+ <link linkend="fcron.8">&fcron;</link>(8).
+ </para>
+ </abstract>
+ <para>
+ Blank lines, line beginning by a hash sign (#) (which are
+ considered comments), leading blanks and tabs are ignored. Each line in a
+ &fcron.conf; file is of the form
+ <blockquote>
+ <para>name = value</para>
+ </blockquote>
+ where the blanks around equal-sign (=) are ignored and
+ optional. Trailing blanks are also ignored.
+ </para>
+ <para>
+ The following names are recognized (default value in parentheses):
+ <variablelist>
+ <title>Valid variables in a fcron.conf file</title>
+ <varlistentry>
+ <term>
+ <varname>fcrontabs</varname>=<replaceable>directory</replaceable>
+ (<filename>&fcrontabsdir;</filename>)
+ </term>
+ <listitem>
+ <para>&Fcron; spool directory.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>pidfile</varname>=<replaceable>file-path</replaceable>
+ (<filename>&fcron.pid;</filename>)
+ </term>
+ <listitem>
+ <para>
+ Location of &fcron; pid file (needed by &fcrontab;
+ to work properly).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>suspendfile</varname>=<replaceable>file-path</replaceable>
+ (<filename>&suspendfile;</filename>)</term>
+ <listitem>
+ <para>
+ Location of &fcron; suspend file. On non-Linux
+ systems, this should be used to let fcron know how
+ long the system was suspended (to memory or disk),
+ so as task schedules can be updated accordingly.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>fifofile</varname>=<replaceable>file-path</replaceable>
+ (<filename>&fcron.fifo;</filename>)
+ </term>
+ <listitem>
+ <para>
+ Location of &fcron; fifo file (needed by
+ &fcrondyn; to communicate with &fcron;).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>fcronallow</varname>=<replaceable>file-path</replaceable>
+ (<filename>&etc;/&fcron.allow;</filename>)
+ </term>
+ <listitem>
+ <para>Location of fcron.allow file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>fcrondeny</varname>=<replaceable>file-path</replaceable>
+ (<filename>&etc;/&fcron.deny;</filename>)
+ </term>
+ <listitem>
+ <para>Location of fcron.deny file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>shell</varname>=<replaceable>file-path</replaceable>
+ (<filename>&shell;</filename>)
+ </term>
+ <listitem>
+ <para>
+ Location of default shell called by &fcron; when
+ running a job. When &fcron; runs a job, &fcron;
+ uses the value of <envar>SHELL</envar> from the
+ fcrontab if any, otherwise it uses the value from
+ <filename>fcron.conf</filename> if any, or in last
+ resort the value from
+ <filename>/etc/passwd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>sendmail</varname>=<replaceable>file-path</replaceable>
+ (<filename>&sendmail;</filename>)
+ </term>
+ <listitem>
+ <para>
+ Location of mailer program called by &fcron; to
+ send job output.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>editor</varname>=<replaceable>file-path</replaceable>
+ (<filename>&editor;</filename>)
+ </term>
+ <listitem>
+ <para>
+ Location of default editor used when invoking
+ "fcrontab -e".
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <varname>displayname</varname>=<replaceable>string</replaceable>
+ (<option>&displayname;</option>)
+ </term>
+ <listitem>
+ <para>
+ Display name for the "From: " header of mails sent
+ by us. N.B. &fcron has been following Vixie cron's
+ default email header format which is not fully
+ compliant with RFC 5322 (see <ulink
+ url="https://github.com/yo8192/fcron/issues/15">Issue
+ #15 </ulink>). During this transition phase, to
+ achieve full RFC compliance, you may set a display
+ name. Leaving it empty will preserve the old
+ behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ File-paths and directories are complete and absolute
+ (i.e. beginning by a "/").
+ </para>
+ <para>
+ To run several instances of &fcron; simultaneously on the same
+ system, you must use a different configuration file for each
+ instance. Each instance must have a different
+ <varname>fcrontabs</varname>, <varname>pidfile</varname> and
+ <varname>fifofile</varname>. Then, use <link
+ linkend="fcron.8">&fcron;</link>(8)'s command line option
+ <parameter>-c</parameter> to select which config file (so which
+ instance) you refer to.
+ </para>
+ </refsect1>
- <refsect1>
- <title>Files</title>
- <variablelist>
- <varlistentry>
- <term><filename>&etc;/&fcron.conf.location;</filename></term>
- <listitem>
- <para>Configuration file for &fcron;, &fcrontab; and
-&fcrondyn;: contains paths (spool dir, pid file) and default programs to use
-(editor, shell, etc). See <link linkend="fcron.conf.5">&fcron.conf;</link>(5) for
-more details.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><filename>&etc;/&fcron.allow;</filename></term>
- <listitem>
- <para>Users allowed to use &fcrontab; and &fcrondyn; (one
-name per line, special name "all" acts for everyone)</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><filename>&etc;/&fcron.deny;</filename></term>
- <listitem>
- <para>Users who are not allowed to use &fcrontab; and
-&fcrondyn; (same format as allow file)</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><filename>&etc;/pam.d/fcron</filename> (or
-<filename>&etc;/pam.conf</filename>)</term>
- <listitem>
- <para><productname>PAM</productname> configuration file for
-&fcron;. Take a look at &pam;(8) for more details.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
+ <refsect1>
+ <title>Files</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>&etc;/&fcron.conf.location;</filename></term>
+ <listitem>
+ <para>
+ Configuration file for &fcron;, &fcrontab; and
+ &fcrondyn;: contains paths (spool dir, pid file) and
+ default programs to use (editor, shell, etc). See
+ <link linkend="fcron.conf.5">&fcron.conf;</link>(5)
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>&etc;/&fcron.allow;</filename></term>
+ <listitem>
+ <para>Users allowed to use &fcrontab; and &fcrondyn; (one
+ name per line, special name "all" acts for everyone)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>&etc;/&fcron.deny;</filename></term>
+ <listitem>
+ <para>
+ Users who are not allowed to use &fcrontab; and
+ &fcrondyn; (same format as allow file)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>&etc;/pam.d/fcron</filename> (or
+ <filename>&etc;/pam.conf</filename>)</term>
+ <listitem>
+ <para>
+ <productname>PAM</productname> configuration file for
+ &fcron;. Take a look at &pam;(8) for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
- &manpage-foot;
+ &manpage-foot;
</refentry>
<!ENTITY sysfcrontab "@@SYSFCRONTAB@">
<!ENTITY rootname "@@ROOTNAME@">
<!ENTITY rootgroup "@@ROOTGROUP@">
+<!ENTITY displayname "@@DISPLAYNAME@">
<!-- shortcuts -->
char *shell = NULL;
char *sendmail = NULL;
char *editor = NULL;
+char *displayname = NULL;
+
+char
+*format_displayname(char *conf_value)
+ /* Format the input string `conf_value` according to RFC5322 sec. 3.2.3.
+ * <https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.3>.
+ * Returns: either the formatted displayname (possibly unchanged or empty)
+ * as a new dynamically allocated string (must be properly freed by the
+ * caller) or NULL on errors like buffer overflow. */
+{
+ bool need_quotes = false;
+ char c = '\0';
+ char *bpos = NULL, *dpos = NULL;
+ char *buf1 = NULL, *buf2 = NULL;
+
+ /* Shorter than max because of the option prefix "displayname = " */
+ const uint buf_len = LINE_LEN - 14;
+ uint cwritten = 0;
+
+ if (strlen(conf_value) == 0) return strdup2("");
+
+ buf1 = (char *)alloc_safe(buf_len * sizeof(char), "1st buffer");
+ buf2 = (char *)alloc_safe(buf_len * sizeof(char), "2nd buffer");
+
+ /* walk the conf_value and rebuild it in buf1 */
+ bpos = buf1;
+ for (dpos = conf_value; *dpos; *dpos++) {
+ c = *dpos;
+ if (strchr(SPECIAL_MBOX_CHARS, c)) {
+ /* insert escape */
+ if (c == DQUOTE) {
+ *bpos++ = BSLASH;
+ ++cwritten;
+ }
+ need_quotes = true;
+ }
+ if (cwritten >= buf_len) {
+ error("Formatted 'displayname' exceeds %u chars", buf_len);
+ Free_safe(buf1);
+ Free_safe(buf2);
+ return NULL;
+ }
+ *bpos++ = c;
+ ++cwritten;
+ }
+
+ if (need_quotes) {
+ if (snprintf(buf2, buf_len, "\"%s\"", buf1) >= buf_len){
+ error("Formatted 'displayname' exceeds %u chars", buf_len);
+ Free_safe(buf1);
+ Free_safe(buf2);
+ return NULL;
+ }
+ Free_safe(buf1);
+
+ return buf2;
+ }
+
+ /* unchanged */
+ Free_safe(buf2);
+
+ return buf1;
+}
void
init_conf(void)
sendmail = strdup2(SENDMAIL);
#endif
editor = strdup2(FCRON_EDITOR);
+ displayname = strdup2(DISPLAYNAME);
}
void
Free_safe(shell);
Free_safe(sendmail);
Free_safe(editor);
+ Free_safe(displayname);
}
void
else if (strncmp(ptr1, "editor", namesize) == 0) {
Set(editor, ptr2);
}
+ else if (strncmp(ptr1, "displayname", namesize) == 0) {
+ char *output = format_displayname(ptr2);
+ Set(displayname, output ? output : "");
+ Free_safe(output);
+ }
else
error("Unknown var name at line %s : line ignored", buf);
#ifndef __FCRONCONF_H__
#define __FCRONCONF_H__
+/* RFC5322's special mailbox address charcters */
+#define DQUOTE '\"'
+#define BSLASH '\\'
+#define SPECIAL_MBOX_CHARS "()<>[].,:;@\"\\"
/* global variables */
extern char *editor;
extern char *shell;
extern char *sendmail;
+extern char *displayname;
/* end of global variables */
/* functions prototypes */
/*
- * FCRON - periodic command scheduler
+ * FCRON - periodic command scheduler
*
* Copyright 2000-2021 Thibault Godouet <fcron@free.fr>
*
* 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
- *
+ *
* The GNU General Public License can also be found in the file
* `LICENSE' that comes with the fcron source distribution.
*/
* Sets client->fcl_user on success, don't do anything on failure
* so that the client stays unauthenticated */
{
- const int true = 1;
+ /* [@PR #17] renamed (previously called 'true') to avoid conflict with
+ stdbool */
+ const int value = 1;
/* There is no ucred.h (or equivalent) on linux to define struct ucred (!!)
* so we do it here */
#if ! ( defined(HAVE_CRED_H) && defined(HAVE_UCRED_H) \
socklen_t cred_size = sizeof(cred);
struct passwd *p_entry = NULL;
- setsockopt(client->fcl_sock_fd, SOL_SOCKET, SO_PASSCRED, &true,
- sizeof(true));
+ setsockopt(client->fcl_sock_fd, SOL_SOCKET, SO_PASSCRED, &value,
+ sizeof(value));
if (getsockopt
(client->fcl_sock_fd, SOL_SOCKET, SO_PEERCRED, &cred,
&cred_size) != 0) {
void
remove_connection(struct fcrondyn_cl **client, struct fcrondyn_cl *prev_client,
select_instance * si)
-/* close the connection, remove it from the list
+/* close the connection, remove it from the list
and make client points to the next entry */
{
debug("closing connection : fd : %d", (*client)->fcl_sock_fd);
/*
- * FCRON - periodic command scheduler
+ * FCRON - periodic command scheduler
*
* Copyright 2000-2021 Thibault Godouet <fcron@free.fr>
*
* 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
- *
+ *
* The GNU General Public License can also be found in the file
* `LICENSE' that comes with the fcron source distribution.
*/
}
+/* [@PR #17] renamed labels 'true' and 'false' to avoid conflict with
+ stdbool */
char *
get_bool(char *ptr, int *i)
/* get a bool value : either true (1) or false (0)
* return NULL on error */
{
if (*ptr == '1')
- goto true;
+ goto conf_true;
else if (*ptr == '0')
- goto false;
+ goto conf_false;
else if (strncmp(ptr, "true", 4) == 0) {
ptr += 3;
- goto true;
+ goto conf_true;
}
else if (strncmp(ptr, "yes", 3) == 0) {
ptr += 2;
- goto true;
+ goto conf_true;
}
else if (strncmp(ptr, "false", 5) == 0) {
ptr += 4;
- goto false;
+ goto conf_false;
}
else if (strncmp(ptr, "no", 2) == 0) {
ptr += 1;
- goto false;
+ goto conf_false;
}
else
return NULL;
- true:
- *i = 1;
+ conf_true:
+ *i = true;
ptr++;
return ptr;
- false:
- *i = 0;
+ conf_false:
+ *i = false;
ptr++;
return ptr;
}
/* The next char must be a space (no other option allowed when using
- * a shortcut: if the user wants to use options, they should use the
+ * a shortcut: if the user wants to use options, they should use the
* native fcron lines */
if (!isspace((int)*ptr)) {
fprintf(stderr, "%s:%d: No space after shortcut: skipping line.\n",
/* skip the % */
ptr++;
- /* a runfreq set to 1 means : this is a periodical line
+ /* a runfreq set to 1 means : this is a periodical line
* (runfreq cannot be changed by read_opt() if already set to 1) */
cl->cl_remain = cl->cl_runfreq = 1;
void
delete_file(const char *user_name)
- /* free a file if user_name is not null
+ /* free a file if user_name is not null
* otherwise free all files */
{
cf_t *file = NULL;
# Location of the default editor for "fcrontab -e"
editor = @@FCRON_EDITOR@
+
+# Display name for the "From: " header of mails sent by us. Default is
+# unset/empty, which keeps the "From: " header as it was before this feature
+# was added -- not RFC5322-compliant, though. A sane RFC5322-compliant setting,
+# could be:
+#
+# displayname = Fcron Deamon
+#
+# Please read fcron.conf(5) before setting it!
+displayname = @@DISPLAYNAME@
/*
- * FCRON - periodic command scheduler
+ * FCRON - periodic command scheduler
*
* Copyright 2000-2021 Thibault Godouet <fcron@free.fr>
*
* 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
- *
+ *
* The GNU General Public License can also be found in the file
* `LICENSE' that comes with the fcron source distribution.
*/
-/*
+/*
WARNING : this file should not be modified.
Compilation's options are in config.h
*/
#ifndef __GLOBAL_H__
#define __GLOBAL_H__
-/* config.h must be included before every other includes
+/* config.h must be included before every other includes
* (contains the compilation options) */
#include "config.h"
#include <stdarg.h>
#endif
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
- * FCRON - periodic command scheduler
+ * FCRON - periodic command scheduler
*
* Copyright 2000-2021 Thibault Godouet <fcron@free.fr>
*
* 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
- *
+ *
* The GNU General Public License can also be found in the file
* `LICENSE' that comes with the fcron source distribution.
*/
#include "job.h"
#include "temp_file.h"
+
void sig_dfl(void);
void end_job(cl_t * line, int status, FILE * mailf, short mailpos,
char **sendmailenv);
signal(SIGPIPE, SIG_DFL);
}
+char *
+make_mailbox_addr(char *displayname_conf, char *mail_from, char *hostname)
+ /* Produce a "mailbox" header as per RFC5322 sec. 3.2.3
+ * <https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.3>.
+ * Returns: either the formatted mailbox header as a new dynamically
+ * allocated string (must be properly freed by the caller) or NULL on
+ * errors like buffer overflow. */
+{
+ char *buf = NULL;
+ uint written = 0;
+ bool need_anglebrackets = false;
+
+ /* Shorter than max because the header prefix "From: " are added
+ downstream. */
+ const uint buf_len = MAIL_LINE_LEN_MAX - 6;
+
+ buf = (char *)alloc_safe(buf_len * sizeof(char), "mailbox addr buffer");
+
+ /* == strlen(),but faster */
+ need_anglebrackets = displayname_conf[0] != '\0';
+
+ /* no @ here, it's handled upstream */
+ if (need_anglebrackets)
+ written = snprintf(buf, buf_len, "%s %c%s%s%c",
+ displayname_conf, '<', mail_from, hostname, '>');
+ else
+ written = snprintf(buf, buf_len, "%s%s", mail_from, hostname);
+
+ if (written >= buf_len) {
+ error("Mailbox addr exceeds %u chars", buf_len);
+ Free_safe(buf);
+ return NULL;
+ }
+
+ return buf;
+}
FILE *
create_mail(cl_t * line, char *subject, char *content_type, char *encoding,
/* hostname to add to email addresses (depending on if they have a '@') */
char *hostname_from = "";
char *hostname_to = "";
+ char *mailbox_addr = "";
int i = 0;
if (mailf == NULL)
hostname[0] = '\0';
#endif /* HAVE_GETHOSTNAME */
- /* write mail header */
- fprintf(mailf, "From: %s%s (fcron)\n", mailfrom, hostname_from);
+ /* write mail header. Global 'displayname' comes from fcronconf.h */
+ if (strlen(displayname) > 0){
+ /* New behavior -- RFC-compliant */
+ mailbox_addr = make_mailbox_addr(displayname, mailfrom, hostname_from);
+ if (mailbox_addr) {
+ fprintf(mailf, "From: %s\n", mailbox_addr);
+ Free_safe(mailbox_addr);
+ }
+ else {
+ error("could not make the mailbox address");
+ fprintf(mailf, "From: %s%s\n", mailfrom, hostname_from);
+ }
+ }
+ else
+ /* Old behavior */
+ fprintf(mailf, "From: %s%s (fcron)\n", mailfrom, hostname_from);
+
fprintf(mailf, "To: %s%s\n", line->cl_mailto, hostname_to);
if (subject)
int
read_pipe(int fd, void *buf, size_t size)
- /* Read data from pipe.
+ /* Read data from pipe.
* Handles signal interruptions, and read in several passes.
* Returns ERR in case of a closed pipe, the errno from read
* for other errors, and OK if everything was read successfully */
int
write_pipe(int fd, void *buf, size_t size)
- /* Read data from pipe.
+ /* Read data from pipe.
* Handles signal interruptions, and read in several passes.
* Returns ERR in case of a closed pipe, the errno from write
* for other errors, and OK if everything was read successfully */
/*
- * FCRON - periodic command scheduler
+ * FCRON - periodic command scheduler
*
* Copyright 2000-2021 Thibault Godouet <fcron@free.fr>
*
* 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
- *
+ *
* The GNU General Public License can also be found in the file
* `LICENSE' that comes with the fcron source distribution.
*/
#ifndef __JOB_H__
#define __JOB_H__
+#define MAIL_LINE_LEN_MAX 998 /* RFC5322's max line length */
+
/* functions prototypes */
extern void change_user_setup_env(struct cl_t *cl, char ***sendmailenv,
char ***jobenv, char **curshell,
--- /dev/null
+# Prototype makefile, while waiting for integration of a test framework
+SRCDIR := ..
+LIBS := @LIBS@
+SRCST := mailbox_addr.c
+OBJST := $(patsubst %.c,%.o,$(SRCST))
+EXEST := $(patsubst %.c,%,$(SRCST))
+OBJSD := $(addprefix $(SRCDIR)/,log.o job.o mem.o filesubs.o subs.o fcronconf.o temp_file.o env_list.o u_list.o)
+
+CFLAGS += -I$(SRCDIR)
+
+.PHONY: clean tests
+
+tests: $(OBJSD)
+ $(CC) $(CFLAGS) $(OBJSD) $(LIBS) $(SRCST) -o $(EXEST)
+ ./$(EXEST)
+
+clean:
+ rm -f *.o core $(EXEST)
--- /dev/null
+/* Prototype test harness, while waiting for integration of a test framework */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "fcron.h"
+#include "job.h"
+#include "fcronconf.h"
+
+#define dasserteq(DESCR, RETURNED, EXPECTED) \
+{ \
+ printf("%s: %ld ?= %ld\n", (DESCR), (long)(RETURNED), (long)(EXPECTED)); \
+ assert((RETURNED) == (EXPECTED)); \
+}
+
+/* These globals should maybe come from a lib instead of the various exes? */
+char *prog_name = NULL;
+pid_t daemon_pid = 0;
+char foreground = 1;
+char default_mail_charset[TERM_LEN] = "";
+pam_handle_t *pamh = NULL;
+const struct pam_conv apamconv = { NULL };
+mode_t saved_umask;
+uid_t rootuid = 0;
+char *tmp_path = "";
+
+char *format_displayname(char *displayname);
+char *make_mailbox_addr(char *displayname, char *mail_from, char *hostname);
+
+
+void _test_format_displayname(char *test_desc, char *arg, char *expected)
+{
+ char *output = NULL;
+
+ output = format_displayname(arg);
+ printf("%s: format_displayname('%s'): '%s' ?= '%s'\n",
+ test_desc, arg, output, expected);
+ assert(strcmp(output, expected) == 0);
+ Free_safe(output);
+}
+
+
+void _test_make_mailbox_addr(char *test_desc, char *displayname,
+ char *mailfrom, char *hostname, char *expected)
+{
+ char *output = NULL;
+
+ output = make_mailbox_addr(displayname, mailfrom, hostname);
+ printf("%s: make_mailbox_addr('%s', '%s', '%s'): '%s' ?= '%s'\n",
+ test_desc, displayname, mailfrom, hostname, output, expected);
+ assert(strcmp(output, expected) == 0);
+ Free_safe(output);
+}
+
+int main(int argc, char* argv[])
+{
+ char *displayname = NULL;
+ char *output = NULL;
+
+ /* Mind that format_displayname() might modify input displayname, thus all
+ special characters must be tested */
+ _test_format_displayname("empty displayname", "", "");
+ _test_format_displayname("displayname with no special char",
+ "Foo Bar", "Foo Bar");
+ _test_format_displayname("displayname with no special char",
+ "Foo'Bar", "Foo'Bar");
+
+ /* Make sure to extend this series, should SPECIAL_MBOX_CHARS change. All
+ those require quoting */
+ _test_format_displayname("displayname with special char",
+ "(Foo Bar", "\"(Foo Bar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo Bar)", "\"Foo Bar)\"");
+ _test_format_displayname("displayname with special char",
+ "Foo B<ar", "\"Foo B<ar\"");
+ _test_format_displayname("displayname with special char",
+ "Fo>o Bar", "\"Fo>o Bar\"");
+ _test_format_displayname("displayname with special char",
+ "F[oo Bar", "\"F[oo Bar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo] Bar", "\"Foo] Bar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo . Bar", "\"Foo . Bar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo, Bar", "\"Foo, Bar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo B:ar", "\"Foo B:ar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo ;Bar", "\"Foo ;Bar\"");
+ _test_format_displayname("displayname with special char",
+ "Foo@Bar", "\"Foo@Bar\"");
+ _test_format_displayname("displayname with double quote",
+ "Foo \" Bar", "\"Foo \\\" Bar\"");
+ _test_format_displayname("displayname with backslash",
+ "Foo \\Bar", "\"Foo \\Bar\"");
+
+ /* make_mailbox_addr() only composes the "mailbox" address header: it's
+ agnostic of any special character */
+ _test_make_mailbox_addr("empty displayname => no angle brackets",
+ "", "baz", "@quux", "baz@quux");
+ _test_make_mailbox_addr("displayname => needs angle brackets",
+ "Foo Bar", "baz", "@quux", "Foo Bar <baz@quux>");
+
+
+ /* overflow tests */
+ displayname = (char *)realloc_safe(displayname,
+ LINE_LEN + 1 * sizeof(char),
+ "displayname buffer");
+ memset(displayname, 'a', LINE_LEN);
+ displayname[LINE_LEN] = '\0';
+ displayname[0] = DQUOTE;
+
+ output = format_displayname(displayname);
+ dasserteq("format_displayname: overflow", output, NULL);
+ Free_safe(output);
+
+ output = make_mailbox_addr(displayname, "baz", "@quux");
+ dasserteq("make_mailbox_addr: overflow", output, NULL);
+ Free_safe(output);
+
+ Free_safe(displayname);
+
+ return 0;
+}
+
+/* Local Variables: */
+/* mode: c */
+/* indent-tabs-mode: nil */
+/* End: */