2010-02-03 15:03:47 +03:00
/ * * *
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd 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 .
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
General Public License for more details .
You should have received a copy of the GNU General Public License
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * * /
2010-02-03 00:22:51 +03:00
using DBus ;
using GLib ;
static string type = null ;
static bool all = false ;
2010-02-03 14:39:12 +03:00
static bool replace = false ;
2010-04-07 18:23:08 +04:00
static bool session = false ;
2010-02-03 00:22:51 +03:00
public static int job_info_compare ( void * key1 , void * key2 ) {
Manager . JobInfo * j1 = ( Manager . JobInfo * ) key1 ;
Manager . JobInfo * j2 = ( Manager . JobInfo * ) key2 ;
2010-02-03 14:39:12 +03:00
return j1 - > id < j2 - > id ? - 1 : ( j1 - > id > j2 - > id ? 1 : 0 ) ;
2010-02-03 00:22:51 +03:00
}
public static int unit_info_compare ( void * key1 , void * key2 ) {
Manager . UnitInfo * u1 = ( Manager . UnitInfo * ) key1 ;
Manager . UnitInfo * u2 = ( Manager . UnitInfo * ) key2 ;
int r = Posix . strcmp ( Posix . strrchr ( u1 - > id , '.' ) , Posix . strrchr ( u2 - > id , '.' ) ) ;
if ( r ! = 0 )
return r ;
return Posix . strcmp ( u1 - > id , u2 - > id ) ;
}
2010-02-05 02:38:41 +03:00
public void on_unit_new ( string id , ObjectPath path ) {
stdout . printf ( " Unit %s added. \n " , id ) ;
}
public void on_job_new ( uint32 id , ObjectPath path ) {
stdout . printf ( " Job %u added. \n " , id ) ;
}
public void on_unit_removed ( string id , ObjectPath path ) {
stdout . printf ( " Unit %s removed. \n " , id ) ;
}
public void on_job_removed ( uint32 id , ObjectPath path ) {
stdout . printf ( " Job %u removed. \n " , id ) ;
}
2010-02-03 00:22:51 +03:00
static const OptionEntry entries [ ] = {
2010-04-07 18:23:08 +04:00
{ " type " , 't' , 0 , OptionArg . STRING , out type , " List only particular type of units " , " TYPE " } ,
{ " all " , 'a' , 0 , OptionArg . NONE , out all , " Show all units, including dead ones " , null } ,
{ " replace " , 0 , 0 , OptionArg . NONE , out replace , " When installing a new job, replace existing conflicting ones " , null } ,
{ " session " , 0 , 0 , OptionArg . NONE , out session , " Connect to session bus " , null } ,
{ " system " , 0 , OptionFlags . REVERSE , OptionArg . NONE , out session , " Connect to system bus " , null } ,
2010-02-03 00:22:51 +03:00
{ null }
} ;
int main ( string [ ] args ) {
2010-04-24 05:03:58 +04:00
OptionContext context = new OptionContext ( " [COMMAND [ARGUMENT...]] " ) ;
2010-02-03 00:22:51 +03:00
context . add_main_entries ( entries , null ) ;
2010-02-05 02:38:41 +03:00
context . set_description (
" Commands: \n " +
2010-05-10 01:53:52 +04:00
" list-units List units \n " +
" list-jobs List jobs \n " +
" clear-jobs Cancel all jobs \n " +
" load [NAME...] Load one or more units \n " +
" cancel [JOB...] Cancel one or more jobs \n " +
" start [NAME...] Start on or more units \n " +
" stop [NAME...] Stop on or more units \n " +
" enter [NAME] Start one unit and stop all others \n " +
" restart [NAME...] Restart on or more units \n " +
" reload [NAME...] Reload on or more units \n " +
" monitor Monitor unit/job changes \n " +
" dump Dump server status \n " +
" snapshot [NAME] Create a snapshot \n " +
" daemon-reload Reload daemon configuration \n " +
" daemon-reexecute Reexecute daemon \n " +
" show-environment Dump environment \n " +
" set-environment [NAME=VALUE...] Set one or more environment variables \n " +
" unset-environment [NAME...] Unset one or more environment variables \n " ) ;
2010-02-03 00:22:51 +03:00
try {
context . parse ( ref args ) ;
} catch ( GLib . OptionError e ) {
message ( " Failed to parse command line: %s " . printf ( e . message ) ) ;
}
try {
2010-04-07 18:23:08 +04:00
Connection bus = Bus . get ( session ? BusType . SESSION : BusType . SYSTEM ) ;
2010-02-03 00:22:51 +03:00
Manager manager = bus . get_object (
" org.freedesktop.systemd1 " ,
" /org/freedesktop/systemd1 " ,
2010-04-21 08:01:13 +04:00
" org.freedesktop.systemd1.Manager " ) as Manager ;
2010-02-03 00:22:51 +03:00
if ( args [ 1 ] = = " list-units " | | args . length < = 1 ) {
2010-02-03 14:39:12 +03:00
var list = manager . list_units ( ) ;
2010-02-03 00:22:51 +03:00
uint n = 0 ;
Posix . qsort ( list , list . length , sizeof ( Manager . UnitInfo ) , unit_info_compare ) ;
2010-04-13 22:59:01 +04:00
stdout . printf ( " %-45s %-6s %-12s %-12s %-17s \n " , " UNIT " , " LOAD " , " ACTIVE " , " SUB " , " JOB " ) ;
2010-02-03 00:22:51 +03:00
foreach ( var i in list ) {
if ( type ! = null & & ! i . id . has_suffix ( " .%s " . printf ( type ) ) )
continue ;
if ( ! all & & i . active_state = = " inactive " )
continue ;
2010-04-13 22:59:01 +04:00
stdout . printf ( " %-45s %-6s %-12s %-12s " , i . id , i . load_state , i . active_state , i . sub_state ) ;
2010-02-03 00:22:51 +03:00
if ( i . job_id ! = 0 )
2010-04-23 22:25:55 +04:00
stdout . printf ( " -> %-15s " , i . job_type ) ;
2010-02-03 00:22:51 +03:00
stdout . puts ( " \n " ) ;
n + + ;
}
if ( all )
stdout . printf ( " \n %u units listed. \n " , n ) ;
else
stdout . printf ( " \n %u live units listed. Pass --all to see dead units, too. \n " , n ) ;
} else if ( args [ 1 ] = = " list-jobs " ) {
2010-02-03 14:39:12 +03:00
var list = manager . list_jobs ( ) ;
2010-02-03 00:22:51 +03:00
Posix . qsort ( list , list . length , sizeof ( Manager . JobInfo ) , job_info_compare ) ;
2010-02-03 14:39:12 +03:00
stdout . printf ( " %4s %-45s %-17s %-7s \n " , " JOB " , " UNIT " , " TYPE " , " STATE " ) ;
2010-02-03 01:32:03 +03:00
2010-02-03 00:22:51 +03:00
foreach ( var i in list )
2010-02-03 14:39:12 +03:00
stdout . printf ( " %4u %-45s → %-15s %-7s \n " , i . id , i . name , i . type , i . state ) ;
2010-02-03 00:22:51 +03:00
2010-02-03 01:32:03 +03:00
stdout . printf ( " \n %u jobs listed. \n " , list . length ) ;
} else if ( args [ 1 ] = = " clear-jobs " ) {
2010-02-03 14:39:12 +03:00
manager . clear_jobs ( ) ;
2010-02-03 01:32:03 +03:00
2010-02-03 00:22:51 +03:00
} else if ( args [ 1 ] = = " load " ) {
if ( args . length < 3 ) {
stderr . printf ( " Missing argument. \n " ) ;
return 1 ;
}
2010-02-03 16:26:55 +03:00
for ( int i = 2 ; i < args . length ; i + + )
2010-02-03 14:39:12 +03:00
manager . load_unit ( args [ i ] ) ;
} else if ( args [ 1 ] = = " cancel " ) {
if ( args . length < 3 ) {
stderr . printf ( " Missing argument. \n " ) ;
return 1 ;
}
2010-02-03 16:26:55 +03:00
for ( int i = 2 ; i < args . length ; i + + ) {
2010-02-03 14:39:12 +03:00
uint32 id ;
if ( args [ i ] . scanf ( " %u " , out id ) ! = 1 ) {
stderr . printf ( " Failed to parse argument. \n " ) ;
return 1 ;
}
ObjectPath p = manager . get_job ( id ) ;
Job j = bus . get_object (
" org.freedesktop.systemd1 " ,
p ,
" org.freedesktop.systemd1.Job " ) as Job ;
j . cancel ( ) ;
}
} else if ( args [ 1 ] = = " start " | |
args [ 1 ] = = " stop " | |
args [ 1 ] = = " reload " | |
args [ 1 ] = = " restart " ) {
if ( args . length < 3 ) {
stderr . printf ( " Missing argument. \n " ) ;
return 1 ;
}
2010-02-03 19:24:30 +03:00
for ( int i = 2 ; i < args . length ; i + + ) {
2010-02-03 14:39:12 +03:00
2010-04-24 02:12:52 +04:00
ObjectPath p = manager . load_unit ( args [ i ] ) ;
2010-02-03 14:39:12 +03:00
Unit u = bus . get_object (
" org.freedesktop.systemd1 " ,
p ,
" org.freedesktop.systemd1.Unit " ) as Unit ;
string mode = replace ? " replace " : " fail " ;
if ( args [ 1 ] = = " start " )
u . start ( mode ) ;
else if ( args [ 1 ] = = " stop " )
u . stop ( mode ) ;
else if ( args [ 1 ] = = " restart " )
u . restart ( mode ) ;
else if ( args [ 1 ] = = " reload " )
u . reload ( mode ) ;
}
2010-04-22 04:42:59 +04:00
} else if ( args [ 1 ] = = " isolate " ) {
if ( args . length ! = 3 ) {
stderr . printf ( " Missing argument. \n " ) ;
return 1 ;
}
2010-04-24 03:54:12 +04:00
ObjectPath p = manager . load_unit ( args [ 2 ] ) ;
2010-04-22 04:42:59 +04:00
Unit u = bus . get_object (
" org.freedesktop.systemd1 " ,
p ,
" org.freedesktop.systemd1.Unit " ) as Unit ;
u . start ( " isolate " ) ;
2010-02-05 02:38:41 +03:00
} else if ( args [ 1 ] = = " monitor " ) {
manager . subscribe ( ) ;
manager . unit_new + = on_unit_new ;
manager . unit_removed + = on_unit_removed ;
manager . job_new + = on_job_new ;
manager . job_removed + = on_job_removed ;
MainLoop l = new MainLoop ( ) ;
l . run ( ) ;
2010-04-10 19:37:56 +04:00
} else if ( args [ 1 ] = = " dump " )
stdout . puts ( manager . dump ( ) ) ;
2010-05-10 01:53:52 +04:00
2010-04-18 05:07:42 +04:00
else if ( args [ 1 ] = = " snapshot " ) {
ObjectPath p = manager . create_snapshot ( args . length > 2 ? args [ 2 ] : " " ) ;
Unit u = bus . get_object (
" org.freedesktop.systemd1 " ,
p ,
" org.freedesktop.systemd1.Unit " ) as Unit ;
stdout . printf ( " %s \n " , u . id ) ;
2010-05-10 01:53:52 +04:00
2010-04-21 05:27:44 +04:00
} else if ( args [ 1 ] = = " daemon-reload " )
manager . reload ( ) ;
2010-05-10 01:53:52 +04:00
2010-04-21 05:27:44 +04:00
else if ( args [ 1 ] = = " daemon-reexecute " | | args [ 1 ] = = " daemon-reexec " )
manager . reexecute ( ) ;
2010-05-10 01:53:52 +04:00
2010-04-21 05:27:44 +04:00
else if ( args [ 1 ] = = " daemon-exit " )
manager . exit ( ) ;
2010-05-10 01:53:52 +04:00
else if ( args [ 1 ] = = " show-environment " ) {
foreach ( var x in manager . environment )
stderr . printf ( " %s \n " , x ) ;
} else if ( args [ 1 ] = = " set-environment " )
manager . set_environment ( args [ 2 : args . length ] ) ;
else if ( args [ 1 ] = = " unset-environment " )
manager . unset_environment ( args [ 2 : args . length ] ) ;
2010-04-21 05:27:44 +04:00
else {
2010-02-03 00:22:51 +03:00
stderr . printf ( " Unknown command %s. \n " , args [ 1 ] ) ;
return 1 ;
}
} catch ( DBus . Error e ) {
stderr . printf ( " %s \n " . printf ( e . message ) ) ;
}
return 0 ;
}