xref: /netbsd-src/sys/arch/atari/stand/tostools/file2swp/file2swp.c (revision 32cef18b87d3d7688d40bcaa0d9376f6918d1bf4)
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