Annotation of hatari/src/zip.c, revision 1.1.1.14

1.1       root        1: /*
1.1.1.2   root        2:   Hatari - zip.c
                      3: 
1.1.1.11  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: 
1.1.1.4   root        7:   Zipped disk support, uses zlib
1.1       root        8: */
1.1.1.9   root        9: const char ZIP_fileid[] = "Hatari zip.c : " __DATE__ " " __TIME__;
1.1       root       10: 
1.1.1.14! root       11: #include "main.h"
1.1       root       12: #include <unistd.h>
                     13: #include <dirent.h>
1.1.1.5   root       14: #include <sys/types.h>
1.1.1.14! root       15: #if HAVE_ZLIB_H
1.1.1.2   root       16: #include <zlib.h>
1.1.1.14! root       17: #endif
1.1.1.2   root       18: 
                     19: #include "dim.h"
                     20: #include "file.h"
                     21: #include "floppy.h"
1.1.1.12  root       22: #include "floppy_ipf.h"
                     23: #include "floppy_stx.h"
1.1.1.3   root       24: #include "log.h"
1.1.1.2   root       25: #include "msa.h"
                     26: #include "st.h"
1.1.1.9   root       27: #include "str.h"
1.1       root       28: #include "unzip.h"
                     29: #include "zip.h"
                     30: 
1.1.1.5   root       31: #ifdef QNX
                     32: #include <sys/dir.h>
                     33: #define dirent direct
                     34: #endif
                     35: 
1.1       root       36: /* #define SAVE_TO_ZIP_IMAGES */
                     37: 
                     38: #define ZIP_PATH_MAX  256
                     39: 
1.1.1.12  root       40: #if HAVE_LIBZ
1.1.1.2   root       41: 
1.1.1.5   root       42: /* Possible disk image extensions to scan for */
                     43: static const char * const pszDiskNameExts[] =
                     44: {
1.1.1.12  root       45:        ".msa",
                     46:        ".st",
                     47:        ".dim",
                     48:        ".ipf",
                     49:        ".raw",
                     50:        ".ctr",
                     51:        ".stx",
                     52:        NULL
1.1.1.5   root       53: };
                     54: 
                     55: 
1.1.1.2   root       56: /*-----------------------------------------------------------------------*/
1.1.1.6   root       57: /**
1.1.1.9   root       58:  * Does filename end with a .ZIP extension? If so, return true.
1.1.1.6   root       59:  */
1.1.1.7   root       60: bool ZIP_FileNameIsZIP(const char *pszFileName)
1.1.1.2   root       61: {
1.1.1.5   root       62:        return File_DoesFileExtensionMatch(pszFileName,".zip");
1.1.1.2   root       63: }
1.1       root       64: 
                     65: 
1.1.1.2   root       66: /*-----------------------------------------------------------------------*/
1.1.1.6   root       67: /**
                     68:  * Check if a file name contains a slash or backslash and return its position.
                     69:  */
                     70: static int Zip_FileNameHasSlash(const char *fn)
1.1       root       71: {
1.1.1.5   root       72:        int i=0;
                     73: 
                     74:        while (fn[i] != '\0')
                     75:        {
                     76:                if (fn[i] == '\\' || fn[i] == '/')
                     77:                        return i;
                     78:                i++;
                     79:        }
                     80:        return -1;
1.1       root       81: }
                     82: 
1.1.1.2   root       83: 
1.1       root       84: /*-----------------------------------------------------------------------*/
1.1.1.6   root       85: /**
                     86:  * Returns a list of files from a zip file. returns NULL on failure,
                     87:  * returns a pointer to an array of strings if successful. Sets nfiles
                     88:  * to the number of files.
                     89:  */
                     90: zip_dir *ZIP_GetFiles(const char *pszFileName)
1.1       root       91: {
1.1.1.5   root       92:        int nfiles;
                     93:        unsigned int i;
                     94:        unz_global_info gi;
                     95:        int err;
                     96:        unzFile uf;
                     97:        char **filelist;
                     98:        unz_file_info file_info;
                     99:        char filename_inzip[ZIP_PATH_MAX];
1.1.1.13  root      100:        zip_dir *zd = NULL;
1.1.1.5   root      101: 
                    102:        uf = unzOpen(pszFileName);
                    103:        if (uf == NULL)
                    104:        {
                    105:                Log_Printf(LOG_ERROR, "ZIP_GetFiles: Cannot open %s\n", pszFileName);
                    106:                return NULL;
                    107:        }
1.1.1.3   root      108: 
1.1.1.5   root      109:        err = unzGetGlobalInfo(uf,&gi);
                    110:        if (err != UNZ_OK)
                    111:        {
                    112:                Log_Printf(LOG_ERROR, "Error %d with zipfile in unzGetGlobalInfo \n",err);
                    113:                return NULL;
                    114:        }
                    115: 
                    116:        /* allocate a file list */
                    117:        filelist = (char **)malloc(gi.number_entry*sizeof(char *));
                    118:        if (!filelist)
                    119:        {
                    120:                perror("ZIP_GetFiles");
1.1.1.13  root      121:                unzClose(uf);
1.1.1.5   root      122:                return NULL;
                    123:        }
                    124: 
                    125:        nfiles = gi.number_entry;  /* set the number of files */
                    126: 
                    127:        for (i = 0; i < gi.number_entry; i++)
                    128:        {
                    129:                err = unzGetCurrentFileInfo(uf, &file_info, filename_inzip, ZIP_PATH_MAX, NULL, 0, NULL, 0);
                    130:                if (err != UNZ_OK)
                    131:                {
1.1.1.13  root      132:                        Log_Printf(LOG_ERROR, "ZIP_GetFiles: Error in ZIP-file\n");
                    133:                        goto cleanup;
1.1.1.5   root      134:                }
                    135: 
                    136:                filelist[i] = (char *)malloc(strlen(filename_inzip) + 1);
                    137:                if (!filelist[i])
                    138:                {
                    139:                        perror("ZIP_GetFiles");
1.1.1.13  root      140:                        goto cleanup;
1.1.1.5   root      141:                }
                    142: 
                    143:                strcpy(filelist[i], filename_inzip);
                    144:                if ((i+1) < gi.number_entry)
                    145:                {
                    146:                        err = unzGoToNextFile(uf);
                    147:                        if (err != UNZ_OK)
                    148:                        {
                    149:                                Log_Printf(LOG_ERROR, "ZIP_GetFiles: Error in ZIP-file\n");
1.1.1.13  root      150:                                goto cleanup;
1.1.1.5   root      151:                        }
                    152:                }
                    153:        }
                    154: 
                    155:        zd = (zip_dir *)malloc(sizeof(zip_dir));
1.1.1.13  root      156:        if (zd)
                    157:        {
                    158:                zd->names = filelist;
                    159:                zd->nfiles = nfiles;
                    160:        }
                    161:        else
1.1.1.5   root      162:        {
                    163:                perror("ZIP_GetFiles");
1.1.1.13  root      164:        }
                    165: 
                    166: cleanup:
                    167:        unzClose(uf);
                    168:        if (!zd && filelist)
                    169:        {
                    170:                /* deallocate memory */
                    171:                for (; i > 0; i--)
                    172:                        free(filelist[i]);
1.1.1.5   root      173:                free(filelist);
                    174:        }
                    175: 
                    176:        return zd;
1.1       root      177: }
                    178: 
1.1.1.2   root      179: 
                    180: /*-----------------------------------------------------------------------*/
1.1.1.6   root      181: /**
                    182:  * Free the memory that has been allocated for a zip_dir.
                    183:  */
1.1.1.2   root      184: void ZIP_FreeZipDir(zip_dir *f_zd)
                    185: {
1.1.1.5   root      186:        while (f_zd->nfiles > 0)
                    187:        {
                    188:                f_zd->nfiles--;
                    189:                free(f_zd->names[f_zd->nfiles]);
                    190:                f_zd->names[f_zd->nfiles] = NULL;
                    191:        }
                    192:        free(f_zd->names);
                    193:        f_zd->names = NULL;
                    194:        free(f_zd);
1.1.1.2   root      195: }
                    196: 
                    197: 
1.1       root      198: /*-----------------------------------------------------------------------*/
1.1.1.6   root      199: /**
1.1.1.10  root      200:  * Free the memory that has been allocated for fentries.
                    201:  */
                    202: static void ZIP_FreeFentries(struct dirent **fentries, int entries)
                    203: {
                    204:        while (entries > 0)
                    205:        {
                    206:                entries--;
                    207:                free(fentries[entries]);
                    208:        }
                    209:        free(fentries);
                    210: }
                    211: 
                    212: 
                    213: /*-----------------------------------------------------------------------*/
                    214: /**
1.1.1.6   root      215:  *   Returns a list of files from the directory (dir) in a zip file list (zip)
                    216:  *   sets entries to the number of entries and returns a dirent structure, or
                    217:  *   NULL on failure. NOTE: only f_name is set in the dirent structures. 
                    218:  */
                    219: struct dirent **ZIP_GetFilesDir(const zip_dir *zip, const char *dir, int *entries)
1.1       root      220: {
1.1.1.5   root      221:        int i,j;
                    222:        zip_dir *files;
                    223:        char *temp;
1.1.1.7   root      224:        bool flag;
1.1.1.5   root      225:        int slash;
                    226:        struct dirent **fentries;
                    227: 
                    228:        files = (zip_dir *)malloc(sizeof(zip_dir));
                    229:        if (!files)
                    230:        {
                    231:                perror("ZIP_GetFilesDir");
                    232:                return NULL;
                    233:        }
                    234: 
                    235:        files->names = (char **)malloc((zip->nfiles + 1) * sizeof(char *));
                    236:        if (!files->names)
                    237:        {
                    238:                perror("ZIP_GetFilesDir");
                    239:                free(files);
                    240:                return NULL;
                    241:        }
                    242: 
                    243:        /* add ".." directory */
                    244:        files->nfiles = 1;
                    245:        temp = (char *)malloc(4);
                    246:        if (!temp)
1.1.1.10  root      247:        {
                    248:                ZIP_FreeZipDir(files);
1.1.1.5   root      249:                return NULL;
1.1.1.10  root      250:        }
1.1.1.5   root      251:        temp[0] = temp[1] = '.';
                    252:        temp[2] = '/';
                    253:        temp[3] = '\0';
                    254:        files->names[0] = temp;
                    255: 
                    256:        for (i = 0; i < zip->nfiles; i++)
                    257:        {
                    258:                if (strlen(zip->names[i]) > strlen(dir))
1.1       root      259:                {
1.1.1.5   root      260:                        if (strncasecmp(zip->names[i], dir, strlen(dir)) == 0)
1.1       root      261:                        {
1.1.1.5   root      262:                                temp = zip->names[i];
                    263:                                temp = (char *)(temp + strlen(dir));
                    264:                                if (temp[0] != '\0')
                    265:                                {
                    266:                                        if ((slash=Zip_FileNameHasSlash(temp)) > 0)
                    267:                                        {
                    268:                                                /* file is in a subdirectory, add this subdirectory if it doesn't exist in the list */
1.1.1.9   root      269:                                                flag = false;
1.1.1.5   root      270:                                                for (j = files->nfiles-1; j > 0; j--)
                    271:                                                {
                    272:                                                        if (strncasecmp(temp, files->names[j], slash+1) == 0)
1.1.1.9   root      273:                                                                flag = true;
1.1.1.5   root      274:                                                }
1.1.1.9   root      275:                                                if (flag == false)
1.1.1.5   root      276:                                                {
1.1.1.6   root      277:                                                        files->names[files->nfiles] = (char *)malloc(slash+2);
1.1.1.5   root      278:                                                        if (!files->names[files->nfiles])
                    279:                                                        {
                    280:                                                                perror("ZIP_GetFilesDir");
1.1.1.10  root      281:                                                                ZIP_FreeZipDir(files);
1.1.1.5   root      282:                                                                return NULL;
                    283:                                                        }
                    284:                                                        strncpy(files->names[files->nfiles], temp, slash+1);
                    285:                                                        ((char *)files->names[files->nfiles])[slash+1] = '\0';
                    286:                                                        files->nfiles++;
                    287:                                                }
                    288:                                        }
                    289:                                        else
                    290:                                        {
                    291:                                                /* add a filename */
                    292:                                                files->names[files->nfiles] = (char *)malloc(strlen(temp)+1);
                    293:                                                if (!files->names[files->nfiles])
                    294:                                                {
                    295:                                                        perror("ZIP_GetFilesDir");
1.1.1.10  root      296:                                                        ZIP_FreeZipDir(files);
1.1.1.5   root      297:                                                        return NULL;
                    298:                                                }
                    299:                                                strncpy(files->names[files->nfiles], temp, strlen(temp));
                    300:                                                ((char *)files->names[files->nfiles])[strlen(temp)] = '\0';
                    301:                                                files->nfiles++;
                    302:                                        }
                    303:                                }
1.1       root      304:                        }
                    305:                }
                    306:        }
                    307: 
1.1.1.5   root      308:        /* copy to a dirent structure */
                    309:        *entries = files->nfiles;
                    310:        fentries = (struct dirent **)malloc(sizeof(struct dirent *)*files->nfiles);
                    311:        if (!fentries)
                    312:        {
                    313:                perror("ZIP_GetFilesDir");
                    314:                ZIP_FreeZipDir(files);
                    315:                return NULL;
                    316:        }
                    317:        for (i = 0; i < files->nfiles; i++)
                    318:        {
                    319:                fentries[i] = (struct dirent *)malloc(sizeof(struct dirent));
                    320:                if (!fentries[i])
                    321:                {
                    322:                        perror("ZIP_GetFilesDir");
1.1.1.10  root      323:                        ZIP_FreeFentries(fentries, i+1);
1.1.1.12  root      324:                        ZIP_FreeZipDir(files);
1.1.1.5   root      325:                        return NULL;
                    326:                }
                    327:                strcpy(fentries[i]->d_name, files->names[i]);
                    328:        }
1.1.1.3   root      329: 
1.1.1.5   root      330:        ZIP_FreeZipDir(files);
1.1.1.3   root      331: 
1.1.1.5   root      332:        return fentries;
1.1       root      333: }
                    334: 
1.1.1.3   root      335: 
1.1       root      336: /*-----------------------------------------------------------------------*/
1.1.1.6   root      337: /**
                    338:  * Check an image file in the archive, return the uncompressed length
                    339:  */
1.1.1.12  root      340: static long ZIP_CheckImageFile(unzFile uf, char *filename, int namelen, int *pImageType)
1.1       root      341: {
1.1.1.5   root      342:        unz_file_info file_info;
                    343: 
                    344:        if (unzLocateFile(uf,filename, 0) != UNZ_OK)
                    345:        {
1.1.1.6   root      346:                Log_Printf(LOG_ERROR, "Error: File \"%s\" not found in the archive!\n", filename);
1.1.1.5   root      347:                return -1;
                    348:        }
                    349: 
1.1.1.6   root      350:        if (unzGetCurrentFileInfo(uf, &file_info, filename, namelen, NULL, 0, NULL, 0) != UNZ_OK)
1.1.1.5   root      351:        {
1.1.1.6   root      352:                Log_Printf(LOG_ERROR, "Error with zipfile in unzGetCurrentFileInfo\n");
1.1.1.5   root      353:                return -1;
                    354:        }
                    355: 
1.1.1.12  root      356:        /* check for .stx, .ipf, .msa, .dim or .st extension */
                    357:        if (STX_FileNameIsSTX(filename, false))
                    358:        {
                    359:                *pImageType = FLOPPY_IMAGE_TYPE_STX;
                    360:                return file_info.uncompressed_size;
                    361:        }
                    362: 
                    363:        if (IPF_FileNameIsIPF(filename, false))
                    364:        {
                    365:                *pImageType = FLOPPY_IMAGE_TYPE_IPF;
                    366:                return file_info.uncompressed_size;
                    367:        }
                    368: 
1.1.1.9   root      369:        if (MSA_FileNameIsMSA(filename, false))
1.1.1.5   root      370:        {
1.1.1.12  root      371:                *pImageType = FLOPPY_IMAGE_TYPE_MSA;
1.1.1.5   root      372:                return file_info.uncompressed_size;
                    373:        }
                    374: 
1.1.1.9   root      375:        if (ST_FileNameIsST(filename, false))
1.1.1.5   root      376:        {
1.1.1.12  root      377:                *pImageType = FLOPPY_IMAGE_TYPE_ST;
1.1.1.5   root      378:                return file_info.uncompressed_size;
                    379:        }
                    380: 
1.1.1.9   root      381:        if (DIM_FileNameIsDIM(filename, false))
1.1.1.5   root      382:        {
1.1.1.12  root      383:                *pImageType = FLOPPY_IMAGE_TYPE_DIM;
1.1.1.5   root      384:                return file_info.uncompressed_size;
                    385:        }
                    386: 
1.1.1.12  root      387:        Log_Printf(LOG_ERROR, "Not an .ST, .MSA, .DIM, .IPF or .STX file.\n");
1.1.1.5   root      388:        return 0;
                    389: }
                    390: 
                    391: /*-----------------------------------------------------------------------*/
1.1.1.6   root      392: /**
                    393:  * Return the first matching file in a zip, or NULL on failure.
                    394:  * String buffer size is ZIP_PATH_MAX
                    395:  */
                    396: static char *ZIP_FirstFile(const char *filename, const char * const ppsExts[])
1.1.1.5   root      397: {
                    398:        zip_dir *files;
                    399:        int i, j;
                    400:        char *name;
                    401: 
                    402:        files = ZIP_GetFiles(filename);
                    403:        if (files == NULL)
                    404:                return NULL;
                    405: 
                    406:        name = malloc(ZIP_PATH_MAX);
                    407:        if (!name)
                    408:        {
                    409:                perror("ZIP_FirstFile");
1.1.1.12  root      410:                ZIP_FreeZipDir(files);
1.1.1.5   root      411:                return NULL;
                    412:        }
                    413: 
                    414:        /* Do we have to scan for a certain extension? */
                    415:        if (ppsExts)
                    416:        {
                    417:                name[0] = '\0';
                    418:                for(i = files->nfiles-1; i >= 0; i--)
                    419:                {
                    420:                        for (j = 0; ppsExts[j] != NULL; j++)
                    421:                        {
                    422:                                if (File_DoesFileExtensionMatch(files->names[i], ppsExts[j]))
                    423:                                {
                    424:                                        strncpy(name, files->names[i], ZIP_PATH_MAX);
                    425:                                        break;
                    426:                                }
                    427:                        }
                    428:                }
                    429:        }
                    430:        else
                    431:        {
                    432:                /* There was no extension given -> use the very first name */
                    433:                strncpy(name, files->names[0], ZIP_PATH_MAX);
                    434:        }
1.1       root      435: 
1.1.1.5   root      436:        /* free the files */
                    437:        ZIP_FreeZipDir(files);
                    438: 
                    439:        if (name[0] == '\0')
1.1.1.12  root      440:        {
                    441:                free(name);
1.1.1.5   root      442:                return NULL;
1.1.1.12  root      443:        }
                    444: 
1.1.1.5   root      445:        return name;
1.1       root      446: }
                    447: 
                    448: 
                    449: /*-----------------------------------------------------------------------*/
1.1.1.6   root      450: /**
                    451:  * Extract a file (filename) from a ZIP-file (uf), the number of 
                    452:  * bytes to uncompress is size. Returns a pointer to a buffer containing
                    453:  * the uncompressed data, or NULL.
                    454:  */
                    455: static void *ZIP_ExtractFile(unzFile uf, const char *filename, uLong size)
1.1       root      456: {
1.1.1.5   root      457:        int err = UNZ_OK;
                    458:        char filename_inzip[ZIP_PATH_MAX];
                    459:        void* buf;
                    460:        uInt size_buf;
                    461:        unz_file_info file_info;
                    462: 
                    463: 
                    464:        if (unzLocateFile(uf,filename, 0) != UNZ_OK)
                    465:        {
                    466:                Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not find file in archive\n");
                    467:                return NULL;
                    468:        }
                    469: 
                    470:        err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
                    471: 
                    472:        if (err != UNZ_OK)
                    473:        {
                    474:                Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not get file info\n");
                    475:                return NULL;
                    476:        }
                    477: 
                    478:        size_buf = size;
                    479:        buf = malloc(size_buf);
                    480:        if (!buf)
                    481:        {
                    482:                perror("ZIP_ExtractFile");
                    483:                return NULL;
                    484:        }
                    485: 
                    486:        err = unzOpenCurrentFile(uf);
                    487:        if (err != UNZ_OK)
                    488:        {
                    489:                Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not open file\n");
1.1.1.10  root      490:                free(buf);
1.1.1.5   root      491:                return NULL;
                    492:        }
                    493: 
                    494:        do
                    495:        {
                    496:                err = unzReadCurrentFile(uf,buf,size_buf);
                    497:                if (err < 0)
                    498:                {
                    499:                        Log_Printf(LOG_ERROR, "ZIP_ExtractFile: could not read file\n");
                    500:                        return NULL;
                    501:                }
                    502:        }
                    503:        while (err > 0);
                    504: 
                    505:        return buf;
1.1       root      506: }
                    507: 
1.1.1.5   root      508: 
1.1       root      509: /*-----------------------------------------------------------------------*/
1.1.1.6   root      510: /**
                    511:  * Load disk image from a .ZIP archive into memory, set  the number
                    512:  * of bytes loaded into pImageSize and return the data or NULL on error.
                    513:  */
1.1.1.12  root      514: Uint8 *ZIP_ReadDisk(int Drive, const char *pszFileName, const char *pszZipPath, long *pImageSize, int *pImageType)
1.1       root      515: {
1.1.1.5   root      516:        uLong ImageSize=0;
                    517:        unzFile uf=NULL;
                    518:        Uint8 *buf;
1.1.1.6   root      519:        char *path;
1.1.1.5   root      520:        Uint8 *pDiskBuffer = NULL;
                    521: 
                    522:        *pImageSize = 0;
1.1.1.12  root      523:        *pImageType = FLOPPY_IMAGE_TYPE_NONE;
1.1.1.5   root      524: 
                    525:        uf = unzOpen(pszFileName);
                    526:        if (uf == NULL)
                    527:        {
                    528:                Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
                    529:                return NULL;
                    530:        }
1.1       root      531: 
1.1.1.5   root      532:        if (pszZipPath == NULL || pszZipPath[0] == 0)
                    533:        {
1.1.1.6   root      534:                path = ZIP_FirstFile(pszFileName, pszDiskNameExts);
                    535:                if (path == NULL)
1.1.1.5   root      536:                {
                    537:                        Log_Printf(LOG_ERROR, "Cannot open %s\n", pszFileName);
                    538:                        unzClose(uf);
                    539:                        return NULL;
                    540:                }
1.1.1.6   root      541:        }
                    542:        else
                    543:        {
                    544:                path = malloc(ZIP_PATH_MAX);
                    545:                if (path == NULL)
                    546:                {
                    547:                        perror("ZIP_ReadDisk");
                    548:                        unzClose(uf);
                    549:                        return NULL;
                    550:                }
                    551:                strncpy(path, pszZipPath, ZIP_PATH_MAX);
                    552:                path[ZIP_PATH_MAX-1] = '\0';
1.1.1.5   root      553:        }
1.1.1.2   root      554: 
1.1.1.12  root      555:        ImageSize = ZIP_CheckImageFile(uf, path, ZIP_PATH_MAX, pImageType);
1.1.1.5   root      556:        if (ImageSize <= 0)
                    557:        {
                    558:                unzClose(uf);
1.1.1.6   root      559:                free(path);
1.1.1.5   root      560:                return NULL;
                    561:        }
                    562: 
                    563:        /* extract to buf */
1.1.1.6   root      564:        buf = ZIP_ExtractFile(uf, path, ImageSize);
                    565: 
1.1.1.5   root      566:        unzCloseCurrentFile(uf);
                    567:        unzClose(uf);
1.1.1.6   root      568:        free(path);
                    569:        path = NULL;
                    570: 
1.1.1.5   root      571:        if (buf == NULL)
                    572:        {
                    573:                return NULL;  /* failed extraction, return error */
                    574:        }
                    575: 
1.1.1.12  root      576:        switch(*pImageType) {
                    577:        case FLOPPY_IMAGE_TYPE_IPF:
                    578: #ifndef HAVE_CAPSIMAGE
                    579:                Log_AlertDlg(LOG_ERROR, "This version of Hatari was not built with IPF support, this disk image can't be handled.");
                    580:                return NULL;
                    581: #else
                    582:                /* return buffer */
                    583:                pDiskBuffer = buf;
                    584:                break;
                    585: #endif
                    586:        case FLOPPY_IMAGE_TYPE_STX:
                    587:                /* return buffer */
                    588:                pDiskBuffer = buf;
                    589:                break;
                    590:        case FLOPPY_IMAGE_TYPE_MSA:
1.1.1.5   root      591:                /* uncompress the MSA file */
1.1.1.13  root      592:                pDiskBuffer = MSA_UnCompress(buf, (long *)&ImageSize, ImageSize);
1.1.1.6   root      593:                free(buf);
                    594:                buf = NULL;
                    595:                break;
1.1.1.12  root      596:        case FLOPPY_IMAGE_TYPE_DIM:
1.1.1.5   root      597:                /* Skip DIM header */
                    598:                ImageSize -= 32;
1.1.1.6   root      599:                memmove(buf, buf+32, ImageSize);
1.1.1.12  root      600:                /* return buffer */
                    601:                pDiskBuffer = buf;
                    602:                break;
                    603:        case FLOPPY_IMAGE_TYPE_ST:
1.1.1.6   root      604:                /* ST image => return buffer directly */
                    605:                pDiskBuffer = buf;
                    606:                break;
1.1.1.5   root      607:        }
1.1.1.6   root      608:        
                    609:        if (pDiskBuffer)
                    610:        {
1.1.1.5   root      611:                *pImageSize = ImageSize;
1.1.1.6   root      612:        }
1.1.1.5   root      613:        return pDiskBuffer;
1.1       root      614: }
                    615: 
                    616: 
                    617: /*-----------------------------------------------------------------------*/
1.1.1.6   root      618: /**
                    619:  * Load first file from a .ZIP archive into memory, and return the number
                    620:  * of bytes loaded.
                    621:  */
                    622: Uint8 *ZIP_ReadFirstFile(const char *pszFileName, long *pImageSize, const char * const ppszExts[])
1.1.1.5   root      623: {
1.1.1.13  root      624:        unzFile uf = NULL;
                    625:        Uint8 *pBuffer = NULL;
1.1.1.5   root      626:        char *pszZipPath;
                    627:        unz_file_info file_info;
                    628: 
                    629:        *pImageSize = 0;
                    630: 
                    631:        /* Open the ZIP file */
                    632:        uf = unzOpen(pszFileName);
                    633:        if (uf == NULL)
                    634:        {
                    635:                Log_Printf(LOG_ERROR, "Cannot open '%s'\n", pszFileName);
                    636:                return NULL;
                    637:        }
                    638: 
                    639:        /* Locate the first file in the ZIP archive */
                    640:        pszZipPath = ZIP_FirstFile(pszFileName, ppszExts);
                    641:        if (pszZipPath == NULL)
                    642:        {
                    643:                Log_Printf(LOG_ERROR, "Failed to locate first file in '%s'\n", pszFileName);
                    644:                unzClose(uf);
                    645:                return NULL;
                    646:        }
                    647: 
                    648:        if (unzLocateFile(uf, pszZipPath, 0) != UNZ_OK)
                    649:        {
1.1.1.6   root      650:                Log_Printf(LOG_ERROR, "Error: Can not locate '%s' in the archive!\n", pszZipPath);
1.1.1.13  root      651:                goto cleanup;
1.1.1.5   root      652:        }
                    653: 
                    654:        /* Get file information (file size!) */
                    655:        if (unzGetCurrentFileInfo(uf, &file_info, pszZipPath, ZIP_PATH_MAX, NULL, 0, NULL, 0) != UNZ_OK)
                    656:        {
                    657:                Log_Printf(LOG_ERROR, "Error with zipfile in unzGetCurrentFileInfo.\n");
1.1.1.13  root      658:                goto cleanup;
1.1.1.5   root      659:        }
                    660: 
                    661:        /* Extract to buffer */
                    662:        pBuffer = ZIP_ExtractFile(uf, pszZipPath, file_info.uncompressed_size);
1.1.1.13  root      663:        if (pBuffer)
                    664:                *pImageSize = file_info.uncompressed_size;
1.1.1.5   root      665: 
                    666:        /* And close the file */
                    667:        unzCloseCurrentFile(uf);
1.1.1.13  root      668: cleanup:
1.1.1.5   root      669:        unzClose(uf);
                    670:        free(pszZipPath);
                    671: 
                    672:        return pBuffer;
                    673: }
1.1.1.12  root      674: 
                    675: #else
                    676: 
                    677: bool ZIP_FileNameIsZIP(const char *pszFileName)
                    678: {
                    679:        return false;
                    680: }
1.1.1.13  root      681: Uint8 *ZIP_ReadDisk(int Drive, const char *name, const char *path, long *size , int *pImageType)
1.1.1.12  root      682: {
                    683:        return NULL;
                    684: }
                    685: struct dirent **ZIP_GetFilesDir(const zip_dir *zip, const char *dir, int *entries)
                    686: {
                    687:        return NULL;
                    688: }
                    689: zip_dir *ZIP_GetFiles(const char *pszFileName)
                    690: {
                    691:        return NULL;
                    692: }
                    693: void ZIP_FreeZipDir(zip_dir *f_zd)
                    694: {
                    695: }
                    696: 
                    697: #endif  /* HAVE_LIBZ */
                    698: 
                    699: /**
                    700:  * Save .ZIP file from memory buffer. Returns true if all is OK.
                    701:  *
                    702:  * Not yet implemented.
                    703:  */
                    704: bool ZIP_WriteDisk(int Drive, const char *pszFileName,unsigned char *pBuffer,int ImageSize)
                    705: {
                    706:        return false;
                    707: }

unix.superglobalmegacorp.com

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