Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/PC/bdist_wininst/extract.c

    r2 r391  
    2020static void normpath(char *path)
    2121{
    22         while (path && *path) {
    23                 if (*path == '/')
    24                         *path = '\\';
    25                 ++path;
    26         }
     22    while (path && *path) {
     23        if (*path == '/')
     24            *path = '\\';
     25        ++path;
     26    }
    2727}
    2828
    2929BOOL ensure_directory(char *pathname, char *new_part, NOTIFYPROC notify)
    3030{
    31         while (new_part && *new_part && (new_part = strchr(new_part, '\\'))) {
    32                 DWORD attr;
    33                 *new_part = '\0';
    34                 attr = GetFileAttributes(pathname);
    35                 if (attr == -1) {
    36                         /* nothing found */
    37                         if (!CreateDirectory(pathname, NULL) && notify)
    38                                 notify(SYSTEM_ERROR,
    39                                        "CreateDirectory (%s)", pathname);
    40                         else
    41                                 notify(DIR_CREATED, pathname);
    42                 }
    43                 if (attr & FILE_ATTRIBUTE_DIRECTORY) {
    44                         ;
    45                 } else {
    46                         SetLastError(183);
    47                         if (notify)
    48                                 notify(SYSTEM_ERROR,
    49                                        "CreateDirectory (%s)", pathname);
    50                 }
    51                 *new_part = '\\';
    52                 ++new_part;
    53         }
    54         return TRUE;
    55 }
    56 
    57 /* XXX Should better explicitely specify
     31    while (new_part && *new_part && (new_part = strchr(new_part, '\\'))) {
     32        DWORD attr;
     33        *new_part = '\0';
     34        attr = GetFileAttributes(pathname);
     35        if (attr == -1) {
     36            /* nothing found */
     37            if (!CreateDirectory(pathname, NULL) && notify)
     38                notify(SYSTEM_ERROR,
     39                       "CreateDirectory (%s)", pathname);
     40            else
     41                notify(DIR_CREATED, pathname);
     42        }
     43        if (attr & FILE_ATTRIBUTE_DIRECTORY) {
     44            ;
     45        } else {
     46            SetLastError(183);
     47            if (notify)
     48                notify(SYSTEM_ERROR,
     49                       "CreateDirectory (%s)", pathname);
     50        }
     51        *new_part = '\\';
     52        ++new_part;
     53    }
     54    return TRUE;
     55}
     56
     57/* XXX Should better explicitly specify
    5858 * uncomp_size and file_times instead of pfhdr!
    5959 */
    6060char *map_new_file(DWORD flags, char *filename,
    61                    char *pathname_part, int size,
    62                    WORD wFatDate, WORD wFatTime,
    63                    NOTIFYPROC notify)
    64 {
    65         HANDLE hFile, hFileMapping;
    66         char *dst;
    67         FILETIME ft;
     61                   char *pathname_part, int size,
     62                   WORD wFatDate, WORD wFatTime,
     63                   NOTIFYPROC notify)
     64{
     65    HANDLE hFile, hFileMapping;
     66    char *dst;
     67    FILETIME ft;
    6868
    6969  try_again:
    70         if (!flags)
    71                 flags = CREATE_NEW;
    72         hFile = CreateFile(filename,
    73                            GENERIC_WRITE | GENERIC_READ,
    74                            0, NULL,
    75                            flags,
    76                            FILE_ATTRIBUTE_NORMAL, NULL);
    77         if (hFile == INVALID_HANDLE_VALUE) {
    78                 DWORD x = GetLastError();
    79                 switch (x) {
    80                 case ERROR_FILE_EXISTS:
    81                         if (notify && notify(CAN_OVERWRITE, filename))
    82                                 hFile = CreateFile(filename,
    83                                                    GENERIC_WRITE|GENERIC_READ,
    84                                                    0, NULL,
    85                                                    CREATE_ALWAYS,
    86                                                    FILE_ATTRIBUTE_NORMAL,
    87                                                    NULL);
    88                         else {
    89                                 if (notify)
    90                                         notify(FILE_OVERWRITTEN, filename);
    91                                 return NULL;
    92                         }
    93                         break;
    94                 case ERROR_PATH_NOT_FOUND:
    95                         if (ensure_directory(filename, pathname_part, notify))
    96                                 goto try_again;
    97                         else
    98                                 return FALSE;
    99                         break;
    100                 default:
    101                         SetLastError(x);
    102                         break;
    103                 }
    104         }
    105         if (hFile == INVALID_HANDLE_VALUE) {
    106                 if (notify)
    107                         notify (SYSTEM_ERROR, "CreateFile (%s)", filename);
    108                 return NULL;
    109         }
    110 
    111         if (notify)
    112                 notify(FILE_CREATED, filename);
    113 
    114         DosDateTimeToFileTime(wFatDate, wFatTime, &ft);
    115         SetFileTime(hFile, &ft, &ft, &ft);
    116 
    117 
    118         if (size == 0) {
    119                 /* We cannot map a zero-length file (Also it makes
    120                    no sense */
    121                 CloseHandle(hFile);
    122                 return NULL;
    123         }
    124 
    125         hFileMapping = CreateFileMapping(hFile,
    126                                         NULL, PAGE_READWRITE, 0, size, NULL);
    127 
    128         CloseHandle(hFile);
    129 
    130         if (hFileMapping == INVALID_HANDLE_VALUE) {
    131                 if (notify)
    132                         notify(SYSTEM_ERROR,
    133                                "CreateFileMapping (%s)", filename);
    134                 return NULL;
    135         }
    136 
    137         dst = MapViewOfFile(hFileMapping,
    138                             FILE_MAP_WRITE, 0, 0, 0);
    139 
    140         CloseHandle(hFileMapping);
    141 
    142         if (!dst) {
    143                 if (notify)
    144                         notify(SYSTEM_ERROR, "MapViewOfFile (%s)", filename);
    145                 return NULL;
    146         }
    147         return dst;
     70    if (!flags)
     71        flags = CREATE_NEW;
     72    hFile = CreateFile(filename,
     73                       GENERIC_WRITE | GENERIC_READ,
     74                       0, NULL,
     75                       flags,
     76                       FILE_ATTRIBUTE_NORMAL, NULL);
     77    if (hFile == INVALID_HANDLE_VALUE) {
     78        DWORD x = GetLastError();
     79        switch (x) {
     80        case ERROR_FILE_EXISTS:
     81            if (notify && notify(CAN_OVERWRITE, filename))
     82                hFile = CreateFile(filename,
     83                                   GENERIC_WRITE|GENERIC_READ,
     84                                   0, NULL,
     85                                   CREATE_ALWAYS,
     86                                   FILE_ATTRIBUTE_NORMAL,
     87                                   NULL);
     88            else {
     89                if (notify)
     90                    notify(FILE_OVERWRITTEN, filename);
     91                return NULL;
     92            }
     93            break;
     94        case ERROR_PATH_NOT_FOUND:
     95            if (ensure_directory(filename, pathname_part, notify))
     96                goto try_again;
     97            else
     98                return FALSE;
     99            break;
     100        default:
     101            SetLastError(x);
     102            break;
     103        }
     104    }
     105    if (hFile == INVALID_HANDLE_VALUE) {
     106        if (notify)
     107            notify (SYSTEM_ERROR, "CreateFile (%s)", filename);
     108        return NULL;
     109    }
     110
     111    if (notify)
     112        notify(FILE_CREATED, filename);
     113
     114    DosDateTimeToFileTime(wFatDate, wFatTime, &ft);
     115    SetFileTime(hFile, &ft, &ft, &ft);
     116
     117
     118    if (size == 0) {
     119        /* We cannot map a zero-length file (Also it makes
     120           no sense */
     121        CloseHandle(hFile);
     122        return NULL;
     123    }
     124
     125    hFileMapping = CreateFileMapping(hFile,
     126                                    NULL, PAGE_READWRITE, 0, size, NULL);
     127
     128    CloseHandle(hFile);
     129
     130    if (hFileMapping == INVALID_HANDLE_VALUE) {
     131        if (notify)
     132            notify(SYSTEM_ERROR,
     133                   "CreateFileMapping (%s)", filename);
     134        return NULL;
     135    }
     136
     137    dst = MapViewOfFile(hFileMapping,
     138                        FILE_MAP_WRITE, 0, 0, 0);
     139
     140    CloseHandle(hFileMapping);
     141
     142    if (!dst) {
     143        if (notify)
     144            notify(SYSTEM_ERROR, "MapViewOfFile (%s)", filename);
     145        return NULL;
     146    }
     147    return dst;
    148148}
    149149
     
    151151BOOL
    152152extract_file(char *dst, char *src, int method, int comp_size,
    153              int uncomp_size, NOTIFYPROC notify)
    154 {
    155         z_stream zstream;
    156         int result;
    157 
    158         if (method == Z_DEFLATED) {
    159                 int x;
    160                 memset(&zstream, 0, sizeof(zstream));
    161                 zstream.next_in = src;
    162                 zstream.avail_in = comp_size+1;
    163                 zstream.next_out = dst;
    164                 zstream.avail_out = uncomp_size;
     153             int uncomp_size, NOTIFYPROC notify)
     154{
     155    z_stream zstream;
     156    int result;
     157
     158    if (method == Z_DEFLATED) {
     159        int x;
     160        memset(&zstream, 0, sizeof(zstream));
     161        zstream.next_in = src;
     162        zstream.avail_in = comp_size+1;
     163        zstream.next_out = dst;
     164        zstream.avail_out = uncomp_size;
    165165
    166166/* Apparently an undocumented feature of zlib: Set windowsize
    167    to negative values to supress the gzip header and be compatible with
     167   to negative values to suppress the gzip header and be compatible with
    168168   zip! */
    169                 result = TRUE;
    170                 if (Z_OK != (x = inflateInit2(&zstream, -15))) {
    171                         if (notify)
    172                                 notify(ZLIB_ERROR,
    173                                        "inflateInit2 returns %d", x);
    174                         result = FALSE;
    175                         goto cleanup;
    176                 }
    177                 if (Z_STREAM_END != (x = inflate(&zstream, Z_FINISH))) {
    178                         if (notify)
    179                                 notify(ZLIB_ERROR,
    180                                        "inflate returns %d", x);
    181                         result = FALSE;
    182                 }
    183           cleanup:
    184                 if (Z_OK != (x = inflateEnd(&zstream))) {
    185                         if (notify)
    186                                 notify (ZLIB_ERROR,
    187                                         "inflateEnd returns %d", x);
    188                         result = FALSE;
    189                 }
    190         } else if (method == 0) {
    191                 memcpy(dst, src, uncomp_size);
    192                 result = TRUE;
    193         } else
    194                 result = FALSE;
    195         UnmapViewOfFile(dst);
    196         return result;
     169        result = TRUE;
     170        if (Z_OK != (x = inflateInit2(&zstream, -15))) {
     171            if (notify)
     172                notify(ZLIB_ERROR,
     173                       "inflateInit2 returns %d", x);
     174            result = FALSE;
     175            goto cleanup;
     176        }
     177        if (Z_STREAM_END != (x = inflate(&zstream, Z_FINISH))) {
     178            if (notify)
     179                notify(ZLIB_ERROR,
     180                       "inflate returns %d", x);
     181            result = FALSE;
     182        }
     183      cleanup:
     184        if (Z_OK != (x = inflateEnd(&zstream))) {
     185            if (notify)
     186                notify (ZLIB_ERROR,
     187                    "inflateEnd returns %d", x);
     188            result = FALSE;
     189        }
     190    } else if (method == 0) {
     191        memcpy(dst, src, uncomp_size);
     192        result = TRUE;
     193    } else
     194        result = FALSE;
     195    UnmapViewOfFile(dst);
     196    return result;
    197197}
    198198
     
    202202BOOL
    203203unzip_archive(SCHEME *scheme, char *dirname, char *data, DWORD size,
    204               NOTIFYPROC notify)
    205 {
    206         int n;
    207         char pathname[MAX_PATH];
    208         char *new_part;
    209 
    210         /* read the end of central directory record */
    211         struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
    212                                                        (struct eof_cdir)];
    213 
    214         int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir -
    215                 pe->ofsCDir;
    216 
    217         /* set position to start of central directory */
    218         int pos = arc_start + pe->ofsCDir;
    219 
    220         /* make sure this is a zip file */
    221         if (pe->tag != 0x06054b50)
    222                 return FALSE;
    223    
    224         /* Loop through the central directory, reading all entries */
    225         for (n = 0; n < pe->nTotalCDir; ++n) {
    226                 int i;
    227                 char *fname;
    228                 char *pcomp;
    229                 char *dst;
    230                 struct cdir *pcdir;
    231                 struct fhdr *pfhdr;
    232 
    233                 pcdir = (struct cdir *)&data[pos];
    234                 pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header +
    235                                              arc_start];
    236 
    237                 if (pcdir->tag != 0x02014b50)
    238                         return FALSE;
    239                 if (pfhdr->tag != 0x04034b50)
    240                         return FALSE;
    241                 pos += sizeof(struct cdir);
    242                 fname = (char *)&data[pos]; /* This is not null terminated! */
    243                 pos += pcdir->fname_length + pcdir->extra_length +
    244                         pcdir->comment_length;
    245 
    246                 pcomp = &data[pcdir->ofs_local_header
    247                               + sizeof(struct fhdr)
    248                               + arc_start
    249                               + pfhdr->fname_length
    250                               + pfhdr->extra_length];
    251 
    252                 /* dirname is the Python home directory (prefix) */
    253                 strcpy(pathname, dirname);
    254                 if (pathname[strlen(pathname)-1] != '\\')
    255                         strcat(pathname, "\\");
    256                 new_part = &pathname[lstrlen(pathname)];
    257                 /* we must now match the first part of the pathname
    258                 * in the archive to a component in the installation
    259                 * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA)
    260                 * and replace this part by the one in the scheme to use
    261                 */
    262                 for (i = 0; scheme[i].name; ++i) {
    263                         if (0 == strnicmp(scheme[i].name, fname,
    264                                           strlen(scheme[i].name))) {
    265                                 char *rest;
    266                                 int len;
    267                                
    268                                 /* length of the replaced part */
    269                                 int namelen = strlen(scheme[i].name);
    270                                
    271                                 strcat(pathname, scheme[i].prefix);
    272                                
    273                                 rest = fname + namelen;
    274                                 len = pfhdr->fname_length - namelen;
    275                                
    276                                 if ((pathname[strlen(pathname)-1] != '\\')
    277                                     && (pathname[strlen(pathname)-1] != '/'))
    278                                         strcat(pathname, "\\");
    279                                 /* Now that pathname ends with a separator,
    280                                 * we must make sure rest does not start with
    281                                 * an additional one.
    282                                 */
    283                                 if ((rest[0] == '\\') || (rest[0] == '/')) {
    284                                         ++rest;
    285                                         --len;
    286                                 }
    287 
    288                                 strncat(pathname, rest, len);
    289                                 goto Done;
    290                         }
    291                 }
    292                 /* no prefix to replace found, go unchanged */
    293                 strncat(pathname, fname, pfhdr->fname_length);
    294           Done:
    295                 normpath(pathname);
    296                 if (pathname[strlen(pathname)-1] != '\\') {
    297                         /*
    298                         * The local file header (pfhdr) does not always
    299                         * contain the compressed and uncompressed sizes of
    300                         * the data depending on bit 3 of the flags field.  So
    301                         * it seems better to use the data from the central
    302                         * directory (pcdir).
    303                         */
    304                         dst = map_new_file(0, pathname, new_part,
    305                                            pcdir->uncomp_size,
    306                                            pcdir->last_mod_file_date,
    307                                            pcdir->last_mod_file_time, notify);
    308                         if (dst) {
    309                                 if (!extract_file(dst, pcomp, pfhdr->method,
    310                                                   pcdir->comp_size,
    311                                                   pcdir->uncomp_size,
    312                                                   notify))
    313                                         return FALSE;
    314                         } /* else ??? */
    315                 }
    316                 if (notify)
    317                         notify(NUM_FILES, new_part, (int)pe->nTotalCDir,
    318                                (int)n+1);
    319         }
    320         return TRUE;
    321 }
     204              NOTIFYPROC notify)
     205{
     206    int n;
     207    char pathname[MAX_PATH];
     208    char *new_part;
     209
     210    /* read the end of central directory record */
     211    struct eof_cdir *pe = (struct eof_cdir *)&data[size - sizeof
     212                                                   (struct eof_cdir)];
     213
     214    int arc_start = size - sizeof (struct eof_cdir) - pe->nBytesCDir -
     215        pe->ofsCDir;
     216
     217    /* set position to start of central directory */
     218    int pos = arc_start + pe->ofsCDir;
     219
     220    /* make sure this is a zip file */
     221    if (pe->tag != 0x06054b50)
     222        return FALSE;
     223
     224    /* Loop through the central directory, reading all entries */
     225    for (n = 0; n < pe->nTotalCDir; ++n) {
     226        int i;
     227        char *fname;
     228        char *pcomp;
     229        char *dst;
     230        struct cdir *pcdir;
     231        struct fhdr *pfhdr;
     232
     233        pcdir = (struct cdir *)&data[pos];
     234        pfhdr = (struct fhdr *)&data[pcdir->ofs_local_header +
     235                                     arc_start];
     236
     237        if (pcdir->tag != 0x02014b50)
     238            return FALSE;
     239        if (pfhdr->tag != 0x04034b50)
     240            return FALSE;
     241        pos += sizeof(struct cdir);
     242        fname = (char *)&data[pos]; /* This is not null terminated! */
     243        pos += pcdir->fname_length + pcdir->extra_length +
     244            pcdir->comment_length;
     245
     246        pcomp = &data[pcdir->ofs_local_header
     247                      + sizeof(struct fhdr)
     248                      + arc_start
     249                      + pfhdr->fname_length
     250                      + pfhdr->extra_length];
     251
     252        /* dirname is the Python home directory (prefix) */
     253        strcpy(pathname, dirname);
     254        if (pathname[strlen(pathname)-1] != '\\')
     255            strcat(pathname, "\\");
     256        new_part = &pathname[lstrlen(pathname)];
     257        /* we must now match the first part of the pathname
     258        * in the archive to a component in the installation
     259        * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA)
     260        * and replace this part by the one in the scheme to use
     261        */
     262        for (i = 0; scheme[i].name; ++i) {
     263            if (0 == strnicmp(scheme[i].name, fname,
     264                              strlen(scheme[i].name))) {
     265                char *rest;
     266                int len;
     267
     268                /* length of the replaced part */
     269                int namelen = strlen(scheme[i].name);
     270
     271                strcat(pathname, scheme[i].prefix);
     272
     273                rest = fname + namelen;
     274                len = pfhdr->fname_length - namelen;
     275
     276                if ((pathname[strlen(pathname)-1] != '\\')
     277                    && (pathname[strlen(pathname)-1] != '/'))
     278                    strcat(pathname, "\\");
     279                /* Now that pathname ends with a separator,
     280                * we must make sure rest does not start with
     281                * an additional one.
     282                */
     283                if ((rest[0] == '\\') || (rest[0] == '/')) {
     284                    ++rest;
     285                    --len;
     286                }
     287
     288                strncat(pathname, rest, len);
     289                goto Done;
     290            }
     291        }
     292        /* no prefix to replace found, go unchanged */
     293        strncat(pathname, fname, pfhdr->fname_length);
     294      Done:
     295        normpath(pathname);
     296        if (pathname[strlen(pathname)-1] != '\\') {
     297            /*
     298            * The local file header (pfhdr) does not always
     299            * contain the compressed and uncompressed sizes of
     300            * the data depending on bit 3 of the flags field.  So
     301            * it seems better to use the data from the central
     302            * directory (pcdir).
     303            */
     304            dst = map_new_file(0, pathname, new_part,
     305                               pcdir->uncomp_size,
     306                               pcdir->last_mod_file_date,
     307                               pcdir->last_mod_file_time, notify);
     308            if (dst) {
     309                if (!extract_file(dst, pcomp, pfhdr->method,
     310                                  pcdir->comp_size,
     311                                  pcdir->uncomp_size,
     312                                  notify))
     313                    return FALSE;
     314            } /* else ??? */
     315        }
     316        if (notify)
     317            notify(NUM_FILES, new_part, (int)pe->nTotalCDir,
     318                   (int)n+1);
     319    }
     320    return TRUE;
     321}
Note: See TracChangeset for help on using the changeset viewer.