Add support for is_newer_than and is_older_than. is_older_than currently doesn't work as expected, but is_newer_than works fine.
This commit is contained in:
parent
e49e5b147c
commit
d695407114
@ -596,7 +596,7 @@ char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_deptree_order)
|
librc_hidden_def(rc_deptree_order)
|
||||||
|
|
||||||
static bool is_newer_than (const char *file, const char *target)
|
bool rc_newer_than (const char *source, const char *target)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
@ -604,28 +604,31 @@ static bool is_newer_than (const char *file, const char *target)
|
|||||||
DIR *dp;
|
DIR *dp;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
char *path;
|
char *path;
|
||||||
|
int serrno = errno;
|
||||||
|
|
||||||
if (stat (file, &buf) != 0 || buf.st_size == 0)
|
if (stat (source, &buf) != 0 || buf.st_size == 0)
|
||||||
return (false);
|
return (false);
|
||||||
mtime = buf.st_mtime;
|
mtime = buf.st_mtime;
|
||||||
|
|
||||||
/* Of course we are newever than targets that don't exist
|
/* Of course we are newer than targets that don't exist
|
||||||
Such as broken symlinks */
|
such as broken symlinks */
|
||||||
if (stat (target, &buf) != 0)
|
if (stat (target, &buf) != 0)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
if (mtime < buf.st_mtime)
|
if (mtime < buf.st_mtime)
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
if (! (dp = opendir (target)))
|
if (! (dp = opendir (target))) {
|
||||||
|
errno = serrno;
|
||||||
return (true);
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
while ((d = readdir (dp))) {
|
while ((d = readdir (dp))) {
|
||||||
if (d->d_name[0] == '.')
|
if (d->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
path = rc_strcatpaths (target, d->d_name, (char *) NULL);
|
path = rc_strcatpaths (target, d->d_name, (char *) NULL);
|
||||||
newer = is_newer_than (file, path);
|
newer = rc_newer_than (source, path);
|
||||||
free (path);
|
free (path);
|
||||||
if (! newer)
|
if (! newer)
|
||||||
break;
|
break;
|
||||||
@ -634,6 +637,7 @@ static bool is_newer_than (const char *file, const char *target)
|
|||||||
|
|
||||||
return (newer);
|
return (newer);
|
||||||
}
|
}
|
||||||
|
librc_hidden_def(rc_newer_than)
|
||||||
|
|
||||||
typedef struct deppair
|
typedef struct deppair
|
||||||
{
|
{
|
||||||
@ -679,18 +683,18 @@ bool rc_deptree_update_needed (void)
|
|||||||
fprintf (stderr, "mkdir `%s': %s\n", depdirs[i], strerror (errno));
|
fprintf (stderr, "mkdir `%s': %s\n", depdirs[i], strerror (errno));
|
||||||
|
|
||||||
/* Quick test to see if anything we use has changed */
|
/* Quick test to see if anything we use has changed */
|
||||||
if (! is_newer_than (RC_DEPTREE, RC_INITDIR) ||
|
if (! rc_newer_than (RC_DEPTREE, RC_INITDIR) ||
|
||||||
! is_newer_than (RC_DEPTREE, RC_CONFDIR) ||
|
! rc_newer_than (RC_DEPTREE, RC_CONFDIR) ||
|
||||||
! is_newer_than (RC_DEPTREE, RC_INITDIR_LOCAL) ||
|
! rc_newer_than (RC_DEPTREE, RC_INITDIR_LOCAL) ||
|
||||||
! is_newer_than (RC_DEPTREE, RC_CONFDIR_LOCAL) ||
|
! rc_newer_than (RC_DEPTREE, RC_CONFDIR_LOCAL) ||
|
||||||
! is_newer_than (RC_DEPTREE, "/etc/rc.conf"))
|
! rc_newer_than (RC_DEPTREE, "/etc/rc.conf"))
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
/* Some init scripts dependencies change depending on config files
|
/* Some init scripts dependencies change depending on config files
|
||||||
* outside of baselayout, like syslog-ng, so we check those too. */
|
* outside of baselayout, like syslog-ng, so we check those too. */
|
||||||
config = rc_config_list (RC_DEPCONFIG);
|
config = rc_config_list (RC_DEPCONFIG);
|
||||||
STRLIST_FOREACH (config, service, i) {
|
STRLIST_FOREACH (config, service, i) {
|
||||||
if (! is_newer_than (RC_DEPTREE, service)) {
|
if (! rc_newer_than (RC_DEPTREE, service)) {
|
||||||
newer = true;
|
newer = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ librc_hidden_proto(rc_deptree_update)
|
|||||||
librc_hidden_proto(rc_deptree_update_needed)
|
librc_hidden_proto(rc_deptree_update_needed)
|
||||||
librc_hidden_proto(rc_find_pids)
|
librc_hidden_proto(rc_find_pids)
|
||||||
librc_hidden_proto(rc_getline)
|
librc_hidden_proto(rc_getline)
|
||||||
|
librc_hidden_proto(rc_newer_than)
|
||||||
librc_hidden_proto(rc_runlevel_exists)
|
librc_hidden_proto(rc_runlevel_exists)
|
||||||
librc_hidden_proto(rc_runlevel_get)
|
librc_hidden_proto(rc_runlevel_get)
|
||||||
librc_hidden_proto(rc_runlevel_list)
|
librc_hidden_proto(rc_runlevel_list)
|
||||||
|
@ -61,7 +61,8 @@ bool rc_runlevel_exists (const char *runlevel);
|
|||||||
char **rc_runlevel_list (void);
|
char **rc_runlevel_list (void);
|
||||||
|
|
||||||
/*! Set the runlevel.
|
/*! Set the runlevel.
|
||||||
* This just changes the stored runlevel and does not start or stop any services.
|
* This just changes the stored runlevel and does not start or stop any
|
||||||
|
* services.
|
||||||
* @param runlevel to store */
|
* @param runlevel to store */
|
||||||
bool rc_runlevel_set (const char *runlevel);
|
bool rc_runlevel_set (const char *runlevel);
|
||||||
|
|
||||||
@ -117,8 +118,8 @@ bool rc_service_delete (const char *runlevel, const char *service);
|
|||||||
* @param pidfile of the process (optional)
|
* @param pidfile of the process (optional)
|
||||||
* @param started if true, add the arguments otherwise remove existing matching arguments */
|
* @param started if true, add the arguments otherwise remove existing matching arguments */
|
||||||
bool rc_service_daemon_set (const char *service, const char *exec,
|
bool rc_service_daemon_set (const char *service, const char *exec,
|
||||||
const char *name, const char *pidfile,
|
const char *name, const char *pidfile,
|
||||||
bool started);
|
bool started);
|
||||||
|
|
||||||
/*! Returns a description of what the service and/or option does.
|
/*! Returns a description of what the service and/or option does.
|
||||||
* @param service to check
|
* @param service to check
|
||||||
@ -157,7 +158,7 @@ char *rc_service_resolve (const char *service);
|
|||||||
* @param service that starts the scheduled service when started
|
* @param service that starts the scheduled service when started
|
||||||
* @param service_to_start service that will be started */
|
* @param service_to_start service that will be started */
|
||||||
bool rc_service_schedule_start (const char *service,
|
bool rc_service_schedule_start (const char *service,
|
||||||
const char *service_to_start);
|
const char *service_to_start);
|
||||||
/*! Return a NULL terminated list of services that are scheduled to start
|
/*! Return a NULL terminated list of services that are scheduled to start
|
||||||
* when the given service has started
|
* when the given service has started
|
||||||
* @param service to check
|
* @param service to check
|
||||||
@ -190,7 +191,7 @@ pid_t rc_service_stop (const char *service);
|
|||||||
* @param indx of the daemon (optional - 1st daemon, 2nd daemon, etc)
|
* @param indx of the daemon (optional - 1st daemon, 2nd daemon, etc)
|
||||||
* @return true if started by this service, otherwise false */
|
* @return true if started by this service, otherwise false */
|
||||||
bool rc_service_started_daemon (const char *service, const char *exec,
|
bool rc_service_started_daemon (const char *service, const char *exec,
|
||||||
int indx);
|
int indx);
|
||||||
|
|
||||||
/*! Return a saved value for a service
|
/*! Return a saved value for a service
|
||||||
* @param service to check
|
* @param service to check
|
||||||
@ -204,7 +205,7 @@ char *rc_service_value_get (const char *service, const char *option);
|
|||||||
* @param value of the option
|
* @param value of the option
|
||||||
* @return true if saved, otherwise false */
|
* @return true if saved, otherwise false */
|
||||||
bool rc_service_value_set (const char *service, const char *option,
|
bool rc_service_value_set (const char *service, const char *option,
|
||||||
const char *value);
|
const char *value);
|
||||||
|
|
||||||
/*! List the services in a runlevel
|
/*! List the services in a runlevel
|
||||||
* @param runlevel to list
|
* @param runlevel to list
|
||||||
@ -248,6 +249,11 @@ bool rc_service_daemons_crashed (const char *service);
|
|||||||
typedef void *rc_depinfo_t;
|
typedef void *rc_depinfo_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*! Check to see if source is newer than target.
|
||||||
|
* If target is a directory then we traverse it and it's children.
|
||||||
|
* @return true if source is newer than target, otherwise false */
|
||||||
|
bool rc_newer_than (const char *source, const char *target);
|
||||||
|
|
||||||
/*! Update the cached dependency tree if it's older than any init script,
|
/*! Update the cached dependency tree if it's older than any init script,
|
||||||
* its configuration file or an external configuration file the init script
|
* its configuration file or an external configuration file the init script
|
||||||
* has specified.
|
* has specified.
|
||||||
@ -271,7 +277,7 @@ rc_depinfo_t *rc_deptree_load (void);
|
|||||||
* @param service to check
|
* @param service to check
|
||||||
* @return NULL terminated list of services in order */
|
* @return NULL terminated list of services in order */
|
||||||
char **rc_deptree_depend (const rc_depinfo_t *deptree,
|
char **rc_deptree_depend (const rc_depinfo_t *deptree,
|
||||||
const char *type, const char *service);
|
const char *type, const char *service);
|
||||||
|
|
||||||
/*! List all the services in order that the given services have
|
/*! List all the services in order that the given services have
|
||||||
* for the given types and options.
|
* for the given types and options.
|
||||||
@ -281,9 +287,9 @@ char **rc_deptree_depend (const rc_depinfo_t *deptree,
|
|||||||
* @param options to pass
|
* @param options to pass
|
||||||
* @return NULL terminated list of services in order */
|
* @return NULL terminated list of services in order */
|
||||||
char **rc_deptree_depends (const rc_depinfo_t *deptree,
|
char **rc_deptree_depends (const rc_depinfo_t *deptree,
|
||||||
const char *const *types,
|
const char *const *types,
|
||||||
const char *const *services, const char *runlevel,
|
const char *const *services, const char *runlevel,
|
||||||
int options);
|
int options);
|
||||||
|
|
||||||
/*! List all the services that should be stoppned and then started, in order,
|
/*! List all the services that should be stoppned and then started, in order,
|
||||||
* for the given runlevel, including sysinit and boot services where
|
* for the given runlevel, including sysinit and boot services where
|
||||||
@ -293,7 +299,7 @@ char **rc_deptree_depends (const rc_depinfo_t *deptree,
|
|||||||
* @param options to pass
|
* @param options to pass
|
||||||
* @return NULL terminated list of services in order */
|
* @return NULL terminated list of services in order */
|
||||||
char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
|
char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
|
||||||
int options);
|
int options);
|
||||||
|
|
||||||
/*! Free a deptree and its information
|
/*! Free a deptree and its information
|
||||||
* @param deptree to free */
|
* @param deptree to free */
|
||||||
@ -440,6 +446,6 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL;
|
|||||||
* @param pid to check for
|
* @param pid to check for
|
||||||
* @return NULL terminated list of pids */
|
* @return NULL terminated list of pids */
|
||||||
pid_t *rc_find_pids (const char *exec, const char *cmd,
|
pid_t *rc_find_pids (const char *exec, const char *cmd,
|
||||||
uid_t uid, pid_t pid);
|
uid_t uid, pid_t pid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,6 +13,7 @@ global:
|
|||||||
rc_environ_fd;
|
rc_environ_fd;
|
||||||
rc_find_pids;
|
rc_find_pids;
|
||||||
rc_getline;
|
rc_getline;
|
||||||
|
rc_newer_than;
|
||||||
rc_runlevel_exists;
|
rc_runlevel_exists;
|
||||||
rc_runlevel_get;
|
rc_runlevel_get;
|
||||||
rc_runlevel_list;
|
rc_runlevel_list;
|
||||||
|
@ -23,7 +23,7 @@ RC_BINLINKS= einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \
|
|||||||
service_coldplugged service_started_daemon \
|
service_coldplugged service_started_daemon \
|
||||||
checkpath fstabinfo mountinfo rc-depend \
|
checkpath fstabinfo mountinfo rc-depend \
|
||||||
service_get_value service_set_value get_options save_options \
|
service_get_value service_set_value get_options save_options \
|
||||||
shell_var
|
shell_var is_newer_than is_older_than
|
||||||
RC_SBINLINKS= mark_service_starting mark_service_started \
|
RC_SBINLINKS= mark_service_starting mark_service_started \
|
||||||
mark_service_stopping mark_service_stopped \
|
mark_service_stopping mark_service_stopped \
|
||||||
mark_service_inactive mark_service_wasinactive \
|
mark_service_inactive mark_service_wasinactive \
|
||||||
|
15
src/rc/rc.c
15
src/rc/rc.c
@ -913,6 +913,21 @@ int main (int argc, char **argv)
|
|||||||
if (strncmp (applet, "mark_service_", strlen ("mark_service_")) == 0)
|
if (strncmp (applet, "mark_service_", strlen ("mark_service_")) == 0)
|
||||||
exit (do_mark_service (argc, argv));
|
exit (do_mark_service (argc, argv));
|
||||||
|
|
||||||
|
if (strcmp (applet, "is_newer_than") == 0 ||
|
||||||
|
strcmp (applet, "is_older_than") == 0)
|
||||||
|
{
|
||||||
|
bool match = false;
|
||||||
|
if (argc < 2)
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
if (strcmp (applet, "is_newer_than") == 0)
|
||||||
|
match = true;
|
||||||
|
while (optind < argc) {
|
||||||
|
if (rc_newer_than (argv[0], argv[optind++]) != match)
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
};
|
||||||
|
|
||||||
if (strcmp (applet, "is_runlevel_start") == 0)
|
if (strcmp (applet, "is_runlevel_start") == 0)
|
||||||
exit (rc_runlevel_starting () ? 0 : 1);
|
exit (rc_runlevel_starting () ? 0 : 1);
|
||||||
else if (strcmp (applet, "is_runlevel_stop") == 0)
|
else if (strcmp (applet, "is_runlevel_stop") == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user