1*32cef18bSdholland /* $NetBSD: file2swp.c,v 1.9 2016/03/12 02:17:05 dholland Exp $ */
2927df399Sleo
3927df399Sleo /*-
4927df399Sleo * Copyright (c) 2002 The NetBSD Foundation, Inc.
5927df399Sleo * All rights reserved.
6927df399Sleo *
7927df399Sleo * Redistribution and use in source and binary forms, with or without
8927df399Sleo * modification, are permitted provided that the following conditions
9927df399Sleo * are met:
10927df399Sleo * 1. Redistributions of source code must retain the above copyright
11927df399Sleo * notice, this list of conditions and the following disclaimer.
12927df399Sleo * 2. Redistributions in binary form must reproduce the above copyright
13927df399Sleo * notice, this list of conditions and the following disclaimer in the
14927df399Sleo * documentation and/or other materials provided with the distribution.
15927df399Sleo *
16927df399Sleo * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17927df399Sleo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18927df399Sleo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19927df399Sleo * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20927df399Sleo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21927df399Sleo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22927df399Sleo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23927df399Sleo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24927df399Sleo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25927df399Sleo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26927df399Sleo * POSSIBILITY OF SUCH DAMAGE.
27927df399Sleo */
28927df399Sleo
29927df399Sleo #include <sys/types.h>
30927df399Sleo #include <stdlib.h>
31927df399Sleo #include <string.h>
32927df399Sleo #include <fcntl.h>
33927df399Sleo #include <unistd.h>
34927df399Sleo #include "libtos.h"
35927df399Sleo #include "diskio.h"
36927df399Sleo #include "ahdilbl.h"
377c8d16d6Sleo #include "disklbl.h"
38927df399Sleo #include "cread.h"
39927df399Sleo
40927df399Sleo char *Infile = "minifs.gz";
41*32cef18bSdholland const char version[] = "$Revision: 1.9 $";
42927df399Sleo
43927df399Sleo extern const char *program_name;
44927df399Sleo
45927df399Sleo int main PROTO((int, char **));
467c8d16d6Sleo static int check_bsdlabel PROTO((disk_t *,u_int32_t,u_int32_t *,u_int32_t *));
477c8d16d6Sleo static int readdisklabel PROTO((disk_t *, u_int32_t *, u_int32_t *));
48927df399Sleo static void usage PROTO((void)) NORETURN;
49927df399Sleo
50927df399Sleo static void
usage(void)51df7f595eScegger usage(void)
52927df399Sleo {
53927df399Sleo eprintf("Usage: %s [OPTIONS] DISK\n"
54927df399Sleo "where OPTIONS are:\n"
55927df399Sleo "\t-V display version information\n"
56927df399Sleo "\t-f FILE File to copy. The FILE may be a gzipped file.\n"
57927df399Sleo "\t If not specified, it defaults to minifs.gz.\n"
58927df399Sleo "\t-h display this help and exit\n"
59927df399Sleo "\t-o FILE send output to FILE instead of stdout\n"
60927df399Sleo "\t-w wait for key press before exiting\n\n"
61927df399Sleo "DISK is the concatenation of BUS, TARGET and LUN.\n"
62927df399Sleo "BUS is one of `i' (IDE), `a' (ACSI) or `s' (SCSI).\n"
63927df399Sleo "TARGET and LUN are one decimal digit each. LUN must\n"
64927df399Sleo "not be specified for IDE devices and is optional for\n"
65927df399Sleo "ACSI/SCSI devices (if omitted, LUN defaults to 0).\n\n"
66927df399Sleo "Examples: a0 refers to ACSI target 0 lun 0\n"
67927df399Sleo " s21 refers to SCSI target 2 lun 1\n"
68927df399Sleo , program_name);
69927df399Sleo xexit(EXIT_SUCCESS);
70927df399Sleo }
71927df399Sleo
72927df399Sleo int
main(int argc,char ** argv)73454af1c0Sdsl main(int argc, char **argv)
74927df399Sleo {
75927df399Sleo extern int optind;
76927df399Sleo extern char *optarg;
77927df399Sleo
78927df399Sleo disk_t *dd;
79*32cef18bSdholland int rv, c, fd;
80927df399Sleo u_int32_t currblk;
817c8d16d6Sleo u_int32_t start, end;
82927df399Sleo char buf[AHDI_BSIZE];
83927df399Sleo
84*32cef18bSdholland rv = 0;
85927df399Sleo init_toslib(*argv);
86927df399Sleo
87927df399Sleo while ((c = getopt(argc, argv, "Vf:ho:w")) != -1) {
88927df399Sleo switch (c) {
89927df399Sleo case 'f':
90927df399Sleo Infile = optarg;
91927df399Sleo break;
92927df399Sleo case 'o':
93927df399Sleo redirect_output(optarg);
94927df399Sleo break;
95927df399Sleo case 'w':
96927df399Sleo set_wait_for_key();
97927df399Sleo break;
98927df399Sleo case 'V':
99927df399Sleo error(-1, "%s", version);
100927df399Sleo break;
101927df399Sleo /* NOT REACHED */
102927df399Sleo case 'h':
103927df399Sleo default:
104927df399Sleo usage();
105927df399Sleo /* NOT REACHED */
106927df399Sleo }
107927df399Sleo }
108927df399Sleo argv += optind;
109927df399Sleo
110927df399Sleo if (!*argv) {
111927df399Sleo error(-1, "missing DISK argument");
112927df399Sleo usage();
113927df399Sleo /* NOT REACHED */
114927df399Sleo }
115927df399Sleo dd = disk_open(*argv);
116927df399Sleo
1177c8d16d6Sleo if (readdisklabel(dd, &start, &end) != 0)
118927df399Sleo xexit(1);
1197c8d16d6Sleo
120927df399Sleo if ((fd = open(Infile, O_RDONLY)) < 0) {
121927df399Sleo eprintf("Unable to open <%s>\n", Infile);
122927df399Sleo xexit(1);
123927df399Sleo }
124927df399Sleo
125927df399Sleo switch(key_wait("Are you sure (y/n)? ")) {
126927df399Sleo case 'y':
127927df399Sleo case 'Y':
1287c8d16d6Sleo currblk = start;
129a9e4e986Sdholland while ((c = read(fd, buf, sizeof(buf))) > 0) {
130927df399Sleo if (disk_write(dd, currblk, 1, buf) < 0) {
131927df399Sleo eprintf("Error writing to swap partition\n");
132927df399Sleo xexit(1);
133927df399Sleo }
1347c8d16d6Sleo if (++currblk >= end) {
135927df399Sleo eprintf("Error: filesize exceeds swap "
136927df399Sleo "partition size\n");
137927df399Sleo xexit(1);
138927df399Sleo }
139927df399Sleo }
140927df399Sleo close(fd);
141927df399Sleo eprintf("Ready\n");
142927df399Sleo xexit(0);
143927df399Sleo break;
144927df399Sleo default :
145927df399Sleo eprintf("Aborted\n");
146927df399Sleo break;
147927df399Sleo }
148927df399Sleo rv = EXIT_FAILURE;
149927df399Sleo return(rv);
150927df399Sleo }
1517c8d16d6Sleo
1527c8d16d6Sleo static int
check_bsdlabel(disk_t * dd,u_int32_t offset,u_int32_t * start,u_int32_t * end)15382357f6dSdsl check_bsdlabel(disk_t *dd, u_int32_t offset, u_int32_t *start, u_int32_t *end)
1547c8d16d6Sleo {
1557c8d16d6Sleo struct disklabel dl;
1567c8d16d6Sleo int err;
1577c8d16d6Sleo
1587c8d16d6Sleo err = bsd_getlabel(dd, &dl, offset);
1597c8d16d6Sleo if (err < 0) {
1607c8d16d6Sleo eprintf("Device I/O error (hardware problem?)\n\n");
1617c8d16d6Sleo return (-1);
1627c8d16d6Sleo }
1637c8d16d6Sleo if (!err) {
1647c8d16d6Sleo if (dl.d_partitions[1].p_size > 0) {
1657c8d16d6Sleo *start = dl.d_partitions[1].p_offset;
1667c8d16d6Sleo *end = *start + dl.d_partitions[1].p_size-1;
1677c8d16d6Sleo eprintf("NetBSD/Atari format%s, Swap partition start:%d, end:%d\n",
1687c8d16d6Sleo offset != 0 ? " (embedded)" : "", *start, *end);
1697c8d16d6Sleo return (0);
1707c8d16d6Sleo }
1717c8d16d6Sleo eprintf("NetBSD/Atari format: no swap defined\n");
1727c8d16d6Sleo }
1737c8d16d6Sleo return 1;
1747c8d16d6Sleo }
1757c8d16d6Sleo
1767c8d16d6Sleo static int
readdisklabel(disk_t * dd,u_int32_t * start,u_int32_t * end)17782357f6dSdsl readdisklabel(disk_t *dd, u_int32_t *start, u_int32_t *end)
1787c8d16d6Sleo {
1797c8d16d6Sleo ptable_t pt;
1807c8d16d6Sleo int err, i;
1817c8d16d6Sleo
1827c8d16d6Sleo
1837c8d16d6Sleo err = check_bsdlabel(dd, LABELSECTOR, start, end);
1847c8d16d6Sleo if (err != 1)
1857c8d16d6Sleo return (err);
1867c8d16d6Sleo memset(&pt, 0, sizeof(pt));
1877c8d16d6Sleo err = ahdi_getparts(dd, &pt, AHDI_BBLOCK, AHDI_BBLOCK);
1887c8d16d6Sleo if (err < 0) {
1897c8d16d6Sleo eprintf("Device I/O error (hardware problem?)\n\n");
1907c8d16d6Sleo return (-1);
1917c8d16d6Sleo }
1927c8d16d6Sleo if (!err) {
1937c8d16d6Sleo /*
1947c8d16d6Sleo * Check for hidden BSD labels
1957c8d16d6Sleo */
1967c8d16d6Sleo for (i = 0; i < pt.nparts; i++) {
1977c8d16d6Sleo if (!strncmp(pt.parts[i].id, "NBD", 3)) {
1987c8d16d6Sleo err = check_bsdlabel(dd, pt.parts[i].start, start, end);
1997c8d16d6Sleo if (err != 1)
2007c8d16d6Sleo return (err);
2017c8d16d6Sleo }
2027c8d16d6Sleo }
2037c8d16d6Sleo for (i = 0; i < pt.nparts; i++) {
2047c8d16d6Sleo if (!strncmp(pt.parts[i].id, "SWP", 3))
2057c8d16d6Sleo break;
2067c8d16d6Sleo }
2077c8d16d6Sleo if (i < pt.nparts) {
2087c8d16d6Sleo *start = pt.parts[i].start;
2097c8d16d6Sleo *end = pt.parts[i].end;
2107c8d16d6Sleo eprintf("AHDI format, SWP partition: start:%d,end: %d\n",
2117c8d16d6Sleo *start, *end);
2127c8d16d6Sleo return (0);
2137c8d16d6Sleo }
2147c8d16d6Sleo eprintf("AHDI format, no swap ('SWP') partition found!\n");
2157c8d16d6Sleo }
2167c8d16d6Sleo eprintf("Unknown label format.\n\n");
2177c8d16d6Sleo return(-1);
2187c8d16d6Sleo }
219