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

« back to all changes in this revision

Viewing changes to msdos/msdos.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
4
  See the accompanying file LICENSE, version 2000-Apr-09 or later
5
5
  (the contents of which are also included in unzip.h) for terms of use.
25
25
             volumelabel()                  (non-djgpp, non-emx)
26
26
             close_outfile()
27
27
             stamp_file()                   (TIMESTAMP only)
 
28
             prepare_ISO_OEM_translat()
28
29
             dateformat()
29
30
             version()
30
31
             zcalloc()                      (16-bit, only)
41
42
             _is_executable()               (djgpp 2.x)
42
43
             __crt0_glob_function()         (djgpp 2.x)
43
44
             __crt0_load_environment_file() (djgpp 2.x)
 
45
             dos_getcodepage()              (all, ASM system call)
44
46
             screensize()                   (emx, Watcom 32-bit)
45
47
             int86x_realmode()              (Watcom 32-bit)
46
48
             stat_bandaid()                 (Watcom)
64
66
static int isfloppy OF((int nDrive));
65
67
static int z_dos_chmod OF((__GPRO__ ZCONST char *fname, int attributes));
66
68
static int volumelabel OF((ZCONST char *newlabel));
 
69
#if (!defined(SFX) && !defined(WINDLL))
 
70
   static int is_running_on_windows OF((void));
 
71
#endif
 
72
static int getdoscodepage OF((void));
67
73
 
68
74
static int created_dir;        /* used by mapname(), checkdir() */
69
75
static int renamed_fullpath;   /* ditto */
102
108
#endif
103
109
static ZCONST char Far AttribsMayBeWrong[] =
104
110
  "\nwarning:  file attributes may not be correct\n";
 
111
#if (!defined(SFX) && !defined(WINDLL))
 
112
   static ZCONST char Far WarnUsedOnWindows[] =
 
113
     "\n%s warning: You are using the MSDOS version on Windows.\n"
 
114
     "Please try the native Windows version before reporting any problems.\n";
 
115
#endif
105
116
 
106
117
 
107
118
 
117
128
#  define F_intdosx(ir,or,sr) int86x_realmode(0x21, ir, or, sr)
118
129
#  define XXX__MK_FP_IS_BROKEN
119
130
#else
120
 
#  define WREGS(v,r) (v.x.r)
 
131
#  if (defined(__DJGPP__) && (__DJGPP__ >= 2))
 
132
#   define WREGS(v,r) (v.w.r)
 
133
#  else
 
134
#   define WREGS(v,r) (v.x.r)
 
135
#  endif
121
136
#  define F_intdosx(ir,or,sr) intdosx(ir, or, sr)
122
137
#endif
123
138
 
1499
1514
  * the file, this routine is optional (but most compilers support it).
1500
1515
  */
1501
1516
{
 
1517
    /* skip restoring time stamps on user's request */
 
1518
    if (uO.D_flag <= 1) {
1502
1519
#ifdef USE_EF_UT_TIME
1503
 
    dos_fdatetime dos_dt;
1504
 
    iztimes z_utime;
1505
 
    struct tm *t;
 
1520
        dos_fdatetime dos_dt;
 
1521
        iztimes z_utime;
 
1522
        struct tm *t;
1506
1523
#endif /* USE_EF_UT_TIME */
1507
1524
 
1508
1525
 
1509
1526
/*---------------------------------------------------------------------------
1510
 
    Copy and/or convert time and date variables, if necessary; then set the
1511
 
    file time/date.  WEIRD BORLAND "BUG":  if output is buffered, and if run
1512
 
    under at least some versions of DOS (e.g., 6.0), and if files are smaller
1513
 
    than DOS physical block size (i.e., 512 bytes) (?), then files MAY NOT
1514
 
    get timestamped correctly--apparently setftime() occurs before any data
1515
 
    are written to the file, and when file is closed and buffers are flushed,
1516
 
    timestamp is overwritten with current time.  Even with a 32K buffer, this
1517
 
    does not seem to occur with larger files.  UnZip output is now unbuffered,
1518
 
    but if it were not, could still avoid problem by adding "fflush(outfile)"
1519
 
    just before setftime() call.  Weird, huh?
 
1527
        Copy and/or convert time and date variables, if necessary; then set
 
1528
        the file time/date.  WEIRD BORLAND "BUG":  if output is buffered,
 
1529
        and if run under at least some versions of DOS (e.g., 6.0), and if
 
1530
        files are smaller than DOS physical block size (i.e., 512 bytes) (?),
 
1531
        then files MAY NOT get timestamped correctly--apparently setftime()
 
1532
        occurs before any data are written to the file, and when file is
 
1533
        closed and buffers are flushed, timestamp is overwritten with
 
1534
        current time.  Even with a 32K buffer, this does not seem to occur
 
1535
        with larger files.  UnZip output is now unbuffered, but if it were
 
1536
        not, could still avoid problem by adding "fflush(outfile)" just
 
1537
        before setftime() call.  Weird, huh?
1520
1538
  ---------------------------------------------------------------------------*/
1521
1539
 
1522
1540
#ifdef USE_EF_UT_TIME
1523
 
    if (G.extra_field &&
 
1541
        if (G.extra_field &&
1524
1542
#ifdef IZ_CHECK_TZ
1525
 
        G.tz_is_valid &&
 
1543
            G.tz_is_valid &&
1526
1544
#endif
1527
 
        (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0,
1528
 
                          G.lrec.last_mod_dos_datetime, &z_utime, NULL)
1529
 
         & EB_UT_FL_MTIME))
1530
 
    {
1531
 
        TTrace((stderr, "close_outfile:  Unix e.f. modif. time = %ld\n",
1532
 
          z_utime.mtime));
1533
 
        /* round up (down if "up" overflows) to even seconds */
1534
 
        if (z_utime.mtime & 1)
1535
 
            z_utime.mtime = (z_utime.mtime + 1 > z_utime.mtime) ?
1536
 
                             z_utime.mtime + 1 : z_utime.mtime - 1;
1537
 
        TIMET_TO_NATIVE(z_utime.mtime)   /* NOP unless MSC 7.0 or Macintosh */
1538
 
        t = localtime(&(z_utime.mtime));
1539
 
    } else
1540
 
        t = (struct tm *)NULL;
1541
 
    if (t != (struct tm *)NULL) {
1542
 
        if (t->tm_year < 80) {
1543
 
            dos_dt.z_dtf.zt_se = 0;
1544
 
            dos_dt.z_dtf.zt_mi = 0;
1545
 
            dos_dt.z_dtf.zt_hr = 0;
1546
 
            dos_dt.z_dtf.zd_dy = 1;
1547
 
            dos_dt.z_dtf.zd_mo = 1;
1548
 
            dos_dt.z_dtf.zd_yr = 0;
 
1545
            (ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0,
 
1546
                              G.lrec.last_mod_dos_datetime, &z_utime, NULL)
 
1547
             & EB_UT_FL_MTIME))
 
1548
        {
 
1549
            TTrace((stderr, "close_outfile:  Unix e.f. modif. time = %ld\n",
 
1550
              z_utime.mtime));
 
1551
            /* round up (down if "up" overflows) to even seconds */
 
1552
            if (z_utime.mtime & 1)
 
1553
                z_utime.mtime = (z_utime.mtime + 1 > z_utime.mtime) ?
 
1554
                                 z_utime.mtime + 1 : z_utime.mtime - 1;
 
1555
            TIMET_TO_NATIVE(z_utime.mtime) /* NOP unless MSC 7 or Macintosh */
 
1556
            t = localtime(&(z_utime.mtime));
 
1557
        } else
 
1558
            t = (struct tm *)NULL;
 
1559
        if (t != (struct tm *)NULL) {
 
1560
            if (t->tm_year < 80) {
 
1561
                dos_dt.z_dtf.zt_se = 0;
 
1562
                dos_dt.z_dtf.zt_mi = 0;
 
1563
                dos_dt.z_dtf.zt_hr = 0;
 
1564
                dos_dt.z_dtf.zd_dy = 1;
 
1565
                dos_dt.z_dtf.zd_mo = 1;
 
1566
                dos_dt.z_dtf.zd_yr = 0;
 
1567
            } else {
 
1568
                dos_dt.z_dtf.zt_se = t->tm_sec >> 1;
 
1569
                dos_dt.z_dtf.zt_mi = t->tm_min;
 
1570
                dos_dt.z_dtf.zt_hr = t->tm_hour;
 
1571
                dos_dt.z_dtf.zd_dy = t->tm_mday;
 
1572
                dos_dt.z_dtf.zd_mo = t->tm_mon + 1;
 
1573
                dos_dt.z_dtf.zd_yr = t->tm_year - 80;
 
1574
            }
1549
1575
        } else {
1550
 
            dos_dt.z_dtf.zt_se = t->tm_sec >> 1;
1551
 
            dos_dt.z_dtf.zt_mi = t->tm_min;
1552
 
            dos_dt.z_dtf.zt_hr = t->tm_hour;
1553
 
            dos_dt.z_dtf.zd_dy = t->tm_mday;
1554
 
            dos_dt.z_dtf.zd_mo = t->tm_mon + 1;
1555
 
            dos_dt.z_dtf.zd_yr = t->tm_year - 80;
 
1576
            dos_dt.z_dostime = G.lrec.last_mod_dos_datetime;
1556
1577
        }
1557
 
    } else {
1558
 
        dos_dt.z_dostime = G.lrec.last_mod_dos_datetime;
1559
 
    }
1560
1578
# ifdef __TURBOC__
1561
 
    setftime(fileno(G.outfile), &dos_dt.ft);
 
1579
        setftime(fileno(G.outfile), &dos_dt.ft);
1562
1580
# else
1563
 
    _dos_setftime(fileno(G.outfile), dos_dt.zft.zdate, dos_dt.zft.ztime);
 
1581
        _dos_setftime(fileno(G.outfile), dos_dt.zft.zdate, dos_dt.zft.ztime);
1564
1582
# endif
1565
1583
#else /* !USE_EF_UT_TIME */
1566
1584
# ifdef __TURBOC__
1567
 
    setftime(fileno(G.outfile),
1568
 
             (struct ftime *)(&(G.lrec.last_mod_dos_datetime)));
 
1585
        setftime(fileno(G.outfile),
 
1586
                 (struct ftime *)(&(G.lrec.last_mod_dos_datetime)));
1569
1587
# else
1570
 
    _dos_setftime(fileno(G.outfile), (ush)(G.lrec.last_mod_dos_datetime >> 16),
1571
 
                                     (ush)(G.lrec.last_mod_dos_datetime));
 
1588
        _dos_setftime(fileno(G.outfile),
 
1589
                      (ush)(G.lrec.last_mod_dos_datetime >> 16),
 
1590
                      (ush)(G.lrec.last_mod_dos_datetime));
1572
1591
# endif
1573
1592
#endif /* ?USE_EF_UT_TIME */
 
1593
    }
1574
1594
 
1575
1595
/*---------------------------------------------------------------------------
1576
1596
    And finally we can close the file...at least everybody agrees on how to
1645
1665
 
1646
1666
 
1647
1667
 
 
1668
void prepare_ISO_OEM_translat(__G)
 
1669
   __GDEF
 
1670
{
 
1671
    switch (getdoscodepage()) {
 
1672
    case 437:
 
1673
    case 850:
 
1674
    case 858:
 
1675
#ifdef IZ_ISO2OEM_ARRAY
 
1676
        iso2oem = iso2oem_850;
 
1677
#endif
 
1678
#ifdef IZ_OEM2ISO_ARRAY
 
1679
        oem2iso = oem2iso_850;
 
1680
#endif
 
1681
 
 
1682
    case 932:   /* Japanese */
 
1683
    case 949:   /* Korean */
 
1684
    case 936:   /* Chinese, simple */
 
1685
    case 950:   /* Chinese, traditional */
 
1686
    case 874:   /* Thai */
 
1687
    case 1258:  /* Vietnamese */
 
1688
#ifdef IZ_ISO2OEM_ARRAY
 
1689
        iso2oem = NULL;
 
1690
#endif
 
1691
#ifdef IZ_OEM2ISO_ARRAY
 
1692
        oem2iso = NULL;
 
1693
#endif
 
1694
 
 
1695
    default:
 
1696
#ifdef IZ_ISO2OEM_ARRAY
 
1697
       iso2oem = NULL;
 
1698
#endif
 
1699
#ifdef IZ_OEM2ISO_ARRAY
 
1700
       oem2iso = NULL;
 
1701
#endif
 
1702
    }
 
1703
} /* end function prepare_ISO_OEM_translat() */
 
1704
 
 
1705
 
 
1706
 
 
1707
 
1648
1708
#ifndef SFX
1649
1709
 
1650
1710
/*************************/
1723
1783
        case 2:
1724
1784
            return DF_YMD;
1725
1785
    }
1726
 
#endif /* !WINDLL && !WATCOMC_386 */
 
1786
#endif /* !WINDLL */
1727
1787
 
1728
1788
    return DF_MDY;   /* default for systems without locale info */
1729
1789
 
1734
1794
 
1735
1795
#ifndef WINDLL
1736
1796
 
 
1797
/**************************************/
 
1798
/*  Function is_running_on_windows()  */
 
1799
/**************************************/
 
1800
 
 
1801
static int is_running_on_windows(void)
 
1802
{
 
1803
    char *var = getenv("OS");
 
1804
 
 
1805
    /* if the OS env.var says 'Windows_NT' then */
 
1806
    /* we're likely running on a variant of WinNT */
 
1807
    if ((var != NULL) && (strcmp("Windows_NT", var) == 0))
 
1808
        return TRUE;
 
1809
 
 
1810
    /* if the windir env.var is non-null then */
 
1811
    /* we're likely running on a variant of Win9x */
 
1812
    /* DOS mode of Win9x doesn't define windir, only winbootdir */
 
1813
    /* NT's command.com can't see lowercase env. vars */
 
1814
    var = getenv("windir");
 
1815
    if ((var != NULL) && (var[0] != '\0'))
 
1816
        return TRUE;
 
1817
 
 
1818
    return FALSE;
 
1819
}
 
1820
 
 
1821
 
 
1822
/**********************************/
 
1823
/*  Function check_for_windows()  */
 
1824
/**********************************/
 
1825
 
 
1826
void check_for_windows(ZCONST char *app)
 
1827
{
 
1828
#ifdef SMALL_MEM
 
1829
    char msg_str[160];          /* enough space for two 79-char-lines  */
 
1830
 
 
1831
    (void)zfstrcpy(msg_buf, WarnUsedOnWindows)
 
1832
#else
 
1833
#   define msg_str WarnUsedOnWindows
 
1834
#endif
 
1835
    /* Print a warning for users running under Windows */
 
1836
    /* to reduce bug reports due to running DOS version */
 
1837
    /* under Windows, when Windows version usually works correctly */
 
1838
    if (is_running_on_windows())
 
1839
        printf(msg_str, app);
 
1840
} /* end function check_for_windows() */
 
1841
 
 
1842
 
1737
1843
/************************/
1738
1844
/*  Function version()  */
1739
1845
/************************/
2174
2280
 
2175
2281
 
2176
2282
 
 
2283
static int getdoscodepage(void)
 
2284
{
 
2285
    union REGS regs;
 
2286
 
 
2287
    WREGS(regs,ax) = 0x6601;
 
2288
#ifdef __EMX__
 
2289
    _int86(0x21, &regs, &regs);
 
2290
    if (WREGS(regs,flags) & 1)
 
2291
#else
 
2292
    intdos(&regs, &regs);
 
2293
    if (WREGS(regs,cflag))
 
2294
#endif
 
2295
    {
 
2296
        Trace((stderr,
 
2297
          "error in DOS function 0x66 (AX = 0x%04x): default to 850...\n",
 
2298
          (unsigned int)(WREGS(regs,ax))));
 
2299
        return 858;
 
2300
    } else
 
2301
        return WREGS(regs,bx);
 
2302
}
 
2303
 
 
2304
 
 
2305
 
2177
2306
#ifdef __EMX__
2178
2307
#ifdef MORE
2179
2308