Back to index

python3.2  3.2.2
Classes | Defines | Typedefs | Functions
archive.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  eof_cdir
struct  cdir
struct  fhdr
struct  meta_data_hdr
struct  tagSCHEME

Defines

#define DIR_CREATED   1
#define CAN_OVERWRITE   2
#define FILE_CREATED   3
#define ZLIB_ERROR   4
#define SYSTEM_ERROR   5
#define NUM_FILES   6
#define FILE_OVERWRITTEN   7

Typedefs

typedef struct tagSCHEME SCHEME
typedef int(* NOTIFYPROC )(int code, LPSTR text,...)

Functions

BOOL extract_file (char *dst, char *src, int method, int comp_size, int uncomp_size, NOTIFYPROC notify)
BOOL unzip_archive (SCHEME *scheme, char *dirname, char *data, DWORD size, NOTIFYPROC notify)
char * map_new_file (DWORD flags, char *filename, char *pathname_part, int size, WORD wFatDate, WORD wFatTime, NOTIFYPROC callback)
BOOL ensure_directory (char *pathname, char *new_part, NOTIFYPROC callback)

Class Documentation

struct eof_cdir

Definition at line 16 of file archive.h.

Class Members
short commentlen
short disknum
short firstdisk
long nBytesCDir
short nTotalCDir
short nTotalCDirThis
long ofsCDir
long tag
struct cdir

Definition at line 27 of file archive.h.

Class Members
short comment_length
short comp_method
long comp_size
long crc32
short disknum_start
long ext_file_attr
short extra_length
short fname_length
short gp_bitflag
short int_file_attr
short last_mod_file_date
short last_mod_file_time
long ofs_local_header
long tag
long uncomp_size
short version_extract
short version_made
struct fhdr

Definition at line 47 of file archive.h.

Class Members
long comp_size
long crc32
short extra_length
short flags
short fname_length
short last_mod_file_date
short last_mod_file_time
short method
long tag
long uncomp_size
short version_needed
struct meta_data_hdr

Definition at line 62 of file archive.h.

Class Members
int bitmap_size
int tag
int uncomp_size
struct tagSCHEME

Definition at line 72 of file archive.h.

Class Members
char * name
char * prefix

Define Documentation

#define CAN_OVERWRITE   2

Definition at line 99 of file archive.h.

#define DIR_CREATED   1

Definition at line 98 of file archive.h.

#define FILE_CREATED   3

Definition at line 100 of file archive.h.

#define FILE_OVERWRITTEN   7

Definition at line 104 of file archive.h.

#define NUM_FILES   6

Definition at line 103 of file archive.h.

#define SYSTEM_ERROR   5

Definition at line 102 of file archive.h.

#define ZLIB_ERROR   4

Definition at line 101 of file archive.h.


Typedef Documentation

typedef int(* NOTIFYPROC)(int code, LPSTR text,...)

Definition at line 77 of file archive.h.

typedef struct tagSCHEME SCHEME

Function Documentation

BOOL ensure_directory ( char *  pathname,
char *  new_part,
NOTIFYPROC  callback 
)

Definition at line 29 of file extract.c.

{
    while (new_part && *new_part && (new_part = strchr(new_part, '\\'))) {
        DWORD attr;
        *new_part = '\0';
        attr = GetFileAttributes(pathname);
        if (attr == -1) {
            /* nothing found */
            if (!CreateDirectory(pathname, NULL) && notify)
                notify(SYSTEM_ERROR,
                       "CreateDirectory (%s)", pathname);
            else
                notify(DIR_CREATED, pathname);
        }
        if (attr & FILE_ATTRIBUTE_DIRECTORY) {
            ;
        } else {
            SetLastError(183);
            if (notify)
                notify(SYSTEM_ERROR,
                       "CreateDirectory (%s)", pathname);
        }
        *new_part = '\\';
        ++new_part;
    }
    return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

BOOL extract_file ( char *  dst,
char *  src,
int  method,
int  comp_size,
int  uncomp_size,
NOTIFYPROC  notify 
)

Definition at line 152 of file extract.c.

{
    z_stream zstream;
    int result;

    if (method == Z_DEFLATED) {
        int x;
        memset(&zstream, 0, sizeof(zstream));
        zstream.next_in = src;
        zstream.avail_in = comp_size+1;
        zstream.next_out = dst;
        zstream.avail_out = uncomp_size;

/* Apparently an undocumented feature of zlib: Set windowsize
   to negative values to suppress the gzip header and be compatible with
   zip! */
        result = TRUE;
        if (Z_OK != (x = inflateInit2(&zstream, -15))) {
            if (notify)
                notify(ZLIB_ERROR,
                       "inflateInit2 returns %d", x);
            result = FALSE;
            goto cleanup;
        }
        if (Z_STREAM_END != (x = inflate(&zstream, Z_FINISH))) {
            if (notify)
                notify(ZLIB_ERROR,
                       "inflate returns %d", x);
            result = FALSE;
        }
      cleanup:
        if (Z_OK != (x = inflateEnd(&zstream))) {
            if (notify)
                notify (ZLIB_ERROR,
                    "inflateEnd returns %d", x);
            result = FALSE;
        }
    } else if (method == 0) {
        memcpy(dst, src, uncomp_size);
        result = TRUE;
    } else
        result = FALSE;
    UnmapViewOfFile(dst);
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* map_new_file ( DWORD  flags,
char *  filename,
char *  pathname_part,
int  size,
WORD  wFatDate,
WORD  wFatTime,
NOTIFYPROC  callback 
)

Definition at line 60 of file extract.c.

{
    HANDLE hFile, hFileMapping;
    char *dst;
    FILETIME ft;

  try_again:
    if (!flags)
        flags = CREATE_NEW;
    hFile = CreateFile(filename,
                       GENERIC_WRITE | GENERIC_READ,
                       0, NULL,
                       flags,
                       FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        DWORD x = GetLastError();
        switch (x) {
        case ERROR_FILE_EXISTS:
            if (notify && notify(CAN_OVERWRITE, filename))
                hFile = CreateFile(filename,
                                   GENERIC_WRITE|GENERIC_READ,
                                   0, NULL,
                                   CREATE_ALWAYS,
                                   FILE_ATTRIBUTE_NORMAL,
                                   NULL);
            else {
                if (notify)
                    notify(FILE_OVERWRITTEN, filename);
                return NULL;
            }
            break;
        case ERROR_PATH_NOT_FOUND:
            if (ensure_directory(filename, pathname_part, notify))
                goto try_again;
            else
                return FALSE;
            break;
        default:
            SetLastError(x);
            break;
        }
    }
    if (hFile == INVALID_HANDLE_VALUE) {
        if (notify)
            notify (SYSTEM_ERROR, "CreateFile (%s)", filename);
        return NULL;
    }

    if (notify)
        notify(FILE_CREATED, filename);

    DosDateTimeToFileTime(wFatDate, wFatTime, &ft);
    SetFileTime(hFile, &ft, &ft, &ft);


    if (size == 0) {
        /* We cannot map a zero-length file (Also it makes
           no sense */
        CloseHandle(hFile);
        return NULL;
    }

    hFileMapping = CreateFileMapping(hFile,
                                     NULL, PAGE_READWRITE, 0, size, NULL);

    CloseHandle(hFile);

    if (hFileMapping == INVALID_HANDLE_VALUE) {
        if (notify)
            notify(SYSTEM_ERROR,
                   "CreateFileMapping (%s)", filename);
        return NULL;
    }

    dst = MapViewOfFile(hFileMapping,
                        FILE_MAP_WRITE, 0, 0, 0);

    CloseHandle(hFileMapping);

    if (!dst) {
        if (notify)
            notify(SYSTEM_ERROR, "MapViewOfFile (%s)", filename);
        return NULL;
    }
    return dst;
}

Here is the call graph for this function:

Here is the caller graph for this function:

BOOL unzip_archive ( SCHEME scheme,
char *  dirname,
char *  data,
DWORD  size,
NOTIFYPROC  notify 
)

Definition at line 203 of file extract.c.

{
    int n;
    char pathname[MAX_PATH];
    char *new_part;

    /* read the end of central directory record */
    struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
                                                   (struct eof_cdir)];

    int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir -
        pe->ofsCDir;

    /* set position to start of central directory */
    int pos = arc_start + pe->ofsCDir;

    /* make sure this is a zip file */
    if (pe->tag != 0x06054b50)
        return FALSE;

    /* Loop through the central directory, reading all entries */
    for (n = 0; n < pe->nTotalCDir; ++n) {
        int i;
        char *fname;
        char *pcomp;
        char *dst;
        struct cdir *pcdir;
        struct fhdr *pfhdr;

        pcdir = (struct cdir *)&data[pos];
        pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header +
                                     arc_start];

        if (pcdir->tag != 0x02014b50)
            return FALSE;
        if (pfhdr->tag != 0x04034b50)
            return FALSE;
        pos += sizeof(struct cdir);
        fname = (char *)&data[pos]; /* This is not null terminated! */
        pos += pcdir->fname_length + pcdir->extra_length +
            pcdir->comment_length;

        pcomp = &data[pcdir->ofs_local_header
                      + sizeof(struct fhdr)
                      + arc_start
                      + pfhdr->fname_length
                      + pfhdr->extra_length];

        /* dirname is the Python home directory (prefix) */
        strcpy(pathname, dirname);
        if (pathname[strlen(pathname)-1] != '\\')
            strcat(pathname, "\\");
        new_part = &pathname[lstrlen(pathname)];
        /* we must now match the first part of the pathname
         * in the archive to a component in the installation
         * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA)
         * and replace this part by the one in the scheme to use
         */
        for (i = 0; scheme[i].name; ++i) {
            if (0 == strnicmp(scheme[i].name, fname,
                              strlen(scheme[i].name))) {
                char *rest;
                int len;

                /* length of the replaced part */
                int namelen = strlen(scheme[i].name);

                strcat(pathname, scheme[i].prefix);

                rest = fname + namelen;
                len = pfhdr->fname_length - namelen;

                if ((pathname[strlen(pathname)-1] != '\\')
                    && (pathname[strlen(pathname)-1] != '/'))
                    strcat(pathname, "\\");
                /* Now that pathname ends with a separator,
                 * we must make sure rest does not start with
                 * an additional one.
                 */
                if ((rest[0] == '\\') || (rest[0] == '/')) {
                    ++rest;
                    --len;
                }

                strncat(pathname, rest, len);
                goto Done;
            }
        }
        /* no prefix to replace found, go unchanged */
        strncat(pathname, fname, pfhdr->fname_length);
      Done:
        normpath(pathname);
        if (pathname[strlen(pathname)-1] != '\\') {
            /*
             * The local file header (pfhdr) does not always
             * contain the compressed and uncompressed sizes of
             * the data depending on bit 3 of the flags field.  So
             * it seems better to use the data from the central
             * directory (pcdir).
             */
            dst = map_new_file(0, pathname, new_part,
                               pcdir->uncomp_size,
                               pcdir->last_mod_file_date,
                               pcdir->last_mod_file_time, notify);
            if (dst) {
                if (!extract_file(dst, pcomp, pfhdr->method,
                                  pcdir->comp_size,
                                  pcdir->uncomp_size,
                                  notify))
                    return FALSE;
            } /* else ??? */
        }
        if (notify)
            notify(NUM_FILES, new_part, (int)pe->nTotalCDir,
                   (int)n+1);
    }
    return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function: