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

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

unix.superglobalmegacorp.com

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