Merge branch 'pathbased' of ssh://terminus.zytor.com/pub/git/syslinux/syslinux into...
[profile/ivi/syslinux.git] / libinstaller / syslxopt.c
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2010 Intel Corp. - All Rights Reserved
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8  *   Boston MA 02111-1307, USA; either version 2 of the License, or
9  *   (at your option) any later version; incorporated herein by reference.
10  *
11  * ----------------------------------------------------------------------- */
12
13 /*
14  * syslxopt.c
15  *
16  * parse cmdline for extlinux and syslinux installer
17  *
18  */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <getopt.h>
24 #include <sysexits.h>
25 #include "../version.h"
26 #include "syslxcom.h"
27 #include "syslxopt.h"
28
29 /* These are the options we can set their values */
30 struct sys_options opt = {
31     .sectors = 0,
32     .heads = 0,
33     .raid_mode = 0,
34     .stupid_mode = 0,
35     .reset_adv = 0,
36     .set_once = NULL,
37     .update_only = -1,
38     .directory = NULL,
39     .device = NULL,
40     .offset = 0,
41     .menu_save = NULL,
42 };
43
44 const struct option long_options[] = {
45     {"force", 0, NULL, 'f'},    /* dummy option for compatibility */
46     {"install", 0, NULL, 'i'},
47     {"directory", 1, NULL, 'd'},
48     {"offset", 1, NULL, 't'},
49     {"update", 0, NULL, 'U'},
50     {"zipdrive", 0, NULL, 'z'},
51     {"sectors", 1, NULL, 'S'},
52     {"stupid", 0, NULL, 's'},
53     {"heads", 1, NULL, 'H'},
54     {"raid-mode", 0, NULL, 'r'},
55     {"version", 0, NULL, 'v'},
56     {"help", 0, NULL, 'h'},
57     {"once", 1, NULL, OPT_ONCE},
58     {"clear-once", 0, NULL, 'O'},
59     {"reset-adv", 0, NULL, OPT_RESET_ADV},
60     {"menu-save", 1, NULL, 'M'},
61     {0, 0, 0, 0}
62 };
63
64 const char short_options[] = "t:fid:UuzS:H:rvho:OM:";
65
66 void __attribute__ ((noreturn)) usage(int rv, enum syslinux_mode mode)
67 {
68     switch (mode) {
69     case MODE_SYSLINUX:
70         /* For unmounted fs installation (syslinux) */
71         fprintf(stderr,
72             "Usage: %s [options] device\n"
73             "  --offset     -t  Offset of the file system on the device \n"
74             "  --directory  -d  Directory for installation target\n",
75             program);
76         break;
77
78     case MODE_EXTLINUX:
79         /* Mounted fs installation (extlinux) */
80         /* Actually extlinux can also use -d to provide a directory too... */
81         fprintf(stderr,
82             "Usage: %s [options] directory\n",
83             program);
84         break;
85     }
86
87     fprintf(stderr,
88             "  --install    -i  Install over the current bootsector\n"
89             "  --update     -U  Update a previous EXTLINUX installation\n"
90             "  --zip        -z  Force zipdrive geometry (-H 64 -S 32)\n"
91             "  --sectors=#  -S  Force the number of sectors per track\n"
92             "  --heads=#    -H  Force number of heads\n"
93             "  --stupid     -s  Slow, safe and stupid mode\n"
94             "  --raid       -r  Fall back to the next device on boot failure\n"
95             "  --once=...   %s  Execute a command once upon boot\n"
96             "  --clear-once -O  Clear the boot-once command\n"
97             "  --reset-adv      Reset auxilliary data\n"
98             "  --menu-save= -M  Set the label to select as default on the next boot\n"
99             "\n"
100             "  Note: geometry is determined at boot time for devices which\n"
101             "  are considered hard disks by the BIOS.  Unfortunately, this is\n"
102             "  not possible for devices which are considered floppy disks,\n"
103             "  which includes zipdisks and LS-120 superfloppies.\n"
104             "\n"
105             "  The -z option is useful for USB devices which are considered\n"
106             "  hard disks by some BIOSes and zipdrives by other BIOSes.\n",
107             mode == MODE_SYSLINUX ? "  " : "-o");
108
109     exit(rv);
110 }
111
112 void parse_options(int argc, char *argv[], enum syslinux_mode mode)
113 {
114     int o;
115
116     program = argv[0];
117     while ((o = getopt_long(argc, argv, short_options,
118                             long_options, NULL)) != EOF) {
119         switch (o) {
120         case 'f':
121             break;
122         case 'z':
123             opt.heads = 64;
124             opt.sectors = 32;
125             break;
126         case 'S':
127             opt.sectors = strtoul(optarg, NULL, 0);
128             if (opt.sectors < 1 || opt.sectors > 63) {
129                 fprintf(stderr,
130                         "%s: invalid number of sectors: %u (must be 1-63)\n",
131                         program, opt.sectors);
132                 exit(EX_USAGE);
133             }
134             break;
135         case 'H':
136             opt.heads = strtoul(optarg, NULL, 0);
137             if (opt.heads < 1 || opt.heads > 256) {
138                 fprintf(stderr,
139                         "%s: invalid number of heads: %u (must be 1-256)\n",
140                         program, opt.heads);
141                 exit(EX_USAGE);
142             }
143             break;
144         case 'r':
145             opt.raid_mode = 1;
146             break;
147         case 's':
148             opt.stupid_mode = 1;
149             break;
150         case 'i':
151             opt.update_only = 0;
152             break;
153         case 'u':
154         case 'U':
155             opt.update_only = 1;
156             break;
157         case 'h':
158             usage(0, mode);
159             break;
160         case 'o':
161             if (mode == MODE_SYSLINUX) {
162                 fprintf(stderr, "%s: -o will change meaning in a future version, use -t or --offset\n", program);
163                 goto opt_offset;
164             }
165             /* else fall through */
166         case OPT_ONCE:
167             opt.set_once = optarg;
168             break;
169         case 't':
170         opt_offset:
171             opt.offset = strtoul(optarg, NULL, 0);
172             break;
173         case 'O':
174             opt.set_once = "";
175             break;
176         case 'd':
177             opt.directory = optarg;
178             break;
179         case OPT_RESET_ADV:
180             opt.reset_adv = 1;
181             break;
182         case 'M':
183             opt.menu_save = optarg;
184             break;
185         case 'v':
186             fprintf(stderr,
187                     "%s " VERSION_STR "  Copyright 1994-" YEAR_STR
188                     " H. Peter Anvin et al\n", program);
189             exit(0);
190         default:
191             fprintf(stderr, "%s: Unknown option: -%c\n", program, optopt);
192             usage(EX_USAGE, mode);
193         }
194     }
195
196     switch (mode) {
197     case MODE_SYSLINUX:
198         opt.device = argv[optind++];
199         break;
200     case MODE_EXTLINUX:
201         if (!opt.directory)
202             opt.directory = argv[optind++];
203         break;
204     }
205
206     if (argv[optind])
207         usage(EX_USAGE, mode);  /* Excess arguments */
208 }