ieee1275: split up grub_machine_get_bootlocation
[grub.git] / util / grub-macbless.c
1 /* grub-probe.c - probe device information for a given path */
2 /*
3  *  GRUB  --  GRand Unified Bootloader
4  *  Copyright (C) 2005,2006,2007,2008,2009,2010  Free Software Foundation, Inc.
5  *
6  *  GRUB is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  GRUB is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <grub/types.h>
22 #include <grub/emu/misc.h>
23 #include <grub/util/misc.h>
24 #include <grub/device.h>
25 #include <grub/disk.h>
26 #include <grub/file.h>
27 #include <grub/fs.h>
28 #include <grub/partition.h>
29 #include <grub/msdos_partition.h>
30 #include <grub/emu/hostdisk.h>
31 #include <grub/emu/getroot.h>
32 #include <grub/term.h>
33 #include <grub/env.h>
34 #include <grub/diskfilter.h>
35 #include <grub/i18n.h>
36 #include <grub/crypto.h>
37 #include <grub/cryptodisk.h>
38 #include <grub/hfsplus.h>
39
40 #include <stdio.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <sys/stat.h>
46
47 #define _GNU_SOURCE     1
48 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
49 #pragma GCC diagnostic ignored "-Wmissing-declarations"
50 #include <argp.h>
51 #pragma GCC diagnostic error "-Wmissing-prototypes"
52 #pragma GCC diagnostic error "-Wmissing-declarations"
53
54 #include "progname.h"
55
56 static void
57 bless (const char *path, int x86)
58 {
59   char *drive_name = NULL;
60   char **devices;
61   char *grub_path = NULL;
62   char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
63   grub_device_t dev = NULL;
64   grub_err_t err;
65   struct stat st;
66
67   grub_path = grub_canonicalize_file_name (path);
68
69   if (stat (grub_path, &st) < 0)
70     grub_util_error (N_("cannot stat `%s': %s"),
71                      grub_path, strerror (errno));
72
73   devices = grub_guess_root_devices (grub_path);
74
75   if (! devices || !devices[0])
76     grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
77
78   drive_name = grub_util_get_grub_dev (devices[0]);
79   if (! drive_name)
80     grub_util_error (_("cannot find a GRUB drive for %s.  Check your device.map"),
81                      devices[0]);
82
83   grub_util_info ("opening %s", drive_name);
84   dev = grub_device_open (drive_name);
85   if (! dev)
86     grub_util_error ("%s", grub_errmsg);
87
88   err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
89   if (err)
90     grub_util_error ("%s", grub_errmsg);
91   free (grub_path);
92   free (filebuf_via_grub);
93   free (filebuf_via_sys);
94   free (drive_name);
95   free (devices);
96   grub_device_close (dev);
97 }
98
99 static struct argp_option options[] = {
100   {"x86",  'x', 0, 0,
101    N_("bless for x86-based macs"), 0},
102   {"ppc",  'p', 0, 0,
103    N_("bless for ppc-based macs"), 0},
104   {"verbose",     'v', 0,      0, N_("print verbose messages."), 0},
105   { 0, 0, 0, 0, 0, 0 }
106 };
107
108 struct arguments
109 {
110   char *arg;
111   int ppc;
112 };
113
114 static error_t
115 argp_parser (int key, char *arg, struct argp_state *state)
116 {
117   /* Get the input argument from argp_parse, which we
118      know is a pointer to our arguments structure. */
119   struct arguments *arguments = state->input;
120
121   switch (key)
122     {
123     case 'v':
124       verbosity++;
125       break;
126
127     case 'x':
128       arguments->ppc = 0;
129       break;
130
131     case 'p':
132       arguments->ppc = 1;
133       break;
134
135     case ARGP_KEY_NO_ARGS:
136       fprintf (stderr, "%s", _("No path or device is specified.\n"));
137       argp_usage (state);
138       break;
139
140     case ARGP_KEY_ARG:
141       if (arguments->arg)
142         {
143           fprintf (stderr, _("Unknown extra argument `%s'."), arg);
144           fprintf (stderr, "\n");
145           return ARGP_ERR_UNKNOWN;
146         }
147       arguments->arg = xstrdup (arg);
148       break;
149
150     default:
151       return ARGP_ERR_UNKNOWN;
152     }
153   return 0;
154 }
155
156 static struct argp argp = {
157   options, argp_parser, N_("--ppc PATH|--x86 FILE"),
158   N_("Mac-style bless on HFS or HFS+"),
159   NULL, NULL, NULL
160 };
161
162 int
163 main (int argc, char *argv[])
164 {
165   struct arguments arguments;
166
167   grub_util_host_init (&argc, &argv);
168
169   /* Check for options.  */
170   memset (&arguments, 0, sizeof (struct arguments));
171   if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
172     {
173       fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
174       exit(1);
175     }
176
177   if (verbosity > 1)
178     grub_env_set ("debug", "all");
179
180   /* Initialize the emulated biosdisk driver.  */
181   grub_util_biosdisk_init (NULL);
182
183   /* Initialize all modules. */
184   grub_init_all ();
185   grub_gcry_init_all ();
186
187   grub_lvm_fini ();
188   grub_mdraid09_fini ();
189   grub_mdraid1x_fini ();
190   grub_diskfilter_fini ();
191   grub_diskfilter_init ();
192   grub_mdraid09_init ();
193   grub_mdraid1x_init ();
194   grub_lvm_init ();
195
196   /* Do it.  */
197   bless (arguments.arg, !arguments.ppc);
198
199   /* Free resources.  */
200   grub_gcry_fini_all ();
201   grub_fini_all ();
202   grub_util_biosdisk_fini ();
203
204   return 0;
205 }