--- /dev/null
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Paul Vixie.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)bitstring.3 5.1 (Berkeley) 12/13/89
+.\"
+.TH BITSTRING 3 "December 13, 1989"
+.UC 4
+.SH NAME
+bit_alloc, bit_clear, bit_decl, bit_ffs, bit_nclear, bit_nset,
+bit_set, bitstr_size, bit_test \- bit-string manipulation macros
+.SH SYNOPSIS
+.ft B
+.nf
+#include <bitstring.h>
+
+name = bit_alloc(nbits)
+bitstr_t *name;
+int nbits;
+
+bit_decl(name, nbits)
+bitstr_t name;
+int nbits;
+
+bit_clear(name, bit)
+bitstr_t name;
+int bit;
+
+bit_ffc(name, nbits, value)
+bitstr_t name;
+int nbits, *value;
+
+bit_ffs(name, nbits, value)
+bitstr_t name;
+int nbits, *value;
+
+bit_nclear(name, start, stop)
+bitstr_t name;
+int start, stop;
+
+bit_nset(name, start, stop)
+bitstr_t name;
+int start, stop;
+
+bit_set(name, bit)
+bitstr_t name;
+int bit;
+
+bitstr_size(nbits)
+int nbits;
+
+bit_test(name, bit)
+bitstr_t name;
+int bit;
+.fi
+.ft R
+.SH DESCRIPTION
+These macros operate on strings of bits.
+.PP
+.I Bit_alloc
+returns a pointer of type
+.I bitstr_t\ *
+to sufficient space to store
+.I nbits
+bits, or NULL if no space is available.
+.PP
+.I Bit_decl
+is a macro for allocating sufficient space to store
+.I nbits
+bits on the stack.
+.PP
+.I Bitstr_size
+returns the number of elements of type
+.I bitstr_t
+necessary to store
+.I nbits
+bits.
+This is useful for copying bit strings.
+.PP
+.I Bit_clear
+and
+.I bit_set
+clear or set the zero-based numbered bit
+.IR bit ,
+in the bit string
+.IR name .
+.PP
+.I Bit_nset
+and
+.I bit_nclear
+set or clear the zero-based numbered bits from
+.I start
+to
+.I stop
+in the bit string
+.IR name .
+.PP
+.I Bit_test
+evaluates to zero if the zero-based numbered bit
+.I bit
+of bit string
+.I name
+is set, and non-zero otherwise.
+.PP
+.I Bit_ffs
+sets
+.I *value
+to the zero-based number of the first bit set in the array of
+.I nbits
+bits referenced by
+.IR name .
+If no bits are set,
+.I *value
+is set to -1.
+.PP
+.I Bit_ffc
+sets
+.I *value
+to the zero-based number of the first bit not set in the array of
+.I nbits
+bits referenced by
+.IR name .
+If all bits are set,
+.I value
+is set to -1.
+.SH EXAMPLE
+.nf
+.in +5
+#include <limits.h>
+#include <bitstring.h>
+
+...
+#define LPR_BUSY_BIT 0
+#define LPR_FORMAT_BIT 1
+#define LPR_DOWNLOAD_BIT 2
+...
+#define LPR_AVAILABLE_BIT 9
+#define LPR_MAX_BITS 10
+
+make_lpr_available()
+{
+ bitstr_t bit_decl(bitlist, LPR_MAX_BITS);
+ ...
+ bit_nclear(bitlist, 0, LPR_MAX_BITS - 1);
+ ...
+ if (!bit_test(bitlist, LPR_BUSY_BIT)) {
+ bit_clear(bitlist, LPR_FORMAT_BIT);
+ bit_clear(bitlist, LPR_DOWNLOAD_BIT);
+ bit_set(bitlist, LPR_AVAILABLE_BIT);
+ }
+}
+.fi
+.SH "SEE ALSO"
+malloc(3)
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2008 Thibault Godouet <fcron@free.fr>
+ *
+ * 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
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+ /* $Id: temp_file.c,v 1.6 2007/04/14 18:04:19 thib Exp thib $ */
+
+/* List of jobs currently being executed.
+ * This is a wrapper for an u_list (unordered list) (see u_list.h and u_list.c),
+ * to make the rest of the code clearer and as a way to ensure the compiler can checks
+ * the type in the rest of the code (u_list extensively uses the void type) */
+
+#include "global.h"
+#include "fcron.h"
+#include "exe_list.h"
+
+exe_list_t *exe_list_init(void)
+{
+ return (exe_list_t *) u_list_init(sizeof(exe_t), EXE_INITIAL_SIZE, EXE_GROW_SIZE);
+}
+
+exe_t *
+exe_list_add(exe_list_t *list, struct cl_t *line)
+{
+ exe_t e = { NULL, 0, 0};
+ e.e_line = line; /* ANSI C does not allow us to directly replace NULL by line above*/
+
+ return (exe_t *) u_list_add( (u_list_t *) list, (u_list_entry_t *) &e);
+}
+
+exe_t *
+exe_list_first(exe_list_t *list)
+{
+ return (exe_t *) u_list_first((u_list_t *) list);
+}
+
+exe_t *
+exe_list_next(exe_list_t *list, exe_t *cur_entry)
+{
+ return (exe_t *) u_list_next((u_list_t *) list, (u_list_entry_t *) cur_entry);
+}
+
+void
+exe_list_remove(exe_list_t *list, exe_t *entry)
+{
+ u_list_remove((u_list_t *) list, (u_list_entry_t *) entry);
+}
+
+exe_list_t *
+exe_list_destroy(exe_list_t *list)
+ /* free() the memory allocated for list and returns NULL */
+{
+ return (exe_list_t *) u_list_destroy((u_list_t *) list);
+}
+
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2008 Thibault Godouet <fcron@free.fr>
+ *
+ * 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
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+ /* $Id: temp_file.h,v 1.4 2007/04/14 18:04:20 thib Exp thib $ */
+
+/* List of jobs currently being executed.
+ * This is a wrapper for an u_list (unordered list) (see u_list.h and u_list.c),
+ * to make the rest of the code clearer and as a way to ensure the compiler can checks
+ * the type in the rest of the code (u_list extensively uses the void type) */
+
+#ifndef __EXE_LIST_H__
+#define __EXE_LIST_H__
+
+#include "u_list.h"
+
+/* Entry to describe one job being executed */
+typedef struct exe_t {
+ struct cl_t *e_line;
+ pid_t e_ctrl_pid; /* pid of the fcron process controling the job */
+ pid_t e_job_pid; /* pid of the job itself */
+} exe_t;
+
+typedef struct u_list_t exe_list_t;
+
+/* functions prototypes */
+extern exe_list_t *exe_list_init(void);
+/* WARNING: exe_t pointers returned by those functions are only
+ * valid for as long as the list is not modified (add/remove) */
+extern exe_t *exe_list_add(exe_list_t *list, struct cl_t *line);
+extern exe_t *exe_list_first(exe_list_t *list);
+extern exe_t *exe_list_next(exe_list_t *list, exe_t *cur_entry);
+extern void exe_list_remove(exe_list_t *list, exe_t *entry);
+extern exe_list_t *exe_list_destroy(exe_list_t *list);
+
+
+#endif /* __EXE_LIST_H__ */
--- /dev/null
+#include "exe_list.h"
+#include "global.h"
+#include "fcron.h"
+
+/* required by log.c */
+char debug_opt = 1;
+char *prog_name = NULL;
+char dosyslog = 1;
+char foreground = 1;
+pid_t daemon_pid = 0;
+uid_t rootuid = 0;
+
+void print_cur(exe_t *e) {
+ printf("Current entry's shell command: %s\n", e?e->e_line->cl_shell:"NULL");
+}
+
+void print_list(exe_list_t *list) {
+ exe_t *e = NULL;
+ printf("Current list:\n");
+ for ( e = exe_list_first(list) ; e != NULL ; e = exe_list_next(list) )
+ printf(" Shell command: %s\n", e?e->e_line->cl_shell:"NULL");
+}
+
+int main(int argc, char *argv[]) {
+ exe_list_t *list = NULL;
+ exe_t *e = NULL;
+ cl_t l1, l2, l3, l4, l5, l6, l7;
+
+ l1.cl_shell = "line 1";
+ l2.cl_shell = "line 2";
+ l3.cl_shell = "line 3";
+ l4.cl_shell = "line 4";
+ l5.cl_shell = "line 5";
+ l6.cl_shell = "line 6";
+ l7.cl_shell = "line 7";
+
+ list = exe_list_init();
+
+ /* trigger a resize of the list during an iteration */
+ printf("Adding l1...\n"); exe_list_add_line(list, &l1);
+ printf("Adding l2...\n"); exe_list_add_line(list, &l2);
+ printf("Adding l3...\n"); exe_list_add_line(list, &l3);
+ e = exe_list_first(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ printf("Adding l4...\n"); exe_list_add_line(list, &l4);
+ printf("Adding l5...\n"); exe_list_add_line(list, &l5);
+ printf("Adding l6...\n"); exe_list_add_line(list, &l6);
+ printf("Adding l7...\n"); exe_list_add_line(list, &l7);
+
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+
+ /* "standard" iteration: */
+ print_list(list);
+
+ /* remove item at the beginning and middle of the list + add an item which is already in there */
+ printf("removing l1, l3, adding l2\n");
+ e = exe_list_first(list); print_cur(e);
+ printf("Removing l1...\n"); exe_list_remove_cur(list);
+ e = exe_list_next(list); print_cur(e); /* this one will be the item replacing l1 */
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ printf("Removing l3...\n"); exe_list_remove_cur(list);
+ exe_list_end_iteration(list);
+ printf("Adding l2...\n"); exe_list_add_line(list, &l2); /* we suppose the list array won't be reallocated() */
+
+ print_list(list);
+
+ /* remove an item at the end of the list: */
+ printf("removing l5, l2\n");
+ e = exe_list_first(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ printf("Removing l5...\n"); exe_list_remove_cur(list);
+ exe_list_end_iteration(list);
+ e = exe_list_first(list); print_cur(e);
+ e = exe_list_next(list); print_cur(e);
+ printf("Removing l2...\n");exe_list_remove_cur(list);
+ exe_list_end_iteration(list);
+
+ print_list(list);
+
+ printf("Adding l1...\n"); exe_list_add_line(list, &l1);
+
+ print_list(list);
+
+ printf("empty the list\n");
+ e = exe_list_first(list); print_cur(e);
+ exe_list_remove_cur(list);
+ e = exe_list_next(list); print_cur(e);
+ exe_list_remove_cur(list);
+ e = exe_list_next(list); print_cur(e);
+ exe_list_remove_cur(list);
+ e = exe_list_next(list); print_cur(e);
+ exe_list_remove_cur(list);
+ e = exe_list_next(list); print_cur(e);
+ exe_list_remove_cur(list);
+ e = exe_list_next(list); print_cur(e);
+
+ print_list(list);
+
+ printf("Destroying the list...\n"); list = exe_list_destroy(list);
+
+ return 0;
+
+}
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2008 Thibault Godouet <fcron@free.fr>
+ *
+ * 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
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+ /* $Id: temp_file.c,v 1.6 2007/04/14 18:04:19 thib Exp thib $ */
+
+/* List of jobs waiting for an appropriate system load average to be executed.
+ * This is a wrapper for an u_list (unordered list) (see u_list.h and u_list.c),
+ * to make the rest of the code clearer and as a way to ensure the compiler can checks
+ * the type in the rest of the code (u_list extensively uses the void type) */
+
+#include "global.h"
+#include "fcron.h"
+#include "lavg_list.h"
+
+lavg_list_t *lavg_list_init(void)
+{
+ lavg_list_t *l = (lavg_list_t *)u_list_init(sizeof(lavg_t), LAVG_INITIAL_SIZE, LAVG_GROW_SIZE);
+ l->max_entries = LAVG_QUEUE_MAX;
+ return l;
+}
+
+lavg_t *
+lavg_list_add(lavg_list_t *list, struct cl_t *line)
+{
+ lavg_t e = { NULL, 0};
+ e.l_line = line; /* ANSI C does not allow us to directly replace NULL by line above*/
+
+ return (lavg_t *) u_list_add( (u_list_t *) list, (u_list_entry_t *) &e);
+}
+
+lavg_t *
+lavg_list_first(lavg_list_t *list)
+{
+ return (lavg_t *) u_list_first((u_list_t *) list);
+}
+
+lavg_t *
+lavg_list_next(lavg_list_t *list, lavg_t *cur_entry)
+{
+ return (lavg_t *) u_list_next((u_list_t *) list, (u_list_entry_t *) cur_entry);
+}
+
+void
+lavg_list_remove(lavg_list_t *list, lavg_t *entry)
+{
+ u_list_remove((u_list_t *) list, (u_list_entry_t *) entry);
+}
+
+lavg_list_t *
+lavg_list_destroy(lavg_list_t *list)
+{
+ return (lavg_list_t *) u_list_destroy((u_list_t *) list);
+}
+
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2008 Thibault Godouet <fcron@free.fr>
+ *
+ * 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
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+ /* $Id: temp_file.h,v 1.4 2007/04/14 18:04:20 thib Exp thib $ */
+
+/* List of jobs waiting for an appropriate system load average to be executed.
+ * This is a wrapper for an u_list (unordered list) (see u_list.h and u_list.c),
+ * to make the rest of the code clearer and as a way to ensure the compiler can checks
+ * the type in the rest of the code (u_list extensively uses the void type) */
+
+#ifndef __LAVG_LIST_H__
+#define __LAVG_LIST_H__
+
+#include "u_list.h"
+
+/* Entry to describe one job waiting for an appropriate load average to be executed */
+typedef struct lavg_t {
+ struct cl_t *l_line;
+ time_t l_until; /* the timeout of the wait for load averages */
+} lavg_t;
+
+typedef struct u_list_t lavg_list_t;
+
+/* functions prototypes */
+extern lavg_list_t *lavg_list_init(void);
+/* WARNING: lavg_t pointers returned by those functions are only
+ * valid for as long as the list is not modified (add/remove) */
+extern lavg_t *lavg_list_add(lavg_list_t *list, struct cl_t *line);
+extern lavg_t *lavg_list_first(lavg_list_t *list);
+extern lavg_t *lavg_list_next(lavg_list_t *list, lavg_t *cur_entry);
+extern void lavg_list_remove(lavg_list_t *list, lavg_t *entry);
+extern lavg_list_t *lavg_list_destroy(lavg_list_t *list);
+
+
+#endif /* __LAVG_LIST_H__ */
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2008 Thibault Godouet <fcron@free.fr>
+ *
+ * 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
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+ /* $Id: temp_file.c,v 1.6 2007/04/14 18:04:19 thib Exp thib $ */
+
+/*
+ * Unordered list of generic items
+ */
+
+#include "global.h"
+#include "fcron.h"
+#include "u_list.h"
+
+/* private functions: */
+int u_list_resize_array(u_list_t *l);
+u_list_entry_t *u_list_last(u_list_t *l);
+
+u_list_t *
+u_list_init(size_t entry_size, int init_size, int grow_size)
+/* Create a new unordered list
+ * Returns the newly created unorderd list
+ * Enough memory to hold init_size entries will initially be allocated,
+ * and it will grow by grow_size entries when more space is needed.
+ * Dies on error. */
+{
+ u_list_t *l = NULL;
+
+ /* sanity check */
+ if ( entry_size < 1 || init_size < 1 || grow_size < 1 )
+ die("Invalid arguments for u_list_init(): entry_size=%d, init_size=%d, "
+ "grow_size=%d", entry_size, init_size, grow_size);
+
+ /* Allocate the list structure: */
+ l = calloc(1, sizeof(struct u_list_t));
+ if ( l == NULL )
+ die_e("Failed creating a new unordered list: could not calloc() u_list_t "
+ "(entry_size: %d)", entry_size);
+
+ /* Initialize the structure and allocate the array: */
+ l->array_size = init_size;
+ l->entry_size = entry_size;
+ l->grow_size = grow_size;
+ l->entries_array = calloc(init_size, entry_size);
+ if ( l->entries_array == NULL )
+ die_e("Failed creating a new unordered list: could not calloc array"
+ "(entry_size: %d, init_size: %d)", entry_size, init_size);
+
+ return l;
+}
+
+int
+u_list_resize_array(u_list_t *l)
+/* Resize l's entries_array up to l->max_entries
+ * Returns OK on success, ERR if the array is already at maximum size */
+{
+ u_list_entry_t *e = NULL;
+ int old_size = l->array_size;
+
+ /* sanity check */
+ if ( l == NULL )
+ die("Invalid argument for u_list_resize_array(): list=%d", l);
+ if ( l->max_entries > 0 && l->array_size >= l->max_entries ) {
+ debug("Resizing u_list_t failed because it is already at max size (size: %d)",
+ l->array_size);
+ return ERR;
+ }
+
+ l->array_size = (l->array_size + l->grow_size);
+ if ( l->max_entries > 0 && l->array_size > l->max_entries )
+ l->array_size = l->max_entries;
+
+ debug("Resizing u_list_t (old size: %d, new size: %d)...", old_size, l->array_size);
+
+ if ( (e = calloc(l->array_size, l->entry_size)) == NULL )
+ die_e("Could not calloc u_list_t to grow entries_array "
+ "(old size: %d, new size: %d)...", old_size, l->array_size);
+
+ memcpy(e, l->entries_array, (l->entry_size * old_size));
+ free_safe(l->entries_array);
+ l->entries_array = e;
+
+ return OK;
+}
+
+u_list_entry_t *
+u_list_last(u_list_t *l)
+/* Returns the pointer of the last entry in the list, or NULL if l is empty */
+{
+ if ( l->num_entries <= 0 )
+ return NULL;
+ else
+ return (u_list_entry_t *)
+ ( (char *)l->entries_array + l->entry_size * ( l->num_entries - 1 ) );
+}
+
+u_list_entry_t *
+u_list_add(u_list_t *l, u_list_entry_t *e)
+/* Add one entry to the list
+ * Returns a pointer to the added element, or NULL if list is already at max size */
+{
+ u_list_entry_t *new = NULL;
+
+ /* sanity check */
+ if ( l == NULL || e == NULL )
+ die("Invalid arguments for u_list_add(): list=%d, entry=%d", l, e);
+
+ /* Check there is some space left, or resize the array */
+ if ( l->num_entries >= l->array_size ) {
+ /* no more space: attempt to grow (the following function dies on error: */
+ if ( u_list_resize_array(l) != OK )
+ return NULL;
+ }
+
+ l->num_entries++;
+ new = u_list_last(l);
+ memcpy(new, e, l->entry_size);
+
+ return new;
+}
+
+u_list_entry_t *
+u_list_first(u_list_t *l)
+/* Return the first entry of the list (then u_list_next() can be used) */
+{
+ /* sanity check */
+ if ( l == NULL )
+ die("Invalid argument for u_list_first(): list=%d", l);
+
+ return (l->num_entries > 0) ? l->entries_array : NULL;
+}
+
+u_list_entry_t *
+u_list_next(u_list_t *l, u_list_entry_t *e)
+/* Return the entry after e */
+{
+ /* sanity checks */
+ if (l==NULL||e==NULL)
+ die("Invalid arguments for u_list_next(): list=%d, entry=%d", l, e);
+ if (e < l->entries_array || e > u_list_last(l) )
+ die("u_list_next(): entry out of list! (entries_array: %d, entry: %d,"
+ "num_entries: %d)", l->entries_array, e, l->num_entries);
+
+ /* // */
+ /* Undefined? -- convert soustraction to float and check if result is an int ? */
+/* if ( ( (char *) e - (char *) l->entries_array ) % l->entry_size != 0 )
+ die("u_list_next(): entry shifted! (entries_array: %d, entry_size: %d, "
+ "entry: %d", l->entries_array, l->entry_size, e);
+*/
+ if ( e < u_list_last(l) )
+ return (u_list_entry_t *) ( (char *) e + l->entry_size);
+ else
+ return NULL;
+}
+
+void
+u_list_remove(u_list_t *l, u_list_entry_t *e)
+{
+ u_list_entry_t *last = NULL;
+
+ /* sanity checks */
+ if ( l == NULL || e == NULL )
+ die("Invalid arguments for u_list_remove(): list=%d, entry=%d", l, e);
+ if (e < l->entries_array || e > u_list_last(l) )
+ die("u_list_next(): entry out of list! (entries_array: %d, entry: %d,"
+ "num_entries: %d)", l->entries_array, e, l->num_entries);
+
+ last = u_list_last(l);
+ if ( e < last ) {
+ /* Override e with the last entry */
+ memcpy(e, last, l->entry_size);
+ }
+ /* erase the last entry and update the number of entries */
+ memset(last, 0, l->entry_size);
+ l->num_entries--;
+
+
+}
+
+u_list_t *
+u_list_destroy(u_list_t *list)
+ /* free() the memory allocated for list and returns NULL */
+{
+ if ( list == NULL )
+ die("Invalid argument for u_list_destroy(): list=%d", list);
+
+ free_safe(list->entries_array);
+ free_safe(list);
+ return NULL;
+}
--- /dev/null
+/*
+ * FCRON - periodic command scheduler
+ *
+ * Copyright 2000-2008 Thibault Godouet <fcron@free.fr>
+ *
+ * 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
+ *
+ * The GNU General Public License can also be found in the file
+ * `LICENSE' that comes with the fcron source distribution.
+ */
+
+ /* $Id: temp_file.h,v 1.4 2007/04/14 18:04:20 thib Exp thib $ */
+
+/*
+ * Unordered list of generic items
+ */
+
+#ifndef __U_LIST_H__
+#define __U_LIST_H__
+
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "subs.h"
+
+typedef void u_list_entry_t;
+
+typedef struct u_list_t {
+ /* PUBLIC: */
+ int max_entries; /* max allowed element number (0: no limit) */
+ int num_entries; /* READ ONLY: num of entries in the list now */
+ /* PRIVATE: DO NOT ACCESS DIRECTLY */
+ int array_size; /* size of the array (in number of entries) */
+ size_t entry_size; /* number of element currently in the array */
+ int grow_size; /* grow array by grow_size entries at a time */
+ u_list_entry_t *entries_array; /* pointer to the actual array */
+} u_list_t;
+
+/* functions prototypes */
+extern u_list_t *u_list_init(size_t entry_size, int init_size, int grow_size);
+/* WARNING: u_list_entry_t pointers returned by those functions are only
+ * valid for as long as the list is not modified (add/remove) */
+extern u_list_entry_t *u_list_add(u_list_t *list, u_list_entry_t *entry);
+extern u_list_entry_t *u_list_first(u_list_t *list);
+extern u_list_entry_t *u_list_next(u_list_t *list, u_list_entry_t *cur_entry);
+extern void u_list_remove(u_list_t *list, u_list_entry_t *entry);
+extern u_list_t *u_list_destroy(u_list_t *list);
+
+
+#endif /* __U_LIST_H__ */