/* ----------------------------------------------------------------------- * * * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin * Copyright 2010 Shao Miller * Copyright 2010-2015 Michal Soltys * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall * be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * ----------------------------------------------------------------------- */ #include #include #include #include #include "chain.h" #include "partiter.h" #include "utility.h" #include "options.h" struct options opt; static int soi_s2n(char *ptr, addr_t *seg, addr_t *off, addr_t *ip, addr_t def) { addr_t segval, offval, ipval, val; char *p; /* defaults */ segval = 0; offval = def; ipval = def; segval = strtoul(ptr, &p, 0); if (p[0] == ':' && p[1] && p[1] != ':') offval = strtoul(p+1, &p, 0); if (p[0] == ':' && p[1] && p[1] != ':') ipval = strtoul(p+1, NULL, 0); /* verify if load address is within [dosmin, dosmax) */ val = (segval << 4) + offval; if (val < dosmin || val >= dosmax) { error("Invalid seg:off:* address specified."); goto bail; } /* * verify if jump address is within [dosmin, dosmax) and offset is 16bit * sane */ val = (segval << 4) + ipval; if (ipval > 0xFFFE || val < dosmin || val >= dosmax) { error("Invalid seg:*:ip address specified."); goto bail; } if (seg) *seg = segval; if (off) *off = offval; if (ip) *ip = ipval; return 0; bail: return -1; } static void usage(void) { size_t i; static const char *const usage[] = { "Usage:", "", " disk + partition selection:", " chain.c32 [options]", " chain.c32 hd#[,#] [options]", " chain.c32 fd#[,#] [options]", " chain.c32 mbr=[,#] [options]", " chain.c32 guid=[,#] [options]", " chain.c32 boot[,#] [options]", "", " direct partition selection:", " chain.c32 guid= [options]", " chain.c32 label=