1 /* $NetBSD: file2swp.c,v 1.3 2008/04/28 20:23:15 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <fcntl.h> 33 #include <unistd.h> 34 #include "libtos.h" 35 #include "diskio.h" 36 #include "ahdilbl.h" 37 #include "disklbl.h" 38 #include "cread.h" 39 40 char *Infile = "minifs.gz"; 41 const char version[] = "$Revision: 1.3 $"; 42 43 extern const char *program_name; 44 45 int main PROTO((int, char **)); 46 static int check_bsdlabel PROTO((disk_t *,u_int32_t,u_int32_t *,u_int32_t *)); 47 static int readdisklabel PROTO((disk_t *, u_int32_t *, u_int32_t *)); 48 static void usage PROTO((void)) NORETURN; 49 50 static void 51 usage() 52 { 53 eprintf("Usage: %s [OPTIONS] DISK\n" 54 "where OPTIONS are:\n" 55 "\t-V display version information\n" 56 "\t-f FILE File to copy. The FILE may be a gzipped file.\n" 57 "\t If not specified, it defaults to minifs.gz.\n" 58 "\t-h display this help and exit\n" 59 "\t-o FILE send output to FILE instead of stdout\n" 60 "\t-w wait for key press before exiting\n\n" 61 "DISK is the concatenation of BUS, TARGET and LUN.\n" 62 "BUS is one of `i' (IDE), `a' (ACSI) or `s' (SCSI).\n" 63 "TARGET and LUN are one decimal digit each. LUN must\n" 64 "not be specified for IDE devices and is optional for\n" 65 "ACSI/SCSI devices (if omitted, LUN defaults to 0).\n\n" 66 "Examples: a0 refers to ACSI target 0 lun 0\n" 67 " s21 refers to SCSI target 2 lun 1\n" 68 , program_name); 69 xexit(EXIT_SUCCESS); 70 } 71 72 int 73 main(argc, argv) 74 int argc; 75 char **argv; 76 { 77 extern int optind; 78 extern char *optarg; 79 80 disk_t *dd; 81 int rv, c, i, fd; 82 u_int32_t currblk; 83 u_int32_t start, end; 84 char buf[AHDI_BSIZE]; 85 86 i = rv = 0; 87 init_toslib(*argv); 88 89 while ((c = getopt(argc, argv, "Vf:ho:w")) != -1) { 90 switch (c) { 91 case 'f': 92 Infile = optarg; 93 break; 94 case 'o': 95 redirect_output(optarg); 96 break; 97 case 'w': 98 set_wait_for_key(); 99 break; 100 case 'V': 101 error(-1, "%s", version); 102 break; 103 /* NOT REACHED */ 104 case 'h': 105 default: 106 usage(); 107 /* NOT REACHED */ 108 } 109 } 110 argv += optind; 111 112 if (!*argv) { 113 error(-1, "missing DISK argument"); 114 usage(); 115 /* NOT REACHED */ 116 } 117 dd = disk_open(*argv); 118 119 if (readdisklabel(dd, &start, &end) != 0) 120 xexit(1); 121 122 if ((fd = open(Infile, O_RDONLY)) < 0) { 123 eprintf("Unable to open <%s>\n", Infile); 124 xexit(1); 125 } 126 127 switch(key_wait("Are you sure (y/n)? ")) { 128 case 'y': 129 case 'Y': 130 currblk = start; 131 while(c = read(fd, buf, sizeof(buf)) > 0) { 132 if (disk_write(dd, currblk, 1, buf) < 0) { 133 eprintf("Error writing to swap partition\n"); 134 xexit(1); 135 } 136 if (++currblk >= end) { 137 eprintf("Error: filesize exceeds swap " 138 "partition size\n"); 139 xexit(1); 140 } 141 } 142 close(fd); 143 eprintf("Ready\n"); 144 xexit(0); 145 break; 146 default : 147 eprintf("Aborted\n"); 148 break; 149 } 150 rv = EXIT_FAILURE; 151 return(rv); 152 } 153 154 static int 155 check_bsdlabel(dd, offset, start, end) 156 disk_t *dd; 157 u_int32_t offset, *start, *end; 158 { 159 struct disklabel dl; 160 int err; 161 162 err = bsd_getlabel(dd, &dl, offset); 163 if (err < 0) { 164 eprintf("Device I/O error (hardware problem?)\n\n"); 165 return (-1); 166 } 167 if (!err) { 168 if (dl.d_partitions[1].p_size > 0) { 169 *start = dl.d_partitions[1].p_offset; 170 *end = *start + dl.d_partitions[1].p_size-1; 171 eprintf("NetBSD/Atari format%s, Swap partition start:%d, end:%d\n", 172 offset != 0 ? " (embedded)" : "", *start, *end); 173 return (0); 174 } 175 eprintf("NetBSD/Atari format: no swap defined\n"); 176 } 177 return 1; 178 } 179 180 static int 181 readdisklabel(dd, start, end) 182 disk_t *dd; 183 u_int32_t *start, *end; 184 { 185 ptable_t pt; 186 int err, i; 187 188 189 err = check_bsdlabel(dd, LABELSECTOR, start, end); 190 if (err != 1) 191 return (err); 192 memset(&pt, 0, sizeof(pt)); 193 err = ahdi_getparts(dd, &pt, AHDI_BBLOCK, AHDI_BBLOCK); 194 if (err < 0) { 195 eprintf("Device I/O error (hardware problem?)\n\n"); 196 return (-1); 197 } 198 if (!err) { 199 /* 200 * Check for hidden BSD labels 201 */ 202 for (i = 0; i < pt.nparts; i++) { 203 if (!strncmp(pt.parts[i].id, "NBD", 3)) { 204 err = check_bsdlabel(dd, pt.parts[i].start, start, end); 205 if (err != 1) 206 return (err); 207 } 208 } 209 for (i = 0; i < pt.nparts; i++) { 210 if (!strncmp(pt.parts[i].id, "SWP", 3)) 211 break; 212 } 213 if (i < pt.nparts) { 214 *start = pt.parts[i].start; 215 *end = pt.parts[i].end; 216 eprintf("AHDI format, SWP partition: start:%d,end: %d\n", 217 *start, *end); 218 return (0); 219 } 220 eprintf("AHDI format, no swap ('SWP') partition found!\n"); 221 } 222 eprintf("Unknown label format.\n\n"); 223 return(-1); 224 } 225