--- ConsoleKit-0.4.1/src/ck-manager.c-orig Fri Jun 15 10:43:58 2012 +++ ConsoleKit-0.4.1/src/ck-manager.c Fri Jun 15 10:44:03 2012 @@ -41,6 +41,7 @@ #if (defined(sun) && defined(__SVR4)) #include +#include #endif #if defined HAVE_POLKIT @@ -1282,10 +1283,36 @@ #if (defined(sun) && defined(__SVR4)) static gint +is_decimal_string(gchar *token, gint *indexp) +{ + gint i; + + for (i = 0; token[i] != 0; i++) + if (!isdigit(token[i])) + return (0); + + if (i > 0) { + if (indexp) + *indexp = strtol(token, 0, 10); + return (1); + } + + /* If the string is empty, return failure */ + return (0); +} + +/* + * The output of bootadm should be parsed intelligently; not based on + * the order of lines, but based on the line semantics. We look for + * the keyword "default" when looking for the default entry. Lines + * that start with a number specify boot entries that should be + * captured for display in the dialog's boot entry list. + */ +static gint parse_output (const gchar *output, GPtrArray **systems) { gchar **lines; - gint default_id = -1; + gint id, default_id = -1; if (output == NULL) return default_id; @@ -1292,45 +1319,40 @@ lines = g_strsplit (output, "\n", 0); for (int i = 0; lines[i] != NULL; i++) { - gchar *index; + gchar **tokens; - if (i == 0 || i == 2) { - /* We do not care 1st & 2nd line. */ - continue; - } else if (i == 1) { - /* default boot menu entry */ - index = strchr (lines[i], ' '); - if (index && (index + 1)) { - default_id = atol (index + 1); - } else { - continue; - } - } else if (lines[i][0] != NULL && systems) { - /* boot menu entries */ - GValue elem = {0}; + /* Split lines into 2 tokens maximum */ + tokens = g_strsplit_set(lines[i], " \t", 2); + if (tokens == 0) { + continue; + } else if (tokens[0] == 0) { + g_strfreev(tokens); + continue; + } - index = strchr (lines[i], ' '); - if (index && (index + 1)) { - gint id; + if (tokens[1] != 0 && strcmp(tokens[0], "default") == 0) { + errno = 0; + default_id = strtol (tokens[1], 0, 10); + if (errno != 0) + default_id = 0; + } else if (is_decimal_string(tokens[0], &id) && systems) { - *index = '\0'; - id = atoi (lines[i]); - g_value_init (&elem, OS_STRUCT_TYPE); - g_value_take_boxed (&elem, - dbus_g_type_specialized_construct (OS_STRUCT_TYPE)); - dbus_g_type_struct_set (&elem, + /* boot menu entries */ + GValue elem = {0}; + + g_value_init (&elem, OS_STRUCT_TYPE); + g_value_take_boxed (&elem, + dbus_g_type_specialized_construct (OS_STRUCT_TYPE)); + dbus_g_type_struct_set (&elem, 0, id, 1, "", 2, "", - 3, (index + 1), + 3, (tokens[1] && tokens[1][0]) ? tokens[1] : "", 4, (default_id == id), G_MAXUINT); - g_ptr_array_add (*systems, - g_value_get_boxed (&elem)); - } else { - continue; - } + g_ptr_array_add (*systems, g_value_get_boxed (&elem)); } + g_strfreev(tokens); } g_strfreev (lines); return default_id;