~ubuntu-branches/ubuntu/quantal/unzip/quantal

« back to all changes in this revision

Viewing changes to win32/win32.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2009-05-08 20:02:40 UTC
  • mfrom: (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090508200240-rk23wg0jdoyc6caj
Tags: 6.0-1
* New upstream release. Closes: #496989.
* Enabled new Unicode support. Closes: #197427. This may or may not work
  for your already created zipfiles, but it's not a bug unless they were
  created using the Unicode feature present in zip 3.0.
* Built using DATE_FORMAT=DF_YMD so that unzip -l show dates in ISO format,
  as that's the only available one which makes sense. Closes: #312886.
* Enabled new bzip2 support. Closes: #426798.
* Exit code for zipgrep should now be the right one. Closes: #441997.
* The reason why a file may not be created is now shown. Closes: #478791.
* Summary of changes in this version not being the debian/* files:
- Manpages in section 1, not 1L.
- Branding patch. UnZip by Debian. Original by Info-ZIP.
- Always #include <unistd.h>. Debian GNU/kFreeBSD needs it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
  Copyright (c) 1990-2005 Info-ZIP.  All rights reserved.
 
2
  Copyright (c) 1990-2008 Info-ZIP.  All rights reserved.
3
3
 
4
 
  See the accompanying file LICENSE, version 2000-Apr-09 or later
 
4
  See the accompanying file LICENSE, version 2007-Mar-04 or later
5
5
  (the contents of which are also included in unzip.h) for terms of use.
6
6
  If, for some reason, all these files are missing, the Info-ZIP license
7
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
157
157
static void map2fat         (char *pathcomp, char **pEndFAT);
158
158
 
159
159
 
160
 
#ifdef __MINGW32__
 
160
#if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING))
161
161
   int _CRT_glob = 0;   /* suppress command line globbing by C RTL */
162
162
#endif
163
163
 
197
197
 
198
198
#else    /* use generic API call */
199
199
 
200
 
    GetModuleFileName(NULL, G.filename, FILNAMSIZ-1);
 
200
    GetModuleFileName(NULL, G.filename, FILNAMSIZ);
201
201
    _ISO_INTERN(G.filename);    /* translate to codepage of C rtl's stdio */
202
202
    return G.filename;
203
203
#endif
221
221
{
222
222
    zDIR *d;                /* malloc'd return value */
223
223
    char *p;                /* malloc'd temporary string */
224
 
    WIN32_FIND_DATA fd;
 
224
    WIN32_FIND_DATAA fd;
225
225
    extent len = strlen(n);
226
226
 
227
227
    /* Start searching for files in directory n */
242
242
    }
243
243
    strcpy(p+len, "/*");
244
244
 
245
 
    if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFile(p, &fd))) {
 
245
    if (INVALID_HANDLE_VALUE == (d->d_hFindFile = FindFirstFileA(p, &fd))) {
246
246
        free((zvoid *)d);
247
247
        free((zvoid *)p);
248
248
        return NULL;
271
271
        d->d_first = 0;
272
272
    else
273
273
    {
274
 
        WIN32_FIND_DATA fd;
 
274
        WIN32_FIND_DATAA fd;
275
275
 
276
 
        if ( !FindNextFile(d->d_hFindFile, &fd) )
 
276
        if ( !FindNextFileA(d->d_hFindFile, &fd) )
277
277
            return NULL;
278
278
 
279
279
        ISO_TO_INTERN(fd.cFileName, d->d_name);
631
631
    SYSTEMTIME w32tm;
632
632
    FILETIME lft;
633
633
 
 
634
    /* The milliseconds field gets always initialized to 0. */
 
635
    w32tm.wMilliseconds = 0;
 
636
 
634
637
#ifdef __BORLANDC__   /* Borland C++ 5.x crashes when trying to reference tm */
635
638
    if (utc < UTIME_1980_JAN_01_00_00)
636
639
        utc = UTIME_1980_JAN_01_00_00;
806
809
#endif
807
810
 
808
811
    if (!FileTimeToLocalFileTime(pft, &lft)) {
809
 
        /* if pft cannot be converted to local time, return current time */
810
 
        return time(NULL);
 
812
        /* if pft cannot be converted to local time, set ut to current time */
 
813
        time(ut);
 
814
        return FALSE;
811
815
    }
812
816
    FTTrace((stdout, "VFatFT2utime, feed for mktime()", 1, &lft));
813
817
#ifndef HAVE_MKTIME
992
996
/* Function SetFileSize() */
993
997
/**************************/
994
998
 
995
 
int SetFileSize(FILE *file, ulg filesize)
 
999
int SetFileSize(FILE *file, zusz_t filesize)
996
1000
{
997
1001
#ifdef __RSXNT__
998
1002
    /* RSXNT environment lacks a translation function from C file pointer
1003
1007
      rommel@ars.de
1004
1008
     */
1005
1009
    HANDLE os_fh;
 
1010
#ifdef Z_UINT8_DEFINED
 
1011
    LARGE_INTEGER fsbuf;
 
1012
#endif
1006
1013
 
1007
1014
    /* Win9x supports FAT file system, only; presetting file size does
1008
1015
       not help to prevent fragmentation. */
1016
1023
     */
1017
1024
    os_fh = (HANDLE)_get_osfhandle(fileno(file));
1018
1025
    /* move file pointer behind the last byte of the expected file size */
1019
 
    if (SetFilePointer(os_fh, filesize, 0, FILE_BEGIN) == 0xFFFFFFFF)
 
1026
#ifdef Z_UINT8_DEFINED
 
1027
    fsbuf.QuadPart = filesize;
 
1028
    if ((SetFilePointer(os_fh, fsbuf.LowPart, &fsbuf.HighPart, FILE_BEGIN)
 
1029
         == 0xFFFFFFFF) && GetLastError() != NO_ERROR)
 
1030
#else
 
1031
    if (SetFilePointer(os_fh, (ulg)filesize, 0, FILE_BEGIN) == 0xFFFFFFFF)
 
1032
#endif
1020
1033
        return -1;
1021
1034
    /* extend/truncate file to the current position */
1022
1035
    if (SetEndOfFile(os_fh) == 0)
1039
1052
    FILETIME Modft;    /* File time type defined in NT, `last modified' time */
1040
1053
    FILETIME Accft;    /* NT file time type, `last access' time */
1041
1054
    FILETIME Creft;    /* NT file time type, `file creation' time */
1042
 
    HANDLE hFile;      /* File handle defined in NT    */
 
1055
    HANDLE hFile = INVALID_HANDLE_VALUE;        /* File handle defined in NT */
1043
1056
    int gotTime;
1044
1057
#ifdef NTSD_EAS
1045
1058
    uch *ebSDptr;
1054
1067
#   define Ansi_Fname  G.filename
1055
1068
#endif
1056
1069
 
 
1070
#ifndef __RSXNT__
 
1071
    if (IsWinNT()) {
 
1072
        /* Truncate the file to the current position.
 
1073
         * This is needed to remove excess allocation in case the
 
1074
         * extraction has failed or stopped prematurely. */
 
1075
        SetEndOfFile((HANDLE)_get_osfhandle(fileno(G.outfile)));
 
1076
    }
 
1077
#endif
 
1078
 
1057
1079
    /* Close the file and then re-open it using the Win32
1058
1080
     * CreateFile call, so that the file can be created
1059
1081
     * with GENERIC_WRITE access, otherwise the SetFileTime
1064
1086
    if (uO.cflag)
1065
1087
        return;
1066
1088
 
1067
 
    gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft);
 
1089
    /* skip restoring time stamps on user's request */
 
1090
    if (uO.D_flag <= 1) {
 
1091
        gotTime = getNTfiletime(__G__ &Modft, &Accft, &Creft);
1068
1092
 
1069
 
    /* open a handle to the file before processing extra fields;
1070
 
       we do this in case new security on file prevents us from updating
1071
 
       time stamps */
1072
 
    hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
1073
 
         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
1093
        /* open a handle to the file before processing extra fields;
 
1094
           we do this in case new security on file prevents us from updating
 
1095
           time stamps */
 
1096
        hFile = CreateFileA(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
 
1097
             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
1098
    } else {
 
1099
        gotTime = 0;
 
1100
    }
1074
1101
 
1075
1102
    /* sfield@microsoft.com: set attributes before time in case we decide to
1076
1103
       support other filetime members later.  This also allows us to apply
1080
1107
       FILE_ATTRIBUTE_ARCHIVE appears in the attributes.  This works well
1081
1108
       as an optimization because FILE_ATTRIBUTE_ARCHIVE gets applied to the
1082
1109
       file anyway, when it's created new. */
1083
 
    if((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) {
1084
 
        if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F))
 
1110
    if ((G.pInfo->file_attr & 0x7F) & ~FILE_ATTRIBUTE_ARCHIVE) {
 
1111
        if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F))
1085
1112
            Info(slide, 1, ((char *)slide,
1086
1113
              "\nwarning (%d): could not set file attributes\n",
1087
1114
              (int)GetLastError()));
1106
1133
    }
1107
1134
#endif /* NTSD_EAS */
1108
1135
 
1109
 
    if ( hFile == INVALID_HANDLE_VALUE )
1110
 
        Info(slide, 1, ((char *)slide,
1111
 
          "\nCreateFile() error %d when trying set file time\n",
1112
 
          (int)GetLastError()));
1113
 
    else {
1114
 
        if (gotTime) {
1115
 
            FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
1116
 
            FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
1117
 
            FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
 
1136
    /* skip restoring time stamps on user's request */
 
1137
    if (uO.D_flag <= 1) {
 
1138
        if ( hFile == INVALID_HANDLE_VALUE )
 
1139
            Info(slide, 1, ((char *)slide,
 
1140
              "\nCreateFile() error %d when trying set file time\n",
 
1141
              (int)GetLastError()));
 
1142
        else {
 
1143
            if (gotTime) {
 
1144
                FILETIME *pModft = (gotTime & EB_UT_FL_MTIME) ? &Modft : NULL;
 
1145
                FILETIME *pAccft = (gotTime & EB_UT_FL_ATIME) ? &Accft : NULL;
 
1146
                FILETIME *pCreft = (gotTime & EB_UT_FL_CTIME) ? &Creft : NULL;
1118
1147
 
1119
 
            if (!SetFileTime(hFile, pCreft, pAccft, pModft))
1120
 
                Info(slide, 0, ((char *)slide, "\nSetFileTime failed: %d\n",
1121
 
                  (int)GetLastError()));
 
1148
                if (!SetFileTime(hFile, pCreft, pAccft, pModft))
 
1149
                    Info(slide, 0, ((char *)slide,
 
1150
                      "\nSetFileTime failed: %d\n", (int)GetLastError()));
 
1151
            }
 
1152
            CloseHandle(hFile);
1122
1153
        }
1123
 
        CloseHandle(hFile);
1124
1154
    }
1125
1155
 
1126
1156
    return;
1186
1216
 
1187
1217
    d_entry->perms = G.pInfo->file_attr;
1188
1218
 
1189
 
    d_entry->gotTime = getNTfiletime(__G__ &(d_entry->Modft),
1190
 
                                     &(d_entry->Accft), &(d_entry->Creft));
 
1219
    d_entry->gotTime = (uO.D_flag <= 0
 
1220
                        ? getNTfiletime(__G__ &(d_entry->Modft),
 
1221
                                        &(d_entry->Accft), &(d_entry->Creft))
 
1222
                        : 0);
1191
1223
    return PK_OK;
1192
1224
} /* end function defer_dir_attribs() */
1193
1225
 
1197
1229
    direntry *d;
1198
1230
{
1199
1231
    int errval;
1200
 
    HANDLE hFile;      /* File handle defined in NT    */
 
1232
    HANDLE hFile = INVALID_HANDLE_VALUE;        /* File handle defined in NT */
1201
1233
#ifdef __RSXNT__
1202
1234
    char *ansi_name;
1203
1235
#endif
1215
1247
#   define Ansi_Dirname  d->fn
1216
1248
#endif
1217
1249
 
1218
 
    /* Open a handle to the directory before processing extra fields;
1219
 
       we do this in case new security on file prevents us from updating
1220
 
       time stamps.
1221
 
       Although the WIN32 documentation recommends to use GENERIC_WRITE
1222
 
       access flag to create the handle for SetFileTime(), this is too
1223
 
       demanding for directories with the "read-only" attribute bit set.
1224
 
       So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
1225
 
       request the minimum required access rights. (This problem is a
1226
 
       Windows bug that has been silently fixed in Windows XP SP2.) */
1227
 
    hFile = CreateFile(Ansi_Dirname, FILE_WRITE_ATTRIBUTES,
1228
 
                       FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
1229
 
                       OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 
1250
    /* Skip restoring directory time stamps on user' request. */
 
1251
    if (uO.D_flag <= 0) {
 
1252
        /* Open a handle to the directory before processing extra fields;
 
1253
           we do this in case new security on file prevents us from updating
 
1254
           time stamps.
 
1255
           Although the WIN32 documentation recommends to use GENERIC_WRITE
 
1256
           access flag to create the handle for SetFileTime(), this is too
 
1257
           demanding for directories with the "read-only" attribute bit set.
 
1258
           So we use the more specific flag FILE_WRITE_ATTRIBUTES here to
 
1259
           request the minimum required access rights. (This problem is a
 
1260
           Windows bug that has been silently fixed in Windows XP SP2.) */
 
1261
        hFile = CreateFileA(Ansi_Dirname, FILE_WRITE_ATTRIBUTES,
 
1262
                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
 
1263
                            OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 
1264
    }
1230
1265
 
1231
1266
#ifdef NTSD_EAS
1232
1267
    if (NtAtt(d)->SDlen > 0) {
1254
1289
    }
1255
1290
#endif /* NTSD_EAS */
1256
1291
 
1257
 
    if (hFile == INVALID_HANDLE_VALUE) {
1258
 
        Info(slide, 1, ((char *)slide,
1259
 
          "warning: CreateFile() error %d (set file times for %s)\n",
1260
 
          (int)GetLastError(), FnFilter1(d->fn)));
1261
 
        if (!errval)
1262
 
            errval = PK_WARN;
1263
 
    } else {
1264
 
        if (NtAtt(d)->gotTime) {
1265
 
            FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME)
1266
 
                              ? &(NtAtt(d)->Modft) : NULL;
1267
 
            FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME)
1268
 
                              ? &(NtAtt(d)->Accft) : NULL;
1269
 
            FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME)
1270
 
                              ? &(NtAtt(d)->Creft) : NULL;
 
1292
    /* Skip restoring directory time stamps on user' request. */
 
1293
    if (uO.D_flag <= 0) {
 
1294
        if (hFile == INVALID_HANDLE_VALUE) {
 
1295
            Info(slide, 1, ((char *)slide,
 
1296
              "warning: CreateFile() error %d (set file times for %s)\n",
 
1297
              (int)GetLastError(), FnFilter1(d->fn)));
 
1298
            if (!errval)
 
1299
                errval = PK_WARN;
 
1300
        } else {
 
1301
            if (NtAtt(d)->gotTime) {
 
1302
                FILETIME *pModft = (NtAtt(d)->gotTime & EB_UT_FL_MTIME)
 
1303
                                  ? &(NtAtt(d)->Modft) : NULL;
 
1304
                FILETIME *pAccft = (NtAtt(d)->gotTime & EB_UT_FL_ATIME)
 
1305
                                  ? &(NtAtt(d)->Accft) : NULL;
 
1306
                FILETIME *pCreft = (NtAtt(d)->gotTime & EB_UT_FL_CTIME)
 
1307
                                  ? &(NtAtt(d)->Creft) : NULL;
1271
1308
 
1272
 
            if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
1273
 
                Info(slide, 0, ((char *)slide,
1274
 
                  "warning:  SetFileTime() for %s error %d\n",
1275
 
                  FnFilter1(d->fn), (int)GetLastError()));
1276
 
                if (!errval)
1277
 
                    errval = PK_WARN;
 
1309
                if (!SetFileTime(hFile, pCreft, pAccft, pModft)) {
 
1310
                    Info(slide, 0, ((char *)slide,
 
1311
                      "warning:  SetFileTime() for %s error %d\n",
 
1312
                      FnFilter1(d->fn), (int)GetLastError()));
 
1313
                    if (!errval)
 
1314
                        errval = PK_WARN;
 
1315
                }
1278
1316
            }
 
1317
            CloseHandle(hFile);
1279
1318
        }
1280
 
        CloseHandle(hFile);
1281
1319
    }
1282
1320
 
1283
1321
    return errval;
1310
1348
#endif
1311
1349
 
1312
1350
    /* open a handle to the file to prepare setting the mod-time stamp */
1313
 
    hFile = CreateFile(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
 
1351
    hFile = CreateFileA(Ansi_Fname, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
1314
1352
         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1315
1353
    if ( hFile == INVALID_HANDLE_VALUE ) {
1316
1354
        errstat = -1;
1347
1385
    rootPathName[2] = '/';
1348
1386
    rootPathName[3] = '\0';
1349
1387
 
1350
 
    return (GetDriveType(rootPathName) == DRIVE_REMOVABLE);
 
1388
    return (GetDriveTypeA(rootPathName) == DRIVE_REMOVABLE);
1351
1389
 
1352
1390
} /* end function isfloppy() */
1353
1391
 
1380
1418
    name = ansi_name;
1381
1419
#endif
1382
1420
 
1383
 
    if ((!strncmp(name, "//", 2) || !strncmp(name,"\\\\", 2)) &&
 
1421
    if ((!strncmp(name, "//", 2) || !strncmp(name, "\\\\", 2)) &&
1384
1422
        (name[2] != '\0' && name[2] != '/' && name[2] != '\\')) {
1385
1423
        /* GetFullPathname() and GetVolumeInformation() do not work
1386
1424
         * on UNC names. For now, we return "error".
1393
1431
        tmp0 = (char *)name;
1394
1432
    else
1395
1433
    {
1396
 
        if (!GetFullPathName(name, MAX_PATH, tmp1, &tmp0))
 
1434
        if (!GetFullPathNameA(name, MAX_PATH, tmp1, &tmp0))
1397
1435
            return FALSE;
1398
1436
        tmp0 = &tmp1[0];
1399
1437
    }
1403
1441
        G.lastRootPath[2] = '/';            /* e.g. "A:/"                */
1404
1442
        G.lastRootPath[3] = '\0';
1405
1443
 
1406
 
        if (!GetVolumeInformation((LPCTSTR)G.lastRootPath,
1407
 
              (LPTSTR)tmp1, (DWORD)MAX_PATH,
 
1444
        if (!GetVolumeInformationA((LPCSTR)G.lastRootPath,
 
1445
              (LPSTR)tmp1, (DWORD)MAX_PATH,
1408
1446
              &volSerNo, &maxCompLen, &fileSysFlags,
1409
 
              (LPTSTR)tmp2, (DWORD)MAX_PATH)) {
 
1447
              (LPSTR)tmp2, (DWORD)MAX_PATH)) {
1410
1448
            G.lastRootPath[0] = '\0';
1411
1449
            return FALSE;
1412
1450
        }
1794
1832
               attribute need not be masked, since it does not prevent
1795
1833
               modifications in the new directory. */
1796
1834
            if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
1797
 
                if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F))
 
1835
                if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F))
1798
1836
                    Info(slide, 1, ((char *)slide,
1799
1837
                      "\nwarning (%d): could not set file attributes for %s\n",
1800
1838
                      (int)GetLastError(), FnFilter1(G.filename)));
1807
1845
 
1808
1846
            /* set file attributes: */
1809
1847
            if(G.pInfo->file_attr & (0x7F & ~FILE_ATTRIBUTE_DIRECTORY)) {
1810
 
                if (!SetFileAttributes(Ansi_Fname, G.pInfo->file_attr & 0x7F))
 
1848
                if (!SetFileAttributesA(Ansi_Fname, G.pInfo->file_attr & 0x7F))
1811
1849
                    Info(slide, 1, ((char *)slide,
1812
1850
                      "\nwarning (%d): could not set file attributes for %s\n",
1813
1851
                      (int)GetLastError(), FnFilter1(G.filename)));
1875
1913
        if (QCOND2)
1876
1914
            Info(slide, 0, ((char *)slide, "labelling %s %-22s\n", drive,
1877
1915
              FnFilter1(G.filename)));
1878
 
        if (!SetVolumeLabel(drive, Ansi_Fname)) {
 
1916
        if (!SetVolumeLabelA(drive, Ansi_Fname)) {
1879
1917
            Info(slide, 1, ((char *)slide,
1880
1918
              "mapname:  error setting volume label\n"));
1881
1919
            return (error & ~MPN_MASK) | MPN_ERR_SKIP;
1919
1957
#endif
1920
1958
 
1921
1959
#ifdef DEBUG
1922
 
    if (stat(pathcomp, &G.statbuf) == 0) {
 
1960
    if (zstat(pathcomp, &G.statbuf) == 0) {
1923
1961
        Trace((stderr,
1924
1962
               "maskDOSdevice() stat(\"%s\", buf) st_mode result: %X, %o\n",
1925
1963
               FnFilter1(pathcomp), G.statbuf.st_mode, G.statbuf.st_mode));
1928
1966
               FnFilter1(pathcomp)));
1929
1967
    }
1930
1968
#endif
1931
 
    if (stat(pathcomp, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) {
 
1969
    if (zstat(pathcomp, &G.statbuf) == 0 && S_ISCHR(G.statbuf.st_mode)) {
1932
1970
        extent i;
1933
1971
 
1934
1972
        /* pathcomp contains a name of a DOS character device (builtin or
2133
2171
            if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */
2134
2172
                Info(slide, 1, ((char *)slide,
2135
2173
                  "checkdir error:  cannot create %s\n\
 
2174
                 %s\n\
2136
2175
                 unable to process %s.\n",
2137
 
                  FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
 
2176
                  FnFilter2(G.buildpathFAT),
 
2177
                  strerror(errno),
 
2178
                  FnFilter1(G.filename)));
2138
2179
                free(G.buildpathHPFS);
2139
2180
                free(G.buildpathFAT);
2140
2181
                /* path didn't exist, tried to create, failed */
2163
2204
            if (MKDIR(G.buildpathFAT, 0777) == -1) { /* create the directory */
2164
2205
                Info(slide, 1, ((char *)slide,
2165
2206
                  "checkdir error:  cannot create %s\n\
 
2207
                 %s\n\
2166
2208
                 unable to process %s.\n",
2167
 
                  FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
 
2209
                  FnFilter2(G.buildpathFAT),
 
2210
                  strerror(errno),
 
2211
                  FnFilter1(G.filename)));
2168
2212
                free(G.buildpathHPFS);
2169
2213
                free(G.buildpathFAT);
2170
2214
                /* path didn't exist, tried to create, failed */
2173
2217
            G.created_dir = TRUE;
2174
2218
        } else if (!S_ISDIR(G.statbuf.st_mode)) {
2175
2219
            Info(slide, 1, ((char *)slide,
2176
 
              "checkdir error:  %s exists but is not directory\n   \
2177
 
              unable to process %s.\n",
 
2220
              "checkdir error:  %s exists but is not directory\n\
 
2221
                 unable to process %s.\n",
2178
2222
              FnFilter2(G.buildpathFAT), FnFilter1(G.filename)));
2179
2223
            free(G.buildpathHPFS);
2180
2224
            free(G.buildpathFAT);
2184
2228
        if (too_long) {
2185
2229
            Info(slide, 1, ((char *)slide,
2186
2230
              "checkdir error:  path too long: %s\n",
2187
 
               FnFilter1(G.buildpathHPFS)));
 
2231
              FnFilter1(G.buildpathHPFS)));
2188
2232
            free(G.buildpathHPFS);
2189
2233
            free(G.buildpathFAT);
2190
2234
            /* no room for filenames:  fatal */
2227
2271
        int error = MPN_OK;
2228
2272
 
2229
2273
        Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
 
2274
        /* The buildpathHPFS buffer has been allocated large enough to
 
2275
         * hold the complete combined name, so there is no need to check
 
2276
         * for OS filename size limit overflow within the copy loop.
 
2277
         */
2230
2278
        while ((*G.endHPFS = *p++) != '\0') {   /* copy to HPFS filename */
2231
2279
            ++G.endHPFS;
2232
 
            if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) {
2233
 
                *--G.endHPFS = '\0';
2234
 
                Info(slide, 1, ((char *)slide,
2235
 
                  "checkdir warning:  path too long; truncating\n \
2236
 
                  %s\n                -> %s\n",
2237
 
                  FnFilter1(G.filename), FnFilter2(G.buildpathHPFS)));
2238
 
                error = MPN_INF_TRUNC;   /* filename truncated */
2239
 
            }
 
2280
        }
 
2281
        /* Now, check for OS filename size overflow.  When detected, the
 
2282
         * mapped HPFS name is truncated and a warning message is shown.
 
2283
         */
 
2284
        if ((G.endHPFS-G.buildpathHPFS) >= FILNAMSIZ) {
 
2285
            G.buildpathHPFS[FILNAMSIZ-1] = '\0';
 
2286
            Info(slide, 1, ((char *)slide,
 
2287
              "checkdir warning:  path too long; truncating\n \
 
2288
              %s\n                -> %s\n",
 
2289
              FnFilter1(G.filename), FnFilter2(G.buildpathHPFS)));
 
2290
            error = MPN_INF_TRUNC;  /* filename truncated */
2240
2291
        }
2241
2292
 
2242
 
        if ( G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
 
2293
        /* The buildpathFAT buffer has the same allocated size as the
 
2294
         * buildpathHPFS buffer, so there is no need for an overflow check
 
2295
         * within the following copy loop, either.
 
2296
         */
 
2297
        if (G.pInfo->vollabel || !IsVolumeOldFAT(__G__ G.buildpathHPFS)) {
 
2298
            /* copy to FAT filename, too */
2243
2299
            p = pathcomp;
2244
 
            while ((*G.endFAT = *p++) != '\0')  /* copy to FAT filename, too */
 
2300
            while ((*G.endFAT = *p++) != '\0')
2245
2301
                ++G.endFAT;
2246
2302
        } else
2247
 
            map2fat(pathcomp, &G.endFAT);   /* map into FAT fn, update endFAT */
 
2303
            /* map into FAT fn, update endFAT */
 
2304
            map2fat(pathcomp, &G.endFAT);
 
2305
 
 
2306
        /* Check that the FAT path does not exceed the FILNAMSIZ limit, and
 
2307
         * truncate when neccessary.
 
2308
         * Note that truncation can only happen when the HPFS path (which is
 
2309
         * never shorter than the FAT path) has been already truncated.
 
2310
         * So, emission of the warning message and setting the error code
 
2311
         * has already happened.
 
2312
         */
 
2313
        if ((G.endFAT-G.buildpathFAT) >= FILNAMSIZ)
 
2314
            G.buildpathFAT[FILNAMSIZ-1] = '\0';
2248
2315
        Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT:  %s\n",
2249
2316
          FnFilter1(G.buildpathHPFS), FnFilter2(G.buildpathFAT)));
2250
2317
 
2287
2354
                *G.buildpathHPFS = (char)ToLower(*G.rootpath);
2288
2355
            else {
2289
2356
                char tmpN[MAX_PATH], *tmpP;
2290
 
                if (GetFullPathName(".", MAX_PATH, tmpN, &tmpP) > MAX_PATH)
 
2357
                if (GetFullPathNameA(".", MAX_PATH, tmpN, &tmpP) > MAX_PATH)
2291
2358
                { /* by definition of MAX_PATH we should never get here */
2292
2359
                    Info(slide, 1, ((char *)slide,
2293
2360
                      "checkdir warning: current dir path too long\n"));
2427
2494
 
2428
2495
int dateformat()
2429
2496
{
2430
 
  TCHAR df[2];  /* LOCALE_IDATE has a maximum value of 2 */
 
2497
  char df[2];   /* LOCALE_IDATE has a maximum value of 2 */
2431
2498
 
2432
 
  if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDATE, df, 2) != 0) {
 
2499
  if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDATE, df, 2) != 0) {
2433
2500
    switch (df[0])
2434
2501
    {
2435
2502
      case '0':
2450
2517
 
2451
2518
char dateseparator()
2452
2519
{
2453
 
  TCHAR df[2];  /* use only if it is one character */
 
2520
  char df[2];   /* use only if it is one character */
2454
2521
 
2455
 
  if ((GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDATE, df, 2) != 0) &&
 
2522
  if ((GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE, df, 2) != 0) &&
2456
2523
      (df[0] != '\0'))
2457
2524
    return df[0];
2458
2525
  else
2622
2689
 * are not stable but vary according to the seasonal change of "daylight
2623
2690
 * saving time in effect / not in effect".
2624
2691
 *
2625
 
 * Other C runtime libs (CygWin, or the crtdll.dll supplied with Win9x/NT
 
2692
 * Other C runtime libs (CygWin), or the crtdll.dll supplied with Win9x/NT
2626
2693
 * return the unix-time equivalent of the UTC FILETIME values as got back
2627
2694
 * from the Win32 API call. This time, return values from NTFS are correct
2628
2695
 * whereas utimes from files on (V)FAT volumes vary according to the DST
2645
2712
 * detects the case and fills in reasonable values.  Otherwise we get    *
2646
2713
 * effects like failure to extract to a root dir because it's not found. */
2647
2714
 
2648
 
int zstat_win32(__W32STAT_GLOBALS__ const char *path, struct stat *buf)
 
2715
int zstat_win32(__W32STAT_GLOBALS__ const char *path, z_stat *buf)
2649
2716
{
2650
 
    if (!stat(path, buf))
 
2717
    if (!zstat(path, buf))
2651
2718
    {
2652
2719
        /* stat was successful, now redo the time-stamp fetches */
2653
2720
#ifndef NO_W32TIMES_IZFIX
2665
2732
#endif
2666
2733
 
2667
2734
        TTrace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
2668
 
        h = CreateFile(Ansi_Path, GENERIC_READ,
2669
 
                       FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2670
 
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 
2735
        h = CreateFileA(Ansi_Path, GENERIC_READ,
 
2736
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
 
2737
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2671
2738
        if (h != INVALID_HANDLE_VALUE) {
2672
2739
            BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
2673
2740
            CloseHandle(h);
2730
2797
#       define Ansi_Path  path
2731
2798
#endif
2732
2799
 
2733
 
        flags = GetFileAttributes(Ansi_Path);
 
2800
        flags = GetFileAttributesA(Ansi_Path);
2734
2801
        if (flags != 0xFFFFFFFF && flags & FILE_ATTRIBUTE_DIRECTORY) {
2735
2802
            Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
2736
2803
                   FnFilter1(path)));
2737
 
            memset(buf, 0, sizeof(struct stat));
 
2804
            memset(buf, 0, sizeof(z_stat));
2738
2805
            buf->st_atime = buf->st_ctime = buf->st_mtime =
2739
2806
              dos_to_unix_time(DOSTIME_MINIMUM);        /* 1-1-80 */
2740
2807
            buf->st_mode = S_IFDIR | S_IREAD |
2850
2917
#  ifdef PASSWD_FROM_STDIN
2851
2918
  stin = GetStdHandle(STD_INPUT_HANDLE);
2852
2919
#  else
2853
 
  stin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
2854
 
                    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
 
2920
  stin = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE,
 
2921
                     FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
2855
2922
  if (stin == INVALID_HANDLE_VALUE)
2856
2923
    return -1;
2857
2924
#  endif
2874
2941
  return ret;
2875
2942
}
2876
2943
#endif /* !WINDLL */
 
2944
 
 
2945
 
 
2946
 
 
2947
#if (defined(UNICODE_SUPPORT) && !defined(FUNZIP))
 
2948
/* convert wide character string to multi-byte character string */
 
2949
char *wide_to_local_string(wide_string, escape_all)
 
2950
  ZCONST zwchar *wide_string;
 
2951
  int escape_all;
 
2952
{
 
2953
  int i;
 
2954
  wchar_t wc;
 
2955
  int bytes_char;
 
2956
  int default_used;
 
2957
  int wsize = 0;
 
2958
  int max_bytes = 9;
 
2959
  char buf[9];
 
2960
  char *buffer = NULL;
 
2961
  char *local_string = NULL;
 
2962
 
 
2963
  for (wsize = 0; wide_string[wsize]; wsize++) ;
 
2964
 
 
2965
  if (max_bytes < MB_CUR_MAX)
 
2966
    max_bytes = MB_CUR_MAX;
 
2967
 
 
2968
  if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
 
2969
    return NULL;
 
2970
  }
 
2971
 
 
2972
  /* convert it */
 
2973
  buffer[0] = '\0';
 
2974
  for (i = 0; i < wsize; i++) {
 
2975
    if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) {
 
2976
      /* wchar_t probably 2 bytes */
 
2977
      /* could do surrogates if state_dependent and wctomb can do */
 
2978
      wc = zwchar_to_wchar_t_default_char;
 
2979
    } else {
 
2980
      wc = (wchar_t)wide_string[i];
 
2981
    }
 
2982
    /* Unter some vendor's C-RTL, the Wide-to-MultiByte conversion functions
 
2983
     * (like wctomb() et. al.) do not use the same codepage as the other
 
2984
     * string arguments I/O functions (fopen, mkdir, rmdir etc.).
 
2985
     * Therefore, we have to fall back to the underlying Win32-API call to
 
2986
     * achieve a consistent behaviour for all supported compiler environments.
 
2987
     * Failing RTLs are for example:
 
2988
     *   Borland (locale uses OEM-CP as default, but I/O functions expect ANSI
 
2989
     *            names)
 
2990
     *   Watcom  (only "C" locale, wctomb() always uses OEM CP)
 
2991
     * (in other words: all supported environments except the Microsoft RTLs)
 
2992
     */
 
2993
    bytes_char = WideCharToMultiByte(
 
2994
                          CP_ACP, WC_COMPOSITECHECK,
 
2995
                          &wc, 1,
 
2996
                          (LPSTR)buf, sizeof(buf),
 
2997
                          NULL, &default_used);
 
2998
    if (default_used)
 
2999
      bytes_char = -1;
 
3000
    if (escape_all) {
 
3001
      if (bytes_char == 1 && (uch)buf[0] <= 0x7f) {
 
3002
        /* ASCII */
 
3003
        strncat(buffer, buf, 1);
 
3004
      } else {
 
3005
        /* use escape for wide character */
 
3006
        char *escape_string = wide_to_escape_string(wide_string[i]);
 
3007
        strcat(buffer, escape_string);
 
3008
        free(escape_string);
 
3009
      }
 
3010
    } else if (bytes_char > 0) {
 
3011
      /* multi-byte char */
 
3012
      strncat(buffer, buf, bytes_char);
 
3013
    } else {
 
3014
      /* no MB for this wide */
 
3015
      /* use escape for wide character */
 
3016
      char *escape_string = wide_to_escape_string(wide_string[i]);
 
3017
      strcat(buffer, escape_string);
 
3018
      free(escape_string);
 
3019
    }
 
3020
  }
 
3021
  if ((local_string = (char *)realloc(buffer, strlen(buffer) + 1)) == NULL) {
 
3022
    free(buffer);
 
3023
    return NULL;
 
3024
  }
 
3025
 
 
3026
  return local_string;
 
3027
}
 
3028
 
 
3029
 
 
3030
#if 0
 
3031
wchar_t *utf8_to_wchar_string(utf8_string)
 
3032
  char *utf8_string;       /* path to get utf-8 name for */
 
3033
{
 
3034
  wchar_t  *qw;
 
3035
  int       ulen;
 
3036
  int       ulenw;
 
3037
 
 
3038
  if (utf8_string == NULL)
 
3039
    return NULL;
 
3040
 
 
3041
    /* get length */
 
3042
    ulenw = MultiByteToWideChar(
 
3043
                CP_UTF8,           /* UTF-8 code page */
 
3044
                0,                 /* flags for character-type options */
 
3045
                utf8_string,       /* string to convert */
 
3046
                -1,                /* string length (-1 = NULL terminated) */
 
3047
                NULL,              /* buffer */
 
3048
                0 );               /* buffer length (0 = return length) */
 
3049
    if (ulenw == 0) {
 
3050
      /* failed */
 
3051
      return NULL;
 
3052
    }
 
3053
    ulenw++;
 
3054
    /* get length in bytes */
 
3055
    ulen = sizeof(wchar_t) * (ulenw + 1);
 
3056
    if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
 
3057
      return NULL;
 
3058
    }
 
3059
    /* convert multibyte to wide */
 
3060
    ulen = MultiByteToWideChar(
 
3061
               CP_UTF8,           /* UTF-8 code page */
 
3062
               0,                 /* flags for character-type options */
 
3063
               utf8_string,       /* string to convert */
 
3064
               -1,                /* string length (-1 = NULL terminated) */
 
3065
               qw,                /* buffer */
 
3066
               ulenw);            /* buffer length (0 = return length) */
 
3067
    if (ulen == 0) {
 
3068
      /* failed */
 
3069
      free(qw);
 
3070
      return NULL;
 
3071
    }
 
3072
 
 
3073
  return qw;
 
3074
}
 
3075
 
 
3076
wchar_t *local_to_wchar_string(local_string)
 
3077
  char *local_string;       /* path of local name */
 
3078
{
 
3079
  wchar_t  *qw;
 
3080
  int       ulen;
 
3081
  int       ulenw;
 
3082
 
 
3083
  if (local_string == NULL)
 
3084
    return NULL;
 
3085
 
 
3086
    /* get length */
 
3087
    ulenw = MultiByteToWideChar(
 
3088
                CP_ACP,            /* ANSI code page */
 
3089
                0,                 /* flags for character-type options */
 
3090
                local_string,      /* string to convert */
 
3091
                -1,                /* string length (-1 = NULL terminated) */
 
3092
                NULL,              /* buffer */
 
3093
                0 );               /* buffer length (0 = return length) */
 
3094
    if (ulenw == 0) {
 
3095
      /* failed */
 
3096
      return NULL;
 
3097
    }
 
3098
    ulenw++;
 
3099
    /* get length in bytes */
 
3100
    ulen = sizeof(wchar_t) * (ulenw + 1);
 
3101
    if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
 
3102
      return NULL;
 
3103
    }
 
3104
    /* convert multibyte to wide */
 
3105
    ulen = MultiByteToWideChar(
 
3106
               CP_ACP,            /* ANSI code page */
 
3107
               0,                 /* flags for character-type options */
 
3108
               local_string,      /* string to convert */
 
3109
               -1,                /* string length (-1 = NULL terminated) */
 
3110
               qw,                /* buffer */
 
3111
               ulenw);            /* buffer length (0 = return length) */
 
3112
    if (ulen == 0) {
 
3113
      /* failed */
 
3114
      free(qw);
 
3115
      return NULL;
 
3116
    }
 
3117
 
 
3118
  return qw;
 
3119
}
 
3120
#endif /* 0 */
 
3121
#endif /* UNICODE_SUPPORT && !FUNZIP */
 
3122
 
 
3123
 
 
3124
 
 
3125
/* --------------------------------------------------- */
 
3126
/* Large File Support
 
3127
 *
 
3128
 * Initial functions by E. Gordon and R. Nausedat
 
3129
 * 9/10/2003
 
3130
 * Lifted from Zip 3b, win32.c and place here by Myles Bennett
 
3131
 * 7/6/2004
 
3132
 *
 
3133
 * These implement 64-bit file support for Windows.  The
 
3134
 * defines and headers are in win32/w32cfg.h.
 
3135
 *
 
3136
 * Moved to win32i64.c by Mike White to avoid conflicts in
 
3137
 * same name functions in WiZ using UnZip and Zip libraries.
 
3138
 * 9/25/2003
 
3139
 */