source: unzip/vendor/current/amiga/makesfx.c@ 200

Last change on this file since 200 was 200, checked in by Yuri Dario, 14 years ago

zip: initial unzip 6.0 import.

File size: 5.9 KB
Line 
1/*
2 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
3
4 See the accompanying file LICENSE, version 2000-Apr-09 or later
5 (the contents of which are also included in unzip.h) for terms of use.
6 If, for some reason, all these files are missing, the Info-ZIP license
7 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
8*/
9/* MakeSFX: join UnZipSFX and a .zip archive into a single self-extracting */
10/* Amiga program. On most systems simple concatenation does the job but for */
11/* the Amiga a special tool is needed. By Paul Kienitz, no rights reserved. */
12/* This program is written portably, so if anyone really wants to they can */
13/* produce Amiga self-extracting programs on a non-Amiga. We are careful */
14/* not to mix Motorola-format longwords read from files with native long */
15/* integers. Not necessarily limited to use with only the Zip format -- */
16/* just combine any archive with any self-extractor program that is capable */
17/* of reading a HUNK_DEBUG section at the end as an archive. */
18
19#include <stat.h>
20#include <string.h>
21#include <stdio.h>
22#include <stdlib.h>
23#ifdef __SASC
24# include <proto/dos.h>
25# ifdef DEBUG
26# include <sprof.h>
27# endif
28#endif /* __SASC */
29#ifdef AZTEC_C
30# include <dos/dos.h>
31# include <clib/dos_protos.h>
32#endif /* AZTEC_C */
33
34typedef unsigned long ulg;
35typedef unsigned char uch;
36typedef unsigned short bool;
37#define false 0
38#define true 1
39
40/* the following are extracted from Commodore include file dos/doshunks.h: */
41#define HUNK_NAME 1000L
42#define HUNK_CODE 1001L
43#define HUNK_DATA 1002L
44#define HUNK_BSS 1003L
45#define HUNK_RELOC32 1004L
46#define HUNK_SYMBOL 1008L
47#define HUNK_DEBUG 1009L
48#define HUNK_END 1010L
49#define HUNK_HEADER 1011L
50#define HUNK_OVERLAY 1013L
51#define HUNK_BREAK 1014L
52
53/* Convert a big-endian (Motorola) sequence of four bytes to a longword: */
54#define CHARS2LONG(b) (((ulg)(b)[0] << 24) | ((ulg)(b)[1] << 16) | \
55 ((ulg)(b)[2] << 8) | ((ulg)(b)[3]))
56/* b must be (uch *) in each of these. Now the reverse: */
57#define LONG2CHARS(b,l) ((b)[0] = (uch)((l) >> 24), (b)[1] = (uch)((l) >> 16),\
58 (b)[2] = (uch)((l) >> 8), (b)[3] = (uch)(l))
59
60#define COPYBUFFER 16384
61
62ulg totalwritten = 0;
63
64
65bool CopyData(FILE *out, FILE *inn, ulg archivesize,
66 char *outname, char *inname)
67{
68 static uch buf[COPYBUFFER];
69 ulg written;
70 size_t chunk;
71
72 if (archivesize) {
73 LONG2CHARS(buf, HUNK_DEBUG);
74 written = (archivesize + 3) / 4;
75 LONG2CHARS(buf + 4, written);
76 if (fwrite(buf, 1, 8, out) < 8) {
77 printf("Error writing in-between data to %s\n", outname);
78 return false;
79 }
80 totalwritten += 8;
81 }
82 written = 0;
83 do {
84 chunk = fread(buf, 1, COPYBUFFER, inn);
85 if (ferror(inn)) {
86 printf("Error reading data from %s\n", inname);
87 return false;
88 }
89 if (!archivesize && !written) { /* true only for first block read */
90 if (CHARS2LONG(buf) != HUNK_HEADER) {
91 printf("%s is not an Amiga executable.\n", inname);
92 return false;
93 }
94 }
95 if (fwrite(buf, 1, chunk, out) < chunk) {
96 printf("Error writing %s to %s\n", archivesize ? "archive data" :
97 "self-extractor code", outname);
98 return false;
99 }
100 written += chunk;
101 totalwritten += chunk;
102 } while (!feof(inn));
103 if (archivesize) {
104 if (written != archivesize) {
105 printf("Wrong number of bytes copied from archive %s\n", outname);
106 return false;
107 }
108 LONG2CHARS(buf, 0);
109 chunk = 3 - (written + 3) % 4;
110 LONG2CHARS(buf + chunk, HUNK_END);
111 chunk += 4;
112 if (fwrite(buf, 1, chunk, out) < chunk) {
113 printf("Error writing end-marker data to %s\n", outname);
114 return false;
115 }
116 totalwritten += chunk;
117 }
118 return true;
119}
120
121
122void main(int argc, char **argv)
123{
124 FILE *out, *arch, *tool;
125 char *toolname = argv[3];
126 struct stat ss;
127 int ret;
128 ulg archivesize;
129
130 if (argc < 3 || argc > 4) {
131 printf("Usage: %s <result-file> <zip-archive> [<self-extractor-"
132 "program>]\nThe third arg defaults to \"UnZipSFX\" in the"
133 " current dir or C:.\n", argv[0]);
134 exit(20);
135 }
136 if (!(arch = fopen(argv[2], "rb"))) {
137 printf("Could not find archive file %s\n", argv[2]);
138 exit(10);
139 }
140 if (stat(argv[2], &ss) || !(archivesize = ss.st_size)) {
141 fclose(arch);
142 printf("Could not check size of archive %s, or file is empty.\n",
143 argv[2]);
144 exit(10);
145 }
146 if (argc < 4)
147 toolname = "UnZipSFX";
148 if (!(tool = fopen(toolname, "rb"))) {
149 BPTR lk = Lock("C:", ACCESS_READ);
150 BPTR ocd = lk ? CurrentDir(lk) : 0;
151 if (!(tool = fopen(toolname, "rb"))) {
152 fclose(arch);
153 printf("Could not find self-extractor program %s\n", toolname);
154 if (lk)
155 UnLock(CurrentDir(ocd));
156 exit(10);
157 }
158 if (lk)
159 UnLock(CurrentDir(ocd));
160 }
161 if (!(out = fopen(argv[1], "wb"))) {
162 fclose(arch);
163 fclose(tool);
164 printf("Could not create output file %s\n", argv[1]);
165 exit(10);
166 }
167 ret = CopyData(out, tool, 0, argv[1], toolname)
168 && CopyData(out, arch, archivesize, argv[1], argv[2]) ? 0 : 10;
169 fclose(out);
170 fclose(arch);
171 fclose(tool);
172 if (ret) {
173 printf("Deleting %s\n", argv[1]);
174 remove(argv[1]);
175 } else
176 printf("%s successfully written, size %lu bytes.\n",
177 argv[1], totalwritten);
178 exit(ret);
179}
180
181
182#if (defined(AZTEC_C) && defined(MCH_AMIGA))
183void _wb_parse(void) { } /* avoid unneeded infrastructure */
184#endif
Note: See TracBrowser for help on using the repository browser.