Permalink
Browse files

Check grub.cfg for correct configuration, and display distribution sp…

…ecific error messages
  • Loading branch information...
1 parent bcdfc15 commit 5868ae3a673bd2ceb84f3f94507a259993b8b246 David Mohr committed May 11, 2010
Showing with 135 additions and 3 deletions.
  1. +2 −0 .gitignore
  2. +1 −0 src/gchd-error.h
  3. +1 −0 src/gchd-internal.h
  4. +20 −3 src/gchd-menu.c
  5. +48 −0 src/gchd-messages.h
  6. +43 −0 src/gchd.c
  7. +1 −0 src/gchd.h
  8. +14 −0 src/grub-choose-default-button-box.c
  9. +5 −0 wscript
View
@@ -4,3 +4,5 @@ _build*_
waf-*/
.lock*wscript
tags
+*-stamp
+*.tar.bz2*
View
@@ -15,6 +15,7 @@ typedef enum
GCHD_ERROR_FAILED_READING_ENV,
GCHD_ERROR_FAILED_WRITING_ENV,
GCHD_ERROR_NO_VOLUMES,
+ GCHD_ERROR_NOT_USING_DEFAULT,
} GchdError;
#define GCHD_ERROR gchd_error_quark ()
View
@@ -28,6 +28,7 @@ typedef struct {
gchar * loc;
GList * entries; /* of type char* */
gint n_entries;
+ gboolean default_saved;
} GchdMenu;
struct _Gchd {
View
@@ -17,11 +17,17 @@ parse_entries (GchdMenu *menu, gchar * contents) {
gchar * entry;
gchar quote;
static const gchar *mi = "menuentry";
+ static const gchar *sd = "set default=\"${saved_entry}\"";
- for (cp = NULL, c = contents; *c != '\0'; cp = c, c++) {
+ for (cp = NULL, c = contents; *c != '\0'; cp = c, c++)
+ {
/* look for the letter 'm' at the beginning of a line */
- if (*c == 'm' && (cp == NULL || *cp == '\n')) {
- if (strncmp (c, mi, strlen(mi)) == 0) {
+ if (*c == 'm' && (cp == NULL || *cp == '\n'))
+ {
+ if (strncmp (c, mi, strlen(mi)) == 0)
+ {
+ /* matched "^menuentry */
+
c += strlen (mi);
/* we expect at least one white space */
@@ -66,6 +72,17 @@ parse_entries (GchdMenu *menu, gchar * contents) {
menu->n_entries++;
}
}
+ else if (*c == 's' && (cp == NULL || *cp == '\n'))
+ {
+ if (strncmp (c, sd, strlen(sd)) == 0)
+ {
+ /* Matched sd to the beginning of the line.
+ * That's good enough, we assume it's only spaces
+ * and comments on the remainder of the line. */
+
+ menu->default_saved = TRUE;
+ }
+ }
}
menu->entries = g_list_reverse (menu->entries);
View
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 David Mohr <david@mcbf.net>
+ *
+ * This program 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.
+ *
+ * This program 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 Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef _HAVE_GCHD_MESSAGES_H
+#define _HAVE_GCHD_MESSAGES_H
+
+#include <glib.h>
+
+static const gchar * not_using_default_message [] =
+{
+ /* Generic message to be displayed while in Windows
+ * and we have no clue what distro is in use.
+ * (0)
+ */
+ "Usually it is required to change the grub configuration under Linux.",
+
+ /* Generic Linux message, the default
+ * (1)
+ */
+ "Set 'set default=\"${saved_entry}\"' in grub.cfg,\n"
+ "but since grub.cfg is generated, the exact way to save\n"
+ "this setting is distribution specific.",
+
+ /* For Debian and Ubuntu at least
+ * (2)
+ */
+ "As root edit '/etc/default/grub' and set 'GRUB_DEFAULT=saved'.\n"
+ "Then run 'update-grub'.",
+};
+
+static const gint n_not_using_default_message = 3;
+static const gint distro = DISTRIBUTION;
+
+#endif /* _HAVE_GCHD_MESSAGES_H */
View
@@ -37,6 +37,8 @@
# include <gio/gio.h>
#endif
+#include "gchd-messages.h"
+
static const gchar * grub_config_locations[] = {
"boot" G_DIR_SEPARATOR_S "grub",
"grub",
@@ -321,3 +323,44 @@ gchd_set_default_entry (Gchd * gchd, gchar * entry, GError **error)
return gchd->set_default_entry (gchd, entry, error);
}
+
+/**
+ * gchd_uses_default:
+ * @gchd : a #Gchd.
+ * @error : error to be set if grub does not use the default entry.
+ *
+ * Checks if grub.cfg is set up to use the default entry set by the
+ * grub environment.
+ *
+ * When this returns false, user action is required, and instructions on
+ * what to do are returned in the error parameter.
+ *
+ * IMPORTANT: Requires that gchd_get_menu_entries has been called!
+ *
+ * Returns: %TRUE if grub is using the saved default,
+ * %FALSE if grub is not set up correctly.
+ **/
+gboolean
+gchd_uses_default (Gchd * gchd, GError ** error)
+{
+#ifdef G_OS_WIN32
+ const gint index = 0;
+#else
+ const gint index = distro;
+#endif
+
+ g_assert (index >= 0 && index < n_not_using_default_message);
+
+ if (!gchd->menu.default_saved)
+ {
+ g_set_error (error,
+ GCHD_ERROR,
+ GCHD_ERROR_NOT_USING_DEFAULT,
+ "Grub is not configured to use the default set by this program.\n"
+ "\n"
+ "%s", not_using_default_message[index]);
+ return FALSE;
+ }
+
+ return TRUE;
+}
View
@@ -31,6 +31,7 @@ gint gchd_get_menu_entries (Gchd * gchd, GList **entries, GError **error);
gchar * gchd_get_default_entry (Gchd * gchd, GError **error);
gboolean gchd_set_default_entry (Gchd * gchd, gchar * entry, GError **error);
+gboolean gchd_uses_default (Gchd * gchd, GError ** error);
void gchd_set_grub_dir (Gchd * gchd, const gchar * grub_dir);
const gchar * gchd_get_grub_dir (Gchd * gchd);
@@ -286,8 +286,13 @@ commit (GrubChooseDefaultWidget * widget, GError **report_error)
GError *my_error = NULL;
GError **error;
+ GError *def_error = NULL;
gboolean r;
+ /* if report_error is not set, then we grab the
+ * error ourselves and report it to the user.
+ */
+
if (report_error == NULL)
error = &my_error;
else
@@ -302,6 +307,15 @@ commit (GrubChooseDefaultWidget * widget, GError **report_error)
g_error_free (my_error);
}
+ if (!gchd_uses_default (priv->gchd, &def_error))
+ {
+ /* warn the user if grub is not configured correctly */
+
+ grub_choose_default_error (gtk_widget_get_toplevel (GTK_WIDGET (widget)),
+ def_error);
+ g_error_free (def_error);
+ }
+
return r;
}
View
@@ -40,6 +40,8 @@ def set_options (opt):
def_direct = False
opt.add_option ('--direct', action='store_true', default=def_direct, help='Directly work on grubenv, default under win32', dest='direct')
+ opt.add_option ('--distribution', action='store', default=1, help='Sets index of the error message to use, see gchd-messages.h for values', dest='distro')
+
def configure (ctx):
print "Configuring", APPNAME
@@ -66,6 +68,9 @@ def configure (ctx):
ctx.define ('PACKAGE', APPNAME)
ctx.define ('DIRECT', 1 if Options.options.direct else 0)
ctx.define ('DEBUG', 1 if Options.options.debug else 0)
+ # TODO: check distro range at this point, and not at runtime in gchd.c
+ ctx.define ('DISTRIBUTION', int(Options.options.distro))
+
ctx.write_config_header ('config.h')
ctx.env.append_value ('CCDEFINES', ['HAVE_CONFIG_H=1'])

0 comments on commit 5868ae3

Please sign in to comment.