|
|
1.1 root 1: /*
1.1.1.5 root 2: Hatari tool: MSA and ST disk image creator and converter - hmsa.c
1.1 root 3:
1.1.1.7 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6: */
7:
8: #include <stdio.h>
9: #include <stdlib.h>
10: #include <stdarg.h>
11: #include <string.h>
12:
13: #include "hmsa.h"
1.1.1.2 root 14: #include "main.h" /* bool etc. */
1.1.1.5 root 15: #include "createBlankImage.h"
1.1 root 16: #include "file.h"
17: #include "msa.h"
18:
1.1.1.3 root 19: /* prototypes for dummy log/alert functions below */
20: #include "dialog.h"
21: #include "log.h"
1.1 root 22:
23: /**
1.1.1.5 root 24: * Print suitable output prefix based on log level
25: */
26: static void print_prefix(LOGTYPE nType)
27: {
28: const char *sType;
29: switch (nType) {
30: case LOG_FATAL:
31: case LOG_ERROR:
32: sType = "ERROR: ";
33: break;
34: case LOG_WARN:
35: sType = "WARNING: ";
36: break;
37: default:
38: return;
39: }
40: fputs(sType, stdout);
41: }
42:
1.1.1.8 root 43: /* output newline if it's missing from text */
44: static void do_newline(const char *text)
45: {
46: if (text[strlen(text)-1] != '\n')
47: fputs("\n", stdout);
48: }
49:
1.1.1.5 root 50: /**
51: * Output Hatari log string.
1.1 root 52: */
1.1.1.9 ! root 53: void Log_Printf(LOGTYPE nType, const char *psFormat, ...)
1.1 root 54: {
55: va_list argptr;
1.1.1.5 root 56: print_prefix(nType);
57: va_start(argptr, psFormat);
58: vfprintf(stdout, psFormat, argptr);
59: va_end(argptr);
1.1 root 60: }
61:
1.1.1.5 root 62: /**
63: * Output Hatari Alert dialog string.
64: */
1.1.1.9 ! root 65: void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...)
1.1.1.5 root 66: {
67: va_list argptr;
68: print_prefix(nType);
69: va_start(argptr, psFormat);
70: vfprintf(stdout, psFormat, argptr);
71: va_end(argptr);
1.1.1.8 root 72: do_newline(psFormat);
1.1.1.5 root 73: }
1.1 root 74:
75: /**
1.1.1.5 root 76: * Output Hatari Query dialog string.
1.1 root 77: */
78: int DlgAlert_Query(const char *text)
79: {
80: puts(text);
1.1.1.8 root 81: do_newline(text);
1.1 root 82: return TRUE;
83: }
84:
1.1.1.8 root 85:
86: /**
87: * ../src/file.c requires zip.c, which calls IPF_FileNameIsIPF
88: * We create an empty function to replace it, as we don't use IPF here
89: * and don't want to compile with all the IPF related files.
90: * We do it also for STX.
91: */
92: extern bool IPF_FileNameIsIPF(const char *pszFileName, bool bAllowGZ); /* function prototype */
1.1.1.9 ! root 93: bool IPF_FileNameIsIPF(const char *pszFileName, bool bAllowGZ)
1.1.1.8 root 94: {
95: return FALSE;
96: }
97: extern bool STX_FileNameIsSTX(const char *pszFileName, bool bAllowGZ); /* function prototype */
1.1.1.9 ! root 98: bool STX_FileNameIsSTX(const char *pszFileName, bool bAllowGZ)
1.1.1.8 root 99: {
100: return FALSE;
101: }
102:
103:
1.1.1.5 root 104: /**
105: * Create MSA or ST image of requested size.
106: * return error string or NULL for success.
107: */
108: static const char* create_image(const char *filename, const char *sizeid)
109: {
110: int tracks, sectors, sides;
111: tracks = 80;
112:
113: if (strcasecmp(sizeid, "ss") == 0) {
114: sides = 1;
115: sectors = 9;
116: } else if (strcasecmp(sizeid, "ds") == 0) {
117: sides = 2;
118: sectors = 9;
119: } else if (strcasecmp(sizeid, "hd") == 0) {
120: sides = 2;
121: sectors = 18;
122: } else if (strcasecmp(sizeid, "ed") == 0) {
123: sides = 2;
124: sectors = 36;
125: } else {
126: return "ERROR: given disk size isn't one of supported ones!\n";
127: }
128: if (CreateBlankImage_CreateFile(filename, tracks, sectors, sides)) {
129: return NULL;
130: }
131: return "ERROR: Disk creation failed.\n";
132: }
133:
134: /**
135: * Print program usage
136: */
137: static void usage(const char *name)
138: {
139: printf("\n\
140: Hatari MSA (Magic Shadow Archiver) / ST disk image creator & converter v0.3.\n\
141: \n\
142: Usage: %s FILENAME [DISK SIZE]\n\
143: \n\
144: If you give only one parameter - the file name of an existing MSA\n\
145: or ST disk image, this image will be converted to the other disk image\n\
146: format under a suitable new file name. Disk image format is recognized\n\
147: based on the file name extension (.msa or .st).\n\
148: \n\
149: If the given file doesn't exist and you give also a disk size\n\
150: (SS, DS, HD, ED), an empty disk of the given size will be created.\n\
151: \n\
1.1.1.7 root 152: This software is distributed under the GNU General Public License, version 2\n\
153: or at your option any later version. Please read the file gpl.txt for details.\n\
1.1.1.5 root 154: \n",
155: name);
156: }
1.1 root 157:
158: /**
1.1.1.5 root 159: * Command line argument parsing and new disk creation
1.1 root 160: */
161: int main(int argc, char *argv[])
162: {
1.1.1.5 root 163: bool isMsa;
1.1 root 164: int retval;
1.1.1.5 root 165: long disksize;
166: unsigned char *diskbuf;
167: const char *srcfile, *srcdot;
168: char *dstfile, *dstdot;
1.1.1.8 root 169: int ImageType;
170: int drive;
1.1.1.5 root 171:
172: if(argc < 2 || argv[1][0] == '-') {
173: usage(argv[0]);
1.1 root 174: return 0;
175: }
176:
1.1.1.5 root 177: srcfile = argv[1];
1.1.1.6 root 178: srcdot = strrchr(srcfile, '.');
1.1.1.5 root 179: if(srcdot == NULL) {
180: usage(argv[0]);
181: fprintf(stderr, "ERROR: extension missing for file name %s!\n", argv[1]);
1.1 root 182: return -1;
183: }
184:
1.1.1.5 root 185: if (strcasecmp(srcdot, ".msa") == 0) {
186: isMsa = true;
187: } else if (strcasecmp(srcdot, ".st") == 0) {
188: isMsa = false;
189: } else {
190: usage(argv[0]);
191: fprintf(stderr, "ERROR: unrecognized file name extension %s (not .msa or .st)!\n", srcdot);
1.1 root 192: return -1;
193: }
194:
1.1.1.5 root 195: if (!File_Exists(srcfile)) {
196: const char *errstr;
197: if (argc != 3) {
198: usage(argv[0]);
199: fprintf(stderr, "ERROR: disk size for the new disk image not given!\n");
1.1 root 200: return -1;
201: }
1.1.1.5 root 202: errstr = create_image(srcfile, argv[2]);
203: if (errstr) {
204: usage(argv[0]);
205: fputs(errstr, stderr);
1.1 root 206: return -1;
207: }
1.1.1.5 root 208: return 0;
209: }
1.1 root 210:
1.1.1.5 root 211: dstfile = malloc(strlen(srcfile) + 6);
212: if (dstfile == NULL) {
213: fprintf(stderr, "ERROR: No memory for new disk name!\n");
214: return -1;
215: }
1.1 root 216:
1.1.1.5 root 217: strcpy(dstfile, srcfile);
1.1.1.6 root 218: dstdot = strrchr(dstfile, '.');
1.1.1.5 root 219: if (isMsa) {
220: /* Convert MSA to ST disk image */
221: strcpy(dstdot, ".st");
222: } else {
223: /* Convert ST to MSA disk image */
224: strcpy(dstdot, ".msa");
225: }
1.1 root 226:
1.1.1.5 root 227: if (File_Exists(dstfile)) {
228: fprintf(stderr, "ERROR: Destination disk image %s exists already!\n", dstfile);
229: free(dstfile);
230: return -1;
231: }
1.1.1.8 root 232:
233: drive = 0; /* drive is not used for ST/MSA/DIM, set it to 0 */
234:
1.1.1.5 root 235: if (isMsa) {
236: /* Read the source disk image */
1.1.1.8 root 237: diskbuf = MSA_ReadDisk(drive, srcfile, &disksize, &ImageType);
1.1.1.5 root 238: if (!diskbuf || disksize < 512*8) {
239: fprintf(stderr, "ERROR: could not read MSA disk %s!\n", srcfile);
240: retval = -1;
241: } else {
242: printf("Converting %s to %s (%li Bytes).\n", srcfile, dstfile, disksize);
243: retval = File_Save(dstfile, diskbuf, disksize, FALSE);
244: }
245: } else {
246: /* Just read disk image directly into buffer */
247: disksize = 0;
248: diskbuf = File_Read(srcfile, &disksize, NULL);
249: if (!diskbuf || disksize < 512*8) {
250: fprintf(stderr, "ERROR: could not read ST disk %s!\n", srcfile);
251: retval = -1;
252: } else {
253: printf("Converting %s to %s (%li Bytes).\n", srcfile, dstfile, disksize);
1.1.1.8 root 254: retval = MSA_WriteDisk(drive, dstfile, diskbuf, disksize);
1.1.1.5 root 255: }
1.1 root 256: }
257:
1.1.1.5 root 258: if (diskbuf) {
259: free(diskbuf);
260: }
261: free(dstfile);
1.1 root 262:
263: return retval;
264: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.