- added alloc_safe() and realloc_safe(): wrappers around calloc() and realloc() that die on error
- checked the code to use free_safe(), Set(), Alloc(), alloc_safe() and realloc_safe() whenever appropriate
next = rm_list;
while( (l = next) != NULL ) {
next = l->next;
- free(l->str);
- free(l);
+ free_safe(l->str);
+ free_safe(l);
}
next = new_list;
while( (l = next) != NULL ) {
next = l->next;
- free(l->str);
- free(l);
+ free_safe(l->str);
+ free_safe(l);
}
next = file_list;
while( (l = next) != NULL ) {
next = l->next;
- free(l->str);
- free(l);
+ free_safe(l->str);
+ free_safe(l);
}
}
err:
if (*str)
- free(*str);
- *str = NULL;
+ free_safe(*str);
return ERR;
}
}
/* get the owner's name */
/* we set cf->cf_user before for SE Linux, so we need to free it here */
- free(cf->cf_user);
+ free_safe(cf->cf_user);
if ( read_strn(fileno(ff), &cf->cf_user, size) != OK ) {
error("Cannot read user's name : file ignored");
goto err;
/* we use file owner's name for more security (see above) */
/* free the value obtained by read_strn() (we need to read it anyway
* to set the file ptr to the next thing to read) */
- free(cf->cf_user);
+ free_safe(cf->cf_user);
cf->cf_user = runas_str;
}
else {
env_list_putenv(cf->cf_env_list, envvar, 1);
}
- free(envvar);
+ free_safe(envvar);
}
break;
}
/* free last cl Alloc : unused */
- free(cl);
+ free_safe(cl);
/* check for an error */
if ( ferror(ff) != 0 )
if ( cl != NULL && cl->cl_next == NULL ) {
/* line is not yet in the line list of the file : free it */
- if ( cl->cl_shell ) free(cl->cl_shell);
- if ( cl->cl_runas) free(cl->cl_runas);
- if ( cl->cl_mailto) free(cl->cl_mailto);
- free(cl);
+ if ( cl->cl_shell ) free_safe(cl->cl_shell);
+ if ( cl->cl_runas) free_safe(cl->cl_runas);
+ if ( cl->cl_mailto) free_safe(cl->cl_mailto);
+ free_safe(cl);
}
/* check if we have started to read the lines and env var */
}
else if (cf->cf_user != NULL)
- free(cf->cf_user);
+ free_safe(cf->cf_user);
return ERR;
error("Line is not valid (empty shell, runas or mailto field)"
" : ignored");
bzero(cl, sizeof(cl));
- if (cl->cl_shell) free(cl->cl_shell);
- if (cl->cl_runas) free(cl->cl_runas);
- if (cl->cl_mailto) free(cl->cl_mailto);
+ if (cl->cl_shell) free_safe(cl->cl_shell);
+ if (cl->cl_runas) free_safe(cl->cl_runas);
+ if (cl->cl_mailto) free_safe(cl->cl_mailto);
return 1;
}
strcspn(cl->cl_mailto, " \t\n") != strlen(cl->cl_mailto) ) ) {
error("mailto field \'%s\' is not valid : set to owner %s.", cl->cl_mailto,
cl->cl_file->cf_user);
- free(cl->cl_mailto);
- cl->cl_mailto = strdup2(cl->cl_file->cf_user);
+ Set(cl->cl_mailto,cl->cl_file->cf_user);
}
/* check if the job hasn't been stopped during execution and insert
/* free serial queue entries */
for ( i = 0; i < serial_array_size; i++)
if (serial_array[i] != NULL && serial_array[i]->cl_file == file ) {
- if ( ! s_a )
- s_a = calloc(serial_array_size, sizeof(cl_t *));
+ if ( ! s_a ) {
+ s_a = alloc_safe(serial_array_size*sizeof(cl_t *), "serial queue");
+ }
debug("removing %s from serial queue",
serial_array[i]->cl_shell);
serial_num--;
!= NULL)
k++;
}
- free(serial_array);
+ free_safe(serial_array);
serial_array = s_a;
serial_array_index = 0;
prev_j->j_next = j->j_next;
else
queue_base = j->j_next;
- free(j);
+ free_safe(j);
break;
}
else
prev_j = j;
/* free line itself */
- free(line->cl_shell);
- free(line->cl_runas);
- free(line->cl_mailto);
- free(line);
+ free_safe(line->cl_shell);
+ free_safe(line->cl_runas);
+ free_safe(line->cl_mailto);
+ free_safe(line);
}
/* delete_file() MUST remove only the first occurrence :
* this is needed by synchronize_file() */
env_list_destroy(file->cf_env_list);
/* finally free file itself */
- free(file->cf_user);
- free(file);
+ free_safe(file->cf_user);
+ free_safe(file);
}
cur_line = file->cf_line_base;
while ( (line = cur_line) != NULL) {
cur_line = line->cl_next;
- free(line->cl_shell);
- free(line->cl_mailto);
- free(line->cl_runas);
- free(line);
+ free_safe(line->cl_shell);
+ free_safe(line->cl_mailto);
+ free_safe(line->cl_runas);
+ free_safe(line);
}
/* free env variables */
env_list_destroy(file->cf_env_list);
/* finally free file itself */
- free(file->cf_user);
- free(file);
+ free_safe(file->cf_user);
+ free_safe(file);
}
}
- free(line);
+ free_safe(line);
fclose(f);
debug("Resizing serial_array");
serial_array_size = (serial_array_size + SERIAL_GROW_SIZE);
- if ( (ptr = calloc(serial_array_size, sizeof(cl_t *))) == NULL )
- die_e("could not calloc serial_array");
+ ptr = alloc_safe(serial_array_size*sizeof(cl_t *), "serial_array");
/* copy lines in order to have the first line at the index 0 */
memcpy(ptr + serial_array_index, serial_array,
memcpy(ptr, serial_array + (old_size - serial_array_index),
(sizeof(cl_t*) * serial_array_index));
serial_array_index = 0;
- free(serial_array);
+ free_safe(serial_array);
serial_array = ptr;
}
}
<title>High priority</title>
<itemizedlist>
<listitem>
- <para>replace all free() by free_safe()</para>
+ <para>move fcron.conf stuff from subs.{c} to a new fcronconf.{c|h}</para>
+ </listitem>
+ <listitem>
+ <para>change copyright to ...,2008,2009,2010</para>
</listitem>
<listitem>
<para>check fcron for memory leaks using library</para>
/* variable already set: overwrite the value if asked
* and return that entry */
if ( overwrite == 1 ) {
- c->e_envvar = realloc(c->e_envvar, len);
- if ( c->e_envvar == NULL )
- die_e("Could not allocate memory to modify env var");
+ c->e_envvar = realloc_safe(c->e_envvar, len, "new env var value");
snprintf(c->e_envvar, len, "%s=%s", name, value);
}
env_list_end_iteration(list);
}
/* if we're here we didn't find a var called 'name': add it */
- e.e_envvar = calloc(1, len);
+ e.e_envvar = alloc_safe(len, "new env var");
snprintf(e.e_envvar, len, "%s=%s", name, value);
return (env_t *) u_list_add( (u_list_t *) list, (u_list_entry_t *) &e);
}
/* variable already set: overwrite the value if asked
* and return that entry */
if ( overwrite == 1 ) {
- c->e_envvar = realloc(c->e_envvar, len);
- if ( c->e_envvar == NULL )
- die_e("Could not allocate memory to modify env var");
+ c->e_envvar = realloc_safe(c->e_envvar, len, "new env var value");
memcpy(c->e_envvar, envvar, len); /* includes the final '\0' */
}
env_list_end_iteration(list);
int i = 0;
char **envp = NULL;
- envp = calloc(list->num_entries + 1, sizeof(char *)); /* +1 for the end-of-list NULL */
- if ( envp == NULL )
- die_e("Could not allocate memory for the environment");
+ /* +1 for the end-of-list NULL */
+ envp = alloc_safe((list->num_entries + 1)*sizeof(char *), "environment export");
for ( c=env_list_first(list), i=0 ; c != NULL && i < list->num_entries ;
c=env_list_next(list), i++ ) {
envp[i] = strdup2(c->e_envvar);
- if ( envp[i] == NULL )
- die_e("Could not allocate memory for an environment entry");
}
/* add a NULL as a end-of-list marker */
envp[ (list->num_entries + 1 ) - 1] = NULL;
lavg_list_destroy(lavg_list);
free_conf();
- free(orig_tz_envvar);
+ free_safe(orig_tz_envvar);
explain("Exiting with code %d", exit_value);
exit (exit_value);
serial_array_index = 0;
serial_num = 0;
serial_array_size = SERIAL_INITIAL_SIZE;
- if ( (serial_array = calloc(serial_array_size, sizeof(cl_t *))) == NULL )
- die_e("could not calloc serial_array");
+ serial_array = alloc_safe(serial_array_size*sizeof(cl_t *), "serial_array");
/* initialize lavg_array */
lavg_list = lavg_list_init();
xexit(int exit_val)
/* clean & exit */
{
- Flush(cmd_str);
+ free_safe(cmd_str);
exit(exit_val);
}
fprintf(stderr, "Warning : too much arguments : '%s' ignored.\n", cmd_str);
/* This is a valid command ... */
- if ( (*cmd = calloc(*cmd_len, sizeof(long int))) == NULL )
- die_e("Could not calloc.");
-
+ *cmd = alloc_safe(*cmd_len*sizeof(long int), "command string");
memcpy(*cmd, buf, *cmd_len * sizeof(long int));
return OK;
send(fd, buf, len, 0);
Overwrite(buf);
Overwrite(password);
- free(password);
+ free_safe(password);
tv.tv_sec = MAX_WAIT_TIME;
tv.tv_usec = 0;
return ERR;
send(fd, cmd, cmd_len * sizeof(long int), 0);
- Flush(cmd);
+ free_safe(cmd);
cmd_len = 0;
tv.tv_sec = MAX_WAIT_TIME;
break;
case 'i':
- Flush(cmd_str);
+ free_safe(cmd_str);
break;
case 'x':
"grow_size=%d", entry_size, init_size, grow_size);
/* Allocate the list structure: */
- l = calloc(1, sizeof(struct fifo_list_t));
- if ( l == NULL )
- die_e("Failed creating a new fifo list: could not calloc() fifo_list_t "
- "(entry_size: %d)", entry_size);
+ l = alloc_safe(sizeof(struct fifo_list_t), "new fifo_list_t");
/* Initialize the structure and allocate the array: */
l->max_entries = l->num_entries = 0;
l->entry_size = entry_size;
l->grow_size = grow_size;
l->first_entry = l->cur_entry = NULL;
- l->entries_array = calloc(init_size, entry_size);
- if ( l->entries_array == NULL )
- die_e("Failed creating a new fifo list: could not calloc array"
- "(entry_size: %d, init_size: %d)", entry_size, init_size);
+ l->entries_array = alloc_safe(init_size*entry_size, "new fifo_list_t array");
return l;
}
debug("Resizing fifo_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 fifo_list_t to grow entries_array "
- "(old size: %d, new size: %d)...", old_size, l->array_size);
-
+ e = alloc_safe(l->array_size*l->entry_size, "larger fifo_list_t array");
memcpy(e, l->entries_array, (l->entry_size * old_size));
free_safe(l->entries_array);
l->entries_array = e;
fclose(file);
- free(default_line.cl_runas);
- free(default_line.cl_mailto);
- free(default_line.cl_tz);
+ free_safe(default_line.cl_runas);
+ free_safe(default_line.cl_mailto);
+ free_safe(default_line.cl_tz);
if ( ! need_correction )
return OK;
buf[i++] = *ptr++;
if ( strcmp(buf, "\0") == 0 ) {
- Flush(cl->cl_tz);
+ free_safe(cl->cl_tz);
}
else {
Set(cl->cl_tz, buf);
bzero(cl, sizeof(cl_t));
Set(cl->cl_runas, runas);
Set(cl->cl_mailto, runas);
- Flush(cl->cl_tz);
+ free_safe(cl->cl_tz);
set_default_opt(cl->cl_option);
}
if (debug_opt)
if ( strcmp(cl->cl_shell, "\0") == 0 ) {
fprintf(stderr, "%s:%d: No shell command: skipping line.\n",
file_name, line);
- free(cl->cl_shell);
+ free_safe(cl->cl_shell);
goto exiterr;
}
return;
exiterr:
- free(cl);
+ free_safe(cl);
need_correction = 1;
return;
}
fprintf(stderr, "\n"); \
fprintf(stderr, "%s:%d: Error while reading " DESCRP " field: " \
"skipping line.\n", file_name, line); \
- free(cl); \
+ free_safe(cl); \
return; \
}
exiterr:
need_correction = 1;
- free(cl);
+ free_safe(cl);
return;
}
exiterr:
need_correction = 1;
- free(cl);
+ free_safe(cl);
return;
}
cur_line = file->cf_line_base;
while ( (line = cur_line) != NULL) {
cur_line = line->cl_next;
- free(line->cl_shell);
- free(line->cl_mailto);
- free(line->cl_runas);
- free(line->cl_tz);
- free(line);
+ free_safe(line->cl_shell);
+ free_safe(line->cl_mailto);
+ free_safe(line->cl_runas);
+ free_safe(line->cl_tz);
+ free_safe(line);
}
break ;
env_list_destroy(file->cf_env_list);
/* finally free file itself */
- free(file->cf_user);
- free(file);
+ free_safe(file->cf_user);
+ free_safe(file);
}
VAR = strdup2(VALUE); \
}
-#define Flush(VAR) \
- { \
- free(VAR); \
- VAR = NULL; \
- }
-
#define Skip_blanks(PTR) \
while((*(PTR) == ' ') || (*(PTR) == '\t')) \
(PTR)++;
setup_user_and_env(cl, pas, sendmailenv, jobenv, curshell, curhome);
become_user(cl, pas, *curhome);
- free(*curhome);
+ free_safe(*curhome);
}
void
log_console_str(msg);
log_fd_str(fd, msg);
- free(msg);
+ free_safe(msg);
}
/* Same as log_syslog(), but also appends an error description corresponding
log_syslog_str(priority, msg);
log_console_str(msg);
- free(msg);
+ free_safe(msg);
}
xcloselog();
- free(msg);
+ free_safe(msg);
}
#endif
va_start(args, fmt);
log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
va_end(args);
- if (getpid() == daemon_pid) error("Aborted");
+ if (getpid() == daemon_pid) {
+ error("Aborted");
+ }
+ else {
+ error("fcron child aborted: this does not affect the main fcron daemon,"
+ " but this may prevent a job from being run or an email from being sent.");
+ }
exit(EXIT_ERR);
va_start(args, fmt);
log_e(COMPLAIN_LEVEL, fmt, args);
va_end(args);
- if (getpid() == daemon_pid) error("Aborted");
+ if (getpid() == daemon_pid) {
+ error("Aborted");
+ }
+ else {
+ error("fcron child aborted: this does not affect the main fcron daemon,"
+ " but this may prevent a job from being run or an email from being sent.");
+ }
+
exit(err_no);
log_fd_str(fd, msg);
- free(msg);
+ free_safe(msg);
va_end(args);
}
log_fd_str(fd, msg);
- free(msg);
+ free_safe(msg);
va_end(args);
}
debug("connection closed : fd : %d", (*client)->fcl_sock_fd);
if (prev_client == NULL ) {
fcrondyn_cl_base = (*client)->fcl_next;
- Flush((*client)->fcl_user);
- Flush(*client);
+ free_safe((*client)->fcl_user);
+ free_safe(*client);
*client = fcrondyn_cl_base;
}
else {
prev_client->fcl_next = (*client)->fcl_next;
- Flush((*client)->fcl_user);
- Flush(*client);
+ free_safe((*client)->fcl_user);
+ free_safe(*client);
*client = prev_client->fcl_next;
}
fcrondyn_cl_num -= 1;
close(client->fcl_sock_fd);
client_buf = client->fcl_next;
- Flush(client);
+ free_safe(client);
fcrondyn_cl_num -= 1;
client = client_buf;
}
return(ptr);
}
+void *
+alloc_safe(size_t len, const char * desc)
+/* allocate len-bytes of memory, and return the pointer.
+ * Die with a log message if there is any error */
+{
+ void *ptr = NULL;
+
+ ptr = calloc(1, len);
+ if ( ptr == NULL ) {
+ die_e("Could not allocate %d bytes of memory%s%s", len, (desc)? "for " : "", desc);
+ }
+ return ptr;
+}
+
+void *
+realloc_safe(void *cur, size_t len, const char * desc)
+/* allocate len-bytes of memory, and return the pointer.
+ * Die with a log message if there is any error */
+{
+ void *new = NULL;
+
+ new = realloc(cur, len);
+ if ( new == NULL ) {
+ die_e("Could not reallocate %d bytes of memory%s%s", len, (desc)? "for " : "", desc);
+ }
+ return new;
+}
+
void
free_safe(void *ptr)
/* free() p and set it to NULL to prevent errors if it is free()ed again */
while ( isspace( (int) *ptr2 ) ) ptr2++;
/* find which var the line refers to and update it */
- if ( strncmp(ptr1, "fcrontabs", namesize) == 0 )
- fcrontabs = strdup2(ptr2);
- else if ( strncmp(ptr1, "pidfile", namesize) == 0 )
- pidfile = strdup2(ptr2);
- else if ( strncmp(ptr1, "fifofile", namesize) == 0 )
- fifofile = strdup2(ptr2);
- else if ( strncmp(ptr1, "fcronallow", namesize) == 0 )
- fcronallow = strdup2(ptr2);
- else if ( strncmp(ptr1, "fcrondeny", namesize) == 0 )
- fcrondeny = strdup2(ptr2);
- else if ( strncmp(ptr1, "shell", namesize) == 0 )
- shell = strdup2(ptr2);
- else if ( strncmp(ptr1, "sendmail", namesize) == 0 )
- sendmail = strdup2(ptr2);
- else if ( strncmp(ptr1, "editor", namesize) == 0 )
- editor = strdup2(ptr2);
+ if ( strncmp(ptr1, "fcrontabs", namesize) == 0 ) { Set(fcrontabs, ptr2); }
+ else if ( strncmp(ptr1, "pidfile", namesize) == 0 ) { Set(pidfile, ptr2); }
+ else if ( strncmp(ptr1, "fifofile", namesize) == 0 ) { Set(fifofile , ptr2); }
+ else if ( strncmp(ptr1, "fcronallow", namesize) == 0 ) { Set(fcronallow , ptr2); }
+ else if ( strncmp(ptr1, "fcrondeny", namesize) == 0 ) { Set(fcrondeny , ptr2); }
+ else if ( strncmp(ptr1, "shell", namesize) == 0 ) { Set(shell , ptr2); }
+ else if ( strncmp(ptr1, "sendmail", namesize) == 0 ) { Set(sendmail , ptr2); }
+ else if ( strncmp(ptr1, "editor", namesize) == 0 ) { Set(editor , ptr2); }
else
error("Unknown var name at line %s : line ignored", buf);
extern int remove_blanks(char *str);
extern int strcmp_until(const char *left, const char *right, char until);
extern char *strdup2(const char *);
+extern void *alloc_safe(size_t len, const char * desc);
+extern void *realloc_safe(void *ptr, size_t len, const char * desc);
extern void free_safe(void *ptr);
extern int get_word(char **str);
extern int temp_file(char **name);
"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);
+ l = alloc_safe(sizeof(struct u_list_t), "new u_list_t");
/* Initialize the structure and allocate the array: */
l->array_size = init_size;
l->grow_size = grow_size;
l->cur_entry = NULL;
l->cur_removed = 0;
- 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);
+ l->entries_array = alloc_safe(init_size*entry_size, "new u_list_t array");
return l;
}
if ( list == NULL )
return NULL;
- new_list = calloc(1, sizeof(struct u_list_t));
- if ( new_list == NULL )
- die_e("Failed copying unordered list: could not calloc() u_list_t");
+ new_list = alloc_safe(sizeof(struct u_list_t), "u_list_t copy");
memcpy(new_list, list, sizeof(struct u_list_t));
new_list->cur_entry = NULL;
- new_list->entries_array = calloc(list->array_size, list->entry_size);
+ new_list->entries_array = alloc_safe(list->array_size*list->entry_size,
+ "u_list_t copy (array)");
memcpy(new_list->entries_array, list->entries_array,
(list->array_size * list->entry_size));
debug("Resizing u_list_t (old size: %d, new size: %d)...", old_size, l->array_size);
- if ( (l->entries_array = realloc(l->entries_array, (l->array_size * l->entry_size))) == NULL )
- die_e("Could not realloc u_list_t to grow entries_array "
- "(old size: %d, new size: %d)...", old_size, l->array_size);
+ l->entries_array = realloc_safe(l->entries_array, (l->array_size * l->entry_size), "larger u_list_t array");
/* allocate newly allocated memory */
memset((char *) l->entries_array+(old_size * l->entry_size), '\0',
(l->array_size-old_size)*l->entry_size);