added zip from Info-ZIP

This commit is contained in:
ahgamut 2021-06-10 05:29:39 +05:30 committed by Justine Tunney
parent 98c53ae526
commit 4ce5664c4b
363 changed files with 119113 additions and 0 deletions

View file

@ -0,0 +1,69 @@
/*
Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 1999-Oct-05 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
This is an Important note about pathnames
*/
static char DuplicVolumeNote[] = {
"\rIMPORTANT NOTE:" \
"\r" \
"\r This port has one weak point: It is based on pathnames !! " \
"\r Because it's a port !! Unlike MacOS: As far as I know all other "\
"\r Operatingsystems (eg.: Unix, DOS, OS/2, ...) are based on pathnames" \
"\r " \
/* a short quote from "Inside Macintintosh, Files"; slightly modified by me */
"\r On a Mac: Files and directories located in the same directory " \
"\r must all have unique names. However, there is no requirement " \
"\r that volumes have unique names. It is perfectly acceptable for two mounted" \
"\r volumes to have the same name. This is one reason why a application should " \
"\r use volume reference numbers rather than volume names to specify volumes," \
"\r but for this Zip-Port I can't use reference numbers. " \
"\r " \
/* end quote */
"\r" \
"\r From the developers point of view:"\
"\r The use of pathnames, however, is highly discouraged. If the user changes"\
"\r names or moves things around, they are worthless." \
"\r Full pathnames are particularly unreliable as a means of identifying files," \
"\r directories or volumes within your application," \
"\r for two primary reasons:" \
"\r" \
"\r* The user can change the name of any element in the path at" \
"\r virtually any time." \
"\r* Volume names on the Macintosh are *not* unique. Multiple" \
"\r mounted volumes can have the same name. For this reason, the use of" \
"\r a full pathname to identify a specific volume may not produce the" \
"\r results you expect. If more than one volume has the same name and" \
"\r a full pathname is used, the File Manager currently uses the first" \
"\r mounted volume it finds with a matching name in the volume queue." \
"\r" \
"\r" \
"\r The main reason is that an attempt to implement support exact saving of" \
"\r the MacOS specific internal file-structures would require a throughout" \
"\r rewrite of major parts of shared code, probably sacrifying compatibility" \
"\r with other systems." \
"\r I have no solution at the moment. The port will just warn you if you try" \
"\r zip from / to a volume which has a duplicate name." \
"\r MacZip has problems to find the archives and files." \
"\r" \
"\r" \
"\r ... and the moral of this story:" \
"\r" \
"\r Don't mount multiple volumes with the same " \
"\r name while zip/unzip is running" \
"\r and "\
"\r My (Big) recommendation: Name all your volumes with a unique name "\
"\r (e.g: add a space character to the name) and" \
"\r MacZip will run without any problem." \
"\r" \
"\r" \
"\r Dirk Haase" \
};

View file

@ -0,0 +1,380 @@
/*
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
#ifndef __macos_charmap_h
#define __macos_charmap_h
/*
Conversion table from MacOS Roman to
"Western Europe & America" Windows codepage 1252
Notes on Mac OS Roman:
----------------------
Mac OS Roman character set is used for at least the following Mac OS
localizations: U.S., British, Canadian French, French, Swiss
French, German, Swiss German, Italian, Swiss Italian, Dutch,
Swedish, Norwegian, Danish, Finnish, Spanish, Catalan,
Portuguese, Brazilian, and the default International system.
Not every char of the charset MacRoman has their equivalent
in Windows CodePage1252.
To make the mapping in most cases possible, I choosed
most similar chars or at least the BULLET. Chars that
do not have a direct match are marked with '***'
The Windows codepage 1252 contains the ISO 8859-1 "Latin 1" codepage,
with some additional printable characters in the range (0x80 - 0x9F),
that is reserved to control codes in the ISO 8859-1 character table.
In all Mac OS encodings, character codes 0x00-0x7F are identical to ASCII
*/
ZCONST unsigned char MacRoman_to_WinCP1252[128] = {
/* Win CP1252 UniCode UniCode Names */
0xC4 , /* 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS */
0xC5 , /* 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE */
0xC7 , /* 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA */
0xC9 , /* 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE */
0xD1 , /* 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE */
0xD6 , /* 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS */
0xDC , /* 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS */
0xE1 , /* 0x00E1 #LATIN SMALL LETTER A WITH ACUTE */
0xE0 , /* 0x00E0 #LATIN SMALL LETTER A WITH GRAVE */
0xE2 , /* 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX */
0xE4 , /* 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS */
0xE3 , /* 0x00E3 #LATIN SMALL LETTER A WITH TILDE */
0xE5 , /* 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE */
0xE7 , /* 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA */
0xE9 , /* 0x00E9 #LATIN SMALL LETTER E WITH ACUTE */
0xE8 , /* 0x00E8 #LATIN SMALL LETTER E WITH GRAVE */
0xEA , /* 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX */
0xEB , /* 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS */
0xED , /* 0x00ED #LATIN SMALL LETTER I WITH ACUTE */
0xEC , /* 0x00EC #LATIN SMALL LETTER I WITH GRAVE */
0xEE , /* 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX */
0xEF , /* 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS */
0xF1 , /* 0x00F1 #LATIN SMALL LETTER N WITH TILDE */
0xF3 , /* 0x00F3 #LATIN SMALL LETTER O WITH ACUTE */
0xF2 , /* 0x00F2 #LATIN SMALL LETTER O WITH GRAVE */
0xF4 , /* 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX */
0xF6 , /* 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS */
0xF5 , /* 0x00F5 #LATIN SMALL LETTER O WITH TILDE */
0xFA , /* 0x00FA #LATIN SMALL LETTER U WITH ACUTE */
0xF9 , /* 0x00F9 #LATIN SMALL LETTER U WITH GRAVE */
0xFB , /* 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX */
0xFC , /* 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS */
0x86 , /* 0x2020 #DAGGER */
0xB0 , /* 0x00B0 #DEGREE SIGN */
0xA2 , /* 0x00A2 #CENT SIGN */
0xA3 , /* 0x00A3 #POUND SIGN */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 #BULLET */
0xB6 , /* 0x00B6 #PILCROW SIGN */
0xDF , /* 0x00DF #LATIN SMALL LETTER SHARP S */
0xAE , /* 0x00AE #REGISTERED SIGN */
0xA9 , /* 0x00A9 #COPYRIGHT SIGN */
0x99 , /* 0x2122 #TRADE MARK SIGN */
0xB4 , /* 0x00B4 #ACUTE ACCENT */
0xA8 , /* 0x00A8 #DIAERESIS */
0x95 , /* 0x2022 # *** BULLET */
0xC6 , /* 0x00C6 #LATIN CAPITAL LETTER AE */
0xD8 , /* 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE */
0x95 , /* 0x2022 # *** BULLET */
0xB1 , /* 0x00B1 #PLUS-MINUS SIGN */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x00A5 #YEN SIGN */
0xB5 , /* 0x00B5 #MICRO SIGN */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0xAA , /* 0x00AA #FEMININE ORDINAL INDICATOR */
0xBA , /* 0x00BA #MASCULINE ORDINAL INDICATOR */
0x95 , /* 0x2022 # *** BULLET */
0xE6 , /* 0x00E6 #LATIN SMALL LETTER AE */
0xF8 , /* 0x00F8 #LATIN SMALL LETTER O WITH STROKE */
0xBF , /* 0x00BF #INVERTED QUESTION MARK */
0xA1 , /* 0x00A1 #INVERTED EXCLAMATION MARK */
0xAC , /* 0x00AC #NOT SIGN */
0x95 , /* 0x2022 # *** BULLET */
0x83 , /* 0x0192 #LATIN SMALL LETTER F WITH HOOK */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0xAB , /* 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
0xBB , /* 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
0x85 , /* 0x2026 #HORIZONTAL ELLIPSIS */
0xA0 , /* 0x00A0 #NO-BREAK SPACE */
0xC0 , /* 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE */
0xC3 , /* 0x00C3 #LATIN CAPITAL LETTER A WITH TILDE */
0xD5 , /* 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x96 , /* 0x2013 #EN DASH */
0x97 , /* 0x2014 #EM DASH */
0x93 , /* 0x201C #LEFT DOUBLE QUOTATION MARK */
0x94 , /* 0x201D #RIGHT DOUBLE QUOTATION MARK */
0x91 , /* 0x2018 #LEFT SINGLE QUOTATION MARK */
0x92 , /* 0x2019 #RIGHT SINGLE QUOTATION MARK */
0xF7 , /* 0x00F7 #DIVISION SIGN */
0x95 , /* 0x2022 # *** BULLET */
0xFF , /* 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS */
0x9F , /* 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS */
0x95 , /* 0x2022 # *** BULLET */
0xA4 , /* 0x00A4 #CURRENCY SIGN */
0x8B , /* 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
0x9B , /* 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x87 , /* 0x2021 #DOUBLE DAGGER */
0xB7 , /* 0x00B7 #MIDDLE DOT */
0x82 , /* 0x201A #SINGLE LOW-9 QUOTATION MARK */
0x84 , /* 0x201E #DOUBLE LOW-9 QUOTATION MARK */
0x89 , /* 0x2030 #PER MILLE SIGN */
0xC2 , /* 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
0xCA , /* 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
0xC1 , /* 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE */
0xCB , /* 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS */
0xC8 , /* 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE */
0xCD , /* 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE */
0xCE , /* 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
0xCF , /* 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS */
0xCC , /* 0x00CC #LATIN CAPITAL LETTER I WITH GRAVE */
0xD3 , /* 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE */
0xD4 , /* 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
0x95 , /* 0x2022 # *** BULLET */
0xD2 , /* 0x00D2 #LATIN CAPITAL LETTER O WITH GRAVE */
0xDA , /* 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE */
0xDB , /* 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
0xD9 , /* 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE */
0x95 , /* 0x2022 # *** BULLET */
0x88 , /* 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT */
0x98 , /* 0x02DC #SMALL TILDE */
0xAF , /* 0x00AF #MACRON */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0xB8 , /* 0x00B8 #CEDILLA */
0x95 , /* 0x2022 # *** BULLET */
0x95 , /* 0x2022 # *** BULLET */
0x95 /* 0x2022 # *** BULLET */
};
ZCONST unsigned char WinCP1252_to_MacRoman[128] = {
/* Mac Roman UniCode UniCode Names */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xE2 , /* 0x201A # SINGLE LOW-9 QUOTATION MARK */
0xC4 , /* 0x0192 # LATIN SMALL LETTER F WITH HOOK */
0xE3 , /* 0x201E # DOUBLE LOW-9 QUOTATION MARK */
0xC9 , /* 0x2026 # HORIZONTAL ELLIPSIS */
0xA0 , /* 0x2020 # DAGGER */
0xE0 , /* 0x2021 # DOUBLE DAGGER */
0xF6 , /* 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT */
0xE4 , /* 0x2030 # PER MILLE SIGN */
0xA5 , /* 0x2022 # *** BULLET */
0xDC , /* 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xD4 , /* 0x2018 # LEFT SINGLE QUOTATION MARK */
0xD5 , /* 0x2019 # RIGHT SINGLE QUOTATION MARK */
0xD2 , /* 0x201C # LEFT DOUBLE QUOTATION MARK */
0xD3 , /* 0x201D # RIGHT DOUBLE QUOTATION MARK */
0xA5 , /* 0x2022 # BULLET */
0xD0 , /* 0x2013 # EN DASH */
0xD1 , /* 0x2014 # EM DASH */
0xF7 , /* 0x02DC # SMALL TILDE */
0xAA , /* 0x2122 # TRADE MARK SIGN */
0xA5 , /* 0x2022 # *** BULLET */
0xDD , /* 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xD9 , /* 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS */
0xCA , /* 0x00A0 # NO-BREAK SPACE */
0xC1 , /* 0x00A1 # INVERTED EXCLAMATION MARK */
0xA2 , /* 0x00A2 # CENT SIGN */
0xA3 , /* 0x00A3 # POUND SIGN */
0xDB , /* 0x00A4 # CURRENCY SIGN */
0xB4 , /* 0x00A5 # YEN SIGN */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xAC , /* 0x00A8 # DIAERESIS */
0xA9 , /* 0x00A9 # COPYRIGHT SIGN */
0xBB , /* 0x00AA # FEMININE ORDINAL INDICATOR */
0xC7 , /* 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
0xC2 , /* 0x00AC # NOT SIGN */
0xA5 , /* 0x2022 # *** BULLET */
0xA8 , /* 0x00AE # REGISTERED SIGN */
0xF8 , /* 0x00AF # MACRON */
0xA1 , /* 0x00B0 # DEGREE SIGN */
0xB1 , /* 0x00B1 # PLUS-MINUS SIGN */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xAB , /* 0x00B4 # ACUTE ACCENT */
0xB5 , /* 0x00B5 # MICRO SIGN */
0xA6 , /* 0x00B6 # PILCROW SIGN */
0xE1 , /* 0x00B7 # MIDDLE DOT */
0xFC , /* 0x00B8 # CEDILLA */
0xA5 , /* 0x2022 # *** BULLET */
0xBC , /* 0x00BA # MASCULINE ORDINAL INDICATOR */
0xC8 , /* 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xC0 , /* 0x00BF # INVERTED QUESTION MARK */
0xCB , /* 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE */
0xE7 , /* 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE */
0xE5 , /* 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
0xCC , /* 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE */
0x80 , /* 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS */
0x81 , /* 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE */
0xAE , /* 0x00C6 # LATIN CAPITAL LETTER AE */
0x82 , /* 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA */
0xE9 , /* 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE */
0x83 , /* 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE */
0xE6 , /* 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
0xE8 , /* 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS */
0xED , /* 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE */
0xEA , /* 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE */
0xEB , /* 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
0xEC , /* 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS */
0xA5 , /* 0x2022 # *** BULLET */
0x84 , /* 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE */
0xF1 , /* 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE */
0xEE , /* 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE */
0xEF , /* 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
0xCD , /* 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE */
0x85 , /* 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS */
0xA5 , /* 0x2022 # *** BULLET */
0xAF , /* 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE */
0xF4 , /* 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE */
0xF2 , /* 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE */
0xF3 , /* 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
0x86 , /* 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xA7 , /* 0x00DF # LATIN SMALL LETTER SHARP S */
0x88 , /* 0x00E0 # LATIN SMALL LETTER A WITH GRAVE */
0x87 , /* 0x00E1 # LATIN SMALL LETTER A WITH ACUTE */
0x89 , /* 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX */
0x8B , /* 0x00E3 # LATIN SMALL LETTER A WITH TILDE */
0x8A , /* 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS */
0x8C , /* 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE */
0xBE , /* 0x00E6 # LATIN SMALL LETTER AE */
0x8D , /* 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA */
0x8F , /* 0x00E8 # LATIN SMALL LETTER E WITH GRAVE */
0x8E , /* 0x00E9 # LATIN SMALL LETTER E WITH ACUTE */
0x90 , /* 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX */
0x91 , /* 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS */
0x93 , /* 0x00EC # LATIN SMALL LETTER I WITH GRAVE */
0x92 , /* 0x00ED # LATIN SMALL LETTER I WITH ACUTE */
0x94 , /* 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX */
0x95 , /* 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS */
0xA5 , /* 0x2022 # *** BULLET */
0x96 , /* 0x00F1 # LATIN SMALL LETTER N WITH TILDE */
0x98 , /* 0x00F2 # LATIN SMALL LETTER O WITH GRAVE */
0x97 , /* 0x00F3 # LATIN SMALL LETTER O WITH ACUTE */
0x99 , /* 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX */
0x9B , /* 0x00F5 # LATIN SMALL LETTER O WITH TILDE */
0x9A , /* 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS */
0xD6 , /* 0x00F7 # DIVISION SIGN */
0xBF , /* 0x00F8 # LATIN SMALL LETTER O WITH STROKE */
0x9D , /* 0x00F9 # LATIN SMALL LETTER U WITH GRAVE */
0x9C , /* 0x00FA # LATIN SMALL LETTER U WITH ACUTE */
0x9E , /* 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX */
0x9F , /* 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS */
0xA5 , /* 0x2022 # *** BULLET */
0xA5 , /* 0x2022 # *** BULLET */
0xD8 /* 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS */
};
/*
The following characters has no equivalent
to each other:
MacCodes
164 0xA4 0x00A7 # SECTION SIGN
253 0xFD 0x02DD # DOUBLE ACUTE ACCENT
189 0xBD 0x03A9 # GREEK CAPITAL LETTER OMEGA
185 0xB9 0x03C0 # GREEK SMALL LETTER PI
255 0xFF 0x02C7 # CARON
249 0xF9 0x02D8 # BREVE
250 0xFA 0x02D9 # DOT ABOVE
251 0xFB 0x02DA # RING ABOVE
254 0xFE 0x02DB # OGONEK
218 0xDA 0x2044 # FRACTION SLASH
182 0xB6 0x2202 # PARTIAL DIFFERENTIAL
198 0xC6 0x2206 # INCREMENT
184 0xB8 0x220F # N-ARY PRODUCT
183 0xB7 0x2211 # N-ARY SUMMATION
195 0xC3 0x221A # SQUARE ROOT
176 0xB0 0x221E # INFINITY
186 0xBA 0x222B # INTEGRAL
197 0xC5 0x2248 # ALMOST EQUAL TO
173 0xAD 0x2260 # NOT EQUAL TO
178 0xB2 0x2264 # LESS-THAN OR EQUAL TO
179 0xB3 0x2265 # GREATER-THAN OR EQUAL TO
215 0xD7 0x25CA # LOZENGE
240 0xF0 0xF8FF # Apple logo
222 0xDE 0xFB01 # LATIN SMALL LIGATURE FI
223 0xDF 0xFB02 # LATIN SMALL LIGATURE FL
245 0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I
206 0xCE 0x0152 # LATIN CAPITAL LIGATURE OE
207 0xCF 0x0153 # LATIN SMALL LIGATURE OE
WinCodes
129 0x81 #UNDEFINED
141 0x8D #UNDEFINED
143 0x8F #UNDEFINED
144 0x90 #UNDEFINED
157 0x9D #UNDEFINED
167 0xA7 0x00A7 #SECTION SIGN
173 0xAD 0x00AD #SOFT HYPHEN
178 0xB2 0x00B2 #SUPERSCRIPT TWO
179 0xB3 0x00B3 #SUPERSCRIPT THREE
185 0xB9 0x00B9 #SUPERSCRIPT ONE
188 0xBC 0x00BC #VULGAR FRACTION ONE QUARTER
189 0xBD 0x00BD #VULGAR FRACTION ONE HALF
190 0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS
208 0xD0 0x00D0 #LATIN CAPITAL LETTER ETH
215 0xD7 0x00D7 #MULTIPLICATION SIGN
221 0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE
222 0xDE 0x00DE #LATIN CAPITAL LETTER THORN
240 0xF0 0x00F0 #LATIN SMALL LETTER ETH
253 0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE
254 0xFE 0x00FE #LATIN SMALL LETTER THORN
140 0x8C 0x0152 #LATIN CAPITAL LIGATURE OE
156 0x9C 0x0153 #LATIN SMALL LIGATURE OE
138 0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON
154 0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON
142 0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON
158 0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON
128 0x80 0x20AC #EURO SIGN
166 0xA6 0x00A6 #BROKEN BAR
*/
#endif /* !__macos_charmap_h */

View file

@ -0,0 +1,920 @@
/*
Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
extrafld.c
contains functions to build extra-fields.
---------------------------------------------------------------------------*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include <sound.h>
#include "zip.h"
#include "unixlike.h"
#include "helpers.h"
#include "pathname.h"
/*****************************************************************************/
/* Macros, typedefs */
/*****************************************************************************/
/* ---------------------------------------------------------------------- */
/* Add a 'MAC3' extra field to the zlist data pointed to by z. */
/* This is the (new) Info-zip extra block for Macintosh */
#define EB_MAC3_HLEN 14 /* fixed length part of MAC3's header */
#define EB_L_MAC3_FINFO_LEN 52 /* fixed part of MAC3 compressible data */
#define EB_MAX_OF_VARDATA 1300 /* max possible datasize */
#define EB_L_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN)
#define EB_C_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN)
/* maximum memcompress overhead is the sum of the compression header length */
/* (6 = ush compression type, ulg CRC) and the worstcase deflate overhead */
/* when uncompressible data are kept in 2 "stored" blocks (5 per block = */
/* byte blocktype + 2 * ush blocklength) */
#define MEMCOMPRESS_OVERHEAD (EB_MEMCMPR_HSIZ + EB_DEFLAT_EXTRA)
#define EB_M3_FL_COMPRESS 0x00
#define EB_M3_FL_DATFRK 0x01 /* data is data-fork */
#define EB_M3_FL_NOCHANGE 0x02 /* filename will be not changed */
#define EB_M3_FL_UNCMPR 0x04 /* data is 'natural' (not compressed) */
#define EB_M3_FL_TIME64 0x08 /* time is coded in 64 bit */
#define EB_M3_FL_NOUTC 0x10 /* only 'local' time-stamps are stored */
#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2))
#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1))
/* disable compressing of extra field
#define MAC_EXTRAFLD_UNCMPR */
/* ---------------------------------------------------------------------- */
/* Add a 'JLEE' extra field to the zlist data pointed to by z. */
/* This is the (old) Info-zip resource-fork extra block for Macintosh
(last Revision 1996-09-22) Layout made by Johnny Lee, Code made by me :-) */
#define EB_L_JLEE_LEN 40 /* fixed length of JLEE's header */
#define EB_C_JLEE_LEN 40 /* fixed length of JLEE's header */
#define EB_L_JLEE_SIZE (EB_HEADSIZE + EB_L_JLEE_LEN)
#define EB_C_JLEE_SIZE (EB_HEADSIZE + EB_C_JLEE_LEN)
/*****************************************************************************/
/* Global Vars */
/*****************************************************************************/
extern MacZipGlobals MacZip;
extern unsigned long count_of_Zippedfiles;
/*****************************************************************************/
/* Prototypes */
/*****************************************************************************/
static int add_UT_ef(struct zlist far *z, iztimes *z_utim);
static int add_JLEE_ef(struct zlist far *z); /* old mac extra field */
static int add_MAC3_ef(struct zlist far *z); /* new mac extra field */
static void make_extrafield_JLEE(char *l_ef);
static unsigned make_extrafield_MAC3(char *ef);
static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize,
unsigned flag);
static void print_extra_info(void);
void UserStop(void);
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/*
* Set the extra-field's for each compressed file
*/
int set_extra_field(struct zlist far *z, iztimes *z_utim)
/* store full data in local header but just modification time stamp info
in central header */
{
int retval;
Assert_it(z, "set_extra_field","")
Assert_it(z_utim, "set_extra_field","")
z_utim = z_utim;
/* Check to make sure z is valid. */
if( z == NULL ) {
return ZE_LOGIC;
}
/* Resource forks are always binary */
if (MacZip.CurrentFork == ResourceFork) z->att = BINARY;
if (noisy)
{
count_of_Zippedfiles++;
InformProgress(MacZip.RawCountOfItems, count_of_Zippedfiles );
}
/*
PrintFileInfo();
*/
switch (MacZip.MacZipMode)
{
case JohnnyLee_EF:
{
retval = add_JLEE_ef( z );
if (retval != ZE_OK) return retval;
break;
}
case NewZipMode_EF:
{ /* */
#ifdef USE_EF_UT_TIME
retval = add_UT_ef(z, z_utim);
if (retval != ZE_OK) return retval;
#endif
retval = add_MAC3_ef( z );
if (retval != ZE_OK) return retval;
break;
}
default:
{
printerr("Unknown Extrafieldmode", -1, -1, __LINE__, __FILE__, "");
return ZE_LOGIC; /* function should never reach this point */
}
}
/* MacStat information is now outdated and
must be refreshed for the next file */
MacZip.isMacStatValid = false;
return ZE_OK;
}
#ifdef USE_EF_UT_TIME
/*
* Build and add the Unix time extra-field. This extra field
* will be included be default. Johnny Lee's implementation does
* not use this kind of extra-field.
* All datas are in Intel (=little-endian) format
Extra field info:
- 'UT' - UNIX time extra field
This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields
(full data in local header, only modification time in central header),
with the 'M3' field added to the end and the size of the 'M3' field
in the central header.
*/
static int add_UT_ef(struct zlist far *z, iztimes *z_utim)
{
char *l_ef = NULL;
char *c_ef = NULL;
Assert_it(z, "add_UT_ef","")
#ifdef IZ_CHECK_TZ
if (!zp_tz_is_valid)
return ZE_OK; /* skip silently if no valid TZ info */
#endif
/* We can't work if there's no entry to work on. */
if( z == NULL ) {
return ZE_LOGIC;
}
/* Check to make sure we've got enough room in the extra fields. */
if( z->ext + EB_L_UT_SIZE > EF_SIZE_MAX ||
z->cext + EB_C_UT_SIZE > EF_SIZE_MAX ) {
return ZE_MEM;
}
/* Allocate memory for the local and central extra fields. */
if( z->extra && z->ext != 0 ) {
l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE );
} else {
l_ef = (char *)malloc( EB_L_UT_SIZE );
z->ext = 0;
}
if( l_ef == NULL ) {
return ZE_MEM;
}
z->extra = l_ef;
l_ef += z->ext;
if( z->cextra && z->cext != 0 ) {
c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE );
} else {
c_ef = (char *)malloc( EB_C_UT_SIZE );
z->cext = 0;
}
if( c_ef == NULL ) {
return ZE_MEM;
}
z->cextra = c_ef;
c_ef += z->cext;
/* Now add the local version of the field. */
*l_ef++ = 'U';
*l_ef++ = 'T';
*l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */
*l_ef++ = (char)0;
*l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_CTIME);
*l_ef++ = (char)(z_utim->mtime);
*l_ef++ = (char)(z_utim->mtime >> 8);
*l_ef++ = (char)(z_utim->mtime >> 16);
*l_ef++ = (char)(z_utim->mtime >> 24);
*l_ef++ = (char)(z_utim->ctime);
*l_ef++ = (char)(z_utim->ctime >> 8);
*l_ef++ = (char)(z_utim->ctime >> 16);
*l_ef++ = (char)(z_utim->ctime >> 24);
z->ext += EB_L_UT_SIZE;
/* Now add the central version. */
memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE);
c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */
z->cext += EB_C_UT_SIZE;
return ZE_OK;
}
#endif /* USE_EF_UT_TIME */
/*
* Build and add the old 'Johnny Lee' Mac extra field
* All native datas are in Motorola (=big-endian) format
*/
static int add_JLEE_ef( struct zlist far *z )
{
char *l_ef = NULL;
char *c_ef = NULL;
Assert_it(z, "add_JLEE_ef","")
/* Check to make sure we've got enough room in the extra fields. */
if ( z->ext + EB_L_JLEE_SIZE > EF_SIZE_MAX ||
z->cext + EB_C_JLEE_SIZE > EF_SIZE_MAX ) {
return ZE_MEM;
}
/* Allocate memory for the local extra fields. */
if ( z->extra && z->ext != 0 ) {
l_ef = (char *)realloc( z->extra, z->ext + EB_L_JLEE_SIZE );
} else {
l_ef = (char *)malloc( EB_L_JLEE_SIZE );
z->ext = 0;
}
if ( l_ef == NULL ) {
return ZE_MEM;
}
z->extra = l_ef;
l_ef += z->ext;
/* Allocate memory for the central extra fields. */
if ( z->cextra && z->cext != 0 ) {
c_ef = (char *)realloc( z->cextra, z->cext + EB_C_JLEE_SIZE );
} else {
c_ef = (char *)malloc( EB_C_JLEE_SIZE );
z->cext = 0;
}
if ( c_ef == NULL ) {
return ZE_MEM;
}
z->cextra = c_ef;
c_ef += z->cext;
if ( verbose ) {
print_extra_info();
}
/**
**
** Now add the local version of the field.
**/
make_extrafield_JLEE(l_ef);
z->ext += EB_L_JLEE_SIZE;
/**
**
** Now add the central version of the field.
** It's identical to the local header. I wonder why ??
* the first two fields are in Intel little-endian format */
make_extrafield_JLEE(c_ef);
z->cext += EB_C_JLEE_SIZE;
return ZE_OK;
}
/*
* This is an implementation of Johnny Lee's extra field.
* I never saw Johnny Lee's code. My code is based on the extra-field
* definition mac (see latest appnote 1997-03-11)
* and on some experiments with Johnny Lee's Zip-app version 1.0, 1992
*
* Unfortunately I cannot agree with his extra-field layout.
* - it wasted space
* - and holds not all mac-specific information
*
* I coded this extra-field only for testing purposes.
* I don't want support this extra-field. Please use my implementation.
*
* This is old implementation of Johnny Lee's extra field.
* All native datas are in Motorola (=big-endian) format
*/
static void make_extrafield_JLEE(char *ef)
{
Assert_it(ef, "make_extrafield_JLEE","")
if (MacZip.isMacStatValid == false)
{
fprintf(stderr,"Internal Logic Error: [%d/%s] MacStat is out of sync !",
__LINE__,__FILE__);
exit(-1);
}
/* the first two fields are in Intel little-endian format */
*ef++ = 0xC8; /* tag for this extra block */
*ef++ = 0x07;
*ef++ = (char)(EB_L_JLEE_LEN); /* total data size this block */
*ef++ = (char)((EB_L_JLEE_LEN) >> 8);
/* the following fields are in motorola big-endian format */
*ef++ = 'J'; /* extra field signature: 4 Bytes */
*ef++ = 'L'; /* the old style extra field */
*ef++ = 'E';
*ef++ = 'E';
/* Start Macintosh Finder FInfo structure 16 Bytes overall */
/* Type: 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType);
/* Creator: 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
/* file Finder Flags: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags);
/* Finders Icon position of a file*/
/* V/Y-Position: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v);
/* H/X-Position: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h);
/* fdFldr Folder containing file 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr);
/* End Macintosh Finder FInfo structure */
/* Creation-time 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat);
/* Modification-time 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat);
/* info Bits 4 Bytes */
*ef++ = 0x00;
*ef++ = 0x00;
*ef++ = 0x00;
if (MacZip.DataForkOnly)
{ /* don't convert filename for unzipping */
/* 0x01 = data-fork; 0x00 = resource-fork */
*ef++ = (char) (MacZip.CurrentFork == DataFork) | 2;
}
else
{
*ef++ = (char) (MacZip.CurrentFork == DataFork);
}
/* file's location folder ID 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID);
/* ============ */
/* 40 Bytes */
}
/*
* Build and add the new mac extra field
* All native data are stored in Intel (=little-endian) format
*/
static int add_MAC3_ef( struct zlist far *z )
{
char *l_ef = NULL;
char *c_ef = NULL;
char *attrbuff = NULL;
off_t attrsize = (EB_L_MAC3_FINFO_LEN + EB_MAX_OF_VARDATA);
char *compbuff = NULL;
unsigned compsize = 0;
unsigned m3_compr;
Boolean compress_data = true;
Assert_it(z, "add_MAC3_ef","")
UserStop(); /* do event handling and let the user stop */
if( verbose ) {
print_extra_info();
}
/* allocate temporary buffer to collect the Mac extra field info */
attrbuff = (char *)malloc( (size_t)attrsize );
if( attrbuff == NULL ) {
return ZE_MEM;
}
/* fill the attribute buffer, to get its (uncompressed) size */
attrsize = make_extrafield_MAC3(attrbuff);
if (compress_data &&
((compbuff = (char *)malloc((size_t)attrsize + MEMCOMPRESS_OVERHEAD))
!= NULL))
{
/* Try compressing the data */
compsize = memcompress( compbuff,
(size_t)attrsize + MEMCOMPRESS_OVERHEAD,
attrbuff,
(size_t)attrsize );
#ifdef MAC_EXTRAFLD_UNCMPR
compsize = attrsize;
#endif
}
else
{
compsize = attrsize;
}
if ((compsize) < attrsize) {
/* compression gained some space ... */
free(attrbuff); /* no longer needed ... */
m3_compr = EB_M3_FL_COMPRESS;
} else {
/* compression does not help, store data in uncompressed mode */
if (compbuff != NULL) free(compbuff);
compbuff = attrbuff;
compsize = attrsize;
m3_compr = EB_M3_FL_UNCMPR;
}
/* Check to make sure we've got enough room in the extra fields. */
if( z->ext + (EB_L_MAC3_SIZE + compsize) > EF_SIZE_MAX ||
z->cext + EB_C_MAC3_SIZE > EF_SIZE_MAX ) {
if (compbuff != NULL) free(compbuff);
return ZE_MEM;
}
/* Allocate memory for the local extra fields. */
if( z->extra && z->ext != 0 ) {
l_ef = (char *)realloc( z->extra, z->ext +
EB_L_MAC3_SIZE + compsize);
} else {
l_ef = (char *)malloc( EB_L_MAC3_SIZE + compsize);
z->ext = 0;
}
if( l_ef == NULL ) {
return ZE_MEM;
}
z->extra = l_ef;
l_ef += z->ext;
/* Allocate memory for the central extra fields. */
if( z->cextra && z->cext != 0 ) {
c_ef = (char *)realloc( z->cextra, z->cext + EB_C_MAC3_SIZE);
} else {
c_ef = (char *)malloc( EB_C_MAC3_SIZE );
z->cext = 0;
}
if( c_ef == NULL ) {
return ZE_MEM;
}
z->cextra = c_ef;
c_ef += z->cext;
/**
** Now add the local version of the field.
**/
l_ef = make_EF_Head_MAC3(l_ef, compsize, (ulg)attrsize, m3_compr);
memcpy(l_ef, compbuff, (size_t)compsize);
l_ef += compsize;
z->ext += EB_L_MAC3_SIZE + compsize;
free(compbuff);
/* And the central version. */
c_ef = make_EF_Head_MAC3(c_ef, 0, (ulg)attrsize, m3_compr);
z->cext += EB_C_MAC3_SIZE;
return ZE_OK;
}
/*
* Build the new mac local extra field header.
* It's identical with the central extra field.
* All native data are in Intel (=little-endian) format
*/
static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize,
unsigned flag)
{
unsigned info_flag = flag;
Assert_it(ef, "make_EF_Head_MAC3","")
/* the first four fields are in Intel little-endian format */
*ef++ = 'M'; /* tag for this extra block 2 Bytes */
*ef++ = '3';
/* total data size this block 2 Bytes */
*ef++ = (char) (EB_MAC3_HLEN + compsize);
*ef++ = (char)((EB_MAC3_HLEN + compsize) >> 8);
*ef++ = (char)(attrsize);
*ef++ = (char)(attrsize >> 8);
*ef++ = (char)(attrsize >> 16);
*ef++ = (char)(attrsize >> 24);
/* info Bits (flags) 2 Bytes */
if (MacZip.DataForkOnly) info_flag |= (EB_M3_FL_DATFRK |
EB_M3_FL_NOCHANGE);
if (MacZip.CurrentFork == DataFork) info_flag |= EB_M3_FL_DATFRK;
if (!MacZip.HaveGMToffset) info_flag |= EB_M3_FL_NOUTC;
*ef++ = (char)info_flag;
*ef++ = (char)0x00; /* reserved at the moment */
/* Note: Apple defined File-Type/-Creator as OSType ( =unsigned long,
see Universal Headers 3.1). However, File-Type/-Creator are a
unique four-character sequence. Therefore the byteorder of the
File-Type/-Creator are NOT changed. The native format is used. */
/* Type: 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType);
/* Creator: 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
return ef;
}
/*
* Build the new mac local extra field header.
* All native data are in Intel (=little-endian) format
*/
unsigned make_extrafield_MAC3(char *ef)
{
char *ef_m3_begin = ef;
char *temp_Pathname;
char tmp_buffer[NAME_MAX];
unsigned char comment[257];
unsigned short FLength = 0;
unsigned short CLength = 0;
short tempFork;
OSErr err;
Assert_it(ef, "make_extrafield_MAC3","")
if (MacZip.isMacStatValid == false)
{
fprintf(stderr,
"Internal Logic Error: [%d/%s] MacStat is out of sync !",
__LINE__, __FILE__);
exit(-1);
}
/* Start Macintosh Finder FInfo structure except Type/Creator
(see make_EF_Head_MAC3()) 8 Bytes overall */
/* file Finder Flags: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8);
/* Finders Icon position of a file*/
/* V/Y-Position: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8);
/* H/X-Position: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8);
/* fdFldr Folder containing file 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8);
/* End Macintosh Finder FInfo structure */
/* 8 Bytes so far ... */
/* Start Macintosh Finder FXInfo structure 16 Bytes overall */
/* Icon ID: 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID >> 8);
/* unused: 6 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0]);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0] >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1]);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1] >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2]);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2] >> 8);
/* Script flag: 1 Byte */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdScript);
/* More flag bits: 1 Byte */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdXFlags);
/* Comment ID 2 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment >> 8);
/* Home Dir ID: 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 24);
/* End Macintosh Finder FXInfo structure */
/* 24 Bytes so far ... */
/* file version number 1 Byte */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFVersNum);
/* directory access rights 1 Byte */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioACUser);
/* Creation-time 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24);
/* Modification-time 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24);
/* Backup-time 4 Bytes */
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 8);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 16);
*ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 24);
/* 38 Bytes so far ... */
#ifdef USE_EF_UT_TIME
if (MacZip.HaveGMToffset) {
/* GMT-Offset times 12 Bytes */
*ef++ = (char)(MacZip.Cr_UTCoffs);
*ef++ = (char)(MacZip.Cr_UTCoffs >> 8);
*ef++ = (char)(MacZip.Cr_UTCoffs >> 16);
*ef++ = (char)(MacZip.Cr_UTCoffs >> 24);
*ef++ = (char)(MacZip.Md_UTCoffs);
*ef++ = (char)(MacZip.Md_UTCoffs >> 8);
*ef++ = (char)(MacZip.Md_UTCoffs >> 16);
*ef++ = (char)(MacZip.Md_UTCoffs >> 24);
*ef++ = (char)(MacZip.Bk_UTCoffs);
*ef++ = (char)(MacZip.Bk_UTCoffs >> 8);
*ef++ = (char)(MacZip.Bk_UTCoffs >> 16);
*ef++ = (char)(MacZip.Bk_UTCoffs >> 24);
}
/* 50 Bytes so far ... */
#endif
/* Text Encoding Base (charset) 2 Bytes */
*ef++ = (char)(MacZip.CurrTextEncodingBase);
*ef++ = (char)(MacZip.CurrTextEncodingBase >> 8);
/* 52 Bytes so far ... */
/* MacZip.CurrentFork will be changed, so we have to save it */
tempFork = MacZip.CurrentFork;
if (!MacZip.StoreFullPath) {
temp_Pathname = StripPartialDir(tmp_buffer, MacZip.SearchDir,
MacZip.FullPath);
} else {
temp_Pathname = MacZip.FullPath;
}
MacZip.CurrentFork = tempFork;
FLength = strlen(temp_Pathname) + 1;
memcpy( ef, temp_Pathname, (size_t)FLength );
ef += FLength; /* make room for the string - variable length */
err = FSpLocationFromFullPath(strlen(MacZip.FullPath), MacZip.FullPath,
&MacZip.fileSpec);
printerr("FSpLocationFromFullPath:", err, err,
__LINE__, __FILE__, tmp_buffer);
err = FSpDTGetComment(&MacZip.fileSpec, comment);
printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err,
__LINE__, __FILE__, "");
PToCCpy(comment,tmp_buffer);
CLength = strlen(tmp_buffer) + 1;
memcpy( ef, tmp_buffer, (size_t)CLength );
ef += CLength; /* make room for the string - variable length */
if (verbose) printf("\n comment: [%s]", tmp_buffer);
return (unsigned)(ef - ef_m3_begin);
}
/*
* Print all native data of the new mac local extra field.
* It's for debugging purposes and disabled by default.
*/
static void PrintFileInfo(void)
{
DateTimeRec MacTime;
printf("\n\n---------------------------------------------"\
"----------------------------------");
printf("\n FullPath Name = [%s]", MacZip.FullPath);
printf("\n File Attributes = %s 0x%x %d",
sBit2Str(MacZip.fpb.hFileInfo.ioFlAttrib),
MacZip.fpb.hFileInfo.ioFlAttrib,
MacZip.fpb.hFileInfo.ioFlAttrib);
printf("\n Enclosing Folder ID# = 0x%x %d",
MacZip.fpb.hFileInfo.ioFlParID,
MacZip.fpb.hFileInfo.ioFlParID);
if (!MacZip.isDirectory)
{
printf("\n File Type = [%c%c%c%c] 0x%lx",
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType);
printf("\n File Creator = [%c%c%c%c] 0x%lx",
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
printf("\n Data Fork :" );
printf("\n Actual (Logical) Length = %d 0x%x ",
MacZip.fpb.hFileInfo.ioFlLgLen,
MacZip.fpb.hFileInfo.ioFlLgLen);
printf("\n Allocated (Physical) Length = %d 0x%x",
MacZip.fpb.hFileInfo.ioFlPyLen,
MacZip.fpb.hFileInfo.ioFlPyLen);
printf("\n Resource Fork :" );
printf("\n Actual (Logical) Length = %d 0x%x",
MacZip.fpb.hFileInfo.ioFlRLgLen,
MacZip.fpb.hFileInfo.ioFlRLgLen );
printf("\n Allocated (Physical) Length = %d 0x%x",
MacZip.fpb.hFileInfo.ioFlRPyLen,
MacZip.fpb.hFileInfo.ioFlRPyLen );
}
printf("\n Dates : ");
SecondsToDate (MacZip.CreatDate, &MacTime);
printf("\n Created = %4d/%2d/%2d %2d:%2d:%2d ",
MacTime.year,
MacTime.month,
MacTime.day,
MacTime.hour,
MacTime.minute,
MacTime.second);
SecondsToDate (MacZip.BackDate, &MacTime);
printf("\n Backup = %4d/%2d/%2d %2d:%2d:%2d ",
MacTime.year,
MacTime.month,
MacTime.day,
MacTime.hour,
MacTime.minute,
MacTime.second);
SecondsToDate (MacZip.ModDate, &MacTime);
printf("\n Modified = %4d/%2d/%2d %2d:%2d:%2d ",
MacTime.year,
MacTime.month,
MacTime.day,
MacTime.hour,
MacTime.minute,
MacTime.second);
if (!MacZip.isDirectory)
{
printf("\n Finder Flags : %s 0x%x %d",
sBit2Str(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags),
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags);
printf("\n Finder Icon Position = X: %d 0x%x ",
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h);
printf("\n Y: %d 0x%x ",
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v);
}
else
{
printf("\n Finder Flags : %s 0x%x %d",
sBit2Str(MacZip.fpb.dirInfo.ioDrUsrWds.frFlags),
MacZip.fpb.dirInfo.ioDrUsrWds.frFlags,
MacZip.fpb.dirInfo.ioDrUsrWds.frFlags);
printf("\n Finder Icon Position = X: %d 0x%x ",
MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h,
MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h);
printf("\n Y: %d 0x%x ",
MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v,
MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v);
}
printf("\n----------------------------------------------------"\
"---------------------------\n");
}
/*
* If the switch '-v' is used, print some more info.
*/
static void print_extra_info(void)
{
char Fork[20];
if (MacZip.CurrentFork == DataFork) sstrcpy(Fork,"<DataFork>");
else sstrcpy(Fork,"<ResourceFork>");
printf("\n%16s [%c%c%c%c] [%c%c%c%c]",Fork,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8,
MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
}

View file

@ -0,0 +1,398 @@
/*
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*
This file implements the getenv() function.
# Background:
# Under Unix: Each Process (= running Program) has a set of
# associated variables. The variables are called enviroment
# variables and, together, constitute the process environment.
# These variables include the search path, the terminal type,
# and the user's login name.
# Unfortunatelly the MacOS has no equivalent. So we need
# a file to define the environment variables.
# Name of this file is "MacZip.Env". It can be placed
# in the current folder of MacZip or in the
# preference folder of the system disk.
# If MacZip founds the "MacZip.Env" file in the current
# the folder of MacZip the "MacZip.Env" file in the
# preference folder will be ignored.
# An environment variable has a name and a value:
# Name=Value
# Note: Spaces are significant:
# ZIPOPT=-r and
# ZIPOPT = -r are different !!!
*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unix.h>
#include <Files.h>
#include <Folders.h>
#include "pathname.h"
#include "helpers.h"
/*****************************************************************************/
/* Module level Vars */
/*****************************************************************************/
static char ListAllKeyValues = 0;
static unsigned LineNumber = 0;
static char CompletePath[NAME_MAX];
Boolean IgnoreEnvironment = false; /* used by dialog.c and initfunc.c
of the Mainapp */
/*****************************************************************************/
/* Macros, typedefs */
/*****************************************************************************/
typedef struct _EnviromentPair {
char *key;
char *value;
} EnviromentPair;
#define MAX_COMMAND 1024
/*****************************************************************************/
/* Prototypes */
/*****************************************************************************/
int get_char(FILE *file);
void unget_char(int ch,FILE *file);
int get_string(char *string,int size, FILE *file, char *terms);
void skip_comments(FILE *file);
char *load_entry(FILE *file);
char *getenv(const char *name);
EnviromentPair *ParseLine(char *line);
OSErr FSpFindFolder_Name(short vRefNum, OSType folderType,
Boolean createFolder,FSSpec *spec, unsigned char *name);
FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
void ShowAllKeyValues(void);
void Set_LineNum(unsigned ln);
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/* get_string(str, max, file, termstr) : like fgets() but
* (1) has terminator string which should include \n
* (2) will always leave room for the null
* (3) uses get_char() so LineNumber will be accurate
* (4) returns EOF or terminating character, whichever
*/
int get_string(char *string, int size, FILE *file, char *terms)
{
int ch;
while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) {
if (size > 1) {
*string++ = (char) ch;
size--;
}
}
if (size > 0)
{
*string = '\0';
}
return ch;
}
void Set_LineNum(unsigned ln)
{
LineNumber = ln;
}
/* get_char(file) : like getc() but increment LineNumber on newlines
*/
int get_char(FILE *file)
{
int ch;
ch = getc(file);
if (ch == '\n')
{
Set_LineNum(LineNumber + 1);
}
return ch;
}
/* skip_comments(file) : read past comment (if any)
*/
void skip_comments(FILE *file)
{
int ch;
while (EOF != (ch = get_char(file)))
{
/* ch is now the first character of a line.
*/
while (ch == ' ' || ch == '\t')
{
ch = get_char(file);
}
if (ch == EOF)
{
break;
}
/* ch is now the first non-blank character of a line.
*/
if (ch != '\n' && ch != '#')
{
break;
}
/* ch must be a newline or comment as first non-blank
* character on a line.
*/
while (ch != '\n' && ch != EOF)
{
ch = get_char(file);
}
/* ch is now the newline of a line which we're going to
* ignore.
*/
}
if (ch != EOF)
{
unget_char(ch, file);
}
}
/* unget_char(ch, file) : like ungetc but do LineNumber processing
*/
void unget_char(int ch, FILE *file)
{
ungetc(ch, file);
if (ch == '\n')
{
Set_LineNum(LineNumber - 1);
}
}
/* this function reads one file entry -- the next -- from a file.
* it skips any leading blank lines, ignores comments, and returns
* NULL if for any reason the entry can't be read and parsed.
*/
char *load_entry(FILE *file)
{
int ch;
static char cmd[MAX_COMMAND];
skip_comments(file);
ch = get_string(cmd, MAX_COMMAND, file, "\n");
if (ch == EOF)
{
return NULL;
}
return cmd;
}
EnviromentPair *ParseLine(char *line)
{
char *tmpPtr;
static EnviromentPair *Env;
unsigned short length = strlen(line);
Env->key = "";
Env->value = "";
for (tmpPtr = line; *tmpPtr; tmpPtr++)
{
if (*tmpPtr == '=')
{
*tmpPtr = 0;
Env->key = line;
if (strlen(Env->key) < length)
{
Env->value = ++tmpPtr;
}
return Env;
}
}
return Env;
}
char *getenv(const char *name)
{
FILE *fp;
char *LineStr = NULL;
EnviromentPair *Env1;
FSSpec spec;
OSErr err;
if (IgnoreEnvironment)
return NULL; /* user wants to ignore the environment vars */
if (name == NULL)
return NULL;
GetCompletePath(CompletePath,"MacZip.Env",&spec,&err);
/* try open the file in the current folder */
fp = FSp_fopen(&spec,"r");
if (fp == NULL)
{ /* Okey, lets try open the file in the preference folder */
FSpFindFolder_Name(
kOnSystemDisk,
kPreferencesFolderType,
kDontCreateFolder,
&spec,
"\pMacZip.Env");
fp = FSp_fopen(&spec,"r");
if (fp == NULL)
{
return NULL; /* there is no enviroment-file */
}
}
LineStr = load_entry(fp);
while (LineStr != NULL)
{ /* parse the file line by line */
Env1 = ParseLine(LineStr);
if (strlen(Env1->value) > 0)
{ /* we found a key/value pair */
if (ListAllKeyValues)
printf("\n Line:%3d [%s] = [%s]",LineNumber,Env1->key,Env1->value);
if (stricmp(name,Env1->key) == 0)
{ /* we found the value of a given key */
return Env1->value;
}
}
LineStr = load_entry(fp); /* read next line */
}
fclose(fp);
return NULL;
}
OSErr FSpFindFolder_Name(
short vRefNum, /* Volume reference number. */
OSType folderType, /* Folder type taken by FindFolder. */
Boolean createFolder, /* Should we create it if non-existant. */
FSSpec *spec, /* Pointer to resulting directory. */
unsigned char *name) /* Name of the file in the folder */
{
short foundVRefNum;
long foundDirID;
OSErr err;
err = FindFolder(vRefNum, folderType, createFolder,
&foundVRefNum, &foundDirID);
if (err != noErr)
{
return err;
}
err = FSMakeFSSpec(foundVRefNum, foundDirID, name, spec);
return err;
}
void ShowAllKeyValues(void)
{
OSErr err;
FSSpec spec;
Boolean tmpIgnoreEnvironment = IgnoreEnvironment;
ListAllKeyValues = 1;
IgnoreEnvironment = false;
GetCompletePath(CompletePath,"MacZip.Env",&spec,&err);
if (err != 0)
{ /* Okey, lets try open the file in the preference folder */
FSpFindFolder_Name(
kOnSystemDisk,
kPreferencesFolderType,
kDontCreateFolder,
&spec,
"\pMacZip.Env");
GetFullPathFromSpec(CompletePath,&spec, &err);
if (err != 0)
{
return; /* there is no enviroment-file */
}
}
printf("\nLocation of the current \"MacZip.Env\" file:\n [%s]",CompletePath);
printf("\n\nList of all environment variables\n");
getenv(" ");
printf("\n\nEnd\n\n");
/* restore used variables */
ListAllKeyValues = 0;
LineNumber = 0;
IgnoreEnvironment = tmpIgnoreEnvironment;
}

View file

@ -0,0 +1,479 @@
/*
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
helpers.c
Some useful functions Used by unzip and zip.
---------------------------------------------------------------------------*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include "zip.h"
#include <ctype.h>
#include <time.h>
#include <sound.h>
#include "macstuff.h"
#include "helpers.h"
#include "pathname.h"
/*****************************************************************************/
/* Global Vars */
/*****************************************************************************/
extern int noisy;
extern char MacPathEnd;
extern char *zipfile; /* filename of the Zipfile */
extern char *tempzip; /* Temporary zip file name */
extern ZCONST unsigned char MacRoman_to_WinCP1252[128];
static char argStr[1024];
static char *argv[MAX_ARGS + 1];
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/*
** Copy a C string to a Pascal string
**
*/
unsigned char *CToPCpy(unsigned char *pstr, char *cstr)
{
register char *dptr;
register unsigned len;
len=0;
dptr=(char *)pstr+1;
while (len<255 && (*dptr++ = *cstr++)!='\0') ++len;
*pstr= (unsigned char)len;
return pstr;
}
/*
** Copy a Pascal string to a C string
**
*/
char *PToCCpy(unsigned char *pstr, char *cstr)
{
strncpy(cstr, (char *) &pstr[1], *pstr);
cstr[pstr[0]] = '\0'; /* set endmarker for c-string */
return cstr;
}
/*
** strcpy() and strcat() work-alikes which allow overlapping buffers.
*/
char *sstrcpy(char *to,const char *from)
{
memmove(to, from, 1+strlen(from));
return to;
}
char *sstrcat(char *to,const char *from)
{
sstrcpy(to + strlen(to), from);
return to;
}
/*
** Alloc memory and init it
**
*/
char *StrCalloc(unsigned short size)
{
char *strPtr = NULL;
if ((strPtr = calloc(size, sizeof(char))) == NULL)
printerr("StrCalloc failed:", -1, size, __LINE__, __FILE__, "");
Assert_it(strPtr,"strPtr == NULL","")
return strPtr;
}
/*
** Release only non NULL pointers
**
*/
char *StrFree(char *strPtr)
{
if (strPtr != NULL)
{
free(strPtr);
}
return NULL;
}
/*
** Return a value in a binary string
**
*/
char *sBit2Str(unsigned short value)
{
static char str[sizeof(value)*8];
int biz = 16;
int strwid = 16;
int i, j;
char *tempPtr = str;
j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1));
for (i = 0; i < j; i++) {
*tempPtr++ = ' ';
}
while (--biz >= 0)
{
*tempPtr++ = ((value >> biz) & 1) + '0';
if (!(biz % 4) && biz) {
*tempPtr++ = ' ';
}
}
*tempPtr = '\0';
return str;
}
/*
** Parse commandline style arguments
**
*/
int ParseArguments(char *s, char ***arg)
{
int n = 1, Quote = 0;
char *p = s, *p1, c;
argv[0] = GetAppName();
*arg = argv;
p1 = (char *) argStr;
while ((c = *p++) != 0) {
if (c==' ') continue;
argv[n++] = p1;
if (n > MAX_ARGS)
return (n-1);
do {
if (c=='\\' && *p++)
c = *p++;
else
if ((c=='"') || (c == '\'')) {
if (!Quote) {
Quote = c;
continue;
}
if (c == Quote) {
Quote = 0;
continue;
}
}
*p1++ = c;
} while (*p && ((c = *p++) != ' ' || Quote));
*p1++ = '\0';
}
return n;
}
/*
** Print commandline style arguments
**
*/
void PrintArguments(int argc, char **argv)
{
printf("\n Arguments:");
printf("\n --------------------------");
while(--argc >= 0)
printf("\n argc: %d argv: [%s]", argc, &*argv[argc]);
printf("\n --------------------------\n\n");
return;
}
/*
** return some error-msg on file-system
**
*/
int PrintUserHFSerr(int cond, int err, char *msg2)
{
char *msg;
if (cond != 0)
{
switch (err)
{
case -35:
msg = "No such Volume";
break;
case -56:
msg = "No such Drive";
break;
case -37:
msg = "Bad Volume Name";
break;
case -49:
msg = "File is already open for writing";
break;
case -43:
msg = "Directory/File not found";
break;
case -120:
msg = "Directory/File not found or incomplete pathname";
break;
default: return err;
}
fprintf(stderr, "\n\n Error: %s ->%s", msg, msg2);
exit(err);
}
return 0;
}
/*
** Check mounted volumes and return number of volumes
** with the same name.
*/
short CheckMountedVolumes(char *FullPath)
{
FSSpec volumes[50]; /* 50 Volumes should be enough */
char VolumeName[257], volume[257];
short actVolCount, volIndex = 1, VolCount = 0;
OSErr err;
int i;
GetVolumeFromPath(FullPath, VolumeName);
err = OnLine(volumes, 50, &actVolCount, &volIndex);
printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
for (i=0; i < actVolCount; i++)
{
PToCCpy(volumes[i].name,volume);
if (stricmp(volume, VolumeName) == 0) VolCount++;
}
printerr("OnLine: ", (VolCount == 0), VolCount, __LINE__, __FILE__, FullPath);
return VolCount;
}
/*
** compares strings, ignoring differences in case
**
*/
int stricmp(const char *p1, const char *p2)
{
int diff;
while (*p1 && *p2)
{
if (*p1 != *p2)
{
if (isalpha(*p1) && isalpha(*p2))
{
diff = toupper(*p1) - toupper(*p2);
if (diff) return diff;
}
else break;
}
p1++;
p2++;
}
return *p1 - *p2;
}
/*
** Convert the MacOS-Strings (Filenames/Findercomments) to a most compatible.
** These strings will be stored in the public area of the zip-archive.
** Every foreign platform (outside macos) will access these strings
** for extraction.
*/
void MakeCompatibleString(char *MacOS_Str,
const char SpcChar1, const char SpcChar2,
const char SpcChar3, const char SpcChar4,
short CurrTextEncodingBase)
{
char *tmpPtr;
register uch curch;
Assert_it(MacOS_Str,"MakeCompatibleString MacOS_Str == NULL","")
for (tmpPtr = MacOS_Str; (curch = *tmpPtr) != '\0'; tmpPtr++)
{
if (curch == SpcChar1)
*tmpPtr = SpcChar2;
else
if (curch == SpcChar3)
*tmpPtr = SpcChar4;
else /* default */
/* now convert from MacRoman to ISO-8859-1 */
/* but convert only if MacRoman is activ */
if ((CurrTextEncodingBase == kTextEncodingMacRoman) &&
(curch > 127))
{
*tmpPtr = (char)MacRoman_to_WinCP1252[curch - 128];
}
} /* end for */
}
Boolean CheckForSwitch(char *Switch, int argc, char **argv)
{
char *p; /* steps through option arguments */
int i; /* arg counter, root directory flag */
for (i = 1; i < argc; i++)
{
if (argv[i][0] == '-')
{
if (argv[i][1])
{
for (p = argv[i]+1; *p; p++)
{
if (*p == Switch[0])
{
return true;
}
if ((Switch[1] != NULL) &&
((*p == Switch[0]) && (*p == Switch[1])))
{
return true;
}
}
}
}
}
return false;
}
#if (defined(USE_SIOUX) || defined(MACUNZIP_STANDALONE))
/*
** checks the condition and returns an error-msg
** this function is for internal use only
*/
OSErr printerr(const char *msg, int cond, int err, int line, char *file,
const char *msg2)
{
if (cond != 0)
{
fprintf(stderr, "\nint err: %d: %s %d [%d/%s] {%s}\n", clock(), msg, err,
line, file, msg2);
}
return cond;
}
/*
fake-functions:
Not Implemented for metrowerks SIOUX
*/
void leftStatusString(char *status)
{
status = status;
}
void rightStatusString(char *status)
{
status = status;
}
void DoWarnUserDupVol( char *FullPath )
{
char VolName[257];
GetVolumeFromPath(FullPath, VolName);
printf("\n There are more than one volume that has the same name !!\n");
printf("\n Volume: %s\n",VolName);
printf("\n This port has one weak point:");
printf("\n It is based on pathnames. As you may be already know:");
printf("\n Pathnames are not unique on a Mac !");
printf("\n MacZip has problems to find the correct location of");
printf("\n the archive or the files.\n");
printf("\n My (Big) recommendation: Name all your volumes with an");
printf("\n unique name and MacZip will run without any problem.");
}
#endif

View file

@ -0,0 +1,57 @@
/*
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
#ifndef HELPERS_H
#define HELPERS_H 1
/* Convert a C string to a Pascal string */
unsigned char *CToPCpy(unsigned char *pstr, char *cstr);
/* Convert a Pascal string to a C string */
char *PToCCpy(unsigned char *pstr, char *cstr);
char *sstrcpy(char *to,const char *from);
char *sstrcat(char *to,const char *from);
char *StrCalloc(unsigned short size);
char *StrFree(char *strPtr);
char *sBit2Str(unsigned short value);
void print_extra_info(void);
int ParseArguments(char *s, char ***arg);
void PrintArguments(int argc, char **argv);
Boolean IsZipFile(char *name);
OSErr printerr(const char *msg, int cond, int err, int line, char *file,
const char *msg2);
int PrintUserHFSerr(int cond, int err, char *msg2);
short CheckMountedVolumes(char *FullPath);
void DoWarnUserDupVol(char *path);
void PrintFileInfo(void);
int stricmp(const char *p1, const char *p2);
void leftStatusString(char *status);
void rightStatusString(char *status);
Boolean isZipFile(FSSpec *fileToOpen);
unsigned long MacFileDate_to_UTime(unsigned long mactime);
Boolean CheckForSwitch(char *Switch, int argc, char **argv);
void MakeCompatibleString(char *MacOS_Str,
const char SpcChar1, const char SpcChar2,
const char SpcChar3, const char SpcChar4,
short CurrTextEncodingBase);
#define MAX_ARGS 25
#endif /* HELPERS_H */

View file

@ -0,0 +1,86 @@
/*
Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 1999-Oct-05 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#ifndef _MACGLOBAL_
#define _MACGLOBAL_
#include <time.h>
/*
all my Global vars are defined here.
*/
#define ResourceFork -1
#define DataFork 1
#define NoFork 0
/*
all my Global vars are defined here.
*/
typedef struct {
short CurrentFork;
short MacZipMode;
Boolean isMacStatValid;
Boolean HaveGMToffset;
short CurrTextEncodingBase;
/* info about the current file */
Boolean isDirectory;
char FullPath[NAME_MAX];
char FileName[NAME_MAX];
FSSpec fileSpec;
long dirID;
CInfoPBRec fpb;
/* time infos about the current file */
time_t CreatDate;
time_t ModDate;
time_t BackDate;
long Cr_UTCoffs; /* offset "local time - UTC" for CreatDate */
long Md_UTCoffs; /* offset "local time - UTC" for ModDate */
long Bk_UTCoffs; /* offset "local time - UTC" for BackDate */
/* some statistics over all*/
unsigned long FoundFiles;
unsigned long FoundDirectories;
unsigned long RawCountOfItems;
unsigned long BytesOfData;
unsigned long attrsize;
/* some switches and user parameters */
Boolean DataForkOnly;
Boolean StoreFullPath;
Boolean StoreFoldersAlso; /* internal switch is true if '-r' is set */
unsigned short SearchLevels;
char Pattern[NAME_MAX];
Boolean IncludeInvisible;
Boolean StatingProgress;
char SearchDir[NAME_MAX];
char CurrentPath[NAME_MAX];
/* current zip / tempzip file info */
char ZipFullPath[NAME_MAX];
FSSpec ZipFileSpec;
unsigned long ZipFileType;
char TempZipFullPath[NAME_MAX];
FSSpec TempZipFileSpec;
} MacZipGlobals;
void UserStop(void);
#endif

View file

@ -0,0 +1,363 @@
/*
Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 1999-Oct-05 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*** macopen.c; stuff only required for the Mac port ***/
#include "zip.h"
#include <string.h>
#include <fcntl.h>
#include <unix.h>
#include <sound.h>
#include "helpers.h"
#include "pathname.h"
#include "macopen.h"
#include "macstuff.h"
#ifdef MACZIP
#include "macglob.h"
extern char *zipfile; /* filename of the Zipfile */
extern char *tempzip; /* Temporary zip file name */
extern MacZipGlobals MacZip;
/* don't include "osdep.h" otherwise we will trap into endless loop */
#undef open
#undef fopen
FILE *MacFopen(const char *path, const char *mode)
{
static char TruncPath[NAME_MAX];
OSErr err = 0;
AssertStr(path,path)
/* open zipfile or tempzip */
if (strcmp(zipfile,path) == 0)
{
GetCompletePath(MacZip.ZipFullPath,path,&MacZip.ZipFileSpec,&err);
err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path);
if (CheckMountedVolumes(MacZip.ZipFullPath) > 1)
DoWarnUserDupVol(MacZip.ZipFullPath);
/* tempfile should appear in the same directory of the zipfile
-> save path of zipfile */
TruncFilename(TruncPath, MacZip.ZipFullPath);
return fopen(MacZip.ZipFullPath, mode);
}
if (strcmp(tempzip,path) == 0)
{ /* add path of zipfile */
sstrcat(TruncPath,tempzip);
GetCompletePath(MacZip.TempZipFullPath,TruncPath,&MacZip.TempZipFileSpec,&err);
err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path);
return fopen(MacZip.TempZipFullPath, mode);
}
printerr("MacFopen:",err,err,__LINE__,__FILE__,path);
return NULL;
}
int MacOpen(const char *path,int oflag, ...)
{
char RealFname[NAME_MAX];
AssertStr(path,path)
RfDfFilen2Real(RealFname,path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork);
/* convert to real fname and init global var MacZip.CurrentFork !! */
switch (MacZip.CurrentFork)
{
case DataFork:
{
return my_open(RealFname, oflag);
break;
}
case ResourceFork:
{
return my_open( RealFname, oflag | O_RSRC);
break;
}
default: /* for now (Zip ver 2.3b) MacOpen should never reach this point */
{ /* however, this may change in the future ... */
printerr("open: no resource / datafork ",-1,-1,__LINE__,__FILE__,path);
return -1;
}
}
}
#ifdef muell
/* file to delete */
int destroy(char *path)
{
static char lastpath[NAME_MAX];
char currpath[NAME_MAX];
static Boolean FirstCall = true;
long rc;
AssertStr(path,path)
RfDfFilen2Real(currpath, path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork);
if (FirstCall == true)
{
FirstCall = false;
rc = remove(currpath);
}
else if (strcmp(currpath,lastpath) == 0) return 0; /* ignore, file is already deleted */
else rc = remove(currpath); /* we are removeing all the files only by their
pathname this is dangerous on a mac but there is no other way without
a complete rewrite of the port */
strcpy(lastpath,currpath);
return rc;
}
#endif
/* this function replaces the function "replace()" defined in fileio.c */
int replace(char *new_f, char *temp_f) /* destination and source file names */
{
OSErr err = 0;
char newfname[NAME_MAX];
AssertStr(new_f,new_f)
AssertStr(temp_f,temp_f)
UserStop();
GetFilename(newfname, new_f);
/* check zipfile name and tempfile name */
/* we are using this function only for replacing the tempfile with the zipfile */
if ((strcmp(zipfile,new_f) == 0) || (strcmp(tempzip,temp_f) == 0))
{
remove(MacZip.ZipFullPath);
/* rename the temp file to the zip file */
err = rename(MacZip.TempZipFullPath,MacZip.ZipFullPath);
printerr("rename:",err,err,__LINE__,__FILE__,MacZip.TempZipFullPath);
if (err != 0) return ZE_CREAT;
else return ZE_OK;
}
else return ZE_CREAT;
}
/* file to delete */
/* we are removeing all the files only by their
pathname this is dangerous on a mac but there is no
other way without a complete rewrite of the port */
int destroy(char *path)
{
static char lastpath[NAME_MAX];
static FSSpec trashfolder;
static Boolean FirstCall = true;
static char Num = 0;
static Boolean Immediate_File_Deletion = false;
char currpath[NAME_MAX], *envptr;
FSSpec fileToDelete;
OSErr err;
/* init this function */
if ((path == NULL) ||
(strlen(path) == 0))
{
FirstCall = true;
Num = 0;
return -1;
}
UserStop();
RfDfFilen2Real(currpath, path, MacZip.MacZipMode,
MacZip.DataForkOnly, &MacZip.CurrentFork);
GetCompletePath(currpath,currpath,&fileToDelete, &err);
if (FirstCall == true)
{
FirstCall = false;
sstrcpy(lastpath,currpath);
err = FSpFindFolder(fileToDelete.vRefNum, kTrashFolderType,
kDontCreateFolder,&trashfolder);
printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path);
envptr = getenv("Immediate_File_Deletion");
if (!(envptr == (char *)NULL || *envptr == '\0'))
{
if (stricmp(envptr,"yes") == 0)
Immediate_File_Deletion = true;
else
Immediate_File_Deletion = false;
}
if (Immediate_File_Deletion)
{
err = FSpDelete(&fileToDelete);
return err;
}
err = CatMove (fileToDelete.vRefNum, fileToDelete.parID,
fileToDelete.name, trashfolder.parID, trashfolder.name);
return err;
}
if (strcmp(currpath,lastpath) == 0)
{
return 0; /* ignore, file is already deleted */
}
else
{
if (Immediate_File_Deletion)
{
err = FSpDelete(&fileToDelete);
sstrcpy(lastpath,path);
return err;
}
err = CatMove (fileToDelete.vRefNum, fileToDelete.parID,
fileToDelete.name, trashfolder.parID, trashfolder.name);
/* -48 = file is already existing so we have to rename it before
moving the file */
if (err == -48)
{
Num++;
if (fileToDelete.name[0] >= 28) /* cut filename if to long */
fileToDelete.name[0] = 28;
P2CStr(fileToDelete.name);
sprintf(currpath,"%s~%d",(char *)fileToDelete.name,Num);
C2PStr(currpath);
C2PStr((char *)fileToDelete.name);
err = HRename (fileToDelete.vRefNum, fileToDelete.parID,
fileToDelete.name, (unsigned char *) currpath);
err = CatMove (fileToDelete.vRefNum, fileToDelete.parID,
(unsigned char *) currpath, trashfolder.parID,
trashfolder.name);
}
}
sstrcpy(lastpath,currpath);
return err;
}
#endif /* #ifdef MACZIP */
/*
* int open(const char *path, int oflag)
*
* Opens a file stream.
*/
int my_open(char *path, int oflag)
{
FSSpec spec;
char permission;
HParamBlockRec hpb;
OSErr err, errno;
Boolean targetIsFolder, wasAliased;
AssertStr(path,path)
/* Setup permission */
if ((oflag & 0x03) == O_RDWR)
permission = fsRdWrPerm;
else
permission = (oflag & O_RDONLY) ? fsRdPerm : 0 + (oflag & O_WRONLY) ? fsWrPerm : 0;
FSpLocationFromFullPath(strlen(path),path, &spec);
if ((oflag & (O_ALIAS | O_NRESOLVE)) == 0)
ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased);
hpb.fileParam.ioNamePtr = spec.name;
hpb.fileParam.ioVRefNum = spec.vRefNum;
hpb.fileParam.ioDirID = spec.parID;
hpb.ioParam.ioPermssn = permission;
if (oflag & O_RSRC) /* open the resource fork of the file */
err = PBHOpenRFSync(&hpb);
else /* open the data fork of the file */
err = PBHOpenDFSync(&hpb);
if ((err == fnfErr) && (oflag & O_CREAT)) {
hpb.fileParam.ioFlVersNum = 0;
err = PBHCreateSync(&hpb);
if (err == noErr) {
/* Set the finder info */
unsigned long secs;
unsigned long isbinary = oflag & O_BINARY;
hpb.fileParam.ioFlFndrInfo.fdType = '\?\?\?\?';
hpb.fileParam.ioFlFndrInfo.fdCreator = '\?\?\?\?';
hpb.fileParam.ioFlFndrInfo.fdFlags = 0;
if (oflag & O_ALIAS) /* set the alias bit */
hpb.fileParam.ioFlFndrInfo.fdFlags = kIsAlias;
else /* clear all flags */
hpb.fileParam.ioFlFndrInfo.fdFlags = 0;
GetDateTime(&secs);
hpb.fileParam.ioFlCrDat = hpb.fileParam.ioFlMdDat = secs;
PBHSetFInfoSync(&hpb);
}
if (err && (err != dupFNErr)) {
errno = err; return -1;
}
if (oflag & O_RSRC) /* open the resource fork of the file */
err = PBHOpenRFSync(&hpb);
else /* open the data fork of the file */
err = PBHOpenDFSync(&hpb);
}
if (err && (err != dupFNErr) && (err != opWrErr)) {
errno = err; return -1;
}
if (oflag & O_TRUNC) {
IOParam pb;
pb.ioRefNum = hpb.ioParam.ioRefNum;
pb.ioMisc = 0L;
err = PBSetEOFSync((ParmBlkPtr)&pb);
if (err != noErr) {
errno = err; return -1;
}
}
if (oflag & O_APPEND) lseek(hpb.ioParam.ioRefNum,0,SEEK_END);
return (hpb.ioParam.ioRefNum);
}

View file

@ -0,0 +1,21 @@
/*
Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 1999-Oct-05 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#ifndef __MACOPEN_H__
#define __MACOPEN_H__
#include <stdio.h>
#include <Files.h>
FILE *MacFopen(const char *path, const char *mode);
int MacOpen(const char *path, int oflag, ...);
int my_open(char *path, int oflag);
#endif /* __MACOPEN_H__ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
/*
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
#ifndef _MACSTUFF_H
#define _MACSTUFF_H 1
#include "MoreFilesExtras.h"
#include "MoreDesktopMgr.h"
#include "MoreFiles.h"
#include "FSpCompat.h"
#include "FullPath.h"
#endif /* _MACSTUFF_H */

View file

@ -0,0 +1,451 @@
/*
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/* -----------------------------------------------------------------------------
The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime,
mktime and time do not work correctly. The supplied link library mactime.c
contains replacement functions for them.
* Caveat: On a Mac, we only know the GMT and DST offsets for
* the current time, not for the time in question.
* Mac has no support for DST handling.
* DST changeover is all manually set by the user.
------------------------------------------------------------------------------*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <OSUtils.h>
#include "mactime.h"
/*
The MacOS function GetDateTime returns the
number of seconds elapsed since midnight, January 1, 1904.
*/
const unsigned long MacOS_2_Unix = 2082844800L;
/*****************************************************************************/
/* Macros, typedefs */
/*****************************************************************************/
#ifndef TEST_TIME_LIB
#define my_gmtime gmtime
#define my_localtime localtime
#define my_mktime mktime
#define my_time time
#endif
/*****************************************************************************/
/* Prototypes */
/*****************************************************************************/
/* internal prototypes */
static void clear_tm(struct tm * tm);
static long GMTDelta(void);
static Boolean DaylightSaving(void);
static time_t GetTimeMac(void);
static time_t Mactime(time_t *timer);
static void normalize(int *i,int *j,int norm);
static struct tm *time2tm(const time_t *timer);
static time_t tm2time(struct tm *tp);
/* Because serial port and SLIP conflict with ReadXPram calls,
we cache the call here so we don't hang on calling ReadLocation() */
static void myReadLocation(MachineLocation * loc);
/* prototypes for STD lib replacement functions */
struct tm *my_gmtime(const time_t *t);
struct tm *my_localtime(const time_t *t);
time_t my_mktime(struct tm *tp);
time_t my_time(time_t *t);
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/*
* Mac file times are based on 1904 Jan 1 00:00 local time,
* not 1970 Jan 1 00:00 UTC.
* So we have to convert the time stamps into UNIX UTC
* compatible values.
*/
time_t MacFtime2UnixFtime(unsigned long macftime)
{
long UTCoffset;
GetGMToffsetMac(macftime, &UTCoffset);
MACOS_TO_UNIX(macftime);
macftime -= UTCoffset;
return macftime;
}
/*
* Mac file times are based on 1904 Jan 1 00:00 local time,
* not 1970 Jan 1 00:00 UTC.
* So we have to convert the time stamps into MacOS local
* compatible values.
*/
unsigned long UnixFtime2MacFtime(time_t unxftime)
{
long UTCoffset;
unsigned long macftime = unxftime;
UNIX_TO_MACOS(macftime);
GetGMToffsetMac(macftime, &UTCoffset);
macftime += UTCoffset;
return macftime;
}
/*
* This function convert a file-localtime to an another
* file-localtime.
*/
time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs)
{
time_t MacGMTTime;
long UTCoffset;
/* convert macloctim into corresponding UTC value */
MacGMTTime = macloctim - s_gmtoffs;
GetGMToffsetMac(macloctim, &UTCoffset);
return (MacGMTTime + UTCoffset);
} /* AdjustForTZmove() */
/*
* This function calculates the difference between the supplied Mac
* ftime value (local time) and the corresponding UTC time in seconds.
*/
Boolean GetGMToffsetMac(unsigned long mactime, long *UTCoffset)
{
mactime = mactime;
/*
* Caveat: On a Mac, we only know the GMT and DST offsets for
* the current time, not for the time in question.
* Mac has no support for DST handling.
* DST changeover is all manually set by the user.
May be later I can include a support of GMT offset calculation for the
time in question here.
*/
*UTCoffset = GMTDelta();
return true;
}
/*****************************************************************************
* Standard Library Replacement Functions
* gmtime(), mktime(), localtime(), time()
*
* The unix epoch is used here.
* These functions gmtime(), mktime(), localtime() and time()
* expects and returns unix times.
*
* At midnight Jan. 1, 1970 GMT, the local time was
* midnight Jan. 1, 1970 + GMTDelta().
*
*
*****************************************************************************/
struct tm *my_gmtime(const time_t *timer)
{
return time2tm(timer);
}
struct tm *my_localtime(const time_t *timer)
{
time_t maclocal;
maclocal = *timer;
maclocal += GMTDelta();
return time2tm(&maclocal);
}
time_t my_mktime(struct tm *tp)
{
time_t maclocal;
maclocal = tm2time(tp);
maclocal -= GMTDelta();
return maclocal;
}
time_t my_time(time_t *time)
{
time_t tmp_time;
GetDateTime(&tmp_time);
MACOS_TO_UNIX(tmp_time);
if (time)
{
*time = tmp_time;
}
return tmp_time;
}
/*****************************************************************************/
/* static module level functions
/*****************************************************************************/
/*
* The geographic location and time zone information of a Mac
* are stored in extended parameter RAM. The ReadLocation
* produdure uses the geographic location record, MachineLocation,
* to read the geographic location and time zone information in
* extended parameter RAM.
*
* Because serial port and SLIP conflict with ReadXPram calls,
* we cache the call here.
*
* Caveat: this caching will give the wrong result if a session
* extend across the DST changeover time, but
* this function resets itself every 2 hours.
*/
static void myReadLocation(MachineLocation * loc)
{
static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */
static time_t first_call = 0, last_call = 86400;
if ((last_call - first_call) > 7200)
{
GetDateTime(&first_call);
ReadLocation(&storedLoc);
}
GetDateTime(&last_call);
*loc = storedLoc;
}
static Boolean DaylightSaving(void)
{
MachineLocation loc;
unsigned char dlsDelta;
myReadLocation(&loc);
dlsDelta = loc.u.dlsDelta;
return (dlsDelta != 0);
}
/* current local time = GMTDelta() + GMT
GMT = local time - GMTDelta() */
static long GMTDelta(void)
{
MachineLocation loc;
long gmtDelta;
myReadLocation(&loc);
/*
* On a Mac, the GMT value is in seconds east of GMT. For example,
* San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour)
* east of GMT. The gmtDelta field is a 3-byte value contained in a
* long word, so you must take care to get it properly.
*/
gmtDelta = loc.u.gmtDelta & 0x00FFFFFF;
if ((gmtDelta & 0x00800000) != 0)
{
gmtDelta |= 0xFF000000;
}
return gmtDelta;
}
/* This routine simulates stdclib time(), time in seconds since 1.1.1970
The time is in GMT */
static time_t GetTimeMac(void)
{
unsigned long maclocal;
/*
* Get the current time expressed as the number of seconds
* elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time).
* On a Mac, current time accuracy is up to a second.
*/
GetDateTime(&maclocal); /* Get Mac local time */
maclocal -= GMTDelta(); /* Get Mac GMT */
MACOS_TO_UNIX(maclocal);
return maclocal; /* return unix GMT */
}
/*
* clear_tm - sets a broken-down time to the equivalent of 1970/1/1 00:00:00
*/
static void clear_tm(struct tm * tm)
{
tm->tm_sec = 0;
tm->tm_min = 0;
tm->tm_hour = 0;
tm->tm_mday = 1;
tm->tm_mon = 0;
tm->tm_year = 0;
tm->tm_wday = 1;
tm->tm_yday = 0;
tm->tm_isdst = -1;
}
static void normalize(int *i,int *j,int norm)
{
while(*i < 0)
{
*i += norm;
(*j)--;
}
while(*i >= norm)
{
*i -= norm;
(*j)++;
}
}
/* Returns the GMT times */
static time_t Mactime(time_t *timer)
{
time_t t = GetTimeMac();
if (timer != NULL)
*timer = t;
return t;
}
static struct tm *time2tm(const time_t *timer)
{
DateTimeRec dtr;
MachineLocation loc;
time_t macLocal = *timer;
static struct tm statictime;
static const short monthday[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
UNIX_TO_MACOS(macLocal);
SecondsToDate(macLocal, &dtr);
statictime.tm_sec = dtr.second; /* second, from 0 to 59 */
statictime.tm_min = dtr.minute; /* minute, from 0 to 59 */
statictime.tm_hour = dtr.hour; /* hour, from 0 to 23 */
statictime.tm_mday = dtr.day; /* day of the month, from 1 to 31 */
statictime.tm_mon = dtr.month - 1; /* month, 1= January and 12 = December */
statictime.tm_year = dtr.year - 1900; /* year, ranging from 1904 to 2040 */
statictime.tm_wday = dtr.dayOfWeek - 1; /* day of the week, 1 = Sun, 7 = Sat */
statictime.tm_yday = monthday[statictime.tm_mon]
+ statictime.tm_mday - 1;
if (2 < statictime.tm_mon && !(statictime.tm_year & 3))
{
++statictime.tm_yday;
}
myReadLocation(&loc);
statictime.tm_isdst = DaylightSaving();
return(&statictime);
}
static time_t tm2time(struct tm *tp)
{
time_t intMacTime;
DateTimeRec dtr;
normalize(&tp->tm_sec, &tp->tm_min, 60);
normalize(&tp->tm_min, &tp->tm_hour,60);
normalize(&tp->tm_hour,&tp->tm_mday,24);
normalize(&tp->tm_mon, &tp->tm_year,12);
dtr.year = tp->tm_year + 1900; /* years since 1900 */
dtr.month = tp->tm_mon + 1; /* month, 0 = January and 11 = December */
dtr.day = tp->tm_mday; /* day of the month, from 1 to 31 */
dtr.hour = tp->tm_hour; /* hour, from 0 to 23 */
dtr.minute = tp->tm_min; /* minute, from 0 to 59 */
dtr.second = tp->tm_sec; /* second, from 0 to 59 */
DateToSeconds(&dtr, &intMacTime);
MACOS_TO_UNIX(intMacTime);
return intMacTime;
}

View file

@ -0,0 +1,61 @@
/*
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
#ifndef _MACTIME_H_
#define _MACTIME_H_
/* -----------------------------------------------------------------------------
The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime,
mktime and time do not work correctly. The supplied link library mactime.c
contains replacement functions for them.
* Caveat: On a Mac, we only know the GMT and DST offsets for
* the current time, not for the time in question.
* Mac has no support for DST handling.
* DST changeover is all manually set by the user.
------------------------------------------------------------------------------*/
#include <time.h>
#include <mactypes.h>
/*****************************************************************************/
/* Macros, typedefs */
/*****************************************************************************/
/*
* ARGH. Mac times are based on 1904 Jan 1 00:00, not 1970 Jan 1 00:00.
* So we have to diddle time_t's appropriately: add or subtract 66 years'
* worth of seconds == number of days times 86400 == (66*365 regular days +
* 17 leap days ) * 86400 == (24090 + 17) * 86400 == 2082844800L seconds.
* We hope time_t is an unsigned long (ulg) on the Macintosh...
*/
/*
This Offset is only used by MacFileDate_to_UTime()
*/
#define MACOS_TO_UNIX(x) (x) -= (unsigned long)MacOS_2_Unix
#define UNIX_TO_MACOS(x) (x) += (unsigned long)MacOS_2_Unix
/*
The MacOS function GetDateTime returns the
number of seconds elapsed since midnight, January 1, 1904.
*/
extern const unsigned long MacOS_2_Unix;
/* prototypes for public utility functions */
time_t MacFtime2UnixFtime(unsigned long macftime);
unsigned long UnixFtime2MacFtime(time_t unxftime);
time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs);
Boolean GetGMToffsetMac(unsigned long macftime, long *UTCoffset);
#endif

View file

@ -0,0 +1,726 @@
/*
Copyright (c) 1990-2003 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
pathname.c
Function dealing with the pathname. Mostly C-string work.
---------------------------------------------------------------------------*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sound.h>
#include "pathname.h"
#include "helpers.h"
#include "macstuff.h"
/*****************************************************************************/
/* Global Vars */
/*****************************************************************************/
const char ResourceMark[] = "XtraStuf.mac:"; /* see also macos.c */
#include "zip.h"
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/*
*----------------------------------------------------------------------
*
* FSpFindFolder --
*
* This function is a version of the FindFolder function that
* returns the result as a FSSpec rather than a vRefNum and dirID.
*
* Results:
* Results will be simaler to that of the FindFolder function.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
OSErr
FSpFindFolder(
short vRefNum, /* Volume reference number. */
OSType folderType, /* Folder type taken by FindFolder. */
Boolean createFolder, /* Should we create it if non-existant. */
FSSpec *spec) /* Pointer to resulting directory. */
{
short foundVRefNum;
long foundDirID;
OSErr err;
err = FindFolder(vRefNum, folderType, createFolder,
&foundVRefNum, &foundDirID);
if (err != noErr) {
return err;
}
err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec);
return err;
}
/*
** return volumename from pathname
**
*/
unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName)
{
const char *VolEnd, *tmpPtr1;
char *tmpPtr2 = VolumeName;
AssertStr(FullPath,"GetVolumeFromPath")
for (VolEnd = FullPath; *VolEnd != '\0' && *VolEnd != ':'; VolEnd++)
;
if (*VolEnd == '\0') return 0;
for (tmpPtr1 = FullPath; tmpPtr1 != VolEnd;)
{
*tmpPtr2++ = *tmpPtr1++;
}
*tmpPtr2 = '\0';
return (unsigned short) strlen(VolumeName);
}
/***********************************/
/* Function FindNewExtractFolder() */
/***********************************/
char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder)
{
char buffer[NAME_MAX], *tmpPtr, *namePtr;
char *last_dotpos = ExtractPath;
short count = 0, folderCount = 0;
OSErr err;
FSSpec Spec;
long theDirID;
Boolean isDirectory;
unsigned short namelen, pathlen = strlen(ExtractPath);
unsigned long ext_length = 0;
unsigned long num_to_cut = 0;
long firstpart_length = pathlen;
AssertStr(ExtractPath,"FindNewExtractFolder ExtractPath == NULL")
for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++)
if (*tmpPtr == ':')
{
folderCount++;
namePtr = tmpPtr;
}
if (folderCount > 1) {
namelen = strlen(namePtr);
} else {
namelen = strlen(ExtractPath);
}
if (uniqueFolder) {
for (count = 0; count < 99; count++)
{
memset(buffer,0,sizeof(buffer));
if (namelen >= 28)
ExtractPath[pathlen-2] = 0x0;
else
ExtractPath[pathlen-1] = 0x0;
sprintf(buffer,"%s%d",ExtractPath,count);
GetCompletePath(ExtractPath, buffer, &Spec,&err);
err = FSpGetDirectoryID(&Spec, &theDirID, &isDirectory);
if (err == -43) break;
}
} else {
/* Look for the last extension pos */
for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++)
if (*tmpPtr == '.') last_dotpos = tmpPtr;
ext_length = strlen(last_dotpos);
if (ext_length < 6) { /* up to 5 chars are treated as a */
/* normal extension like ".html" or ".class" */
int nameLength = last_dotpos - ExtractPath;
if (nameLength > 1) {
ExtractPath[nameLength] = 0x0;
} else {
ExtractPath[pathlen-1] = 0x0;
}
} else {
ExtractPath[pathlen-1] = 0x0;
}
GetCompletePath(ExtractPath, ExtractPath, &Spec,&err);
}
/* Foldernames must always end with a colon */
sstrcat(ExtractPath,":");
return ExtractPath;
}
/*
** creates an archive file name
**
*/
void createArchiveName(char *thePath)
{
char *tmpPtr, *namePtr;
short folderCount = 0;
unsigned short namelen, pathlen = strlen(thePath);
if (thePath[pathlen-1] == ':') thePath[pathlen-1] = 0x0;
for (tmpPtr = thePath; *tmpPtr; tmpPtr++)
if (*tmpPtr == ':')
{
folderCount++;
namePtr = tmpPtr;
}
namelen = strlen(namePtr);
/* we have to eliminate illegal chars:
* The name space for Mac filenames and Zip filenames (unix style names)
* do both include all printable extended-ASCII characters. The only
* difference we have to take care of is the single special character
* used as path delimiter:
* ':' on MacOS and '/' on Unix and '\\' on Dos.
* So, to convert between Mac filenames and Unix filenames without any
* loss of information, we simply interchange ':' and '/'. Additionally,
* we try to convert the coding of the extended-ASCII characters into
* InfoZip's standard ISO 8859-1 codepage table.
*/
MakeCompatibleString(namePtr, '/', '_', '.', '-', -1);
/* Avoid filenames like: "Archive..zip" */
if (thePath[pathlen-1] == '.')
{
thePath[pathlen-1] = 0;
}
if (folderCount >= 1)
{ /* path contains at least one folder */
if (namelen >= 28)
{
pathlen = pathlen-4;
}
thePath[pathlen] = '.';
thePath[pathlen+1] = 'z';
thePath[pathlen+2] = 'i';
thePath[pathlen+3] = 'p';
thePath[pathlen+4] = 0x0;
return;
}
else
{ /* path contains no folder */
FindDesktopFolder(thePath);
createArchiveName(thePath);
}
}
/*
** finds the desktop-folder on a volume with
** largest amount of free-space.
*/
void FindDesktopFolder(char *Path)
{
char buffer[255];
FSSpec volumes[50]; /* 50 Volumes should be enough */
short actVolCount, volIndex = 1, VolCount = 0;
OSErr err;
short i, foundVRefNum;
FSSpec spec;
UInt64 freeBytes;
UInt64 totalBytes;
UInt64 MaxFreeBytes;
err = OnLine(volumes, 50, &actVolCount, &volIndex);
printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
MaxFreeBytes = 0;
for (i=0; i < actVolCount; i++)
{
XGetVInfo(volumes[i].vRefNum,
volumes[i].name,
&volumes[i].vRefNum,
&freeBytes,
&totalBytes);
if (MaxFreeBytes < freeBytes) {
MaxFreeBytes = freeBytes;
foundVRefNum = volumes[i].vRefNum;
}
if ((freeBytes == 0) && (MaxFreeBytes < freeBytes)) {
MaxFreeBytes = freeBytes;
foundVRefNum = volumes[i].vRefNum;
}
}
FSpFindFolder(foundVRefNum, kDesktopFolderType,
kDontCreateFolder,&spec);
GetFullPathFromSpec(buffer, &spec , &err);
sstrcat(buffer,Path);
sstrcpy(Path,buffer);
}
/*
** return the path without the filename
**
*/
char *TruncFilename(char *DirPath, const char *FilePath)
{
char *tmpPtr;
char *dirPtr = NULL;
AssertStr(DirPath,"TruncFilename")
Assert_it(Spec,"TruncFilename","")
sstrcpy(DirPath, FilePath);
for (tmpPtr = DirPath; *tmpPtr; tmpPtr++)
if (*tmpPtr == ':')
dirPtr = tmpPtr;
if (dirPtr)
*++dirPtr = '\0';
else
printerr("TruncFilename: FilePath has no Folders", -1,
-1, __LINE__, __FILE__, FilePath);
return DirPath;
}
/*
** return only filename
**
*/
char *GetFilename(char *FileName, const char *FilePath)
{
const char *tmpPtr;
const char *dirPtr = NULL;
Assert_it(FileName,"GetFilename","")
Assert_it(FilePath,"GetFilename","")
for (tmpPtr = FilePath; *tmpPtr; tmpPtr++)
{
if (*tmpPtr == ':')
{
dirPtr = tmpPtr;
}
}
if (dirPtr)
{
++dirPtr; /* jump over the ':' */
}
else
{
return strcpy(FileName, FilePath); /* FilePath has no Folders */
}
return strcpy(FileName, dirPtr);
}
/*
** return fullpathname from folder/dir-id
**
*/
char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID,
ConstStr255Param name, OSErr *err)
{
FSSpec spec;
*err = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec);
printerr("FSMakeFSSpecCompat:", (*err != -43) && (*err != 0), *err,
__LINE__, __FILE__, "");
if ( (*err == noErr) || (*err == fnfErr) )
{
return GetFullPathFromSpec(CompletePath, &spec, err);
}
return NULL;
}
/*
** convert real-filename to archive-filename
**
*/
char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath,
short CurrentFork, short MacZipMode, Boolean DataForkOnly)
{
AssertStr(RealPath,"Real2RfDfFilen")
AssertStr(RfDfFilen,"Real2RfDfFilen")
if (DataForkOnly) /* make no changes */
{
return sstrcpy(RfDfFilen, RealPath);
}
switch (MacZipMode)
{
case JohnnyLee_EF:
{
sstrcpy(RfDfFilen, RealPath);
if (CurrentFork == DataFork) /* data-fork */
return sstrcat(RfDfFilen, "d");
if (CurrentFork == ResourceFork) /* resource-fork */
return sstrcat(RfDfFilen, "r");
break;
}
case NewZipMode_EF:
{
switch (CurrentFork)
{
case DataFork:
{
sstrcpy(RfDfFilen, RealPath);
return RfDfFilen; /* data-fork */
break;
}
case ResourceFork:
{
sstrcpy(RfDfFilen, ResourceMark);
sstrcat(RfDfFilen, RealPath); /* resource-fork */
return RfDfFilen;
break;
}
default:
{
printerr("Real2RfDfFilen:", -1, -1,
__LINE__, __FILE__, RealPath);
return NULL; /* function should never reach this point */
}
}
break;
}
default:
{
printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath);
return NULL; /* function should never reach this point */
}
}
printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath);
return NULL; /* function should never come reach this point */
}
/*
** convert archive-filename into a real filename
**
*/
char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode,
Boolean DataForkOnly, short *CurrentFork)
{
short length;
int result;
AssertStr(RfDfFilen,"RfDfFilen2Real")
if (DataForkOnly ||
(MacZipMode == UnKnown_EF) ||
(MacZipMode < JohnnyLee_EF))
{
*CurrentFork = DataFork;
return sstrcpy(RealFn,RfDfFilen);
}
result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2);
if (result == 0)
{
MacZipMode = NewZipMode_EF;
}
switch (MacZipMode)
{
case JohnnyLee_EF:
{
sstrcpy(RealFn, RfDfFilen);
length = strlen(RealFn); /* determine Fork type */
if (RealFn[length-1] == 'd') *CurrentFork = DataFork;
else *CurrentFork = ResourceFork;
RealFn[length-1] = '\0'; /* simply cut one char */
return RealFn;
break;
}
case NewZipMode_EF:
{ /* determine Fork type */
result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2);
if (result != 0)
{
*CurrentFork = DataFork;
sstrcpy(RealFn, RfDfFilen);
return RealFn; /* data-fork */
}
else
{
*CurrentFork = ResourceFork;
if (strlen(RfDfFilen) > (sizeof(ResourceMark) - 1))
{
sstrcpy(RealFn, &RfDfFilen[sizeof(ResourceMark)-1]);
}
else RealFn[0] = '\0';
return RealFn; /* resource-fork */
}
break;
}
default:
{
*CurrentFork = NoFork;
printerr("RfDfFilen2Real():", -1, MacZipMode,
__LINE__, __FILE__, RfDfFilen);
return NULL; /* function should never reach this point */
}
}
printerr("RfDfFilen2Real():", -1, MacZipMode, __LINE__, __FILE__, RfDfFilen);
return NULL; /* function should never reach this point */
}
/*
** return the applications name (argv[0])
**
*/
char *GetAppName(void)
{
ProcessSerialNumber psn;
static Str255 AppName;
ProcessInfoRec pinfo;
OSErr err;
GetCurrentProcess(&psn);
pinfo.processName = AppName;
pinfo.processInfoLength = sizeof(pinfo);
pinfo.processAppSpec = NULL;
err = GetProcessInformation(&psn,&pinfo);
AppName[AppName[0]+1] = 0x00;
return (char *)&AppName[1];
}
/*
** return fullpathname from FSSpec
**
*/
char *GetFullPathFromSpec(char *FullPath, FSSpec *Spec, OSErr *err)
{
Handle hFullPath;
short len;
Assert_it(Spec,"GetFullPathFromSpec","")
*err = FSpGetFullPath(Spec, &len, &hFullPath);
printerr("FSpGetFullPath:", (*err != -43) && (*err != 0), *err,
__LINE__, __FILE__, "");
memmove(FullPath, (Handle) *hFullPath, len);
FullPath[len] = '\0'; /* make c-string */
DisposeHandle((Handle)hFullPath); /* we don't need it any more */
printerr("Warning path length exceeds limit: ", len >= NAME_MAX, len,
__LINE__, __FILE__, " chars ");
return FullPath;
}
/*
* This function expands a given partial path to a complete path.
* Path expansions are relative to the running app.
* This function follows the notation:
* 1. relative path:
* a: ":subfolder:filename" -> ":current folder:subfolder:filename"
* b: "::folder2:filename" -> folder2 is beside the current
* folder on the same level
* c: "filename" -> in current folder
*
* An absolute path will be returned.
The following characteristics of Macintosh pathnames should be noted:
A full pathname never begins with a colon, but must contain at
least one colon.
A partial pathname always begins with a colon separator except in
the case where the file partial pathname is a simple file or
directory name.
Single trailing separator colons in full or partial pathnames are
ignored except in the case of full pathnames to volumes.
In full pathnames to volumes, the trailing separator colon is required.
Consecutive separator colons can be used to ascend a level from a
directory to its parent directory. Two consecutive separator colons
will ascend one level, three consecutive separator colons will ascend
two levels, and so on. Ascending can only occur from a directory;
not a file.
*/
char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec,
OSErr *err)
{
Boolean hasDirName = false;
char currentdir[NAME_MAX];
char *tmpPtr;
unsigned short pathlen;
AssertStr(name,"GetCompletePath")
Assert_it(Spec,"GetCompletePath","")
Assert_it((CompletePath != name),"GetCompletePath","")
for (tmpPtr = name; *tmpPtr; tmpPtr++)
if (*tmpPtr == ':') hasDirName = true;
if (name[0] != ':') /* case c: path including volume name or only filename */
{
if (hasDirName)
{ /* okey, starts with volume name, so it must be a complete path */
sstrcpy(CompletePath, name);
}
else
{ /* only filename: add cwd and return */
getcwd(currentdir, NAME_MAX);
sstrcat(currentdir, name);
sstrcpy(CompletePath, currentdir);
}
}
else if (name[1] == ':') /* it's case b: "::folder2:filename" */
{
printerr("GetCompletePath ", -1, *err, __LINE__, __FILE__, "not implemented");
/* it's not yet implemented; do we really need this case ?*/
return NULL;
}
else /* it's case a: ":subfolder:filename" */
{
getcwd(CompletePath, NAME_MAX); /* we don't need a second colon */
CompletePath[strlen(CompletePath)-1] = '\0';
sstrcat(CompletePath, name);
}
pathlen = strlen(CompletePath);
*err = FSpLocationFromFullPath(pathlen, CompletePath, Spec);
return CompletePath;
}
char *MakeFilenameShorter(const char *LongFilename)
{
static char filename[35]; /* contents should be never longer than 32 chars */
static unsigned char Num = 0; /* change the number for every call */
/* this var will rollover without a problem */
char tempLongFilename[1024], charnum[5];
char *last_dotpos = tempLongFilename;
unsigned long full_length = strlen(LongFilename);
unsigned long ext_length = 0;
unsigned long num_to_cut = 0;
long firstpart_length;
char *tmpPtr;
short MaxLength = 31;
if (full_length <= MaxLength) /* filename is not long */
{
return strcpy(filename,LongFilename);
}
Num++;
strcpy(tempLongFilename,LongFilename);
/* Look for the last extension pos */
for (tmpPtr = tempLongFilename; *tmpPtr; tmpPtr++)
if (*tmpPtr == '.') last_dotpos = tmpPtr;
ext_length = strlen(last_dotpos);
firstpart_length = last_dotpos - tempLongFilename;
if (ext_length > 6) /* up to 5 chars are treated as a */
{ /* normal extension like ".html" or ".class" */
firstpart_length = 0;
}
num_to_cut = full_length - MaxLength;
/* number the files to make the names unique */
sprintf(charnum,"~%x", Num);
num_to_cut += strlen(charnum);
if (firstpart_length == 0)
{
firstpart_length = full_length;
tempLongFilename[firstpart_length - num_to_cut] = 0;
sprintf(filename,"%s%s", tempLongFilename, charnum);
}
else
{
tempLongFilename[firstpart_length - num_to_cut] = 0;
sprintf(filename,"%s%s%s", tempLongFilename, charnum, last_dotpos);
}
return filename;
}

View file

@ -0,0 +1,64 @@
/*
Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 2000-Apr-09 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, all these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
*/
#ifndef PATHNAME_H
#define PATHNAME_H 1
char *StripPartialDir(char *CompletePath,
const char *PartialPath, const char *FullPath);
char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath, short CurrentFork,
short MacZipMode, Boolean DataForkOnly);
char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode,
Boolean DataForkOnly, short *CurrentFork);
unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName);
char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec,
OSErr *err);
char *TruncFilename(char *DirPath, const char *FilePath);
char *GetFilename(char *CompletePath, const char *name);
char *GetFullPathFromSpec(char *CompletePath, FSSpec *Spec, OSErr *err);
char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID,
ConstStr255Param name, OSErr *err);
char *GetAppName(void);
void createArchiveName(char *Path);
void FindDesktopFolder(char *Path);
char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder);
OSErr FSpFindFolder(
short vRefNum, /* Volume reference number. */
OSType folderType, /* Folder type taken by FindFolder. */
Boolean createFolder, /* Should we create it if non-existant. */
FSSpec *spec); /* Pointer to resulting directory. */
char *MakeFilenameShorter(const char *LongFilename);
/*
Rule: UnKnown_EF should always be zero.
JohnnyLee_EF, NewZipMode_EF should always greater than all
other definitions
*/
#define UnKnown_EF 0
#define TomBrownZipIt1_EF 10
#define TomBrownZipIt2_EF 20
#define JohnnyLee_EF 30
#define NewZipMode_EF 40
#define ResourceFork -1
#define DataFork 1
#define NoFork 0
#ifndef NAME_MAX
#define NAME_MAX 1024
#endif
#endif /* PATHNAME_H */

View file

@ -0,0 +1,442 @@
/*
These functions are based on Jim Luther's IterateDirectory() found in MoreFiles
However, it's heavily modified by Dirk Haase
*/
/*
** IterateDirectory: File Manager directory iterator routines.
**
** by Jim Luther
**
** File: IterateDirectory.c
**
** Copyright (c) 1995-1998 Jim Luther and Apple Computer, Inc.
** All rights reserved.
**
** You may incorporate this sample code into your applications without
** restriction, though the sample code has been provided "AS IS" and the
** responsibility for its operation is 100% yours.
**
** IterateDirectory is designed to drop into the MoreFiles sample code
** library I wrote while in Apple Developer Technical Support
*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include <Types.h>
#include <Errors.h>
#include <Files.h>
#include <stdio.h>
#include <string.h>
#include "zip.h"
#include "macstuff.h"
#include "helpers.h"
#include "recurse.h"
#include "macglob.h"
#include "pathname.h"
/*****************************************************************************/
/* Macros, typedefs */
/*****************************************************************************/
/* The RecurseGlobals structure is used to minimize the amount of
** stack space used when recursively calling RecurseDirectoryLevel
** and to hold global information that might be needed at any time.
*/
struct RecurseGlobals
{
short vRefNum;
CInfoPBRec cPB; /* the parameter block used for
PBGetCatInfo calls */
unsigned char *itemName; /* the name of the current item */
char *FullPath;
short FullPathLen;
OSErr result; /* temporary holder of results -
saves 2 bytes of stack each level */
Boolean quitFlag; /* set to true if filter wants to
kill interation */
unsigned short maxLevels; /* Maximum levels to
iterate through */
unsigned short currentLevel; /* The current level
IterateLevel is on */
};
typedef struct RecurseGlobals RecurseGlobals;
typedef RecurseGlobals *RecurseGlobalsPtr;
/*****************************************************************************/
/* Global Vars */
/*****************************************************************************/
extern MacZipGlobals MacZip;
extern const char ResourceMark[13]; /* "XtraStuf.mac:" var is initialized in file pathname.c */
extern int extra_fields; /* do not create extra fields if false */
static RecurseGlobals theGlobals;
static unsigned long DirLevels = 0;
static char *buffer;
extern int verbose; /* 1=report oddities in zip file structure */
/*****************************************************************************/
/* Prototypes */
/*****************************************************************************/
int procname(char *filename, int caseflag);
int MatchWild( char *pPat, char *pStr, int case_sens);
Boolean IsZipFile(char *name);
static void RecurseDirectoryLevel(long DirID, RecurseGlobals *Globals);
static Boolean isRegularItem( RecurseGlobals *Globals);
static void ProcessFiles(RecurseGlobals *Globals,
Boolean hasDataFork, Boolean hasResourceFork);
static void ProcessDirectory(RecurseGlobals *Globals,
Boolean IncludeItem, long DirID);
static void ProcessItem(RecurseGlobals *Globals, long DirID);
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
static void RecurseDirectoryLevel(long DirID, RecurseGlobals *Globals)
{
char buffer2[23];
/* if maxLevels is zero, we aren't checking levels */
if ( (Globals->maxLevels == 0) ||
/* if currentLevel < maxLevels, look at this level */
(Globals->currentLevel < Globals->maxLevels) )
{
short index = 1;
++Globals->currentLevel; /* go to next level */
if (DirLevels < Globals->currentLevel) DirLevels = Globals->currentLevel;
sprintf(buffer2,"Globals->currentLevel: %d",Globals->currentLevel);
do
{ /* Isn't C great... What I'd give for a "WITH
theGlobals DO" about now... */
/* Get next source item at the current directory level */
Globals->cPB.dirInfo.ioFDirIndex = index;
Globals->cPB.dirInfo.ioDrDirID = DirID;
Globals->result = PBGetCatInfoSync((CInfoPBPtr)&Globals->cPB);
ShowCounter(false);
if ( Globals->result == noErr )
{
ProcessItem(Globals, DirID);
} /* if ( Globals->result == noErr ) */
++index; /* prepare to get next item */
/* time to fall back a level? */
} while ( (Globals->result == noErr) && (!Globals->quitFlag) );
if ( (Globals->result == fnfErr) || /* fnfErr is OK -
it only means we hit
the end of this level */
(Globals->result == afpAccessDenied) ) /* afpAccessDenied is OK,
too - it only means we cannot see inside a directory */
{
Globals->result = noErr;
}
--Globals->currentLevel; /* return to previous level as we leave */
}
}
/*****************************************************************************/
pascal OSErr RecurseDirectory(short vRefNum,
long thedirID,
ConstStr255Param name,
unsigned short maxLevels)
{
OSErr result;
short theVRefNum;
Boolean isDirectory;
long DirID;
/* Get the real directory ID and make sure it is a directory */
result = GetDirectoryID(vRefNum, thedirID, name, &DirID, &isDirectory);
if ( result == noErr )
{
if ( isDirectory == true )
{
/* Get the real vRefNum */
result = DetermineVRefNum(name, vRefNum, &theVRefNum);
if ( result == noErr )
{
/* Set up the globals we need to access from
the recursive routine. */
theGlobals.cPB.hFileInfo.ioNamePtr = theGlobals.itemName;
theGlobals.cPB.hFileInfo.ioVRefNum = theVRefNum;
theGlobals.itemName[0] = 0;
theGlobals.result = noErr;
theGlobals.quitFlag = false;
theGlobals.maxLevels = maxLevels;
theGlobals.currentLevel = 0; /* start at level 0 */
/* Here we go into recursion land... */
RecurseDirectoryLevel(DirID, &theGlobals);
result = theGlobals.result; /* set the result */
}
}
else
{
result = dirNFErr; /* a file was passed instead
of a directory */
}
}
return ( result );
}
/*****************************************************************************/
pascal OSErr FSpRecurseDirectory(const FSSpec *spec,
unsigned short maxLevels)
{
OSErr rc;
theGlobals.vRefNum = spec->vRefNum;
/* make room for pathnames */
theGlobals.itemName = (unsigned char *) StrCalloc(NAME_MAX);
theGlobals.FullPath = StrCalloc(NAME_MAX);
buffer = StrCalloc(NAME_MAX);
if ((noisy) && (MacZip.DataForkOnly))
printf("\n Warning: Datafork only \n");
/* reset the count to zero */
ShowCounter(true);
if (noisy) leftStatusString("Build File List; Items done:");
if (noisy) printf("\n Collecting Filenames ...");
rc = RecurseDirectory(spec->vRefNum, spec->parID, spec->name,maxLevels);
printerr("RecurseDirectory:",rc,rc,__LINE__,__FILE__,"");
if (noisy) printf("\n... done \n\n %6d matched files found \n",
MacZip.FoundFiles);
if (noisy) printf(" %6d folders found in %d Levels \n",
MacZip.FoundDirectories,DirLevels);
if (MacZip.BytesOfData > (1024*1024))
if (noisy) printf(" %4.3f MBytes unzipped size\n\n",
(float) MacZip.BytesOfData/(1024*1024));
else
if (noisy) printf(" %4.3f KBytes unzipped size\n\n",
(float) MacZip.BytesOfData/1024);
/* free all memory of pathnames */
theGlobals.itemName = (unsigned char *) StrFree((char *)theGlobals.itemName);
theGlobals.FullPath = StrFree(theGlobals.FullPath);
buffer = StrFree(buffer);
return rc;
}
/*
* Return true if filename == zipfile
* After the first match no further check will be done !
*
*/
Boolean IsZipFile(char *filen)
{
static firstMatch = false;
if (filen == NULL)
firstMatch = false;
if (!firstMatch)
{
if (stricmp(filen, MacZip.ZipFullPath) == 0)
{
firstMatch = true;
return true;
}
}
return false;
}
static Boolean isRegularItem( RecurseGlobals *Globals)
{
Boolean isInvisible = false,
isAlias = false,
isSystem = false;
isSystem = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags &
(1 << 12)) == 0 );
isInvisible = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags &
(1 << 14)) == 0 );
isAlias = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags &
(1 << 15)) == 0);
if (isAlias == true)
{
return false;
}
if (MacZip.IncludeInvisible == true)
{
return true;
}
if ((isSystem == true) ||
(isInvisible == true))
{
return false;
}
return true;
}
static void ProcessFiles(RecurseGlobals *Globals,
Boolean hasDataFork, Boolean hasResourceFork)
{
/* some file statistics */
MacZip.FoundFiles++;
if (hasDataFork == true)
{
MacZip.BytesOfData =
Globals->cPB.hFileInfo.ioFlLgLen +
MacZip.BytesOfData;
MacZip.CurrentFork = DataFork;
MacZip.RawCountOfItems++;
if (MacZip.DataForkOnly == true)
{
procname(Globals->FullPath, false);
hasResourceFork = false;
}
else
{
procname(Real2RfDfFilen(buffer,Globals->FullPath,
DataFork, MacZip.MacZipMode,
MacZip.DataForkOnly), false);
}
}
if (hasResourceFork == true)
{
MacZip.BytesOfData =
Globals->cPB.hFileInfo.ioFlRLgLen +
MacZip.BytesOfData;
MacZip.CurrentFork = ResourceFork;
MacZip.RawCountOfItems++;
procname(Real2RfDfFilen(buffer, Globals->FullPath,
ResourceFork, MacZip.MacZipMode,
MacZip.DataForkOnly), false);
}
}
static void ProcessDirectory(RecurseGlobals *Globals,
Boolean IncludeItem, long DirID)
{
OSErr rc;
MacZip.isDirectory = true;
GetFullPathFromID(Globals->FullPath,Globals->vRefNum, DirID,
Globals->itemName, &rc);
MacZip.RawCountOfItems++;
MacZip.FoundDirectories++;
if (MacZip.StoreFoldersAlso)
{
procname(Globals->FullPath, false);
}
/* We have a directory */
if ( !Globals->quitFlag && IncludeItem)
{
/* Dive again if the IterateFilterProc didn't say "quit" and dir is
not an alias */
RecurseDirectoryLevel(Globals->cPB.dirInfo.ioDrDirID,
Globals);
}
}
static void ProcessItem(RecurseGlobals *Globals, long DirID)
{
OSErr rc;
Boolean IncludeItem = false, hasDataFork = false;
Boolean hasResourceFork = false;
IncludeItem = isRegularItem(Globals);
/* Is it a File? */
if ( (Globals->cPB.hFileInfo.ioFlAttrib & ioDirMask) == 0 )
{
PToCCpy(Globals->itemName,MacZip.FileName);
MacZip.isDirectory = false;
hasDataFork = (Globals->cPB.hFileInfo.ioFlLgLen != 0);
hasResourceFork = (Globals->cPB.hFileInfo.ioFlRLgLen != 0);
/* include also files with zero recource- and data-fork */
if ((hasDataFork == 0) && (hasResourceFork == 0))
hasDataFork = true;
if ((hasDataFork == 0) &&
(hasResourceFork != 0) &&
(extra_fields == false))
{
IncludeItem = false;
}
GetFullPathFromID(Globals->FullPath,Globals->vRefNum,
DirID, Globals->itemName, &rc);
printerr("GetFullPathFromID:",rc,rc,__LINE__,
__FILE__,MacZip.FileName);
if (IncludeItem && /* don't include the zipfile itself */
(!IsZipFile(Globals->FullPath)) )
{
if (MATCH(MacZip.Pattern, MacZip.FileName, false) == true)
{
ProcessFiles(Globals, hasDataFork, hasResourceFork);
} /* if (MatchWild( MacZip.FileName,MacZip.Pattern ) ==
true) */
} /* if (!IsZipFile(Globals->FullPath)) */
} /* Is it a File? */
/* Is it a directory? */
if ( (Globals->cPB.hFileInfo.ioFlAttrib & ioDirMask) != 0 )
{
ProcessDirectory(Globals,IncludeItem, DirID);
} /* Is it a directory? */
}

View file

@ -0,0 +1,129 @@
/*
** IterateDirectory: File Manager directory iterator routines.
**
** by Jim Luther
**
** File: IterateDirectory.h
**
** Copyright (c) 1995-1998 Jim Luther and Apple Computer, Inc.
** All rights reserved.
**
** You may incorporate this sample code into your applications without
** restriction, though the sample code has been provided "AS IS" and the
** responsibility for its operation is 100% yours.
**
** IterateDirectory is designed to drop into the MoreFiles sample code
** library I wrote while in Apple Developer Technical Support
*/
#ifndef __RECURSEDIRECTORY__
#define __RECURSEDIRECTORY__
#include <Types.h>
#include <Files.h>
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************/
pascal OSErr RecurseDirectory(short vRefNum,
long dirID,
ConstStr255Param name,
unsigned short maxLevels );
/* Iterate (scan) through a directory's content.
The IterateDirectory function performs a recursive iteration (scan) of
the specified directory and calls your IterateFilterProc function once
for each file and directory found.
The maxLevels parameter lets you control how deep the recursion goes.
If maxLevels is 1, IterateDirectory only scans the specified directory;
if maxLevels is 2, IterateDirectory scans the specified directory and
one subdirectory below the specified directory; etc. Set maxLevels to
zero to scan all levels.
The yourDataPtr parameter can point to whatever data structure you might
want to access from within the IterateFilterProc.
vRefNum input: Volume specification.
dirID input: Directory ID.
name input: Pointer to object name, or nil when dirID
specifies a directory that's the object.
maxLevels input: Maximum number of directory levels to scan or
zero to scan all directory levels.
iterateFilter input: A pointer to the routine you want called once
for each file and directory found by
IterateDirectory.
yourDataPtr input: A pointer to whatever data structure you might
want to access from within the IterateFilterProc.
Result Codes
noErr 0 No error
nsvErr -35 No such volume
ioErr -36 I/O error
bdNamErr -37 Bad filename
fnfErr -43 File not found
paramErr -50 No default volume or iterateFilter was NULL
dirNFErr -120 Directory not found or incomplete pathname
or a file was passed instead of a directory
afpAccessDenied -5000 User does not have the correct access
afpObjectTypeErr -5025 Directory not found or incomplete pathname
__________
See also: RecurseFilterProcPtr, FSpRecurseDirectory
*/
/*****************************************************************************/
pascal OSErr FSpRecurseDirectory(const FSSpec *spec,
unsigned short maxLevels);
/* Iterate (scan) through a directory's content.
The FSpIterateDirectory function performs a recursive iteration (scan)
of the specified directory and calls your IterateFilterProc function once
for each file and directory found.
The maxLevels parameter lets you control how deep the recursion goes.
If maxLevels is 1, FSpIterateDirectory only scans the specified directory;
if maxLevels is 2, FSpIterateDirectory scans the specified directory and
one subdirectory below the specified directory; etc. Set maxLevels to
zero to scan all levels.
The yourDataPtr parameter can point to whatever data structure you might
want to access from within the IterateFilterProc.
spec input: An FSSpec record specifying the directory to scan.
maxLevels input: Maximum number of directory levels to scan or
zero to scan all directory levels.
iterateFilter input: A pointer to the routine you want called once
for each file and directory found by
FSpIterateDirectory.
yourDataPtr input: A pointer to whatever data structure you might
want to access from within the IterateFilterProc.
Result Codes
noErr 0 No error
nsvErr -35 No such volume
ioErr -36 I/O error
bdNamErr -37 Bad filename
fnfErr -43 File not found
paramErr -50 No default volume or iterateFilter was NULL
dirNFErr -120 Directory not found or incomplete pathname
afpAccessDenied -5000 User does not have the correct access
afpObjectTypeErr -5025 Directory not found or incomplete pathname
__________
See also: RecurseFilterProcPtr, RecurseDirectory
*/
/*****************************************************************************/
#endif /* __RECURSEDIRECTORY__ */

View file

@ -0,0 +1,313 @@
/*
Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 1999-Oct-05 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
unixlike.c
Macintosh-specific routines to emulate unixfunctions.
---------------------------------------------------------------------------*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include "zip.h"
#include <string.h>
#include <stdio.h>
#include <sound.h>
#include "unixlike.h"
#include "helpers.h"
#include "pathname.h"
#include "macstuff.h"
#include "macglob.h"
#include "mactime.h"
/*****************************************************************************/
/* Global Vars */
/*****************************************************************************/
extern MacZipGlobals MacZip;
extern int errno;
/*****************************************************************************/
/* Prototypes */
/*****************************************************************************/
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
/*
*----------------------------------------------------------------------
*
* MacStat --
*
* This function replaces the library version of stat. The stat
* function provided by most Mac compiliers is rather broken and
* incomplete.
*
* Results:
* See stat documentation.
*
* Side effects:
* See stat documentation.
*
*----------------------------------------------------------------------
*/
int Zmacstat(const char *Fname, struct stat *buf)
{
OSErr err, rc;
short fullPathLength;
Handle hFullPath;
char path[NAME_MAX], path2[NAME_MAX];
HVolumeParam vpb;
static unsigned long count_of_files = 0;
AssertStr(Fname,Fname)
Assert_it(buf,"","")
UserStop();
memset(buf, 0, sizeof(buf)); /* zero out all fields */
RfDfFilen2Real(path2, Fname, MacZip.MacZipMode, MacZip.DataForkOnly,
&MacZip.CurrentFork);
GetCompletePath(path, path2, &MacZip.fileSpec, &err);
err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
printerr("GetCompletePath:", err, err, __LINE__, __FILE__, path);
if (err != noErr) {
errno = err;
return -1;
}
/* Collect here some more information, it's not related to Macstat.
(note: filespec gets changed later in this function) */
/* clear string-buffer */
memset(MacZip.FullPath, 0x00, sizeof(MacZip.FullPath));
rc = FSpGetFullPath(&MacZip.fileSpec, &fullPathLength, &hFullPath);
strncpy(MacZip.FullPath, *hFullPath, fullPathLength);
DisposeHandle(hFullPath); /* we don't need it any more */
/* Collect some more information not related to Macstat */
/*
* Fill the fpb & vpb struct up with info about file or directory.
*/
FSpGetDirectoryID(&MacZip.fileSpec, &MacZip.dirID, &MacZip.isDirectory);
vpb.ioVRefNum = MacZip.fpb.hFileInfo.ioVRefNum = MacZip.fileSpec.vRefNum;
vpb.ioNamePtr = MacZip.fpb.hFileInfo.ioNamePtr = MacZip.fileSpec.name;
if (MacZip.isDirectory) {
MacZip.fpb.hFileInfo.ioDirID = MacZip.fileSpec.parID;
/*
* Directories are executable by everyone.
*/
buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH | UNX_IFDIR;
} else {
MacZip.fpb.hFileInfo.ioDirID = MacZip.dirID;
}
MacZip.fpb.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync((CInfoPBPtr)&MacZip.fpb);
if (err == noErr) {
vpb.ioVolIndex = 0;
err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
if (err == noErr && buf != NULL) {
/*
* Files are always readable by everyone.
*/
buf->st_mode |= UNX_IRUSR | UNX_IRGRP | UNX_IROTH;
/*
* Use the Volume Info & File Info to fill out stat buf.
*/
if (MacZip.fpb.hFileInfo.ioFlAttrib & 0x10) {
buf->st_mode |= UNX_IFDIR;
buf->st_nlink = 2;
} else {
buf->st_nlink = 1;
if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) {
buf->st_mode |= UNX_IFLNK;
} else {
buf->st_mode |= UNX_IFREG;
}
}
if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') {
/*
* Applications are executable by everyone.
*/
buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH;
}
if ((MacZip.fpb.hFileInfo.ioFlAttrib & 0x01) == 0){
/*
* If not locked, then everyone has write acces.
*/
buf->st_mode |= UNX_IWUSR | UNX_IWGRP | UNX_IWOTH;
}
buf->st_ino = MacZip.fpb.hFileInfo.ioDirID;
buf->st_dev = MacZip.fpb.hFileInfo.ioVRefNum;
buf->st_uid = -1;
buf->st_gid = -1;
buf->st_rdev = 0;
if (MacZip.CurrentFork == ResourceFork)
buf->st_size = MacZip.fpb.hFileInfo.ioFlRLgLen;
else
buf->st_size = MacZip.fpb.hFileInfo.ioFlLgLen;
buf->st_blksize = vpb.ioVAlBlkSiz;
buf->st_blocks = (buf->st_size + buf->st_blksize - 1)
/ buf->st_blksize;
/*
* The times returned by the Mac file system are in the
* local time zone. We convert them to GMT so that the
* epoch starts from GMT. This is also consistent with
* what is returned from "clock seconds".
*/
if (!MacZip.isDirectory) {
MacZip.CreatDate = MacZip.fpb.hFileInfo.ioFlCrDat;
MacZip.ModDate = MacZip.fpb.hFileInfo.ioFlMdDat;
MacZip.BackDate = MacZip.fpb.hFileInfo.ioFlBkDat;
} else {
MacZip.CreatDate = MacZip.fpb.dirInfo.ioDrCrDat;
MacZip.ModDate = MacZip.fpb.dirInfo.ioDrMdDat;
MacZip.BackDate = MacZip.fpb.dirInfo.ioDrBkDat;
}
#ifdef IZ_CHECK_TZ
if (!zp_tz_is_valid)
{
MacZip.HaveGMToffset = false;
MacZip.Md_UTCoffs = 0L;
MacZip.Cr_UTCoffs = 0L;
MacZip.Bk_UTCoffs = 0L;
}
else
#endif
{
/* Do not use GMT offsets when Md_UTCoffs calculation
* fails, since this time stamp is used for time
* comparisons in Zip and UnZip operations.
* We do not bother when GMT offset calculation fails for
* any other time stamp value. Instead we simply assume
* a default value of 0.
*/
MacZip.HaveGMToffset =
GetGMToffsetMac(MacZip.ModDate, &MacZip.Md_UTCoffs);
if (MacZip.HaveGMToffset) {
GetGMToffsetMac(MacZip.CreatDate, &MacZip.Cr_UTCoffs);
GetGMToffsetMac(MacZip.BackDate, &MacZip.Bk_UTCoffs);
} else {
MacZip.Cr_UTCoffs = 0L;
MacZip.Bk_UTCoffs = 0L;
}
}
#ifdef DEBUG_TIME
{
printf("\nZmacstat: MacZip.HaveGMToffset: %d",
MacZip.HaveGMToffset);
printf("\nZmacstat: Mac modif: %lu local -> UTOffset: %d",
MacZip.ModDate, MacZip.Md_UTCoffs);
printf("\nZmacstat: Mac creat: %lu local -> UTOffset: %d",
MacZip.CreatDate, MacZip.Cr_UTCoffs);
printf("\nZmacstat: Mac back: %lu local -> UTOffset: %d",
MacZip.BackDate, MacZip.Bk_UTCoffs);
}
#endif /* DEBUG_TIME */
buf->st_mtime = MacFtime2UnixFtime(MacZip.ModDate);
buf->st_ctime = MacFtime2UnixFtime(MacZip.CreatDate);
buf->st_atime = buf->st_mtime;
#ifdef DEBUG_TIME
{
printf("\nZmacstat: Unix modif: %lu UTC; Mac: %lu local",
buf->st_mtime, MacZip.ModDate);
printf("\nZmacstat: Unix creat: %lu UTC; Mac: %lu local\n",
buf->st_ctime, MacZip.CreatDate);
}
#endif /* DEBUG_TIME */
if (noisy)
{
if (MacZip.StatingProgress)
{
count_of_files++;
InformProgress(MacZip.RawCountOfItems, count_of_files );
}
else
count_of_files = 0;
}
}
}
if (err != noErr) {
errno = err;
}
MacZip.isMacStatValid = true;
return (err == noErr ? 0 : -1);
}
/*
*----------------------------------------------------------------------
*
* chmod --
*
* Results:
* See chmod documentation.
*
* Side effects:
* See chmod documentation.
*
*----------------------------------------------------------------------
*/
int chmod(char *path, int mode)
{
HParamBlockRec hpb;
OSErr err;
hpb.fileParam.ioNamePtr = C2PStr(path);
hpb.fileParam.ioVRefNum = 0;
hpb.fileParam.ioDirID = 0;
if (mode & 0200) {
err = PBHRstFLockSync(&hpb);
} else {
err = PBHSetFLockSync(&hpb);
}
if (err != noErr) {
errno = err;
return -1;
}
return 0;
}

View file

@ -0,0 +1,86 @@
/*
Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
See the accompanying file LICENSE, version 1999-Oct-05 or later
(the contents of which are also included in zip.h) for terms of use.
If, for some reason, both of these files are missing, the Info-ZIP license
also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
* Directory Operations for Mac based on BSD 4.3 <macdir.h>
* By Jason Linhart, January 1997
*/
#ifndef _UNIXLIKE_H
#define _UNIXLIKE_H 1
#include <stat.h>
#ifndef NAME_MAX
#define NAME_MAX 2048
#endif
#define UNX_IFMT 0170000 /* Unix file type mask */
#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */
#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */
#define UNX_IFREG 0100000 /* Unix regular file */
#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */
#define UNX_IFDIR 0040000 /* Unix directory */
#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */
#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */
#define UNX_ISUID 04000 /* Unix set user id on execution */
#define UNX_ISGID 02000 /* Unix set group id on execution */
#define UNX_ISVTX 01000 /* Unix directory permissions control */
#define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */
#define UNX_IRWXU 00700 /* Unix read, write, execute: owner */
#define UNX_IRUSR 00400 /* Unix read permission: owner */
#define UNX_IWUSR 00200 /* Unix write permission: owner */
#define UNX_IXUSR 00100 /* Unix execute permission: owner */
#define UNX_IRWXG 00070 /* Unix read, write, execute: group */
#define UNX_IRGRP 00040 /* Unix read permission: group */
#define UNX_IWGRP 00020 /* Unix write permission: group */
#define UNX_IXGRP 00010 /* Unix execute permission: group */
#define UNX_IRWXO 00007 /* Unix read, write, execute: other */
#define UNX_IROTH 00004 /* Unix read permission: other */
#define UNX_IWOTH 00002 /* Unix write permission: other */
#define UNX_IXOTH 00001 /* Unix execute permission: other */
/* historical file modes */
#define S_IREAD 0x100
#define S_IWRITE 0x80
#define S_IEXEC 0x40
#define isatty(arg) 1
#define EINVAL 22 /* Invalid argument */
#define ENAMETOOLONG 63 /* File name too long */
struct dirent {
char d_name[NAME_MAX];
};
/*
* The following definitions are usually found in fcntl.h.
* However, MetroWerks has screwed that file up a couple of times
* and all we need are the defines.
*/
#define O_APPEND 0x0100 /* open the file in append mode */
#define O_CREAT 0x0200 /* create the file if it doesn't exist */
#define O_EXCL 0x0400 /* if the file exists don't create it again */
#define O_TRUNC 0x0800 /* truncate the file after opening it */
int Zmacstat (const char *path, struct stat *buf);
int chmod(char *path, int mode);
#include "macstuff.h"
#endif /* _UNIXLIKE_H */

View file

@ -0,0 +1,43 @@
(This file must be converted with BinHex 4.0)
:#RTTF#jbBbjcDA3!8dP84&0*9#%!N!3([`#3"&(E8dP8)3!"!!!([h*-BA8#Q3#
3!aDCQ3d!"RTTF#jbB`!!&[Bi"2[rG!"-5QS!N!1!!*!%"32,j+m2!*!Drj!%8P0
53e*6483"",#mXHDaqlGG!!!GmJ#3"JFj!*!%6Mi!N!MGc!`!P@6pq1R*k4&+Z,d
p"5$(b(-Upcc#j%EiHCfjPTq%8h+X8d)MR$`rF[b9Vh`pTLc2jqZ9r'RNq9VN1'&
'MMmj6Sk6#5HFc0J4lN8iHFU2--,*K%Z1NIR+#1XNR("#bE-)2I+FF$*G@H6BL+`
*!&6IV1ml1d+22#-$4UEm*#01"T`m*4`Ji(03ThM'$-EBilf-V8-e6Q8bXEVD@Xi
2bilcmGEY"lV6QGjZrK)I1CKZ$BfR4pSbLD'f`F'qVPKb+*(-*V2CPLfaGj1CE+a
Z+-$kpr4hpHrCf@d%f66E!A2P-rA6phmUj)QrdYP4r[6)H+cZF"hRV``NHSG5`b!
F6-0YBZ$!JH&%#frIb,2TmH4`LVGN4c1(%U1Q8#cf)P44dU"#-`D)I($H4I5qc[j
NJLI5)qpN5)Ic[S(-`-&1H(U2L*U'-H`1Y1p&qc#*YVk4(RNUbp(ae(#'R,B[d%B
(Nd40$id1C`FhmUlKNBmbkAf$Sra8qpDYcm0,H%GIhbiej(!EESbmC+a*'3dqdlC
j)%*H#+!,D!K4#J#3!$9H-J)mB*6L!50R"%"&hi6DD*61[-qq22%f1hkXPq@r)'`
(1hjQJ19cKP'bY0#60RQ3!&kd,r))mj-X,LBCCa&CeiX#f`ibZ$9##+[1HUJ34G5
584+#&@p9i[UDj-&PD2rAi0qYdMpMQ""M8FLBT`#FUMje-i6rVXl2qI`jK@XY#eH
+%JH[5(`6,qEcH@K,(FfA4rZDNG,4mp60fALH@TT,SC!!5Sf0$HHP31&mP"AfKN)
K-!N[&XjM@##`1I,(a"V"#L%@#U9'*'lT-5CaU8GqpLTFkUP"%klmfMLJ1QpH5r2
djNdfhIXJFIqqN!!&1QHe$jUlHF`jZ2I41X8k$@ZbKF1C2"Cq6YZaF(Z+5Yra&63
"alCh62Vm6N(RqR90&)#m`cE3mILqV`@qBmcQkf0"9Ei%#**RRRpcS0DmV!N6DB-
&#R112Ym4-1d)GJ(R0,i,0!TEJ!%$#Mj$SFqp80)XU4&"+j!!DmFJk)S2*[(KNMR
mHApd)4Im@I2aqEBrpd,EVi3ehd@qETI[eprhmmlp0UGjqhe`q#[[Ljk#GDclAll
[P91j$d[[ir`4X1LcbmVcI$8cCd49rY*`E2l+F1l-Uk0CV,edY8%d('d@pD*qVRk
L@64FE9KlU9Q%E`3$i@+cD"BSp)'26f,8K%[iL[#3!$-h&aDPY5L2CJBBpF5Kh5k
+ASJVqckQ9kG`*C95rEka+29B5U+f"eYIqF&ZC()P-%GbHXQ44)a!l[Z9q3[c5Z!
aN!!pGHT"X#q,IJ$8lG#i224dkNXMhd,#3I"ap4JkEk@YlrKEp1r14erRqIYVJY@
RbX4G0GVTc4A5A20`[E`GcX60GGI#0@$KHMqfFB9BIV4&%kr6+kH*J`(FR3lKcJj
pNqpN!JiZ-`'&1jQ!a*e-31RCQB$%R8c!dY1CJ19(C`+@AjGIa[qCCq8qH,K8FA%
LH$LpGbZiFpp0ehUR[lZTL-[HU3T8q*FVkd5&AaDBjrX##ha2S$UImK6,r-Z9MDM
#PaVqNfUH+VqmXplAGpG!G`k,I&I!i[ZC`J,Iba3@rEQC`J,Iba5@rFQGIhNq5h`
r-lM2ArAJIYjp(jEjYX!5he+i`cIhZRrjYq)%rjNh@"K4Ej!!V8&p!,8@0C*$l3L
bk#`f"%i9DMaRk,i*YC&aj0dFH6G(hXf4Gh2Nh4ajYp5aY(5[I@a#hBBDeh9E'*X
Kq3q,)QS*99$0SCj&R68Va[9Ie6lJ9444KDk%dDE9%CrPQhJ,hbD#)RJ8936RJK1
bjb%HMTILXr&#r&Um++SIZ#*1fAP1hM-c'CG*VekG*BkGApkj'DZA13GkPA1JPcN
(iC4c%*m@1&[2l0@LLCK%pFUBG%kj4M@2,@pY&UjA+*Y2#Zil5%pF&GI[LBAVh-2
$3I"aCG,5ekC[qL[MlZ1QRP32Ga5YQFY`Cf-[rZ!JX+GrCir-1R)J6J!jdY[ekRU
IXFT6',*jNmH[B69Hq&&6$N-NlS3K8Xm03mM2+VTKb253!iSqNDRHIKqNq$hqV6$
%pVF8KPMc@68N$0Q#[KXH1UJL$1P'',*PpB``C"5M'eXG)JbTfDal(BB!AfdN$-'
cjq2P-%6bli8Kq,pej"NCErJr%NGk[[Pkpa44M+pBl4Mq$SC![ij'pZ[3j20d)N[
i$qR%J5hSI`01r3hJcl+!m54`kMY9f'+N1PrYaRqe4SCq@E8Hr)$%dK,,5@`LdR2
b$cBKPr+"5-q*AH`)BBm-4AUqlG-DHk"a9QQ`Yi"0+Beefb-pTlj6'Z(2`,ZS0"j
+!KY9'SpQ-0f,5U2Q'(Lr+Sd(h`3fV65DpX2VT0+)[!EHKdUMS4ABTdVMX4IJG8T
T'*pJ6K'P8IXk0+iTMFB8I'L[i9r!Qp6c`!dlH9,2idGJTp9PD'b(MjH9AZ0cQ02
TqYdI$#8c2*2-$Kr+**,r!`#3!dm4!!!: