* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: conf.c,v 1.4 2000-05-31 19:11:15 thib Exp $ */
+ /* $Id: conf.c,v 1.5 2000-06-03 20:27:15 thib Exp $ */
#include "fcron.h"
* it's the size of all time table (mins, days ...) */
const size_t size=( bitstr_size(60) + bitstr_size(24) +
bitstr_size(32) + bitstr_size(12) +
- bitstr_size(7) );
+ bitstr_size(7) + sizeof(time_t) +
+ sizeof(short int) );
- /* assign old pointer to the old file, and remove it
- * from the list */
old = cur_f;
- if (prev != NULL)
- prev->cf_next = cur_f->cf_next;
- else
- /* this is the first file in the list */
- file_base = cur_f->cf_next;
-
/* load new file */
Alloc(cur_f, CF);
if ( read_file(file_name, cur_f) != 0 ) {
return;
}
- /* set cf_user field ( len("new.")=4 ) */
+ /* set cf_user field */
cur_f->cf_user = strdup2(user);
+ /* assign old pointer to the old file, and move it to the first
+ * place of the list : delete_file() only remove the first
+ * occurrence of the file which has the name given in argument */
+ if (prev != NULL) {
+ prev->cf_next = old->cf_next;
+ old->cf_next = file_base;
+ file_base = old;
+ }
+ else
+ /* this is the first file in the list : no need to move it */
+
+
/* compare each lines between the new and the old
* version of the file */
for (new_l = cur_f->cf_line_base; new_l; new_l = new_l->cl_next)
/* compare the shell command and the fields
from cl_mins down to cl_runfreq or the timefreq */
if ( strcmp(new_l->cl_shell, old_l->cl_shell) == 0 &&
- new_l->cl_timefreq == old_l->cl_timefreq &&
memcmp(new_l->cl_mins, old_l->cl_mins, size) == 0
) {
new_l->cl_remain = old_l->cl_remain;
if ( (new_l->cl_nextexe = old_l->cl_nextexe) > 0 )
insert_nextexe(new_l);
- else insert_freq(new_l);
+ else
+ insert_freq(new_l);
if (debug_opt) {
if (new_l->cl_nextexe > 0) {
}
}
+ /* remove old file from the list */
+ delete_file(user);
+
+
/* insert new file in the list */
cur_f->cf_next = file_base;
file_base = cur_f;
cur_line = line->cl_next;
/* remove line from the lists */
- if( line->cl_runfreq != 0 ) {
+ if( line->cl_timefreq != 0 ) {
for ( j = freq_base; j != NULL; j = j->j_next )
if ( j->j_line == line ) {
- prev_j->j_next = j->j_next;
+ if (prev_j != NULL) prev_j->j_next = j->j_next;
+ else freq_base = j->j_next;
free(j);
break;
}
+ else
+ prev_j = j;
}
else
for ( j = queue_base; j != NULL; j = j->j_next )
if ( j->j_line == line ) {
- prev_j->j_next = j->j_next;
+ if (prev_j != NULL) prev_j->j_next = j->j_next;
+ else queue_base = j->j_next;
free(j);
break;
}
+ else
+ prev_j = j;
/* free line itself */
free(line->cl_shell);
free(line);
}
+ /* delete_file() MUST remove only the first occurrence :
+ * this is needed by synchronize_file() */
break ;
} else {
prev_file = file;
* `LICENSE' that comes with the fcron source distribution.
*/
- /* $Id: database.c,v 1.6 2000-05-31 19:11:35 thib Exp $ */
+ /* $Id: database.c,v 1.7 2000-06-03 20:28:34 thib Exp $ */
#include "fcron.h"
debug("Looking for jobs to execute ...");
/* job based on date & time */
- for (j=queue_base; (j!=NULL)&&(j->j_line->cl_nextexe <= t2); j=j->j_next){
+ while ( (j=queue_base) && j->j_line->cl_nextexe <= t2 ){
set_next_exe(j->j_line, 0);
if (--(j->j_line->cl_remain) > 0) {
debug(" cl_Remain: %d", j->j_line->cl_remain);
}
/* job based on frequency */
- for (j=freq_base; (j!=NULL)&&(j->j_line->cl_remain <= 0); j=j->j_next){
+ while ( (j=freq_base) && j->j_line->cl_remain <= 0 ){
j->j_line->cl_remain = j->j_line->cl_timefreq;
insert_freq(j->j_line);
if (j->j_line->cl_pid > 0) {
/* wait_chld() - check for job completion */
{
struct job *j = NULL;
+ struct job *jprev = NULL;
int pid;
int status;
}
else if ( pid == j->j_line->cl_mailpid ) {
end_mailer(j->j_line, status);
+
+ /* remove file from exe list */
+ if (jprev != NULL)
+ jprev->j_next = j->j_next;
+ else
+ exe_base = j->j_next;
+ free(j);
+
goto nextloop;
}
+ jprev = j;
}
nextloop:
}
/* return after all jobs completion. */
{
struct job *j = NULL;
+ struct job *jprev = NULL;
int pid;
int status;
debug("Waiting for all jobs");
while ( (*counter > 0) && (pid = wait3(&status, 0, NULL)) > 0 ) {
-
for (j = exe_base; j != NULL ; j = j->j_next) {
-
- if (pid < 0 || pid == j->j_line->cl_pid)
+ if (pid < 0 || pid == j->j_line->cl_pid) {
end_job(j->j_line, status);
- else if ( pid == j->j_line->cl_mailpid )
+ goto nextloop;
+ }
+ else if ( pid == j->j_line->cl_mailpid ) {
end_mailer(j->j_line, status);
+
+ /* remove file from exe list */
+ if (jprev != NULL)
+ jprev->j_next = j->j_next;
+ else
+ exe_base = j->j_next;
+ free(j);
+
+ goto nextloop;
+ }
+ jprev = j;
}
+ nextloop:
}
}
insert_nextexe(CL *line)
/* insert a job based on time and date in the corresponding queue list */
{
- struct job *newjob = NULL;
+ struct job *newjob = NULL;
- if (queue_base != NULL) {
- struct job *j = NULL;
- struct job *jprev = NULL;
- struct job *old_entry = NULL;
+ if (queue_base != NULL) {
+ struct job *j = NULL;
+ struct job *jprev = NULL;
+ struct job *old_entry = NULL;
- j = queue_base;
- while (j != NULL && (line->cl_nextexe > j->j_line->cl_nextexe)) {
- if ( j->j_line == line ) {
- old_entry = j;
+ /* find the job in the list */
+ for (j = queue_base; j != NULL ; j = j->j_next)
+ if ( j->j_line == line ) {
+ old_entry = j;
+ /* remove it from the list */
+ if (jprev != NULL) {
jprev->j_next = j->j_next;
j = jprev;
}
- jprev = j;
- j = j->j_next;
- }
- if (old_entry == NULL) {
- /* this job wasn't in the queue : we append it */
- Alloc(newjob, job);
- newjob->j_line = line;
- }
- else
- /* this job was already in the queue : we move it */
- newjob = old_entry;
+ else
+ /* first element of the list */
+ j = queue_base = j->j_next;
- newjob->j_next = j;
+ break;
+ }
- if (jprev == NULL)
- queue_base = newjob;
- else
- jprev->j_next = newjob;
+ if (j == NULL || line->cl_nextexe < j->j_line->cl_nextexe)
+ j = queue_base;
+ while (j != NULL && (line->cl_nextexe >= j->j_line->cl_nextexe)) {
+ jprev = j;
+ j = j->j_next;
+ }
- }
- else {
- /* no job in queue */
+ if (old_entry == NULL) {
+ /* this job wasn't in the queue : we append it */
Alloc(newjob, job);
- newjob->j_line = line;
- queue_base = newjob;
+ newjob->j_line = line;
}
+ else
+ /* this job was already in the queue : we move it */
+ newjob = old_entry;
+
+ newjob->j_next = j;
+
+ if (jprev == NULL)
+ queue_base = newjob;
+ else
+ jprev->j_next = newjob;
+
+ }
+ else {
+ /* no job in queue */
+ Alloc(newjob, job);
+ newjob->j_line = line;
+ queue_base = newjob;
+ }
}
void
insert_freq(CL *line)
- /* insert a job based on frequency in the corresponding queue list */
+ /* insert a job based on frequency in the corresponding queue list *
+ * if the job was already in the queue list, move it to the right rank. */
{
struct job *newjob = NULL;
struct job *jprev = NULL;
struct job *old_entry = NULL;
- j = freq_base;
- while (j != NULL && (line->cl_remain > j->j_line->cl_remain)) {
+ /* find the job in the list */
+ for (j = freq_base; j != NULL ; j = j->j_next)
if ( j->j_line == line ) {
old_entry = j;
- jprev->j_next = j->j_next;
- j = jprev;
+ /* remove it from the list */
+ if (jprev != NULL) {
+ jprev->j_next = j->j_next;
+ j = jprev;
+ }
+ else
+ /* first element of the list */
+ j = freq_base = j->j_next;
+
+ break;
}
+
+ if ( j == NULL || line->cl_remain < j->j_line->cl_remain)
+ j = freq_base;
+ while (j != NULL && (line->cl_remain >= j->j_line->cl_remain)) {
jprev = j;
j = j->j_next;
- }
+ }
+
if (old_entry == NULL) {
/* this job wasn't in the queue : we append it */
Alloc(newjob, job);
now = time(NULL);
if (queue_base == NULL && freq_base == NULL)
- /* no lines : we sleep as much as we can */
+ /* no lines : we sleep as much as we can, so how much lim permits us */
goto end;
else if (queue_base == NULL && freq_base != NULL) {
tts = freq_base->j_line->cl_remain;
tts = freq_base->j_line->cl_remain;
end:
+ if (tts > lim)
+ tts = lim;
+
debug("Time to sleep: %lds", tts);
return tts;