Annotation of hatari/tools/hmsa/hmsa.c, revision 1.1.1.8

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.3   root       53: extern 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:  */
                     65: extern void Log_AlertDlg(LOGTYPE nType, const char *psFormat, ...)
                     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 */
        !            93: extern bool IPF_FileNameIsIPF(const char *pszFileName, bool bAllowGZ)
        !            94: {
        !            95:        return FALSE;
        !            96: }
        !            97: extern bool STX_FileNameIsSTX(const char *pszFileName, bool bAllowGZ);         /* function prototype */
        !            98: extern bool STX_FileNameIsSTX(const char *pszFileName, bool bAllowGZ)
        !            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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.