/[pupa]/pupa/util/i386/pc/pupa-setup.c
ViewVC logotype

Diff of /pupa/util/i386/pc/pupa-setup.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by okuji, Tue Jan 7 07:54:07 2003 UTC revision 1.5 by marco_g, Mon Nov 17 18:07:09 2003 UTC
# Line 3  Line 3 
3   *  PUPA  --  Preliminary Universal Programming Architecture for GRUB   *  PUPA  --  Preliminary Universal Programming Architecture for GRUB
4   *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.   *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.
5   *  Copyright (C) 2002  Yoshinori K. Okuji <okuji@enbug.org>   *  Copyright (C) 2002  Yoshinori K. Okuji <okuji@enbug.org>
6     *  Copyright (C) 2003  Marco Gerards <metgerards@student.han.nl>
7   *   *
8   *  PUPA is free software; you can redistribute it and/or modify   *  PUPA is free software; you can redistribute it and/or modify
9   *  it under the terms of the GNU General Public License as published by   *  it under the terms of the GNU General Public License as published by
# Line 38  Line 39 
39  #include <sys/types.h>  #include <sys/types.h>
40  #include <sys/stat.h>  #include <sys/stat.h>
41  #include <dirent.h>  #include <dirent.h>
42    #include <pupa/util/getroot.h>
43    
44  #define _GNU_SOURCE     1  #define _GNU_SOURCE     1
45  #include <getopt.h>  #include <getopt.h>
# Line 62  struct boot_blocklist Line 64  struct boot_blocklist
64    pupa_uint16_t segment;    pupa_uint16_t segment;
65  } __attribute__ ((packed));  } __attribute__ ((packed));
66    
67    void
68    pupa_putchar (int c)
69    {
70      putchar (c);
71    }
72    
73    void
74    pupa_refresh (void)
75    {
76    }
77    
78  static void  static void
79  setup (const char *prefix, const char *dir,  setup (const char *prefix, const char *dir,
80         const char *boot_file, const char *core_file,         const char *boot_file, const char *core_file,
# Line 479  get_device_name (char *dev) Line 492  get_device_name (char *dev)
492    return dev + 1;    return dev + 1;
493  }  }
494    
 static char *  
 xgetcwd (void)  
 {  
   size_t size = 10;  
   char *path;  
   
   path = xmalloc (size);  
   while (! getcwd (path, size))  
     {  
       size <<= 1;  
       path = xrealloc (path, size);  
     }  
   
   return path;  
 }  
   
 static void  
 strip_extra_slashes (char *dir)  
 {  
   char *p = dir;  
   
   while ((p = strchr (p, '/')) != 0)  
     {  
       if (p[1] == '/')  
         {  
           memmove (p, p + 1, strlen (p));  
           continue;  
         }  
       else if (p[1] == '\0')  
         {  
           p[0] = '\0';  
           break;  
         }  
         
       p++;  
     }  
 }  
   
 static char *  
 get_prefix (const char *dir)  
 {  
   char *saved_cwd;  
   char *abs_dir, *prev_dir;  
   char *prefix;  
   struct stat st, prev_st;  
     
   /* Save the current directory.  */  
   saved_cwd = xgetcwd ();  
   
   if (chdir (dir) < 0)  
     pupa_util_error ("Cannot change directory to `%s'", dir);  
   
   abs_dir = xgetcwd ();  
   strip_extra_slashes (abs_dir);  
   prev_dir = xstrdup (abs_dir);  
     
   if (stat (".", &prev_st) < 0)  
     pupa_util_error ("Cannot stat `%s'", dir);  
   
   if (! S_ISDIR (prev_st.st_mode))  
     pupa_util_error ("`%s' is not a directory", dir);  
   
   while (1)  
     {  
       if (chdir ("..") < 0)  
         pupa_util_error ("Cannot change directory to the parent");  
   
       if (stat (".", &st) < 0)  
         pupa_util_error ("Cannot stat current directory");  
   
       if (! S_ISDIR (st.st_mode))  
         pupa_util_error ("Current directory is not a directory???");  
   
       if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino)  
         break;  
   
       free (prev_dir);  
       prev_dir = xgetcwd ();  
       prev_st = st;  
     }  
   
   strip_extra_slashes (prev_dir);  
   prefix = xmalloc (strlen (abs_dir) - strlen (prev_dir) + 2);  
   prefix[0] = '/';  
   strcpy (prefix + 1, abs_dir + strlen (prev_dir));  
   strip_extra_slashes (prefix);  
   
   if (chdir (saved_cwd) < 0)  
     pupa_util_error ("Cannot change directory to `%s'", dir);  
   
   free (saved_cwd);  
   free (abs_dir);  
   free (prev_dir);  
   
   pupa_util_info ("prefix = %s", prefix);  
   return prefix;  
 }  
   
 static char *  
 find_root_device (const char *dir, dev_t dev)  
 {  
   DIR *dp;  
   char *saved_cwd;  
   struct dirent *ent;  
     
   dp = opendir (dir);  
   if (! dp)  
     return 0;  
   
   saved_cwd = xgetcwd ();  
   
   pupa_util_info ("changing current directory to %s", dir);  
   if (chdir (dir) < 0)  
     {  
       free (saved_cwd);  
       closedir (dp);  
       return 0;  
     }  
     
   while ((ent = readdir (dp)) != 0)  
     {  
       struct stat st;  
         
       if (strcmp (ent->d_name, ".") == 0 || strcmp (ent->d_name, "..") == 0)  
         continue;  
   
       if (lstat (ent->d_name, &st) < 0)  
         /* Ignore any error.  */  
         continue;  
   
       if (S_ISLNK (st.st_mode))  
         /* Don't follow symbolic links.  */  
         continue;  
         
       if (S_ISDIR (st.st_mode))  
         {  
           /* Find it recursively.  */  
           char *res;  
   
           res = find_root_device (ent->d_name, dev);  
   
           if (res)  
             {  
               if (chdir (saved_cwd) < 0)  
                 pupa_util_error ("Cannot restore the original directory");  
                 
               free (saved_cwd);  
               closedir (dp);  
               return res;  
             }  
         }  
   
       if (S_ISBLK (st.st_mode) && st.st_rdev == dev)  
         {  
           /* Found!  */  
           char *res;  
           char *cwd;  
   
           cwd = xgetcwd ();  
           res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 2);  
           sprintf (res, "%s/%s", cwd, ent->d_name);  
           strip_extra_slashes (res);  
           free (cwd);  
   
           if (chdir (saved_cwd) < 0)  
             pupa_util_error ("Cannot restore the original directory");  
   
           free (saved_cwd);  
           closedir (dp);  
           return res;  
         }  
     }  
   
   if (chdir (saved_cwd) < 0)  
     pupa_util_error ("Cannot restore the original directory");  
   
   free (saved_cwd);  
   closedir (dp);  
   return 0;  
 }  
   
 static char *  
 guess_root_device (const char *dir)  
 {  
   struct stat st;  
   char *os_dev;  
     
   if (stat (dir, &st) < 0)  
     pupa_util_error ("Cannot stat `%s'", dir);  
   
   /* This might be truly slow, but is there any better way?  */  
   os_dev = find_root_device ("/dev", st.st_dev);  
   if (! os_dev)  
     return 0;  
   
   return pupa_util_biosdisk_get_pupa_dev (os_dev);  
 }  
   
495  int  int
496  main (int argc, char *argv[])  main (int argc, char *argv[])
497  {  {
# Line 774  main (int argc, char *argv[]) Line 589  main (int argc, char *argv[])
589        usage (1);        usage (1);
590      }      }
591    
592    prefix = get_prefix (dir ? : DEFAULT_DIRECTORY);    prefix = pupa_get_prefix (dir ? : DEFAULT_DIRECTORY);
593        
594    /* Initialize the emulated biosdisk driver.  */    /* Initialize the emulated biosdisk driver.  */
595    pupa_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);    pupa_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
# Line 795  main (int argc, char *argv[]) Line 610  main (int argc, char *argv[])
610      }      }
611    else    else
612      {      {
613        root_dev = guess_root_device (dir ? : DEFAULT_DIRECTORY);        root_dev = pupa_guess_root_device (dir ? : DEFAULT_DIRECTORY);
614        if (! root_dev)        if (! root_dev)
615          {          {
616            pupa_util_info ("guessing the root device failed, because of `%s'",            pupa_util_info ("guessing the root device failed, because of `%s'",

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26