31004e
From f18b04893c6f40415fb577a286982a3046fcecd2 Mon Sep 17 00:00:00 2001
a5bd9f
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
a5bd9f
Date: Sun, 24 Mar 2013 13:05:59 +0100
f74b50
Subject: [PATCH 227/482] 	Add new 'proc' filesystem framework and put
a5bd9f
 luks_script into it.
a5bd9f
a5bd9f
---
a5bd9f
 ChangeLog                   |   4 ++
a5bd9f
 Makefile.util.def           |   1 +
a5bd9f
 grub-core/Makefile.core.def |   5 ++
a5bd9f
 grub-core/disk/cryptodisk.c | 113 +++++++++++++++++++++++++++++
a5bd9f
 grub-core/disk/geli.c       |   2 -
a5bd9f
 grub-core/disk/luks.c       |   2 -
a5bd9f
 grub-core/fs/proc.c         | 172 ++++++++++++++++++++++++++++++++++++++++++++
a5bd9f
 include/grub/cryptodisk.h   |   5 +-
a5bd9f
 include/grub/disk.h         |   1 +
a5bd9f
 include/grub/procfs.h       |  50 +++++++++++++
a5bd9f
 10 files changed, 350 insertions(+), 5 deletions(-)
a5bd9f
 create mode 100644 grub-core/fs/proc.c
a5bd9f
 create mode 100644 include/grub/procfs.h
a5bd9f
a5bd9f
diff --git a/ChangeLog b/ChangeLog
a5bd9f
index 9841659..8f3878d 100644
a5bd9f
--- a/ChangeLog
a5bd9f
+++ b/ChangeLog
a5bd9f
@@ -1,3 +1,7 @@
a5bd9f
+2013-03-24  Vladimir Serbinenko  <phcoder@gmail.com>
a5bd9f
+
a5bd9f
+	Add new 'proc' filesystem framework and put luks_script into it.
a5bd9f
+
a5bd9f
 2013-03-23  Vladimir Serbinenko  <phcoder@gmail.com>
a5bd9f
 
a5bd9f
 	* grub-core/term/at_keyboard.c: Increase robustness on coreboot
a5bd9f
diff --git a/Makefile.util.def b/Makefile.util.def
a5bd9f
index 1ccf390..62bcf2d 100644
a5bd9f
--- a/Makefile.util.def
a5bd9f
+++ b/Makefile.util.def
a5bd9f
@@ -33,6 +33,7 @@ library = {
a5bd9f
   common = grub-core/disk/diskfilter.c;
a5bd9f
   common = grub-core/partmap/gpt.c;
a5bd9f
   common = grub-core/partmap/msdos.c;
a5bd9f
+  common = grub-core/fs/proc.c;
a5bd9f
 };
a5bd9f
 
a5bd9f
 library = {
a5bd9f
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
a5bd9f
index a614b22..b1c1ab9 100644
a5bd9f
--- a/grub-core/Makefile.core.def
a5bd9f
+++ b/grub-core/Makefile.core.def
a5bd9f
@@ -1068,6 +1068,11 @@ module = {
a5bd9f
 };
a5bd9f
 
a5bd9f
 module = {
a5bd9f
+  name = procfs;
a5bd9f
+  common = fs/proc.c;
a5bd9f
+};
a5bd9f
+
a5bd9f
+module = {
a5bd9f
   name = affs;
a5bd9f
   common = fs/affs.c;
a5bd9f
 };
a5bd9f
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
a5bd9f
index f39c1ab..374edd1 100644
a5bd9f
--- a/grub-core/disk/cryptodisk.c
a5bd9f
+++ b/grub-core/disk/cryptodisk.c
a5bd9f
@@ -22,6 +22,9 @@
a5bd9f
 #include <grub dl.h="">
a5bd9f
 #include <grub extcmd.h="">
a5bd9f
 #include <grub i18n.h="">
a5bd9f
+#include <grub fs.h="">
a5bd9f
+#include <grub file.h="">
a5bd9f
+#include <grub procfs.h="">
a5bd9f
 
a5bd9f
 #ifdef GRUB_UTIL
a5bd9f
 #include <errno.h>
a5bd9f
@@ -403,6 +406,8 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke
a5bd9f
   err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize);
a5bd9f
   if (err)
a5bd9f
     return err;
a5bd9f
+  grub_memcpy (dev->key, key, keysize);
a5bd9f
+  dev->keysize = keysize;
a5bd9f
 
a5bd9f
   /* Configure ESSIV if necessary.  */
a5bd9f
   if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV)
a5bd9f
@@ -979,6 +984,112 @@ static struct grub_disk_dev grub_cryptodisk_dev = {
a5bd9f
   .next = 0
a5bd9f
 };
a5bd9f
 
a5bd9f
+static char
a5bd9f
+hex (grub_uint8_t val)
a5bd9f
+{
a5bd9f
+  if (val < 10)
a5bd9f
+    return '0' + val;
a5bd9f
+  return 'a' + val - 10;
a5bd9f
+}
a5bd9f
+
a5bd9f
+/* Open a file named NAME and initialize FILE.  */
a5bd9f
+static char *
a5bd9f
+luks_script_get (void)
a5bd9f
+{
a5bd9f
+  grub_cryptodisk_t i;
a5bd9f
+  grub_size_t size = 0;
a5bd9f
+  char *ptr, *ret;
a5bd9f
+
a5bd9f
+  for (i = cryptodisk_list; i != NULL; i = i->next)
a5bd9f
+    if (grub_strcmp (i->modname, "luks") == 0)
a5bd9f
+      {
a5bd9f
+	size += sizeof ("luks_mount ");
a5bd9f
+	size += grub_strlen (i->uuid);
a5bd9f
+	size += grub_strlen (i->cipher->cipher->name);
a5bd9f
+	size += 54;
a5bd9f
+	if (i->essiv_hash)
a5bd9f
+	  size += grub_strlen (i->essiv_hash->name);
a5bd9f
+	size += i->keysize * 2;
a5bd9f
+      }
a5bd9f
+
a5bd9f
+  ret = grub_malloc (size + 1);
a5bd9f
+  if (!ret)
a5bd9f
+    return 0;
a5bd9f
+
a5bd9f
+  ptr = ret;
a5bd9f
+
a5bd9f
+  for (i = cryptodisk_list; i != NULL; i = i->next)
a5bd9f
+    if (grub_strcmp (i->modname, "luks") == 0)
a5bd9f
+      {
a5bd9f
+	unsigned j;
a5bd9f
+	const char *iptr;
a5bd9f
+	ptr = grub_stpcpy (ptr, "luks_mount ");
a5bd9f
+	ptr = grub_stpcpy (ptr, i->uuid);
a5bd9f
+	*ptr++ = ' ';
a5bd9f
+	grub_snprintf (ptr, 21, "%" PRIuGRUB_UINT64_T " ", i->offset);
a5bd9f
+	while (*ptr)
a5bd9f
+	  ptr++;
a5bd9f
+	for (iptr = i->cipher->cipher->name; *iptr; iptr++)
a5bd9f
+	  *ptr++ = grub_tolower (*iptr);
a5bd9f
+	switch (i->mode)
a5bd9f
+	  {
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_ECB:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-ecb"); 
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_CBC:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-cbc");
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_PCBC:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-pcbc");
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_XTS:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-xts");
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_LRW:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-lrw");
a5bd9f
+	    break;
a5bd9f
+	  }
a5bd9f
+
a5bd9f
+	switch (i->mode_iv)
a5bd9f
+	  {
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_NULL:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-null"); 
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_PLAIN:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-plain"); 
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-plain64"); 
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_BENBI:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-benbi"); 
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_ESSIV:
a5bd9f
+	    ptr = grub_stpcpy (ptr, "-essiv:"); 
a5bd9f
+	    ptr = grub_stpcpy (ptr, i->essiv_hash->name);
a5bd9f
+	    break;
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
a5bd9f
+	  case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
a5bd9f
+	    break;
a5bd9f
+	  }
a5bd9f
+	*ptr++ = ' ';
a5bd9f
+	for (j = 0; j < i->keysize; j++)
a5bd9f
+	  {
a5bd9f
+	    *ptr++ = hex (i->key[j] >> 4);
a5bd9f
+	    *ptr++ = hex (i->key[j] & 0xf);
a5bd9f
+	  }
a5bd9f
+	*ptr++ = '\n';
a5bd9f
+      }
a5bd9f
+  *ptr = '\0';
a5bd9f
+  return ret;
a5bd9f
+}
a5bd9f
+
a5bd9f
+struct grub_procfs_entry luks_script =
a5bd9f
+{
a5bd9f
+  .name = "luks_script",
a5bd9f
+  .get_contents = luks_script_get
a5bd9f
+};
a5bd9f
+
a5bd9f
 static grub_extcmd_t cmd;
a5bd9f
 
a5bd9f
 GRUB_MOD_INIT (cryptodisk)
a5bd9f
@@ -987,10 +1098,12 @@ GRUB_MOD_INIT (cryptodisk)
a5bd9f
   cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
a5bd9f
 			      N_("SOURCE|-u UUID|-a|-b"),
a5bd9f
 			      N_("Mount a crypto device."), options);
a5bd9f
+  grub_procfs_register ("luks_script", &luks_script);
a5bd9f
 }
a5bd9f
 
a5bd9f
 GRUB_MOD_FINI (cryptodisk)
a5bd9f
 {
a5bd9f
   grub_disk_dev_unregister (&grub_cryptodisk_dev);
a5bd9f
   cryptodisk_cleanup ();
a5bd9f
+  grub_procfs_unregister (&luks_script);
a5bd9f
 }
a5bd9f
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
a5bd9f
index f9315df..0b94414 100644
a5bd9f
--- a/grub-core/disk/geli.c
a5bd9f
+++ b/grub-core/disk/geli.c
a5bd9f
@@ -381,9 +381,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
a5bd9f
       newdev->rekey_shift = 20;
a5bd9f
     }
a5bd9f
 
a5bd9f
-#ifdef GRUB_UTIL
a5bd9f
   newdev->modname = "geli";
a5bd9f
-#endif
a5bd9f
 
a5bd9f
   newdev->total_length = grub_disk_get_size (disk) - 1;
a5bd9f
   grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
a5bd9f
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
a5bd9f
index 44f3cac..afcb7e4 100644
a5bd9f
--- a/grub-core/disk/luks.c
a5bd9f
+++ b/grub-core/disk/luks.c
a5bd9f
@@ -290,9 +290,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
a5bd9f
   newdev->log_sector_size = 9;
a5bd9f
   newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
a5bd9f
   grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
a5bd9f
-#ifdef GRUB_UTIL
a5bd9f
   newdev->modname = "luks";
a5bd9f
-#endif
a5bd9f
   COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
a5bd9f
   return newdev;
a5bd9f
 }
a5bd9f
diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c
a5bd9f
new file mode 100644
a5bd9f
index 0000000..8f27682
a5bd9f
--- /dev/null
a5bd9f
+++ b/grub-core/fs/proc.c
a5bd9f
@@ -0,0 +1,172 @@
a5bd9f
+/*
a5bd9f
+ *  GRUB  --  GRand Unified Bootloader
a5bd9f
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
a5bd9f
+ *
a5bd9f
+ *  GRUB is free software: you can redistribute it and/or modify
a5bd9f
+ *  it under the terms of the GNU General Public License as published by
a5bd9f
+ *  the Free Software Foundation, either version 3 of the License, or
a5bd9f
+ *  (at your option) any later version.
a5bd9f
+ *
a5bd9f
+ *  GRUB is distributed in the hope that it will be useful,
a5bd9f
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
a5bd9f
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
a5bd9f
+ *  GNU General Public License for more details.
a5bd9f
+ *
a5bd9f
+ *  You should have received a copy of the GNU General Public License
a5bd9f
+ *  along with GRUB.  If not, see <http: www.gnu.org="" licenses=""/>.
a5bd9f
+ */
a5bd9f
+
a5bd9f
+#include <grub procfs.h="">
a5bd9f
+#include <grub disk.h="">
a5bd9f
+#include <grub fs.h="">
a5bd9f
+#include <grub file.h="">
a5bd9f
+#include <grub mm.h="">
a5bd9f
+#include <grub dl.h="">
a5bd9f
+
a5bd9f
+GRUB_MOD_LICENSE ("GPLv3+");
a5bd9f
+
a5bd9f
+struct grub_procfs_entry *grub_procfs_entries;
a5bd9f
+
a5bd9f
+static int
a5bd9f
+grub_procdev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
a5bd9f
+			 grub_disk_pull_t pull)
a5bd9f
+{
a5bd9f
+  if (pull != GRUB_DISK_PULL_NONE)
a5bd9f
+    return 0;
a5bd9f
+
a5bd9f
+  return hook ("proc", hook_data);
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_err_t
a5bd9f
+grub_procdev_open (const char *name, grub_disk_t disk)
a5bd9f
+{
a5bd9f
+  if (grub_strcmp (name, "proc"))
a5bd9f
+      return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a procfs disk");
a5bd9f
+
a5bd9f
+  disk->total_sectors = 0;
a5bd9f
+  disk->id = (unsigned long) "proc";
a5bd9f
+
a5bd9f
+  disk->data = 0;
a5bd9f
+
a5bd9f
+  return GRUB_ERR_NONE;
a5bd9f
+}
a5bd9f
+
a5bd9f
+static void
a5bd9f
+grub_procdev_close (grub_disk_t disk __attribute((unused)))
a5bd9f
+{
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_err_t
a5bd9f
+grub_procdev_read (grub_disk_t disk __attribute((unused)),
a5bd9f
+		grub_disk_addr_t sector __attribute((unused)),
a5bd9f
+		grub_size_t size __attribute((unused)),
a5bd9f
+		char *buf __attribute((unused)))
a5bd9f
+{
a5bd9f
+  return GRUB_ERR_OUT_OF_RANGE;
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_err_t
a5bd9f
+grub_procdev_write (grub_disk_t disk __attribute ((unused)),
a5bd9f
+		       grub_disk_addr_t sector __attribute ((unused)),
a5bd9f
+		       grub_size_t size __attribute ((unused)),
a5bd9f
+		       const char *buf __attribute ((unused)))
a5bd9f
+{
a5bd9f
+  return GRUB_ERR_OUT_OF_RANGE;
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_ssize_t
a5bd9f
+grub_procfs_read (grub_file_t file, char *buf, grub_size_t len)
a5bd9f
+{
a5bd9f
+  char *data = file->data;
a5bd9f
+
a5bd9f
+  grub_memcpy (buf, data + file->offset, len);
a5bd9f
+
a5bd9f
+  return len;
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_err_t
a5bd9f
+grub_procfs_close (grub_file_t file)
a5bd9f
+{
a5bd9f
+  char *data;
a5bd9f
+
a5bd9f
+  data = file->data;
a5bd9f
+  grub_free (data);
a5bd9f
+
a5bd9f
+  return GRUB_ERR_NONE;
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_err_t
a5bd9f
+grub_procfs_dir (grub_device_t device, const char *path,
a5bd9f
+		 grub_fs_dir_hook_t hook, void *hook_data)
a5bd9f
+{
a5bd9f
+  const char *ptr;
a5bd9f
+  struct grub_dirhook_info info;
a5bd9f
+  struct grub_procfs_entry *entry;
a5bd9f
+
a5bd9f
+  grub_memset (&info, 0, sizeof (info));
a5bd9f
+
a5bd9f
+  /* Check if the disk is our dummy disk.  */
a5bd9f
+  if (grub_strcmp (device->disk->name, "proc"))
a5bd9f
+    return grub_error (GRUB_ERR_BAD_FS, "not a procfs");
a5bd9f
+  for (ptr = path; *ptr == '/'; ptr++);
a5bd9f
+  if (*ptr)
a5bd9f
+    return 0;
a5bd9f
+  FOR_LIST_ELEMENTS((entry), (grub_procfs_entries))
a5bd9f
+    if (hook (entry->name, &info, hook_data))
a5bd9f
+      return 0;
a5bd9f
+  return 0;
a5bd9f
+}
a5bd9f
+
a5bd9f
+static grub_err_t
a5bd9f
+grub_procfs_open (struct grub_file *file, const char *path)
a5bd9f
+{
a5bd9f
+  const char *pathptr;
a5bd9f
+  struct grub_procfs_entry *entry;
a5bd9f
+
a5bd9f
+  for (pathptr = path; *pathptr == '/'; pathptr++);
a5bd9f
+
a5bd9f
+  FOR_LIST_ELEMENTS((entry), (grub_procfs_entries))
a5bd9f
+    if (grub_strcmp (pathptr, entry->name) == 0)
a5bd9f
+    {
a5bd9f
+      file->data = entry->get_contents ();
a5bd9f
+      if (!file->data)
a5bd9f
+	return grub_errno;
a5bd9f
+      file->size = grub_strlen (file->data);
a5bd9f
+      return GRUB_ERR_NONE;
a5bd9f
+    }
a5bd9f
+
a5bd9f
+  return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path);
a5bd9f
+}
a5bd9f
+
a5bd9f
+static struct grub_disk_dev grub_procfs_dev = {
a5bd9f
+  .name = "proc",
a5bd9f
+  .id = GRUB_DISK_DEVICE_PROCFS_ID,
a5bd9f
+  .iterate = grub_procdev_iterate,
a5bd9f
+  .open = grub_procdev_open,
a5bd9f
+  .close = grub_procdev_close,
a5bd9f
+  .read = grub_procdev_read,
a5bd9f
+  .write = grub_procdev_write,
a5bd9f
+  .next = 0
a5bd9f
+};
a5bd9f
+
a5bd9f
+static struct grub_fs grub_procfs_fs =
a5bd9f
+  {
a5bd9f
+    .name = "procfs",
a5bd9f
+    .dir = grub_procfs_dir,
a5bd9f
+    .open = grub_procfs_open,
a5bd9f
+    .read = grub_procfs_read,
a5bd9f
+    .close = grub_procfs_close,
a5bd9f
+    .next = 0
a5bd9f
+  };
a5bd9f
+
a5bd9f
+GRUB_MOD_INIT (procfs)
a5bd9f
+{
a5bd9f
+  grub_disk_dev_register (&grub_procfs_dev);
a5bd9f
+  grub_fs_register (&grub_procfs_fs);
a5bd9f
+}
a5bd9f
+
a5bd9f
+GRUB_MOD_FINI (procfs)
a5bd9f
+{
a5bd9f
+  grub_disk_dev_unregister (&grub_procfs_dev);
a5bd9f
+  grub_fs_unregister (&grub_procfs_fs);
a5bd9f
+}
a5bd9f
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
a5bd9f
index 0bb5d44..c3ee820 100644
a5bd9f
--- a/include/grub/cryptodisk.h
a5bd9f
+++ b/include/grub/cryptodisk.h
a5bd9f
@@ -49,6 +49,7 @@ typedef enum
a5bd9f
 #define GRUB_CRYPTODISK_GF_SIZE (1U << GRUB_CRYPTODISK_GF_LOG_SIZE)
a5bd9f
 #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3)
a5bd9f
 #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES)
a5bd9f
+#define GRUB_CRYPTODISK_MAX_KEYLEN 128
a5bd9f
 
a5bd9f
 struct grub_cryptodisk;
a5bd9f
 
a5bd9f
@@ -80,11 +81,13 @@ struct grub_cryptodisk
a5bd9f
   grub_uint8_t *lrw_precalc;
a5bd9f
   grub_uint8_t iv_prefix[64];
a5bd9f
   grub_size_t iv_prefix_len;
a5bd9f
+  grub_uint8_t key[GRUB_CRYPTODISK_MAX_KEYLEN];
a5bd9f
+  grub_size_t keysize;
a5bd9f
 #ifdef GRUB_UTIL
a5bd9f
   char *cheat;
a5bd9f
-  const char *modname;
a5bd9f
   int cheat_fd;
a5bd9f
 #endif
a5bd9f
+  const char *modname;
a5bd9f
   int log_sector_size;
a5bd9f
   grub_cryptodisk_rekey_func_t rekey;
a5bd9f
   int rekey_shift;
a5bd9f
diff --git a/include/grub/disk.h b/include/grub/disk.h
a5bd9f
index f0e3df3..d19b1ac 100644
a5bd9f
--- a/include/grub/disk.h
a5bd9f
+++ b/include/grub/disk.h
a5bd9f
@@ -43,6 +43,7 @@ enum grub_disk_dev_id
a5bd9f
     GRUB_DISK_DEVICE_CRYPTODISK_ID,
a5bd9f
     GRUB_DISK_DEVICE_ARCDISK_ID,
a5bd9f
     GRUB_DISK_DEVICE_HOSTDISK_ID,
a5bd9f
+    GRUB_DISK_DEVICE_PROCFS_ID,
a5bd9f
   };
a5bd9f
 
a5bd9f
 struct grub_disk;
a5bd9f
diff --git a/include/grub/procfs.h b/include/grub/procfs.h
a5bd9f
new file mode 100644
a5bd9f
index 0000000..55cbb21
a5bd9f
--- /dev/null
a5bd9f
+++ b/include/grub/procfs.h
a5bd9f
@@ -0,0 +1,50 @@
a5bd9f
+/*
a5bd9f
+ *  GRUB  --  GRand Unified Bootloader
a5bd9f
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
a5bd9f
+ *
a5bd9f
+ *  GRUB is free software: you can redistribute it and/or modify
a5bd9f
+ *  it under the terms of the GNU General Public License as published by
a5bd9f
+ *  the Free Software Foundation, either version 3 of the License, or
a5bd9f
+ *  (at your option) any later version.
a5bd9f
+ *
a5bd9f
+ *  GRUB is distributed in the hope that it will be useful,
a5bd9f
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
a5bd9f
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
a5bd9f
+ *  GNU General Public License for more details.
a5bd9f
+ *
a5bd9f
+ *  You should have received a copy of the GNU General Public License
a5bd9f
+ *  along with GRUB.  If not, see <http: www.gnu.org="" licenses=""/>.
a5bd9f
+ */
a5bd9f
+
a5bd9f
+#ifndef GRUB_PROCFS_HEADER
a5bd9f
+#define GRUB_PROCFS_HEADER	1
a5bd9f
+
a5bd9f
+#include <grub list.h="">
a5bd9f
+
a5bd9f
+struct grub_procfs_entry
a5bd9f
+{
a5bd9f
+  struct grub_procfs_entry *next;
a5bd9f
+  struct grub_procfs_entry **prev;
a5bd9f
+
a5bd9f
+  const char *name;
a5bd9f
+  char * (*get_contents) (void);
a5bd9f
+};
a5bd9f
+
a5bd9f
+extern struct grub_procfs_entry *grub_procfs_entries;
a5bd9f
+
a5bd9f
+static inline void
a5bd9f
+grub_procfs_register (const char *name __attribute__ ((unused)),
a5bd9f
+		      struct grub_procfs_entry *entry)
a5bd9f
+{
a5bd9f
+  grub_list_push (GRUB_AS_LIST_P (&grub_procfs_entries),
a5bd9f
+		  GRUB_AS_LIST (entry));
a5bd9f
+}
a5bd9f
+
a5bd9f
+static inline void
a5bd9f
+grub_procfs_unregister (struct grub_procfs_entry *entry)
a5bd9f
+{
a5bd9f
+  grub_list_remove (GRUB_AS_LIST (entry));
a5bd9f
+}
a5bd9f
+
a5bd9f
+
a5bd9f
+#endif
a5bd9f
-- 
31004e
1.8.2.1
a5bd9f