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