Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 650 git-svn-id: svn://10.65.10.50/trunk@14148 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1063 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1063 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*---------------------------------------------------------------------------*
 | 
						|
 |              PDFlib - A library for generating PDF on the fly             |
 | 
						|
 +---------------------------------------------------------------------------+
 | 
						|
 | Copyright (c) 1997-2005 Thomas Merz and PDFlib GmbH. All rights reserved. |
 | 
						|
 +---------------------------------------------------------------------------+
 | 
						|
 |                                                                           |
 | 
						|
 |    This software is subject to the PDFlib license. It is NOT in the       |
 | 
						|
 |    public domain. Extended versions and commercial licenses are           |
 | 
						|
 |    available, please check http://www.pdflib.com.                         |
 | 
						|
 |                                                                           |
 | 
						|
 *---------------------------------------------------------------------------*/
 | 
						|
 | 
						|
/* $Id: pc_file.c,v 1.2 2006-07-11 13:10:33 alex Exp $
 | 
						|
 *
 | 
						|
 * Various file routines
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
#include "pc_util.h"
 | 
						|
#include "pc_md5.h"
 | 
						|
#include "pc_file.h"
 | 
						|
 | 
						|
 | 
						|
/* headers for getpid() or _getpid().
 | 
						|
*/
 | 
						|
#if defined(WIN32)
 | 
						|
#define WIN32_LEAN_AND_MEAN
 | 
						|
#include <windows.h>
 | 
						|
#include <process.h>
 | 
						|
#include <io.h>
 | 
						|
#else
 | 
						|
#if defined(MAC)
 | 
						|
#include <MacErrors.h>
 | 
						|
#else
 | 
						|
#include <sys/types.h>
 | 
						|
#include <unistd.h>
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef WINCE
 | 
						|
#include <time.h>
 | 
						|
#else
 | 
						|
#include <winbase.h>
 | 
						|
#endif
 | 
						|
 | 
						|
/* platform independent wrapper functions for 64-bit file handling.
 | 
						|
*/
 | 
						|
int
 | 
						|
pdc__fseek(FILE *fp, pdc_off_t offset, int whence)
 | 
						|
{
 | 
						|
#if defined(_LARGEFILE_SOURCE)
 | 
						|
    #if defined(WIN32)
 | 
						|
	switch (whence)
 | 
						|
	{
 | 
						|
	    case SEEK_SET:
 | 
						|
		return fsetpos(fp, &offset);
 | 
						|
 | 
						|
	    case SEEK_CUR:
 | 
						|
	    {
 | 
						|
		pdc_off_t pos;
 | 
						|
 | 
						|
		fgetpos(fp, &pos);
 | 
						|
		pos += offset;
 | 
						|
		return fsetpos(fp, &pos);
 | 
						|
	    }
 | 
						|
 | 
						|
	    case SEEK_END:
 | 
						|
	    {
 | 
						|
		pdc_off_t pos, len;
 | 
						|
 | 
						|
		pos = _telli64(fileno(fp));
 | 
						|
		_lseeki64(fileno(fp), 0, SEEK_END);
 | 
						|
		len = _telli64(fileno(fp));
 | 
						|
		_lseeki64(fileno(fp), pos, SEEK_SET);
 | 
						|
 | 
						|
		len += offset;
 | 
						|
		return fsetpos(fp, &len);
 | 
						|
	    }
 | 
						|
 | 
						|
	    default:
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
    #else
 | 
						|
	return fseeko(fp, offset, whence);
 | 
						|
    #endif
 | 
						|
#else
 | 
						|
    return fseek(fp, offset, whence);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
pdc_off_t
 | 
						|
pdc__ftell(FILE *fp)
 | 
						|
{
 | 
						|
#if defined(_LARGEFILE_SOURCE)
 | 
						|
    #if defined(WIN32)
 | 
						|
	pdc_off_t pos;
 | 
						|
 | 
						|
	fgetpos(fp, &pos);
 | 
						|
	return pos;
 | 
						|
    #else
 | 
						|
	return ftello(fp);
 | 
						|
    #endif
 | 
						|
#else
 | 
						|
    return ftell(fp);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
size_t
 | 
						|
pdc__fread(void *ptr, size_t size, size_t nmemb, FILE *fp)
 | 
						|
{
 | 
						|
    return fread(ptr, size, nmemb, fp);
 | 
						|
}
 | 
						|
 | 
						|
size_t
 | 
						|
pdc__fwrite(void *ptr, size_t size, size_t nmemb, FILE *fp)
 | 
						|
{
 | 
						|
    return fwrite(ptr, size, nmemb, fp);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdc__fgetc(FILE *fp)
 | 
						|
{
 | 
						|
    return fgetc(fp);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdc__feof(FILE *fp)
 | 
						|
{
 | 
						|
    return feof(fp);
 | 
						|
}
 | 
						|
 | 
						|
struct pdc_file_s
 | 
						|
{
 | 
						|
    pdc_core       *pdc;       /* pdcore struct */
 | 
						|
    char           *filename;  /* file name */
 | 
						|
    FILE           *fp;        /* file struct or NULL. Then data != NULL: */
 | 
						|
    const pdc_byte *data;      /* file data or NULL. Then fp != NULL */
 | 
						|
    const pdc_byte *end;       /* first byte above data buffer */
 | 
						|
    const pdc_byte *pos;       /* current file position in data buffer */
 | 
						|
};
 | 
						|
 | 
						|
FILE   *
 | 
						|
pdc_get_fileptr(pdc_file *sfp)
 | 
						|
{
 | 
						|
    return sfp->fp;
 | 
						|
}
 | 
						|
 | 
						|
#if defined(_MSC_VER) && defined(_MANAGED)
 | 
						|
#pragma unmanaged
 | 
						|
#endif
 | 
						|
int
 | 
						|
pdc_get_fopen_errnum(pdc_core *pdc, int errnum)
 | 
						|
{
 | 
						|
    int outnum = errnum, isread;
 | 
						|
 | 
						|
    (void) pdc;
 | 
						|
 | 
						|
    isread = (errnum == PDC_E_IO_RDOPEN);
 | 
						|
 | 
						|
#if defined(MVS)
 | 
						|
 | 
						|
    switch (errno)
 | 
						|
    {
 | 
						|
        case 49:
 | 
						|
        outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF;
 | 
						|
    }
 | 
						|
    return outnum;
 | 
						|
 | 
						|
#elif defined(WIN32)
 | 
						|
    {
 | 
						|
	DWORD lasterror = GetLastError();
 | 
						|
        switch (lasterror)
 | 
						|
        {
 | 
						|
            case ERROR_FILE_NOT_FOUND:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_ACCESS_DENIED:
 | 
						|
            case ERROR_INVALID_PASSWORD:
 | 
						|
            case ERROR_NETWORK_ACCESS_DENIED:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_PD : PDC_E_IO_WROPEN_PD;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_INVALID_NAME:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_IS;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_PATH_NOT_FOUND:
 | 
						|
            case ERROR_INVALID_DRIVE:
 | 
						|
            case ERROR_BAD_NETPATH:
 | 
						|
            case ERROR_BAD_UNIT:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NP;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_TOO_MANY_OPEN_FILES:
 | 
						|
            case ERROR_SHARING_BUFFER_EXCEEDED:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_FILE_EXISTS:
 | 
						|
            outnum = PDC_E_IO_WROPEN_AE;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_BUFFER_OVERFLOW:
 | 
						|
            outnum = PDC_E_IO_WROPEN_TL;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_WRITE_FAULT:
 | 
						|
            case ERROR_CANNOT_MAKE:
 | 
						|
            outnum = PDC_E_IO_WROPEN_NC;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_HANDLE_DISK_FULL:
 | 
						|
            case ERROR_DISK_FULL:
 | 
						|
            outnum = PDC_E_IO_WROPEN_NS;
 | 
						|
            break;
 | 
						|
 | 
						|
            case ERROR_SHARING_VIOLATION:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_SV : PDC_E_IO_WROPEN_SV;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if (lasterror)
 | 
						|
        {
 | 
						|
            errno = (int) lasterror;
 | 
						|
            return outnum;
 | 
						|
        }
 | 
						|
 | 
						|
        /* if lasterror == 0 we must look for errno (see .NET) */
 | 
						|
    }
 | 
						|
 | 
						|
#endif /* WIN32 */
 | 
						|
 | 
						|
    switch (errno)
 | 
						|
    {
 | 
						|
#ifdef EACCES
 | 
						|
        case EACCES:
 | 
						|
        outnum = isread ? PDC_E_IO_RDOPEN_PD : PDC_E_IO_WROPEN_PD;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef EMACOSERR
 | 
						|
        case EMACOSERR:
 | 
						|
#if defined(MAC)
 | 
						|
 | 
						|
        switch (__MacOSErrNo)
 | 
						|
        {
 | 
						|
            case fnfErr:
 | 
						|
            case dirNFErr:
 | 
						|
            case resFNotFound:
 | 
						|
            case afpDirNotFound:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF;
 | 
						|
            break;
 | 
						|
 | 
						|
            case permErr:
 | 
						|
            case wrPermErr:
 | 
						|
            case wPrErr:
 | 
						|
            case afpAccessDenied:
 | 
						|
            case afpVolLocked:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_PD : PDC_E_IO_WROPEN_PD;
 | 
						|
            break;
 | 
						|
 | 
						|
            case nsvErr:
 | 
						|
            case afpObjectTypeErr:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_IS;
 | 
						|
            break;
 | 
						|
 | 
						|
            case tmfoErr:
 | 
						|
            case afpTooManyFilesOpen:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM;
 | 
						|
            break;
 | 
						|
 | 
						|
            case opWrErr:
 | 
						|
            outnum = PDC_E_IO_WROPEN_AE;
 | 
						|
            break;
 | 
						|
 | 
						|
            case dirFulErr:
 | 
						|
            case dskFulErr:
 | 
						|
            case afpDiskFull:
 | 
						|
            outnum = PDC_E_IO_WROPEN_NS;
 | 
						|
            break;
 | 
						|
 | 
						|
            case fLckdErr:
 | 
						|
            case afpLockErr:
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_SV : PDC_E_IO_WROPEN_SV;
 | 
						|
            break;
 | 
						|
 | 
						|
            default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if (__MacOSErrNo)
 | 
						|
        {
 | 
						|
            return outnum;
 | 
						|
        }
 | 
						|
#endif
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef ENOENT
 | 
						|
        case ENOENT:
 | 
						|
        outnum = isread ? PDC_E_IO_RDOPEN_NF : PDC_E_IO_WROPEN_NF;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef EMFILE
 | 
						|
        case EMFILE:
 | 
						|
        outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef ENFILE
 | 
						|
        case ENFILE:
 | 
						|
        outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef EISDIR
 | 
						|
        case EISDIR:
 | 
						|
        outnum = isread ? PDC_E_IO_RDOPEN_ID : PDC_E_IO_WROPEN_ID;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef EEXIST
 | 
						|
        case EEXIST:
 | 
						|
        outnum = PDC_E_IO_WROPEN_AE;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef ENAMETOOLONG
 | 
						|
        case ENAMETOOLONG:
 | 
						|
        outnum = PDC_E_IO_WROPEN_TL;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
#ifdef ENOSPC
 | 
						|
        case ENOSPC:
 | 
						|
        outnum = PDC_E_IO_WROPEN_NS;
 | 
						|
        break;
 | 
						|
#endif
 | 
						|
        default:
 | 
						|
        /* observed on Solaris */
 | 
						|
        if (errno == 0)
 | 
						|
        {
 | 
						|
            outnum = isread ? PDC_E_IO_RDOPEN_TM : PDC_E_IO_WROPEN_TM;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        outnum = errnum;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    return outnum;
 | 
						|
}
 | 
						|
#if defined(_MSC_VER) && defined(_MANAGED)
 | 
						|
#pragma managed
 | 
						|
#endif
 | 
						|
 | 
						|
void
 | 
						|
pdc_set_fopen_errmsg(pdc_core *pdc, int errnum, const char *qualifier,
 | 
						|
                     const char *filename)
 | 
						|
{
 | 
						|
    const char *stemp = NULL;
 | 
						|
 | 
						|
    errnum = pdc_get_fopen_errnum(pdc, errnum);
 | 
						|
    if (errnum == PDC_E_IO_RDOPEN)
 | 
						|
        errnum = PDC_E_IO_RDOPEN_CODE;
 | 
						|
    else if (errnum == PDC_E_IO_WROPEN)
 | 
						|
        errnum = PDC_E_IO_WROPEN_CODE;
 | 
						|
    if (errnum == PDC_E_IO_RDOPEN_CODE || errnum == PDC_E_IO_WROPEN_CODE)
 | 
						|
    {
 | 
						|
#if defined(EMACOSERR) && defined(MAC)
 | 
						|
        errno = (int) __MacOSErrNo;
 | 
						|
#endif
 | 
						|
        stemp = pdc_errprintf(pdc, "%d", errno);
 | 
						|
    }
 | 
						|
 | 
						|
    pdc_set_errmsg(pdc, errnum, qualifier, filename, stemp, 0);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
pdc_logg_openclose(pdc_core *pdc, FILE *fp, pdc_bool opened)
 | 
						|
{
 | 
						|
    if (pdc_trace_protocol_is_enabled(pdc, 3, trc_filesearch))
 | 
						|
    {
 | 
						|
        int errno2 = 0;
 | 
						|
 | 
						|
#if defined(WIN32)
 | 
						|
        errno2 = (int) GetLastError();
 | 
						|
#elif defined(MAC)
 | 
						|
        errno2 = __MacOSErrNo;
 | 
						|
#endif
 | 
						|
 | 
						|
        pdc_trace(pdc, "\t%p", fp);
 | 
						|
        if (opened)
 | 
						|
            pdc_trace(pdc, " opened");
 | 
						|
        else
 | 
						|
            pdc_trace(pdc, " closed");
 | 
						|
#if PDC_FILENO_EXISTS
 | 
						|
        if (fp != NULL && opened)
 | 
						|
            pdc_trace(pdc, ", fileno=%d", fileno(fp));
 | 
						|
#endif
 | 
						|
        pdc_trace(pdc, ", errno=%d", errno);
 | 
						|
        if (errno2 != 0)
 | 
						|
            pdc_trace(pdc, ", errno2=%d", errno2);
 | 
						|
        pdc_trace(pdc, "\n");
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void *
 | 
						|
pdc_read_file(pdc_core *pdc, FILE *fp, pdc_off_t *o_filelen, int incore)
 | 
						|
{
 | 
						|
    static const char fn[] = "pdc_read_file";
 | 
						|
    pdc_off_t filelen = 0, len = 0;
 | 
						|
    char *content = NULL;
 | 
						|
 | 
						|
 | 
						|
#if !defined(MVS) || !defined(I370)
 | 
						|
 | 
						|
    pdc__fseek(fp, 0, SEEK_END);
 | 
						|
    filelen = pdc__ftell(fp);
 | 
						|
    pdc__fseek(fp, 0, SEEK_SET);
 | 
						|
 | 
						|
    if (incore && filelen)
 | 
						|
    {
 | 
						|
        content = (char *) pdc_malloc(pdc, (size_t) (filelen + 1), fn);
 | 
						|
        len = (pdc_off_t) pdc__fread(content, 1, (size_t) filelen, fp);
 | 
						|
        if (len != filelen)
 | 
						|
        {
 | 
						|
            pdc_free(pdc, content);
 | 
						|
            filelen = 0;
 | 
						|
            content = NULL;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
    if (content) content[filelen] = 0;
 | 
						|
    *o_filelen = filelen;
 | 
						|
    return (void *) content;
 | 
						|
}
 | 
						|
 | 
						|
FILE *
 | 
						|
pdc_wfopen(pdc_core *pdc, const char *filename, const char *mode)
 | 
						|
{
 | 
						|
    FILE *fp = NULL;
 | 
						|
 | 
						|
#if defined(PDC_UNICODE_FILENAME)
 | 
						|
 | 
						|
    pdc_byte *outfilename = NULL;
 | 
						|
    pdc_text_format nameformat = pdc_utf8;
 | 
						|
    pdc_text_format targetnameformat = pdc_utf16;
 | 
						|
    int len = (int) strlen(filename);
 | 
						|
    int outlen = 0;
 | 
						|
 | 
						|
    /* convert filename from UTF-8 to UTF-16 or Latin-1 */
 | 
						|
    pdc_convert_string(pdc, nameformat, 0, NULL, (pdc_byte *) filename, len,
 | 
						|
                       &targetnameformat, NULL, &outfilename, &outlen,
 | 
						|
                       PDC_CONV_TRYBYTES, pdc_true);
 | 
						|
 | 
						|
    if (targetnameformat == pdc_bytes)
 | 
						|
    {
 | 
						|
        fp = fopen((const char *) outfilename, mode);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        wchar_t wmode[8];
 | 
						|
        int i;
 | 
						|
 | 
						|
        len = (int) strlen(mode);
 | 
						|
        for (i = 0; i < len; i++)
 | 
						|
            wmode[i] = (wchar_t) mode[i];
 | 
						|
        wmode[len] = 0;
 | 
						|
 | 
						|
        fp = _wfopen((wchar_t *) outfilename, wmode);
 | 
						|
    }
 | 
						|
 | 
						|
    pdc_free(pdc, outfilename);
 | 
						|
 | 
						|
#else
 | 
						|
    (void) pdc;
 | 
						|
 | 
						|
    fp = fopen(filename, mode);
 | 
						|
#endif
 | 
						|
 | 
						|
    pdc_logg_openclose(pdc, fp, pdc_true);
 | 
						|
 | 
						|
    return fp;
 | 
						|
}
 | 
						|
 | 
						|
pdc_file *
 | 
						|
pdc_fopen(pdc_core *pdc, const char *filename, const char *qualifier,
 | 
						|
          const pdc_byte *data, size_t size, int flags)
 | 
						|
{
 | 
						|
    static const char fn[] = "pdc_fopen";
 | 
						|
    pdc_file *sfile;
 | 
						|
 | 
						|
    sfile = (pdc_file *) pdc_calloc(pdc, sizeof(pdc_file), fn);
 | 
						|
 | 
						|
    if (data)
 | 
						|
    {
 | 
						|
        sfile->data = data;
 | 
						|
        sfile->pos = sfile->data;
 | 
						|
        sfile->end = sfile->data + size;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        sfile->fp = pdc_wfopen(pdc, filename,
 | 
						|
                        (flags & PDC_FILE_BINARY) ? READBMODE : READTMODE);
 | 
						|
        if (sfile->fp == NULL)
 | 
						|
        {
 | 
						|
            pdc_free(pdc, sfile);
 | 
						|
            if (qualifier == NULL)
 | 
						|
                qualifier = "";
 | 
						|
            pdc_set_fopen_errmsg(pdc, PDC_E_IO_RDOPEN, qualifier, filename);
 | 
						|
            return NULL;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    sfile->pdc = pdc;
 | 
						|
    sfile->filename = pdc_strdup(pdc, filename);
 | 
						|
 | 
						|
 | 
						|
    return sfile;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdc_file_isvirtual(pdc_file *sfp)
 | 
						|
{
 | 
						|
    return sfp->fp ? pdc_false : pdc_true;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
pdc_file_name(pdc_file *sfp)
 | 
						|
{
 | 
						|
    return sfp->filename;
 | 
						|
}
 | 
						|
 | 
						|
pdc_core *
 | 
						|
pdc_file_getpdc(pdc_file *sfp)
 | 
						|
{
 | 
						|
    return sfp->pdc;
 | 
						|
}
 | 
						|
 | 
						|
pdc_off_t
 | 
						|
pdc_file_size(pdc_file *sfp)
 | 
						|
{
 | 
						|
    pdc_off_t filelen;
 | 
						|
 | 
						|
    if (sfp->fp)
 | 
						|
    {
 | 
						|
        pdc_off_t pos = pdc__ftell(sfp->fp);
 | 
						|
 | 
						|
        pdc_read_file(sfp->pdc, sfp->fp, &filelen, 0);
 | 
						|
        pdc__fseek(sfp->fp, pos, SEEK_SET);
 | 
						|
    }
 | 
						|
    else
 | 
						|
        filelen = (pdc_off_t) (sfp->end - sfp->data);
 | 
						|
 | 
						|
    return filelen;
 | 
						|
}
 | 
						|
 | 
						|
const void *
 | 
						|
pdc_freadall(pdc_file *sfp, size_t *filelen, pdc_bool *ismem)
 | 
						|
{
 | 
						|
    pdc_off_t flen;	/* TODO2GB: >2GB on 32-bit platforms? */
 | 
						|
 | 
						|
    if (sfp->fp)
 | 
						|
    {
 | 
						|
        const void *result = pdc_read_file(sfp->pdc, sfp->fp, &flen, 1);
 | 
						|
 | 
						|
        if (ismem) *ismem = pdc_false;
 | 
						|
	*filelen = (size_t) flen;
 | 
						|
	return result;
 | 
						|
    }
 | 
						|
 | 
						|
    if (ismem) *ismem = pdc_true;
 | 
						|
    *filelen = (size_t) (sfp->end - sfp->data);
 | 
						|
    return sfp->data;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
pdc_fgetc_e(pdc_file *sfp)
 | 
						|
{
 | 
						|
    int c = pdc_fgetc(sfp);
 | 
						|
    return c;
 | 
						|
}
 | 
						|
 | 
						|
char *
 | 
						|
pdc_fgetline(char *s, int size, pdc_file *sfp)
 | 
						|
{
 | 
						|
    int i, c;
 | 
						|
 | 
						|
    c = pdc_fgetc_e(sfp);
 | 
						|
    if (c == EOF)
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    size--;
 | 
						|
    for (i = 0; i < size; i++)
 | 
						|
    {
 | 
						|
        if (c == '\n' || c == '\r' || c == EOF) break;
 | 
						|
        s[i] = (char) c;
 | 
						|
        c = pdc_fgetc_e(sfp);
 | 
						|
    }
 | 
						|
    s[i] = 0;
 | 
						|
 | 
						|
    /* Skip windows line end \r\n */
 | 
						|
    if (c == '\r')
 | 
						|
    {
 | 
						|
        c = pdc_fgetc_e(sfp);
 | 
						|
 | 
						|
        if (c != '\n' && c != EOF)
 | 
						|
	{
 | 
						|
	    if (sfp->fp)
 | 
						|
		ungetc(c, sfp->fp);
 | 
						|
	    else
 | 
						|
		pdc_fseek(sfp, -1, SEEK_CUR);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    return s;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Emulation of C file functions - relevant for PDFlib
 | 
						|
 */
 | 
						|
 | 
						|
pdc_off_t
 | 
						|
pdc_ftell(pdc_file *sfp)
 | 
						|
{
 | 
						|
    if (sfp->fp)
 | 
						|
        return pdc__ftell(sfp->fp);
 | 
						|
 | 
						|
    return (pdc_off_t) (sfp->pos - sfp->data);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdc_fseek(pdc_file *sfp, pdc_off_t offset, int whence)
 | 
						|
{
 | 
						|
    if (sfp->fp)
 | 
						|
        return pdc__fseek(sfp->fp, offset, whence);
 | 
						|
 | 
						|
    switch (whence)
 | 
						|
    {
 | 
						|
        case SEEK_SET:
 | 
						|
        if (sfp->data + offset > sfp->end)
 | 
						|
            return -1;
 | 
						|
        sfp->pos = sfp->data + offset;
 | 
						|
        break;
 | 
						|
 | 
						|
        case SEEK_CUR:
 | 
						|
        if (sfp->pos + offset > sfp->end)
 | 
						|
            return -1;
 | 
						|
        sfp->pos += offset;
 | 
						|
        break;
 | 
						|
 | 
						|
        case SEEK_END:
 | 
						|
        if (sfp->end + offset > sfp->end)
 | 
						|
            return -1;
 | 
						|
        sfp->pos = sfp->end + offset;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
size_t
 | 
						|
pdc_fread(void *ptr, size_t size, size_t nmemb, pdc_file *sfp)
 | 
						|
{
 | 
						|
    size_t nbytes = 0;
 | 
						|
 | 
						|
    if (sfp->fp)
 | 
						|
        return pdc__fread(ptr, size, nmemb, sfp->fp);
 | 
						|
 | 
						|
    nbytes = size * nmemb;
 | 
						|
    if (sfp->pos + nbytes > sfp->end)
 | 
						|
    {
 | 
						|
        nbytes = (size_t) (sfp->end - sfp->pos);
 | 
						|
        nmemb = nbytes / size;
 | 
						|
        nbytes = nmemb *size;
 | 
						|
    }
 | 
						|
    memcpy(ptr, sfp->pos, nbytes);
 | 
						|
    sfp->pos += nbytes;
 | 
						|
 | 
						|
    return nmemb;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdc_fgetc(pdc_file *sfp)
 | 
						|
{
 | 
						|
    int ch = 0;
 | 
						|
 | 
						|
    if (sfp->fp)
 | 
						|
        return pdc__fgetc(sfp->fp);
 | 
						|
 | 
						|
    if (sfp->pos < sfp->end)
 | 
						|
    {
 | 
						|
	ch = (int) *sfp->pos;
 | 
						|
	sfp->pos++;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	ch = EOF;
 | 
						|
    }
 | 
						|
 | 
						|
    return ch;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdc_feof(pdc_file *sfp)
 | 
						|
{
 | 
						|
    if (sfp->fp)
 | 
						|
        return pdc__feof(sfp->fp);
 | 
						|
 | 
						|
    return (sfp->pos >= sfp->end) ? 1 : 0;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
pdc_wfclose(pdc_core *pdc, FILE *fp)
 | 
						|
{
 | 
						|
    fclose(fp);
 | 
						|
    pdc_logg_openclose(pdc, fp, pdc_false);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
pdc_fclose(pdc_file *sfp)
 | 
						|
{
 | 
						|
    if (sfp)
 | 
						|
    {
 | 
						|
        if (sfp->fp)
 | 
						|
        {
 | 
						|
            pdc_wfclose(sfp->pdc, sfp->fp);
 | 
						|
            sfp->fp = NULL;
 | 
						|
        }
 | 
						|
        if (sfp->filename)
 | 
						|
        {
 | 
						|
            pdc_free(sfp->pdc, sfp->filename);
 | 
						|
            sfp->filename = NULL;
 | 
						|
        }
 | 
						|
        pdc_free(sfp->pdc, sfp);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Concatenating a directory name with a file base name to a full valid
 | 
						|
 * file name. On MVS platforms an extension at the end of basename
 | 
						|
 * will be discarded.
 | 
						|
 */
 | 
						|
void
 | 
						|
pdc_file_fullname(const char *dirname, const char *basename, char *fullname)
 | 
						|
{
 | 
						|
    const char *pathsep = PDC_PATHSEP;
 | 
						|
 | 
						|
#ifdef MVS
 | 
						|
    pdc_bool lastterm = pdc_false;
 | 
						|
#endif
 | 
						|
 | 
						|
    if (!dirname || !dirname[0])
 | 
						|
    {
 | 
						|
        strcpy(fullname, basename);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        fullname[0] = 0;
 | 
						|
 | 
						|
#ifdef MVS
 | 
						|
        if (strncmp(dirname, PDC_FILEQUOT, 1))
 | 
						|
            strcat(fullname, PDC_FILEQUOT);
 | 
						|
#endif
 | 
						|
 | 
						|
        strcat(fullname, dirname);
 | 
						|
 | 
						|
#ifdef VMS
 | 
						|
        /* look for logical name or whose result */
 | 
						|
        if(getenv(dirname))
 | 
						|
            pathsep = PDC_PATHSEP_LOG;
 | 
						|
        else if (fullname[strlen(fullname)-1] == ']')
 | 
						|
            pathsep = "";
 | 
						|
#endif
 | 
						|
 | 
						|
        strcat(fullname, pathsep);
 | 
						|
        strcat(fullname, basename);
 | 
						|
 | 
						|
#ifdef MVS
 | 
						|
        lastterm = pdc_true;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef MVS
 | 
						|
    {
 | 
						|
        int ie, len;
 | 
						|
 | 
						|
        len = strlen(fullname);
 | 
						|
        for (ie = len - 1; ie >= 0; ie--)
 | 
						|
        {
 | 
						|
            if (fullname[ie] == pathsep[0])
 | 
						|
                break;
 | 
						|
 | 
						|
            if (fullname[ie] == '.')
 | 
						|
            {
 | 
						|
                fullname[ie] = 0;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (lastterm)
 | 
						|
        {
 | 
						|
            strcat(fullname, PDC_PATHTERM);
 | 
						|
            strcat(fullname, PDC_FILEQUOT);
 | 
						|
        }
 | 
						|
    }
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
#define EXTRA_SPACE     32     /* extra space for separators, FILEQUOT etc. */
 | 
						|
 | 
						|
char *
 | 
						|
pdc_file_fullname_mem(pdc_core *pdc, const char *dirname, const char *basename)
 | 
						|
{
 | 
						|
    static const char fn[] = "pdc_file_fullname_mem";
 | 
						|
    char *fullname;
 | 
						|
    size_t len;
 | 
						|
 | 
						|
    len = strlen(basename);
 | 
						|
    if (dirname && dirname[0])
 | 
						|
        len += strlen(dirname);
 | 
						|
    len += EXTRA_SPACE;
 | 
						|
    fullname = (char *) pdc_malloc(pdc, len, fn);
 | 
						|
 | 
						|
    pdc_file_fullname(dirname, basename, fullname);
 | 
						|
 | 
						|
    return fullname;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Function reads a text file and creates a string list
 | 
						|
 * of all no-empty and no-comment lines. The strings are stripped
 | 
						|
 * by leading and trailing white space characters.
 | 
						|
 *
 | 
						|
 * The caller is responsible for freeing the resultated string list
 | 
						|
 * by calling the function pdc_cleanup_stringlist.
 | 
						|
 *
 | 
						|
 * Not for unicode strings.
 | 
						|
 *
 | 
						|
 * Return value: Number of strings
 | 
						|
 */
 | 
						|
 | 
						|
#define PDC_BUFSIZE 1024
 | 
						|
#define PDC_ARGV_CHUNKSIZE 256
 | 
						|
 | 
						|
int
 | 
						|
pdc_read_textfile(pdc_core *pdc, pdc_file *sfp, char ***linelist)
 | 
						|
{
 | 
						|
    static const char fn[] = "pdc_read_textfile";
 | 
						|
    char   buf[PDC_BUFSIZE];
 | 
						|
    char  *content = NULL;
 | 
						|
    char **argv = NULL;
 | 
						|
    int    nlines = 0;
 | 
						|
    pdc_off_t filelen;
 | 
						|
    size_t len, maxl = 0;
 | 
						|
    int    tocont, incont = 0;
 | 
						|
    int    i, is = 0, isb = 0;
 | 
						|
 | 
						|
    /* Get file length */
 | 
						|
    filelen = pdc_file_size(sfp);
 | 
						|
    if (filelen)
 | 
						|
    {
 | 
						|
        /* Allocate content array */
 | 
						|
        content = (char *) pdc_malloc(pdc, (size_t) filelen, fn);
 | 
						|
 | 
						|
        /* Read loop */
 | 
						|
        while (pdc_fgetline(buf, PDC_BUFSIZE, sfp) != NULL)
 | 
						|
        {
 | 
						|
            /* Strip blank and comment lines */
 | 
						|
            pdc_str2trim(buf);
 | 
						|
            if (buf[0] == 0 || buf[0] == '%')
 | 
						|
                continue;
 | 
						|
 | 
						|
            /* Strip inline comments */
 | 
						|
            len = strlen(buf);
 | 
						|
            for (i = 1; i < (int) len; i++)
 | 
						|
            {
 | 
						|
                if (buf[i] == '%')
 | 
						|
                {
 | 
						|
                    if (buf[i-1] == '\\')
 | 
						|
                    {
 | 
						|
                        memmove(&buf[i-1], &buf[i], (size_t) (len - i));
 | 
						|
                        len--;
 | 
						|
                        buf[len] = 0;
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        buf[i] = 0;
 | 
						|
                        pdc_strtrim(buf);
 | 
						|
                        len = strlen(buf);
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            /* Continuation line */
 | 
						|
            tocont = (buf[len-1] == '\\') ? 1:0;
 | 
						|
            if (tocont)
 | 
						|
            {
 | 
						|
                buf[len-1] = '\0';
 | 
						|
                len--;
 | 
						|
            }
 | 
						|
            if (!incont)
 | 
						|
                isb = is;
 | 
						|
            incont = tocont;
 | 
						|
 | 
						|
            /* Copy line */
 | 
						|
            strcpy(&content[is], buf);
 | 
						|
 | 
						|
            /* Save whole line */
 | 
						|
            if (!incont)
 | 
						|
            {
 | 
						|
                if (nlines >= (int) maxl)
 | 
						|
                {
 | 
						|
                    maxl += PDC_ARGV_CHUNKSIZE;
 | 
						|
                    argv = (argv == NULL) ?
 | 
						|
                            (char **)pdc_malloc(pdc, maxl * sizeof(char *), fn):
 | 
						|
                            (char **)pdc_realloc(pdc, argv, maxl *
 | 
						|
                                                 sizeof(char *), fn);
 | 
						|
                }
 | 
						|
                argv[nlines] = &content[isb];
 | 
						|
                nlines++;
 | 
						|
 | 
						|
                pdc_trace_protocol(pdc, 2, trc_filesearch,
 | 
						|
                        "\t\tLine %d; \"%s\"\n", nlines, argv[nlines - 1]);
 | 
						|
            }
 | 
						|
 | 
						|
            /* Next index */
 | 
						|
            is += (int) (len + 1 - incont);
 | 
						|
        }
 | 
						|
 | 
						|
        if (!argv) pdc_free(pdc, content);
 | 
						|
    }
 | 
						|
 | 
						|
    *linelist = argv;
 | 
						|
    return nlines;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* generate a temporary file name from the current time, pid, 'dirname',
 | 
						|
** and the data in 'inbuf' using MD5. prepend 'dirname' to the file name.
 | 
						|
** the result is written to 'outbuf'. if 'outbuf' is NULL, memory will be
 | 
						|
** allocated and must be freed by the caller. otherwise, 'pdc' can be set
 | 
						|
** to NULL.
 | 
						|
**
 | 
						|
** if 'dirname' isn't specified the function looks for an environment
 | 
						|
** variable via the define PDC_TMPDIR_ENV. This define is set in
 | 
						|
** pc_config.h. If the environment variable has a value and if the
 | 
						|
** directory exists (check with the temporary file together) the
 | 
						|
** directory will be used.
 | 
						|
*/
 | 
						|
 | 
						|
#ifdef MVS
 | 
						|
#define TMP_NAME_LEN	9
 | 
						|
#define TMP_SUFFIX	""
 | 
						|
#define TMP_SUFF_LEN	0
 | 
						|
#else
 | 
						|
#define TMP_NAME_LEN	14
 | 
						|
#define TMP_SUFFIX	".TMP"
 | 
						|
#define TMP_SUFF_LEN	4
 | 
						|
#endif
 | 
						|
 | 
						|
char *
 | 
						|
pdc_temppath(
 | 
						|
    pdc_core *pdc,
 | 
						|
    char *outbuf,
 | 
						|
    const char *inbuf,
 | 
						|
    size_t inlen,
 | 
						|
    const char *dirname)
 | 
						|
{
 | 
						|
    char		name[TMP_NAME_LEN + TMP_SUFF_LEN + 1];
 | 
						|
    MD5_CTX             md5;
 | 
						|
    time_t              timer;
 | 
						|
    unsigned char       digest[MD5_DIGEST_LENGTH];
 | 
						|
    int                 i;
 | 
						|
    size_t              dirlen;
 | 
						|
#ifdef VMS
 | 
						|
    char               *tmpdir = NULL;
 | 
						|
#endif /* VMS */
 | 
						|
 | 
						|
#if defined(WIN32)
 | 
						|
#if defined(__BORLANDC__)
 | 
						|
    int pid = getpid();
 | 
						|
#else
 | 
						|
    int pid = _getpid();
 | 
						|
#endif
 | 
						|
#else
 | 
						|
#if !defined(MAC)
 | 
						|
    pid_t pid = getpid();
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef PDC_TMPDIR_ENV
 | 
						|
    if (!dirname)
 | 
						|
    {
 | 
						|
        dirname = (char *) getenv(PDC_TMPDIR_ENV);
 | 
						|
    }
 | 
						|
#endif /* !PDC_TMPDIR_ENV */
 | 
						|
 | 
						|
    time(&timer);
 | 
						|
 | 
						|
    MD5_Init(&md5);
 | 
						|
#if !defined(MAC)
 | 
						|
    MD5_Update(&md5, (unsigned char *) &pid, sizeof pid);
 | 
						|
#endif
 | 
						|
    MD5_Update(&md5, (unsigned char *) &timer, sizeof timer);
 | 
						|
 | 
						|
    if (inlen == 0 && inbuf != (const char *) 0)
 | 
						|
	inlen = strlen(inbuf);
 | 
						|
 | 
						|
    if (inlen != 0)
 | 
						|
	MD5_Update(&md5, (unsigned char *) inbuf, inlen);
 | 
						|
 | 
						|
    dirlen = dirname ? strlen(dirname) : 0;
 | 
						|
    if (dirlen)
 | 
						|
	MD5_Update(&md5, (const unsigned char *) dirname, dirlen);
 | 
						|
 | 
						|
    MD5_Final(digest, &md5);
 | 
						|
 | 
						|
    for (i = 0; i < TMP_NAME_LEN - 1; ++i)
 | 
						|
        name[i] = (char) (PDF_A + digest[i % MD5_DIGEST_LENGTH] % 26);
 | 
						|
 | 
						|
    name[i] = 0;
 | 
						|
    strcat(name, TMP_SUFFIX);
 | 
						|
 | 
						|
    if (!outbuf)
 | 
						|
        outbuf = pdc_file_fullname_mem(pdc, dirname, name);
 | 
						|
    else
 | 
						|
        pdc_file_fullname(dirname, name, outbuf);
 | 
						|
    return outbuf;
 | 
						|
}
 | 
						|
 | 
						|
#if defined(MAC) || defined(MACOSX)
 | 
						|
 | 
						|
#ifdef PDF_TARGET_API_MAC_CARBON
 | 
						|
 | 
						|
/* Construct an FSSpec from a Posix path name. Only required for
 | 
						|
 * Carbon (host font support and file type/creator).
 | 
						|
 */
 | 
						|
 | 
						|
OSStatus
 | 
						|
FSPathMakeFSSpec(const UInt8 *path, FSSpec *spec)
 | 
						|
{
 | 
						|
    OSStatus        result;
 | 
						|
    FSRef           ref;
 | 
						|
 | 
						|
    /* convert the POSIX path to an FSRef */
 | 
						|
    result = FSPathMakeRef(path, &ref, NULL);
 | 
						|
 | 
						|
    if (result != noErr)
 | 
						|
            return result;
 | 
						|
 | 
						|
    /* and then convert the FSRef to an FSSpec */
 | 
						|
    result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
 | 
						|
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
 | 
						|
#endif /* !PDF_TARGET_API_MAC_CARBON */
 | 
						|
 | 
						|
#endif /* (defined(MAC) || defined(MACOSX)) */
 | 
						|
 |