]> git.ozlabs.org Git - petitboot/blobdiff - discover/device-handler.c
ui/ncurses: Keep track of the default boot option
[petitboot] / discover / device-handler.c
index cf379e78ca7f7ecc1f52adbca0fedc2e22903fa8..e75f41232db072e2db2a1aae4e6346b3574bdd99 100644 (file)
@@ -81,6 +81,7 @@ struct device_handler {
        struct autoboot_option  *temp_autoboot;
 
        struct discover_boot_option *default_boot_option;
+       struct discover_boot_option *last_boot_option;
        int                     default_boot_option_priority;
 
        struct list             unresolved_boot_options;
@@ -534,6 +535,7 @@ static void _device_handler_vstatus(struct device_handler *handler,
        status.type = type;
        status.message = talloc_vasprintf(handler, fmt, ap);
        status.backlog = false;
+       status.boot_active = false;
 
        device_handler_status(handler, &status);
 
@@ -755,6 +757,8 @@ static int default_timeout(void *arg)
 
        opt = handler->default_boot_option;
 
+       handler->last_boot_option = opt;
+
        if (handler->sec_to_boot) {
                countdown_status(handler, opt, handler->sec_to_boot);
                handler->sec_to_boot--;
@@ -926,6 +930,10 @@ static void set_default(struct device_handler *handler,
                return;
        }
 
+       if (handler->default_boot_option)
+               handler->default_boot_option->option->is_autoboot_default = false;
+       opt->option->is_autoboot_default = true;
+
        handler->sec_to_boot = config_get()->autoboot_timeout_sec;
        handler->default_boot_option = opt;
        handler->default_boot_option_priority = new_prio;
@@ -1278,6 +1286,7 @@ static int device_handler_requery_timeout_fn(void *data)
        struct requery_data *rqd = data;
        struct device_handler *handler;
        struct discover_device *device;
+       bool autoboot;
 
        handler = rqd->handler;
        device = rqd->device;
@@ -1300,9 +1309,14 @@ static int device_handler_requery_timeout_fn(void *data)
                talloc_free(opt);
        }
 
+       /* Track whether autoboot was enabled, if we cancel a default option
+        * it will be switched off.
+        */
+       autoboot = handler->autoboot_enabled;
+
        list_for_each_entry_safe(&device->boot_options, opt, tmp, list) {
                if (opt == handler->default_boot_option) {
-                       pb_log("Default option %s cancelled since device is being requeried",
+                       pb_log("Default option %s cancelled since device is being requeried\n",
                                        opt->option->name);
                        device_handler_cancel_default(handler);
                }
@@ -1310,6 +1324,8 @@ static int device_handler_requery_timeout_fn(void *data)
                talloc_free(opt);
        }
 
+       handler->autoboot_enabled = autoboot;
+
        discover_server_notify_device_remove(handler->server, device->device);
        device->notified = false;
 
@@ -1444,13 +1460,22 @@ static struct discover_boot_option *find_boot_option_by_id(
 }
 
 void device_handler_boot(struct device_handler *handler,
-               struct boot_command *cmd)
+               bool change_default, struct boot_command *cmd)
 {
        struct discover_boot_option *opt = NULL;
 
        if (cmd->option_id && strlen(cmd->option_id))
                opt = find_boot_option_by_id(handler, cmd->option_id);
 
+       /* Don't allow a normal client to change the default */
+       if (!change_default && handler->last_boot_option &&
+                       opt != handler->last_boot_option) {
+               pb_log("Non-root user tried to change boot option\n");
+               device_handler_status_err(handler,
+                               "Must be root to change default boot option\n");
+               return;
+       }
+
        if (handler->pending_boot)
                boot_cancel(handler->pending_boot);
 
@@ -1492,8 +1517,11 @@ void device_handler_update_config(struct device_handler *handler,
        int rc;
 
        rc = config_set(config);
-       if (rc)
+       if (rc) {
+               device_handler_status_err(handler,
+                               "Failed to update configuration!");
                return;
+       }
 
        discover_server_notify_config(handler->server, config);
        device_handler_update_lang(config->lang);