@@ -797,7 +797,7 @@ static void svc_start_real(void)
797797 rc_plugin_run (RC_HOOK_SERVICE_START_OUT , applet );
798798}
799799
800- static void
800+ static int
801801svc_start (void )
802802{
803803 if (dry_run )
@@ -810,6 +810,8 @@ svc_start(void)
810810 printf (" %s\n" , applet );
811811 else
812812 svc_start_real ();
813+
814+ return 0 ;
813815}
814816
815817static int
@@ -1000,7 +1002,7 @@ svc_stop(void)
10001002 return 0 ;
10011003}
10021004
1003- static void
1005+ static int
10041006svc_restart (void )
10051007{
10061008 if (!(rc_service_state (applet ) & RC_SERVICE_STOPPED )) {
@@ -1015,6 +1017,8 @@ svc_restart(void)
10151017 start_services (restart_services );
10161018 rc_stringlist_free (restart_services );
10171019 restart_services = NULL ;
1020+
1021+ return 0 ;
10181022}
10191023
10201024static bool
@@ -1047,11 +1051,130 @@ service_plugable(void)
10471051 return allow ;
10481052}
10491053
1050- int main (int argc , char * * argv )
1054+ static int
1055+ simple_command (void )
1056+ {
1057+ char * save = prefix ;
1058+ int retval ;
1059+
1060+ eprefix (NULL );
1061+ prefix = NULL ;
1062+
1063+ retval = svc_exec (optarg );
1064+
1065+ eprefix (save );
1066+ prefix = save ;
1067+
1068+ return retval ;
1069+ }
1070+
1071+ static int
1072+ resolve_deptype (void )
10511073{
1052- bool doneone = false;
1053- int retval , opt , depoptions = RC_DEP_TRACE ;
1074+ int depoptions = RC_DEP_TRACE ;
10541075 RC_STRING * svc ;
1076+
1077+ errno = 0 ;
1078+ if (rc_conf_yesno ("rc_depend_strict" ) || errno == ENOENT )
1079+ depoptions |= RC_DEP_STRICT ;
1080+
1081+ if (!deptree && ((deptree = _rc_deptree_load (0 , NULL )) == NULL ))
1082+ eerrorx ("failed to load deptree" );
1083+
1084+ tmplist = rc_stringlist_new ();
1085+ rc_stringlist_add (tmplist , optarg );
1086+ services = rc_deptree_depends (deptree , tmplist , applet_list , runlevel , depoptions );
1087+ rc_stringlist_free (tmplist );
1088+
1089+ tmplist = NULL ;
1090+ TAILQ_FOREACH (svc , services , entries )
1091+ printf ("%s " , svc -> value );
1092+ printf ("\n" );
1093+
1094+ rc_stringlist_free (services );
1095+ services = NULL ;
1096+
1097+ return 0 ;
1098+ }
1099+
1100+ static int
1101+ cmd_condrestart (void )
1102+ {
1103+ if (rc_service_state (applet ) & RC_SERVICE_STARTED )
1104+ svc_restart ();
1105+ return 0 ;
1106+ }
1107+
1108+ static int
1109+ cmd_stop (void )
1110+ {
1111+ RC_STRING * svc ;
1112+
1113+ if (strcmp (optarg , "pause" ) == 0 ) {
1114+ ewarn ("WARNING: 'pause' is deprecated; please use '--nodeps stop'" );
1115+ deps = false;
1116+ }
1117+
1118+ if (deps && in_background )
1119+ get_started_services ();
1120+
1121+ if (svc_stop () == 1 )
1122+ return 0 ; /* Service has been stopped already */
1123+
1124+ if (deps ) {
1125+ if (!in_background && !rc_runlevel_stopping () && rc_service_state (applet ) & RC_SERVICE_STOPPED )
1126+ unhotplug ();
1127+
1128+ if (in_background && rc_service_state (applet ) & RC_SERVICE_INACTIVE ) {
1129+ TAILQ_FOREACH (svc , restart_services , entries )
1130+ if (rc_service_state (svc -> value ) & RC_SERVICE_STOPPED )
1131+ rc_service_schedule_start (applet , svc -> value );
1132+ }
1133+ }
1134+
1135+ return 0 ;
1136+ }
1137+
1138+ static int
1139+ cmd_zap (void )
1140+ {
1141+ einfo ("Manually resetting %s to stopped state" , applet );
1142+ if (!rc_service_mark (applet , RC_SERVICE_STOPPED ))
1143+ eerrorx ("rc_service_mark: %s" , strerror (errno ));
1144+ unhotplug ();
1145+
1146+ return 0 ;
1147+ }
1148+
1149+ struct {
1150+ const char * name ;
1151+ int (* handler )(void );
1152+ bool reset_restart_list ;
1153+ } commands [] = {
1154+ { "describe" , simple_command , false },
1155+ { "help" , simple_command , false },
1156+ { "depend" , simple_command , false },
1157+ { "status" , simple_command , false },
1158+ { "ineed" , resolve_deptype , false },
1159+ { "iuse" , resolve_deptype , false },
1160+ { "iwant" , resolve_deptype , false },
1161+ { "needsme" , resolve_deptype , false },
1162+ { "usesme" , resolve_deptype , false },
1163+ { "wantsme" , resolve_deptype , false },
1164+ { "iafter" , resolve_deptype , false },
1165+ { "ibefore" , resolve_deptype , false },
1166+ { "iprovide" , resolve_deptype , false },
1167+ { "start" , svc_start , true },
1168+ { "stop" , cmd_stop , true },
1169+ { "restart" , svc_restart , true },
1170+ { "condrestart" , cmd_condrestart , true },
1171+ { "conditionalrestart" , cmd_condrestart , true },
1172+ { "zap" , cmd_zap , true },
1173+ };
1174+
1175+ int main (int argc , char * * argv )
1176+ {
1177+ int retval , opt ;
10551178 const char * workingdir = "/" ;
10561179 char * pidstr = NULL ;
10571180 size_t l = 0 , ll ;
@@ -1066,8 +1189,7 @@ int main(int argc, char **argv)
10661189 applet = basename_c (argv [0 ]);
10671190
10681191 if (stat (argv [1 ], & stbuf ) != 0 ) {
1069- fprintf (stderr , "openrc-run `%s': %s\n" ,
1070- argv [1 ], strerror (errno ));
1192+ fprintf (stderr , "openrc-run `%s': %s\n" , argv [1 ], strerror (errno ));
10711193 exit (EXIT_FAILURE );
10721194 }
10731195
@@ -1151,6 +1273,7 @@ int main(int argc, char **argv)
11511273
11521274 /* eprefix is kinda klunky, but it works for our purposes */
11531275 if (rc_conf_yesno ("rc_parallel" )) {
1276+ RC_STRING * svc ;
11541277 /* Get the longest service name */
11551278 services = rc_services_in_runlevel (NULL );
11561279 TAILQ_FOREACH (svc , services , entries ) {
@@ -1212,9 +1335,15 @@ int main(int argc, char **argv)
12121335 applet_list = rc_stringlist_new ();
12131336 rc_stringlist_add (applet_list , applet );
12141337
1338+ if (optind >= argc )
1339+ usage (EXIT_FAILURE );
1340+
12151341 /* Now run each option */
12161342 retval = EXIT_SUCCESS ;
1343+
1344+ next_cmd :
12171345 while (optind < argc ) {
1346+ int cmdval ;
12181347 optarg = argv [optind ++ ];
12191348
12201349 /* Abort on a sighup here */
@@ -1228,101 +1357,27 @@ int main(int argc, char **argv)
12281357 unsetenv ("RC_CMD" );
12291358 setenv ("RC_CMD" , optarg , 1 );
12301359
1231- doneone = true;
1360+ for (size_t i = 0 ; i < ARRAY_SIZE (commands ); i ++ ) {
1361+ if (strcmp (optarg , commands [i ].name ) != 0 )
1362+ continue ;
12321363
1233- if (strcmp (optarg , "describe" ) == 0 ||
1234- strcmp (optarg , "help" ) == 0 ||
1235- strcmp (optarg , "depend" ) == 0 )
1236- {
1237- char * save = prefix ;
1238- eprefix (NULL );
1239- prefix = NULL ;
1240- svc_exec (optarg );
1241- eprefix (save );
1242- prefix = save ;
1243- } else if (strcmp (optarg , "ineed" ) == 0 ||
1244- strcmp (optarg , "iuse" ) == 0 ||
1245- strcmp (optarg , "iwant" ) == 0 ||
1246- strcmp (optarg , "needsme" ) == 0 ||
1247- strcmp (optarg , "usesme" ) == 0 ||
1248- strcmp (optarg , "wantsme" ) == 0 ||
1249- strcmp (optarg , "iafter" ) == 0 ||
1250- strcmp (optarg , "ibefore" ) == 0 ||
1251- strcmp (optarg , "iprovide" ) == 0 )
1252- {
1253- errno = 0 ;
1254- if (rc_conf_yesno ("rc_depend_strict" ) ||
1255- errno == ENOENT )
1256- depoptions |= RC_DEP_STRICT ;
1257-
1258- if (!deptree &&
1259- ((deptree = _rc_deptree_load (0 , NULL )) == NULL ))
1260- eerrorx ("failed to load deptree" );
1261-
1262- tmplist = rc_stringlist_new ();
1263- rc_stringlist_add (tmplist , optarg );
1264- services = rc_deptree_depends (deptree , tmplist ,
1265- applet_list ,
1266- runlevel , depoptions );
1267- rc_stringlist_free (tmplist );
1268- tmplist = NULL ;
1269- TAILQ_FOREACH (svc , services , entries )
1270- printf ("%s " , svc -> value );
1271- printf ("\n" );
1272- rc_stringlist_free (services );
1273- services = NULL ;
1274- } else if (strcmp (optarg , "status" ) == 0 ) {
1275- eprefix (NULL );
1276- prefix = NULL ;
1277- retval = svc_exec ("status" );
1278- } else {
1279- if (strcmp (optarg , "conditionalrestart" ) == 0 ||
1280- strcmp (optarg , "condrestart" ) == 0 )
1281- {
1282- if (rc_service_state (applet ) & RC_SERVICE_STARTED )
1283- svc_restart ();
1284- } else if (strcmp (optarg , "restart" ) == 0 ) {
1285- svc_restart ();
1286- } else if (strcmp (optarg , "start" ) == 0 ) {
1287- svc_start ();
1288- } else if (strcmp (optarg , "stop" ) == 0 || strcmp (optarg , "pause" ) == 0 ) {
1289- if (strcmp (optarg , "pause" ) == 0 ) {
1290- ewarn ("WARNING: 'pause' is deprecated; please use '--nodeps stop'" );
1291- deps = false;
1292- }
1293- if (deps && in_background )
1294- get_started_services ();
1295- if (svc_stop () == 1 )
1296- continue ; /* Service has been stopped already */
1297- if (deps ) {
1298- if (!in_background && !rc_runlevel_stopping () && rc_service_state (applet ) & RC_SERVICE_STOPPED )
1299- unhotplug ();
1300-
1301- if (in_background && rc_service_state (applet ) & RC_SERVICE_INACTIVE ) {
1302- TAILQ_FOREACH (svc , restart_services , entries )
1303- if (rc_service_state (svc -> value ) & RC_SERVICE_STOPPED )
1304- rc_service_schedule_start (applet , svc -> value );
1305- }
1306- }
1307- } else if (strcmp (optarg , "zap" ) == 0 ) {
1308- einfo ("Manually resetting %s to stopped state" ,
1309- applet );
1310- if (!rc_service_mark (applet ,
1311- RC_SERVICE_STOPPED ))
1312- eerrorx ("rc_service_mark: %s" ,
1313- strerror (errno ));
1314- unhotplug ();
1315- } else
1316- retval = svc_exec (optarg );
1364+ if ((cmdval = commands [i ].handler ()) != 0 )
1365+ retval = cmdval ;
1366+
1367+ if (commands [i ].reset_restart_list ) {
1368+ /* We should ensure this list is empty after
1369+ * an action is done */
1370+ rc_stringlist_free (restart_services );
1371+ restart_services = NULL ;
1372+ }
13171373
1318- /* We should ensure this list is empty after
1319- * an action is done */
1320- rc_stringlist_free (restart_services );
1321- restart_services = NULL ;
1374+ goto next_cmd ;
13221375 }
13231376
1324- if (!doneone )
1325- usage (EXIT_FAILURE );
1377+ if ((cmdval = svc_exec (optarg )) != 0 )
1378+ retval = cmdval ;
1379+ rc_stringlist_free (restart_services );
1380+ restart_services = NULL ;
13261381 }
13271382
13281383 return retval ;
0 commit comments