2012-05-16 05:36:42 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2012 Lennart Poettering
2013-12-23 07:53:23 +04:00
Copyright 2013 Zbigniew Jędrzejewski - Szmek
2012-05-16 05:36:42 +04:00
systemd is free software ; you can redistribute it and / or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
( at your option ) any later version .
systemd 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
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <errno.h>
# include <assert.h>
# include <string.h>
# include <unistd.h>
# include <getopt.h>
# include "hashmap.h"
# include "util.h"
# include "path-util.h"
# include "log.h"
# include "pager.h"
# include "build.h"
2013-05-16 13:09:03 +04:00
# include "strv.h"
2012-05-16 05:36:42 +04:00
2013-12-23 04:45:02 +04:00
static const char prefixes [ ] =
" /etc \0 "
" /run \0 "
" /usr/local/lib \0 "
" /usr/local/share \0 "
" /usr/lib \0 "
" /usr/share \0 "
# ifdef HAVE_SPLIT_USR
" /lib \0 "
# endif
;
static const char suffixes [ ] =
" sysctl.d \0 "
" tmpfiles.d \0 "
" modules-load.d \0 "
" binfmt.d \0 "
" systemd/system \0 "
" systemd/user \0 "
" systemd/system-preset \0 "
" systemd/user-preset \0 "
" udev/rules.d \0 "
" modprobe.d \0 " ;
static const char have_dropins [ ] =
" systemd/system \0 "
" systemd/user \0 " ;
2012-05-16 05:36:42 +04:00
static bool arg_no_pager = false ;
2012-05-21 04:01:52 +04:00
static int arg_diff = - 1 ;
2012-05-16 05:36:42 +04:00
2012-05-21 04:01:52 +04:00
static enum {
2012-05-16 20:53:46 +04:00
SHOW_MASKED = 1 < < 0 ,
2012-05-16 20:57:57 +04:00
SHOW_EQUIVALENT = 1 < < 1 ,
SHOW_REDIRECTED = 1 < < 2 ,
2012-05-17 00:49:30 +04:00
SHOW_OVERRIDDEN = 1 < < 3 ,
2012-05-16 20:53:46 +04:00
SHOW_UNCHANGED = 1 < < 4 ,
2013-05-16 13:09:03 +04:00
SHOW_EXTENDED = 1 < < 5 ,
2012-05-16 20:53:46 +04:00
SHOW_DEFAULTS =
2013-05-16 13:09:03 +04:00
( SHOW_MASKED | SHOW_EQUIVALENT | SHOW_REDIRECTED | SHOW_OVERRIDDEN | SHOW_EXTENDED )
2012-05-21 04:01:52 +04:00
} arg_flags = 0 ;
2012-05-16 20:53:46 +04:00
2013-12-23 04:45:02 +04:00
static void pager_open_if_enabled ( void ) {
if ( arg_no_pager )
return ;
pager_open ( false ) ;
}
2012-05-16 05:36:42 +04:00
static int equivalent ( const char * a , const char * b ) {
2012-11-14 02:45:41 +04:00
_cleanup_free_ char * x = NULL , * y = NULL ;
2012-05-16 05:36:42 +04:00
x = canonicalize_file_name ( a ) ;
if ( ! x )
return - errno ;
y = canonicalize_file_name ( b ) ;
2012-11-14 02:45:41 +04:00
if ( ! y )
2012-05-16 05:36:42 +04:00
return - errno ;
2012-11-14 02:45:41 +04:00
return path_equal ( x , y ) ;
2012-05-16 05:36:42 +04:00
}
2012-05-21 04:01:52 +04:00
static int notify_override_masked ( const char * top , const char * bottom ) {
if ( ! ( arg_flags & SHOW_MASKED ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 0 ;
2013-08-02 09:59:02 +04:00
printf ( " %s%s%s %s → %s \n " ,
ansi_highlight_red ( ) , " [MASKED] " , ansi_highlight_off ( ) , top , bottom ) ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 1 ;
}
2012-05-21 04:01:52 +04:00
static int notify_override_equivalent ( const char * top , const char * bottom ) {
if ( ! ( arg_flags & SHOW_EQUIVALENT ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 0 ;
2013-08-02 09:59:02 +04:00
printf ( " %s%s%s %s → %s \n " ,
2013-12-23 04:45:02 +04:00
ansi_highlight_green ( ) , " [EQUIVALENT] " , ansi_highlight_off ( ) , top , bottom ) ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 1 ;
}
2012-05-21 04:01:52 +04:00
static int notify_override_redirected ( const char * top , const char * bottom ) {
if ( ! ( arg_flags & SHOW_REDIRECTED ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 0 ;
2013-08-02 09:59:02 +04:00
printf ( " %s%s%s %s → %s \n " ,
ansi_highlight ( ) , " [REDIRECTED] " , ansi_highlight_off ( ) , top , bottom ) ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 1 ;
}
2012-05-17 00:49:30 +04:00
static int notify_override_overridden ( const char * top , const char * bottom ) {
if ( ! ( arg_flags & SHOW_OVERRIDDEN ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 0 ;
2013-08-02 09:59:02 +04:00
printf ( " %s%s%s %s → %s \n " ,
ansi_highlight ( ) , " [OVERRIDDEN] " , ansi_highlight_off ( ) , top , bottom ) ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 1 ;
}
2013-05-16 13:09:03 +04:00
static int notify_override_extended ( const char * top , const char * bottom ) {
if ( ! ( arg_flags & SHOW_EXTENDED ) )
return 0 ;
2013-08-02 09:59:02 +04:00
printf ( " %s%s%s %s → %s \n " ,
ansi_highlight ( ) , " [EXTENDED] " , ansi_highlight_off ( ) , top , bottom ) ;
2013-05-16 13:09:03 +04:00
return 1 ;
}
2012-05-21 04:01:52 +04:00
static int notify_override_unchanged ( const char * f ) {
if ( ! ( arg_flags & SHOW_UNCHANGED ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 0 ;
2012-05-21 04:02:31 +04:00
printf ( " [UNCHANGED] %s \n " , f ) ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return 1 ;
}
2012-05-21 04:01:52 +04:00
static int found_override ( const char * top , const char * bottom ) {
2012-11-14 02:45:41 +04:00
_cleanup_free_ char * dest = NULL ;
2012-05-16 05:36:42 +04:00
int k ;
pid_t pid ;
assert ( top ) ;
assert ( bottom ) ;
2013-05-16 04:42:22 +04:00
if ( null_or_empty_path ( top ) > 0 )
return notify_override_masked ( top , bottom ) ;
2012-05-16 05:36:42 +04:00
k = readlink_malloc ( top , & dest ) ;
if ( k > = 0 ) {
if ( equivalent ( dest , bottom ) > 0 )
2013-05-16 04:42:22 +04:00
return notify_override_equivalent ( top , bottom ) ;
2012-05-16 05:36:42 +04:00
else
2013-05-16 04:42:22 +04:00
return notify_override_redirected ( top , bottom ) ;
2012-05-16 05:36:42 +04:00
}
2013-05-16 04:42:22 +04:00
k = notify_override_overridden ( top , bottom ) ;
2012-05-21 04:01:52 +04:00
if ( ! arg_diff )
2013-05-16 04:42:22 +04:00
return k ;
2012-05-16 05:36:42 +04:00
putchar ( ' \n ' ) ;
fflush ( stdout ) ;
pid = fork ( ) ;
if ( pid < 0 ) {
log_error ( " Failed to fork off diff: %m " ) ;
return - errno ;
} else if ( pid = = 0 ) {
execlp ( " diff " , " diff " , " -us " , " -- " , bottom , top , NULL ) ;
log_error ( " Failed to execute diff: %m " ) ;
_exit ( 1 ) ;
}
wait_for_terminate ( pid , NULL ) ;
putchar ( ' \n ' ) ;
2013-05-16 04:42:22 +04:00
return k ;
2012-05-16 05:36:42 +04:00
}
2013-05-16 13:09:03 +04:00
static int enumerate_dir_d ( Hashmap * top , Hashmap * bottom , Hashmap * drops , const char * toppath , const char * drop ) {
2013-12-23 04:45:02 +04:00
_cleanup_free_ char * unit = NULL ;
2013-05-16 13:09:03 +04:00
_cleanup_free_ char * path = NULL ;
_cleanup_strv_free_ char * * list = NULL ;
char * * file ;
char * c ;
int r ;
2013-12-23 04:45:02 +04:00
assert ( ! endswith ( drop , " / " ) ) ;
2013-05-16 13:09:03 +04:00
path = strjoin ( toppath , " / " , drop , NULL ) ;
if ( ! path )
return - ENOMEM ;
2013-12-23 04:45:02 +04:00
log_debug ( " Looking at %s " , path ) ;
2013-05-16 13:09:03 +04:00
2013-12-23 04:45:02 +04:00
unit = strdup ( drop ) ;
if ( ! unit )
2013-05-16 13:09:03 +04:00
return - ENOMEM ;
2013-12-23 04:45:02 +04:00
c = strrchr ( unit , ' . ' ) ;
2013-05-16 13:09:03 +04:00
if ( ! c )
return - EINVAL ;
* c = 0 ;
r = get_files_in_directory ( path , & list ) ;
if ( r < 0 ) {
log_error ( " Failed to enumerate %s: %s " , path , strerror ( - r ) ) ;
return r ;
}
STRV_FOREACH ( file , list ) {
Hashmap * h ;
int k ;
char * p ;
char * d ;
if ( ! endswith ( * file , " .conf " ) )
continue ;
p = strjoin ( path , " / " , * file , NULL ) ;
if ( ! p )
return - ENOMEM ;
2013-12-23 04:45:02 +04:00
d = p + strlen ( toppath ) + 1 ;
2013-05-16 13:09:03 +04:00
2013-12-23 04:45:02 +04:00
log_debug ( " Adding at top: %s → %s " , d , p ) ;
2013-05-16 13:09:03 +04:00
k = hashmap_put ( top , d , p ) ;
if ( k > = 0 ) {
p = strdup ( p ) ;
if ( ! p )
return - ENOMEM ;
2013-12-23 04:45:02 +04:00
d = p + strlen ( toppath ) + 1 ;
2013-05-16 13:09:03 +04:00
} else if ( k ! = - EEXIST ) {
free ( p ) ;
return k ;
}
2013-12-23 04:45:02 +04:00
log_debug ( " Adding at bottom: %s → %s " , d , p ) ;
2013-05-16 13:09:03 +04:00
free ( hashmap_remove ( bottom , d ) ) ;
k = hashmap_put ( bottom , d , p ) ;
if ( k < 0 ) {
free ( p ) ;
return k ;
}
2013-12-23 04:45:02 +04:00
h = hashmap_get ( drops , unit ) ;
2013-05-16 13:09:03 +04:00
if ( ! h ) {
h = hashmap_new ( string_hash_func , string_compare_func ) ;
if ( ! h )
return - ENOMEM ;
2013-12-23 04:45:02 +04:00
hashmap_put ( drops , unit , h ) ;
unit = strdup ( unit ) ;
if ( ! unit )
2013-05-16 13:09:03 +04:00
return - ENOMEM ;
}
p = strdup ( p ) ;
if ( ! p )
return - ENOMEM ;
2013-12-23 04:45:02 +04:00
log_debug ( " Adding to drops: %s → %s → %s " , unit , basename ( p ) , p ) ;
2013-12-07 06:29:55 +04:00
k = hashmap_put ( h , basename ( p ) , p ) ;
2013-05-16 13:09:03 +04:00
if ( k < 0 ) {
free ( p ) ;
if ( k ! = - EEXIST )
return k ;
}
}
return 0 ;
}
static int enumerate_dir ( Hashmap * top , Hashmap * bottom , Hashmap * drops , const char * path , bool dropins ) {
2012-11-14 02:45:41 +04:00
_cleanup_closedir_ DIR * d ;
2012-05-16 05:36:42 +04:00
assert ( top ) ;
assert ( bottom ) ;
2013-05-16 13:09:03 +04:00
assert ( drops ) ;
2012-05-16 05:36:42 +04:00
assert ( path ) ;
2013-12-23 04:45:02 +04:00
log_debug ( " Looking at %s " , path ) ;
2012-05-16 05:36:42 +04:00
d = opendir ( path ) ;
if ( ! d ) {
if ( errno = = ENOENT )
return 0 ;
2013-12-23 04:45:02 +04:00
log_error ( " Failed to open %s: %m " , path ) ;
2012-05-16 05:36:42 +04:00
return - errno ;
}
for ( ; ; ) {
2012-09-20 00:21:09 +04:00
struct dirent * de ;
2012-05-16 05:36:42 +04:00
int k ;
char * p ;
2013-12-19 14:16:12 +04:00
errno = 0 ;
de = readdir ( d ) ;
2012-05-16 05:36:42 +04:00
if ( ! de )
2013-12-23 04:45:02 +04:00
return - errno ;
2012-05-16 05:36:42 +04:00
2013-05-16 13:09:03 +04:00
if ( dropins & & de - > d_type = = DT_DIR & & endswith ( de - > d_name , " .d " ) )
enumerate_dir_d ( top , bottom , drops , path , de - > d_name ) ;
2012-05-16 05:36:42 +04:00
if ( ! dirent_is_file ( de ) )
continue ;
2012-07-13 15:41:01 +04:00
p = strjoin ( path , " / " , de - > d_name , NULL ) ;
2012-11-14 02:45:41 +04:00
if ( ! p )
return - ENOMEM ;
2012-05-16 05:36:42 +04:00
2013-12-23 04:45:02 +04:00
log_debug ( " Adding at top: %s → %s " , basename ( p ) , p ) ;
2013-12-07 06:29:55 +04:00
k = hashmap_put ( top , basename ( p ) , p ) ;
2012-05-16 05:36:42 +04:00
if ( k > = 0 ) {
p = strdup ( p ) ;
2012-11-14 02:45:41 +04:00
if ( ! p )
return - ENOMEM ;
2012-05-16 05:36:42 +04:00
} else if ( k ! = - EEXIST ) {
free ( p ) ;
2012-11-14 02:45:41 +04:00
return k ;
2012-05-16 05:36:42 +04:00
}
2013-12-23 04:45:02 +04:00
log_debug ( " Adding at bottom: %s → %s " , basename ( p ) , p ) ;
2013-12-07 06:29:55 +04:00
free ( hashmap_remove ( bottom , basename ( p ) ) ) ;
k = hashmap_put ( bottom , basename ( p ) , p ) ;
2012-05-16 05:36:42 +04:00
if ( k < 0 ) {
free ( p ) ;
2012-11-14 02:45:41 +04:00
return k ;
2012-05-16 05:36:42 +04:00
}
}
}
2013-12-23 07:53:23 +04:00
static int process_suffix ( const char * suffix , const char * onlyprefix ) {
2012-05-16 05:36:42 +04:00
const char * p ;
char * f ;
2013-12-23 04:45:02 +04:00
Hashmap * top , * bottom , * drops ;
2013-05-16 13:09:03 +04:00
Hashmap * h ;
char * key ;
2012-05-16 05:36:42 +04:00
int r = 0 , k ;
2013-05-16 13:09:03 +04:00
Iterator i , j ;
2012-05-16 05:36:42 +04:00
int n_found = 0 ;
2013-12-23 04:45:02 +04:00
bool dropins ;
2012-05-16 05:36:42 +04:00
assert ( suffix ) ;
2013-12-23 04:45:02 +04:00
assert ( ! startswith ( suffix , " / " ) ) ;
assert ( ! strstr ( suffix , " // " ) ) ;
2012-05-16 05:36:42 +04:00
2013-12-23 04:45:02 +04:00
dropins = nulstr_contains ( have_dropins , suffix ) ;
2012-05-16 05:36:42 +04:00
2013-12-23 04:45:02 +04:00
top = hashmap_new ( string_hash_func , string_compare_func ) ;
2012-05-16 05:36:42 +04:00
bottom = hashmap_new ( string_hash_func , string_compare_func ) ;
2013-05-16 13:09:03 +04:00
drops = hashmap_new ( string_hash_func , string_compare_func ) ;
2013-12-23 04:45:02 +04:00
if ( ! top | | ! bottom | | ! drops ) {
2013-05-16 13:09:03 +04:00
r = - ENOMEM ;
goto finish ;
}
2012-05-16 05:36:42 +04:00
NULSTR_FOREACH ( p , prefixes ) {
2012-11-14 02:45:41 +04:00
_cleanup_free_ char * t = NULL ;
2012-05-16 05:36:42 +04:00
2012-07-13 15:41:01 +04:00
t = strjoin ( p , " / " , suffix , NULL ) ;
2012-05-16 05:36:42 +04:00
if ( ! t ) {
r = - ENOMEM ;
goto finish ;
}
2013-05-16 13:09:03 +04:00
k = enumerate_dir ( top , bottom , drops , t , dropins ) ;
2013-12-23 04:45:02 +04:00
if ( r = = 0 )
2012-05-16 05:36:42 +04:00
r = k ;
}
2013-05-16 13:09:03 +04:00
HASHMAP_FOREACH_KEY ( f , key , top , i ) {
2012-05-16 05:36:42 +04:00
char * o ;
2013-05-16 13:09:03 +04:00
o = hashmap_get ( bottom , key ) ;
2012-05-16 05:36:42 +04:00
assert ( o ) ;
2013-12-23 07:53:23 +04:00
if ( ! onlyprefix | | startswith ( o , onlyprefix ) ) {
if ( path_equal ( o , f ) ) {
notify_override_unchanged ( f ) ;
} else {
k = found_override ( f , o ) ;
if ( k < 0 )
r = k ;
else
n_found + = k ;
}
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
}
2012-05-16 05:36:42 +04:00
2013-05-16 13:09:03 +04:00
h = hashmap_get ( drops , key ) ;
if ( h )
2013-05-16 04:42:22 +04:00
HASHMAP_FOREACH ( o , h , j )
2013-12-23 07:53:23 +04:00
if ( ! onlyprefix | | startswith ( o , onlyprefix ) )
n_found + = notify_override_extended ( f , o ) ;
2012-05-16 05:36:42 +04:00
}
finish :
if ( top )
hashmap_free_free ( top ) ;
if ( bottom )
hashmap_free_free ( bottom ) ;
2013-05-16 13:09:03 +04:00
if ( drops ) {
HASHMAP_FOREACH_KEY ( h , key , drops , i ) {
hashmap_free_free ( hashmap_remove ( drops , key ) ) ;
hashmap_remove ( drops , key ) ;
free ( key ) ;
}
hashmap_free ( drops ) ;
}
2012-05-16 05:36:42 +04:00
return r < 0 ? r : n_found ;
}
2013-12-23 07:53:23 +04:00
static int process_suffixes ( const char * onlyprefix ) {
const char * n ;
int n_found = 0 , r ;
NULSTR_FOREACH ( n , suffixes ) {
r = process_suffix ( n , onlyprefix ) ;
if ( r < 0 )
return r ;
else
n_found + = r ;
}
return n_found ;
}
static int process_suffix_chop ( const char * arg ) {
2012-05-16 05:36:42 +04:00
const char * p ;
2013-12-23 07:53:23 +04:00
assert ( arg ) ;
2012-05-16 05:36:42 +04:00
2013-12-23 07:53:23 +04:00
if ( ! path_is_absolute ( arg ) )
return process_suffix ( arg , NULL ) ;
2012-05-16 05:36:42 +04:00
/* Strip prefix from the suffix */
NULSTR_FOREACH ( p , prefixes ) {
2013-12-23 07:53:23 +04:00
const char * suffix = startswith ( arg , p ) ;
if ( suffix ) {
2012-05-16 05:36:42 +04:00
suffix + = strspn ( suffix , " / " ) ;
2013-12-23 07:53:23 +04:00
if ( * suffix )
return process_suffix ( suffix , NULL ) ;
else
return process_suffixes ( arg ) ;
2012-05-16 05:36:42 +04:00
}
}
2013-12-23 07:53:23 +04:00
log_error ( " Invalid suffix specification %s. " , arg ) ;
2012-05-16 05:36:42 +04:00
return - EINVAL ;
}
2013-11-06 21:28:39 +04:00
static int help ( void ) {
2012-05-16 05:36:42 +04:00
printf ( " %s [OPTIONS...] [SUFFIX...] \n \n "
" Find overridden configuration files. \n \n "
" -h --help Show this help \n "
" --version Show package version \n "
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
" --no-pager Do not pipe output into a pager \n "
2012-05-17 00:49:30 +04:00
" --diff[=1|0] Show a diff when overridden files differ \n "
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
" -t --type=LIST... Only display a selected set of override types \n " ,
2012-05-16 05:36:42 +04:00
program_invocation_short_name ) ;
2013-11-06 21:28:39 +04:00
return 0 ;
2012-05-16 05:36:42 +04:00
}
2012-05-21 04:01:52 +04:00
static int parse_flags ( const char * flag_str , int flags ) {
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
char * w , * state ;
size_t l ;
FOREACH_WORD ( w , l , flag_str , state ) {
2013-02-13 00:47:36 +04:00
if ( strneq ( " masked " , w , l ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
flags | = SHOW_MASKED ;
2013-02-13 00:47:36 +04:00
else if ( strneq ( " equivalent " , w , l ) )
2012-05-16 20:57:57 +04:00
flags | = SHOW_EQUIVALENT ;
2013-02-13 00:47:36 +04:00
else if ( strneq ( " redirected " , w , l ) )
2012-05-16 20:57:57 +04:00
flags | = SHOW_REDIRECTED ;
2013-02-13 00:47:36 +04:00
else if ( strneq ( " overridden " , w , l ) )
2012-05-17 00:49:30 +04:00
flags | = SHOW_OVERRIDDEN ;
2013-02-13 00:47:36 +04:00
else if ( strneq ( " unchanged " , w , l ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
flags | = SHOW_UNCHANGED ;
2013-05-16 13:09:03 +04:00
else if ( strneq ( " extended " , w , l ) )
flags | = SHOW_EXTENDED ;
2013-02-13 00:47:36 +04:00
else if ( strneq ( " default " , w , l ) )
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
flags | = SHOW_DEFAULTS ;
2012-05-21 04:01:52 +04:00
else
return - EINVAL ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
}
return flags ;
}
2012-05-21 04:01:52 +04:00
static int parse_argv ( int argc , char * argv [ ] ) {
2012-05-16 05:36:42 +04:00
enum {
ARG_NO_PAGER = 0x100 ,
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
ARG_DIFF ,
2012-05-16 05:36:42 +04:00
ARG_VERSION
} ;
static const struct option options [ ] = {
{ " help " , no_argument , NULL , ' h ' } ,
{ " version " , no_argument , NULL , ARG_VERSION } ,
{ " no-pager " , no_argument , NULL , ARG_NO_PAGER } ,
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
{ " diff " , optional_argument , NULL , ARG_DIFF } ,
{ " type " , required_argument , NULL , ' t ' } ,
2013-11-06 21:28:39 +04:00
{ }
2012-05-16 05:36:42 +04:00
} ;
int c ;
assert ( argc > = 1 ) ;
assert ( argv ) ;
2012-11-14 03:18:02 +04:00
while ( ( c = getopt_long ( argc , argv , " ht: " , options , NULL ) ) > = 0 ) {
2012-05-16 05:36:42 +04:00
switch ( c ) {
case ' h ' :
help ( ) ;
return 0 ;
case ARG_VERSION :
puts ( PACKAGE_STRING ) ;
puts ( SYSTEMD_FEATURES ) ;
return 0 ;
case ARG_NO_PAGER :
arg_no_pager = true ;
break ;
2012-05-21 04:01:52 +04:00
case ' t ' : {
int f ;
f = parse_flags ( optarg , arg_flags ) ;
if ( f < 0 ) {
log_error ( " Failed to parse flags field. " ) ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
return - EINVAL ;
2012-05-21 04:01:52 +04:00
}
arg_flags = f ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
break ;
2012-05-21 04:01:52 +04:00
}
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
case ARG_DIFF :
2012-05-21 04:01:52 +04:00
if ( ! optarg )
arg_diff = 1 ;
else {
int b ;
b = parse_boolean ( optarg ) ;
if ( b < 0 ) {
log_error ( " Failed to parse diff boolean. " ) ;
return - EINVAL ;
} else if ( b )
arg_diff = 1 ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
else
2012-05-21 04:01:52 +04:00
arg_diff = 0 ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
}
break ;
2013-11-06 21:28:39 +04:00
case ' ? ' :
2012-05-16 05:36:42 +04:00
return - EINVAL ;
2013-11-06 21:28:39 +04:00
default :
assert_not_reached ( " Unhandled option " ) ;
2012-05-16 05:36:42 +04:00
}
}
return 1 ;
}
int main ( int argc , char * argv [ ] ) {
int r = 0 , k ;
int n_found = 0 ;
log_parse_environment ( ) ;
log_open ( ) ;
2012-05-21 04:01:52 +04:00
r = parse_argv ( argc , argv ) ;
2012-05-16 05:36:42 +04:00
if ( r < = 0 )
goto finish ;
2012-05-21 04:01:52 +04:00
if ( arg_flags = = 0 )
arg_flags = SHOW_DEFAULTS ;
if ( arg_diff < 0 )
2012-05-17 00:49:30 +04:00
arg_diff = ! ! ( arg_flags & SHOW_OVERRIDDEN ) ;
2012-05-21 04:01:52 +04:00
else if ( arg_diff )
2012-05-17 00:49:30 +04:00
arg_flags | = SHOW_OVERRIDDEN ;
delta: Support filtering what type of deltas to show
Not everyone is interested in every kind of deltas (and some might
even be interested knowing which files do not have overrides), so this
here is an implementation of a --type=LIST... option for
systemd-delta, that makes it possible to filter what subset of deltas
we want.
The available modifiers are masked, equivalent, redirected, overriden,
and unchanged - they should be self explanatory, and the man page
explains them in a little more detail anyway.
As a side effect, in case of overriden files, the diff output was made
optional.
By default, everything is shown (with a diff, if appropriate) except
for completely unchanged files.
Signed-off-by: Gergely Nagy <algernon@balabit.hu>
2012-05-16 20:11:27 +04:00
2013-12-23 04:45:02 +04:00
pager_open_if_enabled ( ) ;
2012-05-16 05:36:42 +04:00
if ( optind < argc ) {
int i ;
for ( i = optind ; i < argc ; i + + ) {
2013-12-23 04:45:02 +04:00
path_kill_slashes ( argv [ i ] ) ;
k = process_suffix_chop ( argv [ i ] ) ;
2012-05-16 05:36:42 +04:00
if ( k < 0 )
r = k ;
else
n_found + = k ;
}
} else {
2013-12-23 07:53:23 +04:00
k = process_suffixes ( NULL ) ;
if ( k < 0 )
r = k ;
else
n_found + = k ;
2012-05-16 05:36:42 +04:00
}
if ( r > = 0 )
2013-05-16 04:42:22 +04:00
printf ( " %s%i overridden configuration files found. \n " ,
n_found ? " \n " : " " , n_found ) ;
2012-05-16 05:36:42 +04:00
finish :
pager_close ( ) ;
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS ;
}