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