1 /* $OpenBSD: installboot.c,v 1.13 2019/10/29 17:41:45 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2012, 2013 Joel Sing <jsing@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <err.h> 20 #include <fcntl.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <unistd.h> 25 #include <util.h> 26 27 #include "installboot.h" 28 29 int nowrite; 30 int stages; 31 int verbose; 32 33 char *root = "/"; 34 char *stage1; 35 char *stage2; 36 37 static __dead void 38 usage(void) 39 { 40 extern char *__progname; 41 42 fprintf(stderr, "usage: %s [-nv] [-r root] disk [stage1%s]\n", 43 __progname, (stages >= 2) ? " [stage2]" : ""); 44 45 exit(1); 46 } 47 48 int 49 main(int argc, char **argv) 50 { 51 char *dev, *realdev; 52 int devfd, opt; 53 54 md_init(); 55 56 while ((opt = getopt(argc, argv, "nr:v")) != -1) { 57 switch (opt) { 58 case 'n': 59 nowrite = 1; 60 break; 61 case 'r': 62 root = strdup(optarg); 63 if (root == NULL) 64 err(1, "strdup"); 65 break; 66 case 'v': 67 verbose = 1; 68 break; 69 default: 70 usage(); 71 } 72 } 73 74 argc -= optind; 75 argv += optind; 76 77 if (argc < 1 || argc > stages + 1) 78 usage(); 79 80 dev = argv[0]; 81 if (argc > 1) 82 stage1 = argv[1]; 83 if (argc > 2) 84 stage2 = argv[2]; 85 86 /* Prefix stages with root, unless they were user supplied. */ 87 if (verbose) 88 fprintf(stderr, "Using %s as root\n", root); 89 if (argc <= 1 && stage1 != NULL) { 90 stage1 = fileprefix(root, stage1); 91 if (stage1 == NULL) 92 exit(1); 93 } 94 if (argc <= 2 && stage2 != NULL) { 95 stage2 = fileprefix(root, stage2); 96 if (stage2 == NULL) 97 exit(1); 98 } 99 100 if ((devfd = opendev(dev, (nowrite ? O_RDONLY : O_RDWR), OPENDEV_PART, 101 &realdev)) == -1) 102 err(1, "open: %s", realdev); 103 104 if (verbose) { 105 fprintf(stderr, "%s bootstrap on %s\n", 106 (nowrite ? "would install" : "installing"), realdev); 107 if (stage1 || stage2) { 108 if (stage1) 109 fprintf(stderr, "using first-stage %s", stage1); 110 if (stage2) 111 fprintf(stderr, ", second-stage %s", stage2); 112 fprintf(stderr, "\n"); 113 } 114 } 115 116 md_loadboot(); 117 118 #ifdef SOFTRAID 119 sr_installboot(devfd, dev); 120 #else 121 md_installboot(devfd, realdev); 122 #endif 123 124 return 0; 125 } 126