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

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

unix.superglobalmegacorp.com

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