]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Add AROS hostdisk and getroot routines.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 4 Oct 2013 00:35:03 +0000 (02:35 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 4 Oct 2013 00:35:03 +0000 (02:35 +0200)
ChangeLog
grub-core/kern/emu/hostdisk_aros.c [new file with mode: 0644]
grub-core/kern/emu/hostdisk_os.c
grub-core/kern/emu/misc.c
include/grub/emu/hostdisk.h
include/grub/emu/misc.h
util/getroot_aros.c [new file with mode: 0644]
util/getroot_os.c

index 7638bb3bfab6bb3e259b3ed007f9138919a42f62..54e8180e7846e86263327efb1bcb1e7706945408 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-10-04  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Add AROS hostdisk and getroot routines.
+
 2013-10-04  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Make cryptodisk and diskfilter probe data retrievable programmatically
diff --git a/grub-core/kern/emu/hostdisk_aros.c b/grub-core/kern/emu/hostdisk_aros.c
new file mode 100644 (file)
index 0000000..feb0ee1
--- /dev/null
@@ -0,0 +1,481 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config-util.h>
+
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/msdos_partition.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/emu/misc.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/getroot.h>
+#include <grub/misc.h>
+#include <grub/i18n.h>
+#include <grub/list.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <string.h>
+#include <dos/dos.h>
+#include <dos/filesystem.h>
+#include <dos/exall.h>
+#include <proto/dos.h>
+#include <devices/hardblocks.h>
+#include <devices/newstyle.h>
+#include <proto/exec.h>
+#include <proto/utility.h>
+#include <proto/partition.h>
+#include <devices/trackdisk.h>
+#include <exec/errors.h>
+
+#define BOUNCE_SIZE 1048576
+
+static ULONG *bounce;
+
+static grub_uint64_t
+grub_util_get_fd_size_volume (grub_util_fd_t fd __attribute__ ((unused)),
+                             const char *dev,
+                             unsigned *log_secsize)
+{
+  struct DriveGeometry *geo;
+  LONG err;
+  unsigned sector_size, log_sector_size;
+
+  if (!bounce)
+    bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
+  if (!bounce)
+    grub_util_error ("out of memory");
+
+  fd->ioreq->iotd_Req.io_Command = TD_GETGEOMETRY;
+  fd->ioreq->iotd_Req.io_Length = sizeof (*geo);
+  fd->ioreq->iotd_Req.io_Data = bounce;
+  fd->ioreq->iotd_Req.io_Offset = 0;
+  fd->ioreq->iotd_Req.io_Actual = 0;
+  err = DoIO ((struct IORequest *) fd->ioreq);
+  if (err)
+    {
+      grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ());
+      return -1;
+    }
+
+  geo = (struct DriveGeometry *) bounce;
+
+  sector_size = geo->dg_SectorSize;
+
+  if (sector_size & (sector_size - 1) || !sector_size)
+    return -1;
+
+  for (log_sector_size = 0;
+       (1 << log_sector_size) < sector_size;
+       log_sector_size++);
+
+  if (log_secsize)
+    *log_secsize = log_sector_size;
+
+  return (grub_uint64_t) geo->dg_TotalSectors * (grub_uint64_t) geo->dg_SectorSize;
+}
+
+static grub_uint64_t
+grub_util_get_fd_size_file (grub_util_fd_t fd,
+                           const char *dev __attribute__ ((unused)),
+                           unsigned *log_secsize)
+{
+  off_t oo, ro;
+  *log_secsize = 9;
+  /* FIXME: support 64-bit offsets.  */
+  oo = lseek (fd->fd, 0, SEEK_CUR);
+  ro = lseek (fd->fd, 0, SEEK_END);
+  lseek (fd->fd, oo, SEEK_SET);
+  return ro;
+}
+
+grub_err_t
+grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
+{
+  switch (fd->type)
+    {
+    case GRUB_UTIL_FD_FILE:
+      if (lseek (fd->fd, 0, SEEK_SET) == (off_t) -1)
+       return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
+                          name, strerror (errno));
+      fd->off = off;
+      return 0;
+    case GRUB_UTIL_FD_DISK:
+      fd->off = off;
+      return 0;
+    }
+
+  return 0;
+}
+
+grub_util_fd_t
+grub_util_fd_open (const char *dev, int flg)
+{
+  grub_util_fd_t ret = xmalloc (sizeof (*ret));
+  const char *p, *p1, *p2;
+  char *tmp;
+  IPTR unit = 0;
+  ULONG flags = 0;
+
+  ret->off = 0;
+
+  if (dev[0] == '\0')
+    {
+      free (ret);
+      return NULL;
+    }
+
+  p = strchr (dev, ':');
+
+  if (!p || p[1])
+    {
+      ret->type = GRUB_UTIL_FD_FILE;
+      ret->fd = open (dev, flg);
+      if (ret->fd < 0)
+       {
+         free (ret);
+         return NULL;
+       }
+      return ret;
+    }
+
+  p1 = strchr (dev, '/');
+  if (!p1)
+    p1 = p;
+  else
+    {
+      unit = grub_strtoul (p1 + 1, (char **) &p2, 16);
+      if (p2 && *p2 == '/')
+       flags = grub_strtoul (p2 + 1, 0, 16);
+    }
+
+  ret->mp = CreateMsgPort();
+  if (!ret->mp)
+    {
+      free (ret);
+      return NULL;
+    }
+  ret->ioreq = (struct IOExtTD *) CreateIORequest(ret->mp,
+                                                sizeof(struct IOExtTD));
+  if (!ret->ioreq)
+    {
+      free (ret);
+      DeleteMsgPort (ret->mp);
+      return NULL;
+    }
+
+  tmp = xmalloc (p1 - dev + 1);
+  memcpy (tmp, dev, p1 - dev);
+  tmp[p1 - dev] = '\0';
+  ret->type = GRUB_UTIL_FD_DISK;
+
+  ret->is_floppy = (strcmp (tmp, TD_NAME) == 0);
+  ret->is_64 = 1;
+
+  if (OpenDevice ((unsigned char *) tmp, unit, (struct IORequest *) ret->ioreq, flags))
+    {
+      free (tmp);
+      free (ret);
+      DeleteMsgPort (ret->mp);
+      return NULL;
+    }
+  free (tmp);
+  return ret;
+}
+
+static ssize_t
+grub_util_fd_read_file (grub_util_fd_t fd, char *buf, size_t len)
+{
+  ssize_t size = len;
+
+  while (len)
+    {
+      ssize_t ret = read (fd->fd, buf, len);
+
+      if (ret <= 0)
+        {
+          if (errno == EINTR)
+            continue;
+          else
+            return ret;
+        }
+
+      fd->off += ret;
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static ssize_t
+grub_util_fd_write_file (grub_util_fd_t fd, const char *buf, size_t len)
+{
+  ssize_t size = len;
+
+  while (len)
+    {
+      ssize_t ret = write (fd->fd, buf, len);
+
+      if (ret <= 0)
+        {
+          if (errno == EINTR)
+            continue;
+          else
+            return ret;
+        }
+
+      fd->off += ret;
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+static void
+stop_motor (grub_util_fd_t fd)
+{
+  if (!fd->is_floppy)
+    return;
+  fd->ioreq->iotd_Req.io_Command = TD_MOTOR;
+  fd->ioreq->iotd_Req.io_Length = 0;
+  fd->ioreq->iotd_Req.io_Data = 0;
+  fd->ioreq->iotd_Req.io_Offset = 0;
+  fd->ioreq->iotd_Req.io_Actual = 0;
+  DoIO ((struct IORequest *) fd->ioreq);
+}
+
+static ssize_t
+grub_util_fd_read_volume (grub_util_fd_t fd, char *buf, size_t len)
+{
+  grub_uint64_t adj = 0;
+
+  if (!bounce)
+    bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
+  if (!bounce)
+    grub_util_error ("out of memory");
+
+  while (len)
+    {
+      size_t cr = len;
+      LONG err;
+      if (cr > BOUNCE_SIZE)
+       cr = BOUNCE_SIZE;
+    retry:
+      if (fd->is_64)
+       fd->ioreq->iotd_Req.io_Command = NSCMD_TD_READ64;
+      else
+       fd->ioreq->iotd_Req.io_Command = CMD_READ;
+      fd->ioreq->iotd_Req.io_Length = cr;
+      fd->ioreq->iotd_Req.io_Data = bounce;
+      fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF;
+      fd->ioreq->iotd_Req.io_Actual = fd->off >> 32;
+      err = DoIO ((struct IORequest *) fd->ioreq);
+      if (err == IOERR_NOCMD && fd->is_64)
+       {
+         fd->is_64 = 0;
+         goto retry;
+       }
+      if (err)
+       {
+         grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ());
+         stop_motor (fd);
+         return -1;
+       }
+      memcpy (buf, bounce, cr);
+      adj += cr;
+      len -= cr;
+      buf += cr;
+    }
+
+  fd->off += adj;
+  stop_motor (fd);
+  return adj;
+}
+
+static ssize_t
+grub_util_fd_write_volume (grub_util_fd_t fd, const char *buf, size_t len)
+{
+  grub_uint64_t adj = 0;
+  if (!bounce)
+    bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
+  if (!bounce)
+    grub_util_error ("out of memory");
+
+  while (len)
+    {
+      size_t cr = len;
+      LONG err;
+      if (cr > BOUNCE_SIZE)
+       cr = BOUNCE_SIZE;
+    retry:
+      if (fd->is_64)
+       fd->ioreq->iotd_Req.io_Command = NSCMD_TD_WRITE64;
+      else
+       fd->ioreq->iotd_Req.io_Command = CMD_WRITE;
+      fd->ioreq->iotd_Req.io_Length = cr;
+      fd->ioreq->iotd_Req.io_Data = bounce;
+      fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF;
+      fd->ioreq->iotd_Req.io_Actual = fd->off >> 32;
+      memcpy (bounce, buf, cr);
+      err = DoIO ((struct IORequest *) fd->ioreq);
+      if (err == IOERR_NOCMD && fd->is_64)
+       {
+         fd->is_64 = 0;
+         goto retry;
+       }
+      if (err)
+       {
+         grub_util_info ("I/O failed with error %d", err);
+         stop_motor (fd);
+         return -1;
+       }
+
+      adj += cr;
+      len -= cr;
+      buf += cr;
+    }
+
+  fd->off += adj;
+  stop_motor (fd);
+  return adj;
+}
+
+ssize_t
+grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
+{
+  switch (fd->type)
+    {
+    case GRUB_UTIL_FD_FILE:
+      return grub_util_fd_read_file (fd, buf, len);
+    case GRUB_UTIL_FD_DISK:
+      return grub_util_fd_read_volume (fd, buf, len);
+    }
+  return -1;
+}
+
+ssize_t
+grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
+{
+  switch (fd->type)
+    {
+    case GRUB_UTIL_FD_FILE:
+      return grub_util_fd_write_file (fd, buf, len);
+    case GRUB_UTIL_FD_DISK:
+      return grub_util_fd_write_volume (fd, buf, len);
+    }
+  return -1;
+}
+
+grub_uint64_t
+grub_util_get_fd_size (grub_util_fd_t fd,
+                      const char *dev,
+                      unsigned *log_secsize)
+{
+  switch (fd->type)
+    {
+    case GRUB_UTIL_FD_FILE:
+      return grub_util_get_fd_size_file (fd, dev, log_secsize);
+
+    case GRUB_UTIL_FD_DISK:
+      return grub_util_get_fd_size_volume (fd, dev, log_secsize);
+    }
+  return -1;
+}
+
+void
+grub_util_fd_close (grub_util_fd_t fd)
+{
+  switch (fd->type)
+    {
+    case GRUB_UTIL_FD_FILE:
+      close (fd->fd);
+      return;
+    case GRUB_UTIL_FD_DISK:
+      CloseDevice ((struct IORequest *) fd->ioreq);
+      DeleteIORequest((struct IORequest *) fd->ioreq);
+      DeleteMsgPort (fd->mp);
+      return;
+    }
+}
+
+static void
+grub_util_fd_sync_volume (grub_util_fd_t fd)
+{
+  fd->ioreq->iotd_Req.io_Command = CMD_UPDATE;
+  fd->ioreq->iotd_Req.io_Length = 0;
+  fd->ioreq->iotd_Req.io_Data = 0;
+  fd->ioreq->iotd_Req.io_Offset = 0;
+  fd->ioreq->iotd_Req.io_Actual = 0;
+  DoIO ((struct IORequest *) fd->ioreq);
+}
+
+void
+grub_util_fd_sync (grub_util_fd_t fd)
+{
+  switch (fd->type)
+    {
+    case GRUB_UTIL_FD_FILE:
+      fsync (fd->fd);
+      return;
+    case GRUB_UTIL_FD_DISK:
+      grub_util_fd_sync_volume (fd);
+      return;
+    }
+}
+
+
+void
+grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
+{
+}
+
+void
+grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
+{
+}
+
+
+const char *
+grub_util_fd_strerror (void)
+{
+  static char buf[201];
+  LONG err = IoErr ();
+  if (!err)
+    return _("Success");
+  memset (buf, '\0', sizeof (buf));
+  Fault (err, (const unsigned char *) "", (STRPTR) buf, sizeof (buf));
+  if (buf[0] == ':')
+    return buf + 1;
+  return buf;
+}
index 1957510e2e72ec9d3ec4b6b75159fb847b4d3d3a..904ab0d38534d8de6eac809bc0a6e1939b6777ec 100644 (file)
@@ -12,6 +12,8 @@
 #include "hostdisk_hurd.c"
 #elif defined(__CYGWIN__) || defined(__MINGW32__)
 #include "hostdisk_windows.c"
+#elif defined(__AROS__)
+#include "hostdisk_aros.c"
 #else
 # warning "No hostdisk OS-specific functions is available for your system. Device detection may not work properly."
 #include "hostdisk_basic.c"
index 53065ab9a19fe130d79b0dedd4ce2b4999e9e369..4dee33ae25767fe1054137abae2d674027dc66a8 100644 (file)
 # include <sys/mnttab.h>
 #endif
 
+#ifdef __AROS__
+#include <dos/dos.h>
+#include <dos/filesystem.h>
+#include <dos/exall.h>
+#include <proto/dos.h>
+#endif
+
 int verbosity;
 
 void
@@ -194,7 +201,26 @@ char *
 canonicalize_file_name (const char *path)
 {
   char *ret;
-#ifdef __MINGW32__
+#ifdef __AROS__
+  BPTR lck;
+  const char *p;
+
+  p = strchr (path, ':');
+  if (p && !p[1])
+    return xstrdup (path);
+
+  ret = xmalloc (2048);
+  lck = Lock ((const unsigned char *) path, SHARED_LOCK);
+
+  if (!lck || !NameFromLock (lck, (unsigned char *) ret, 2040))
+    {
+      free (ret);
+      ret = xstrdup (path);
+    }
+  if (lck)
+    UnLock (lck);
+
+#elif defined (__MINGW32__)
   ret = xmalloc (PATH_MAX);
   if (!_fullpath (ret, path, PATH_MAX))
     return NULL;
index b44efa4b582fa4a75c0bd0a76dc277bddf92cff1..28038e6d22eeb84ecc42238166d0cf551819a98c 100644 (file)
 #include <grub/partition.h>
 #include <sys/types.h>
 
-#if defined (__CYGWIN__) || defined (__MINGW32__)
+#if defined (__AROS__)
+struct grub_util_fd
+{
+  enum { GRUB_UTIL_FD_FILE, GRUB_UTIL_FD_DISK } type;
+  grub_uint64_t off;
+  union
+  {
+    int fd;
+    struct {
+      struct IOExtTD *ioreq;
+      struct MsgPort *mp;
+      unsigned int is_floppy:1;
+      unsigned int is_64:1;
+    };
+  };
+};
+typedef struct grub_util_fd *grub_util_fd_t;
+
+#define GRUB_UTIL_FD_INVALID NULL
+#define GRUB_UTIL_FD_IS_VALID(x) ((x) != GRUB_UTIL_FD_INVALID)
+#define GRUB_UTIL_FD_STAT_IS_FUNCTIONAL 0
+
+#elif defined (__CYGWIN__) || defined (__MINGW32__)
 #include <windows.h>
 typedef HANDLE grub_util_fd_t;
 #define GRUB_UTIL_FD_INVALID INVALID_HANDLE_VALUE
index e2ba8ee70292ef64e589a161724172c2c0f2e816..e25049b6ada15db3fcbb1b36ff49bd812092999a 100644 (file)
@@ -25,7 +25,9 @@
 #include <grub/symbol.h>
 #include <grub/types.h>
 
-#if defined __CYGWIN__ || defined (__MINGW32__)
+#if defined (__AROS__)
+# define DEFAULT_DIRECTORY     "SYS:" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME
+#elif defined __CYGWIN__ || defined (__MINGW32__)
 # define DEFAULT_DIRECTORY     "C:\\"GRUB_BOOT_DIR_NAME"\\"GRUB_DIR_NAME
 #elif defined (__NetBSD__)
 /* NetBSD uses /boot for its boot block.  */
diff --git a/util/getroot_aros.c b/util/getroot_aros.c
new file mode 100644 (file)
index 0000000..a16cb3a
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config-util.h>
+#include <config.h>
+
+#include <grub/util/misc.h>
+#include <grub/util/lvm.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/emu/misc.h>
+#include <grub/emu/hostdisk.h>
+#include <grub/emu/getroot.h>
+
+#include <string.h>
+#include <dos/dos.h>
+#include <dos/filesystem.h>
+#include <dos/exall.h>
+#include <proto/dos.h>
+#include <proto/exec.h>
+#include <devices/trackdisk.h>
+
+char *
+grub_util_part_to_disk (const char *dev,
+                       struct stat *st __attribute__ ((unused)),
+                       int *is_part)
+{
+  const char *p;
+  char *dname;
+  char *ret;
+  struct DosList *dl;
+  struct DeviceNode *dn;
+  struct FileSysStartupMsg *fm;
+  struct DosEnvec *envec;
+
+  if (!dev[0])
+    return xstrdup (dev);
+
+  p = dev + strlen (dev) - 1;
+  if (*p != ':')
+    return xstrdup (dev);
+  dname = xmalloc (p - dev + 1);
+  memcpy (dname, dev, p - dev);
+  dname[p - dev] = '\0';
+  dl = LockDosList(LDF_READ);
+
+  if (!dl)
+    {
+      free (dname);
+      return xstrdup (dev);
+    }
+
+  dn = (struct DeviceNode *) FindDosEntry (dl, (unsigned char *) dname,
+                                          LDF_DEVICES);
+  UnLockDosList (LDF_READ);
+  free (dname);
+  if (!dn)
+    return xstrdup (dev);
+
+  fm = (struct FileSysStartupMsg *) BADDR(dn->dn_Startup);
+  envec = (struct DosEnvec *) fm->fssm_Environ;
+
+  if (envec->de_LowCyl == 0)
+    return xstrdup (dev);
+
+  *is_part = 1;
+
+  ret = xasprintf ("%s/%lx/%lx:", fm->fssm_Device, fm->fssm_Unit, (unsigned long) fm->fssm_Flags);
+
+  return ret;
+}
+
+enum grub_dev_abstraction_types
+grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused)))
+{
+  return GRUB_DEV_ABSTRACTION_NONE;
+}
+
+int
+grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)),
+                         enum grub_dev_abstraction_types ab __attribute__ ((unused)))
+{
+  return 0;
+}
+
+char *
+grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+
+grub_disk_addr_t
+grub_util_find_partition_start_os (const char *dev)
+{
+  const char *p;
+  char *dname;
+  struct DosList *dl;
+  struct DeviceNode *dn;
+  struct FileSysStartupMsg *fm;
+  struct DosEnvec *envec;
+
+  if (!dev[0])
+    return 0;
+
+  p = dev + strlen (dev) - 1;
+  if (*p != ':')
+    return 0;
+  dname = xmalloc (p - dev + 1);
+  memcpy (dname, dev, p - dev);
+  dname[p - dev] = '\0';
+  dl = LockDosList(LDF_READ);
+  if (!dl)
+    {
+      free (dname);
+      return 0;
+    }
+  dn = (struct DeviceNode *) FindDosEntry (dl, (unsigned char *) dname,
+                                          LDF_DEVICES);
+  UnLockDosList (LDF_READ);
+  free (dname);
+  if (!dn)
+    return 0;
+
+  fm = (struct FileSysStartupMsg *) BADDR(dn->dn_Startup);
+  envec = (struct DosEnvec *) fm->fssm_Environ;
+
+  return (((grub_uint64_t) envec->de_Surfaces
+         * (grub_uint64_t) envec->de_BlocksPerTrack
+         * (grub_uint64_t) envec->de_LowCyl)
+         * (grub_uint64_t) envec->de_SizeBlock) >> 7;
+}
+
+char *
+grub_make_system_path_relative_to_its_root (const char *path)
+{
+  char *p;
+  unsigned char *tmp = xmalloc (2048);
+  char *ret;
+  BPTR lck;
+  lck = Lock ((const unsigned char *) path, SHARED_LOCK);
+  if (!lck || !NameFromLock (lck, tmp, 2040))
+    {
+      free (tmp);
+      tmp = (unsigned char *) xstrdup (path);
+    }
+  if (lck)
+    UnLock (lck);
+  p = strchr ((char *) tmp, ':');
+  if (!p)
+    return (char *) tmp;
+  if (p[1] == '/' || p[1] == '\0')
+    {
+      ret = xstrdup (p + 1);
+    }
+  else
+    {
+      ret = xmalloc (strlen (p + 1) + 2);
+      ret[0] = '/';
+      strcpy (ret + 1, p + 1);
+    }
+
+  free (tmp);
+  return ret;
+}
+
+char **
+grub_guess_root_devices (const char *path)
+{
+  char **os_dev = NULL;
+  struct InfoData id;
+  BPTR lck;
+  struct DeviceList *dl;
+  struct DosList *dl2;
+  size_t sz;
+  const char *nm;
+
+  lck = Lock ((const unsigned char *) path, SHARED_LOCK);
+  if (!lck)
+    grub_util_info ("Lock(%s) failed", path);
+  if (!lck || !Info (lck, &id))
+    {
+      char *p;
+      if (lck)
+       UnLock (lck);
+      grub_util_info ("Info(%s) failed", path);
+      os_dev = xmalloc (2 * sizeof (os_dev[0]));
+      sz = strlen (path);
+      os_dev[0] = xmalloc (sz + 2);
+      memcpy (os_dev[0], path, sz);
+      os_dev[0][sz] = ':';
+      os_dev[0][sz+1] = '\0';
+      p = strchr (os_dev[0], ':');
+      *(p + 1) = '\0';
+      os_dev[1] = NULL;
+      return os_dev;
+    }
+  dl = BADDR (id.id_VolumeNode);
+
+  if (!dl->dl_Task)
+    grub_util_error ("unsupported device %s", dl->dl_Name);
+
+  grub_util_info ("dl=%p, dl->dl_Name=%s, dl->dl_Task=%p",
+                 dl, dl->dl_Name,
+                 dl->dl_Task);
+
+  for (dl2 = LockDosList(LDF_READ | LDF_DEVICES);
+       dl2;
+       dl2 = NextDosEntry (dl2, LDF_DEVICES))
+    {
+      if (dl2->dol_Task == dl->dl_Task)
+       break;
+    }
+
+  if (lck)
+    UnLock (lck);
+
+  if (dl2)
+    nm = (char *) dl2->dol_Name;
+  else
+    nm = (char *) dl->dl_Name;
+
+  grub_util_info ("dl2=%p, nm=%s", dl2, nm);
+
+  os_dev = xmalloc (2 * sizeof (os_dev[0]));
+  sz = strlen (nm);
+  
+  os_dev[0] = xmalloc (sz + 2);
+  memcpy (os_dev[0], nm, sz);
+  os_dev[0][sz] = ':';
+  os_dev[0][sz+1] = '\0';
+  os_dev[1] = NULL;
+
+  UnLockDosList (LDF_READ | LDF_DEVICES);
+
+  return os_dev;
+}
+
+int
+grub_util_biosdisk_is_floppy (grub_disk_t disk)
+{
+  const char *dname, *p;
+
+  dname = grub_util_biosdisk_get_osdev (disk);
+
+  p = strchr (dname, ':');
+  if (!p || p[1])
+    return 0;
+
+  if (strncmp (dname, TD_NAME, sizeof (TD_NAME) - 1) == 0
+      && (TD_NAME[sizeof (TD_NAME) - 1] == '/'
+         || TD_NAME[sizeof (TD_NAME) - 1] == ':'))
+    return 1;
+  return 0;
+}
+
index a2ed13262432ff3be2cb57476d1ccd32c7a4896c..ed20e5f31f7d459484a3041ac9ff17f344f24078 100644 (file)
@@ -12,6 +12,8 @@
 #include "getroot_hurd.c"
 #elif defined(__CYGWIN__) || defined (__MINGW32__)
 #include "getroot_windows.c"
+#elif defined(__AROS__)
+#include "getroot_aros.c"
 #else
 # warning "No getroot OS-specific functions is available for your system. Device detection may not work properly."
 #include "getroot_basic.c"