~ubuntu-branches/ubuntu/precise/unzip/precise-proposed

« back to all changes in this revision

Viewing changes to amiga/filedate.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-06-06 17:57:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040606175746-nl7p2dgp3aobyc2c
Tags: upstream-5.51
ImportĀ upstreamĀ versionĀ 5.51

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (c) 1990-2002 Info-ZIP.  All rights reserved.
 
3
 
 
4
  See the accompanying file LICENSE, version 2000-Apr-09 or later
 
5
  (the contents of which are also included in zip.h) for terms of use.
 
6
  If, for some reason, all these files are missing, the Info-ZIP license
 
7
  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
 
8
*/
 
9
/* Low-level Amiga routines shared between Zip and UnZip.
 
10
 *
 
11
 * Contains:  FileDate()
 
12
 *            getenv()          [replaces inadequate standard library version]
 
13
 *            setenv()          [SAS/C only, replaces standard library version]
 
14
 *            set_TZ()          [SAS/C only]
 
15
 *            GetPlatformLocalTimezone() [callback from timezone.c tzset()]
 
16
 *            time()
 
17
 *            sendpkt()
 
18
 *            Agetch()
 
19
 *
 
20
 * The first five are used by most Info-ZIP programs except fUnZip.
 
21
 * The last two are used by all except the non-CRYPT version of fUnZip.
 
22
 * Probably some of the stuff in here is unused by ZipNote and ZipSplit too...
 
23
 * sendpkt() is used by Agetch() and FileDate(), and by screensize() in
 
24
 * amiga/amiga.c (UnZip); time() is used only by Zip.
 
25
 */
 
26
 
 
27
 
 
28
/* HISTORY/CHANGES
 
29
 *  2 Sep 92, Greg Roelofs, Original coding.
 
30
 *  6 Sep 92, John Bush, Incorporated into UnZip 5.1
 
31
 *  6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or
 
32
 *            redefines SetFileDate() depending upon AMIGADOS2 definition.
 
33
 * 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining
 
34
 *            revision via OpenLibrary() call.  Now only one version of
 
35
 *            the program runs on both platforms (1.3.x vs. 2.x)
 
36
 * 11 Oct 92, John Bush, Merged with Zip version and changed arg passing
 
37
 *            to take time_t input instead of struct DateStamp.
 
38
 *            Arg passing made to conform with utime().
 
39
 * 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some
 
40
 *            lint-ish errors; simplified test for AmigaDOS version.
 
41
 * 11 Nov 95, Paul Kienitz, added Agetch() for crypt password input and
 
42
 *            UnZip's "More" prompt -- simplifies crypt.h and avoids
 
43
 *            use of library code redundant with sendpkt().  Made it
 
44
 *            available to fUnZip, which does not use FileDate().
 
45
 * 22 Nov 95, Paul Kienitz, created a new tzset() that gets the current
 
46
 *            timezone from the Locale preferences.  These exist only under
 
47
 *            AmigaDOS 2.1 and up, but it is probably correctly set on more
 
48
 *            Amigas than the TZ environment variable is.  We check that
 
49
 *            only if TZ is not validly set.  We do not parse daylight
 
50
 *            savings syntax except to check for presence vs. absence of a
 
51
 *            DST part; United States rules are assumed.  This is better
 
52
 *            than the tzset()s in the Amiga compilers' libraries do.
 
53
 * 15 Jan 96, Chr. Spieler, corrected the logic when to select low level
 
54
 *            sendpkt() (when FileDate(), Agetch() or windowheight() is used),
 
55
 *            and AMIGA's Agetch() (CRYPT, and UnZip(SFX)'s UzpMorePause()).
 
56
 * 10 Feb 96, Paul Kienitz, re-fiddled that selection logic again, moved
 
57
 *            stuff around for clarity.
 
58
 * 16 Mar 96, Paul Kienitz, created a replacement localtime() to go with the
 
59
 *            new tzset(), because Aztec's is hopelessly broken.  Also
 
60
 *            gmtime(), which localtime() calls.
 
61
 * 12 Apr 96, Paul Kienitz, daylight savings was being handled incorrectly.
 
62
 * 21 Apr 96, Paul Kienitz, had to replace time() as well, Aztec's returns
 
63
 *            local time instead of GMT.  That's why their localtime() was bad,
 
64
 *            because it assumed time_t was already local, and gmtime() was
 
65
 *            the one that checked TZ.
 
66
 * 23 Apr 96, Chr. Spieler, deactivated time() replacement for UnZip stuff.
 
67
 *            Currently, the UnZip sources do not make use of time() (and do
 
68
 *            not supply the working mktime() replacement, either!).
 
69
 * 29 Apr 96, Paul Kienitz, created a replacement getenv() out of code that
 
70
 *            was previously embedded in tzset(), for reliable global test
 
71
 *            of whether TZ is set or not.
 
72
 * 19 Jun 96, Haidinger Walter, re-adapted for current SAS/C compiler.
 
73
 *  7 Jul 96, Paul Kienitz, smoothed together compiler-related changes.
 
74
 *  4 Feb 97, Haidinger Walter, added set_TZ() for SAS/C.
 
75
 * 23 Apr 97, Paul Kienitz, corrected Unix->Amiga DST error by adding
 
76
 *            mkgmtime() so localtime() could be used.
 
77
 * 28 Apr 97, Christian Spieler, deactivated mkgmtime() definition for ZIP;
 
78
 *            the Zip sources supply this function as part of util.c.
 
79
 * 24 May 97, Haidinger Walter, added time_lib support for SAS/C and moved
 
80
 *            set_TZ() to time_lib.c.
 
81
 * 12 Jul 97, Paul Kienitz, adapted time_lib stuff for Aztec.
 
82
 * 26 Jul 97, Chr. Spieler, old mkgmtime() fixed (ydays[] def, sign vs unsign).
 
83
 * 30 Dec 97, Haidinger Walter, adaptation for SAS/C using z-stat.h functions.
 
84
 * 19 Feb 98, Haidinger Walter, removed alloc_remember, more SAS.C fixes.
 
85
 * 23 Apr 98, Chr. Spieler, removed mkgmtime(), changed FileDate to convert to
 
86
 *            Amiga file-time directly.
 
87
 * 24 Apr 98, Paul Kienitz, clip Unix dates earlier than 1978 in FileDate().
 
88
 * 02 Sep 98, Paul Kienitz, C. Spieler, always include zip.h to get a defined
 
89
 *            header inclusion sequence that resolves all header dependencies.
 
90
 * 06 Jun 00, Paul Kienitz, removed time_lib.c due to its incompatible license,
 
91
 *            moved set_TZ() back here, replaced minimal tzset() and localtime()
 
92
 *            with new versions derived from GNU glibc source.  Gave locale_TZ()
 
93
 *            reasonable European defaults for daylight savings.
 
94
 * 17 Jun 00, Paul Kienitz, threw out GNU code because of objections to the GPL
 
95
 *            virus, replaced with similar functions based on the public domain
 
96
 *            timezone code at ftp://elsie.nci.nih.gov/pub.  As with the GNU
 
97
 *            stuff, support for timezone files and leap seconds was removed.
 
98
 * 23 Aug 00, Paul Kienitz, moved timezone code out from here into separate
 
99
 *            platform-independent module 'timezone.c'.
 
100
 * 31 Dec 00, Christian Spieler, moved system-specific timezone help funcions
 
101
 *            back in here, from 'timezone.c'.
 
102
 * 07 Jan 01, Paul Kienitz, Chr. Spieler, added missing #include "timezone.h"
 
103
 *            and "symbolic" preprocessor constants for time calculations.
 
104
 * 15 Jan 02, Paul Kienitz, excluded all time handling code from compilation
 
105
 *            for Zip utilities (when "defined(UTIL)")
 
106
 */
 
107
 
 
108
#ifndef __amiga_filedate_c
 
109
#define __amiga_filedate_c
 
110
 
 
111
 
 
112
#include "zip.h"
 
113
#include <ctype.h>
 
114
#include <errno.h>
 
115
 
 
116
#include <exec/types.h>
 
117
#include <exec/execbase.h>
 
118
#include <exec/memory.h>
 
119
#include <dos/dosextens.h>
 
120
 
 
121
#ifdef AZTEC_C
 
122
#  include <libraries/dos.h>
 
123
#  include <libraries/dosextens.h>
 
124
#  include <clib/exec_protos.h>
 
125
#  include <clib/dos_protos.h>
 
126
#  include <clib/locale_protos.h>
 
127
#  include <pragmas/exec_lib.h>
 
128
#  include <pragmas/dos_lib.h>
 
129
#  include <pragmas/locale_lib.h>
 
130
#  define ESRCH  ENOENT
 
131
#  define EOSERR EIO
 
132
#endif
 
133
 
 
134
#ifdef __SASC
 
135
#  include <stdlib.h>
 
136
#  if (defined(_M68020) && (!defined(__USE_SYSBASE)))
 
137
                            /* on 68020 or higher processors it is faster   */
 
138
#    define __USE_SYSBASE   /* to use the pragma libcall instead of syscall */
 
139
#  endif                    /* to access functions of the exec.library      */
 
140
#  include <proto/exec.h>   /* see SAS/C manual:part 2,chapter 2,pages 6-7  */
 
141
#  include <proto/dos.h>
 
142
#  include <proto/locale.h>
 
143
#  ifdef DEBUG
 
144
#     include <sprof.h>
 
145
#  endif
 
146
#  ifdef MWDEBUG
 
147
#    include <stdio.h>      /* include both before memwatch.h again just */
 
148
#    include <stdlib.h>     /* to be safe */
 
149
#    include "memwatch.h"
 
150
#  endif /* MWDEBUG */
 
151
#endif /* __SASC */
 
152
 
 
153
#include "crypt.h"            /* just so we can tell if CRYPT is supported */
 
154
 
 
155
 
 
156
#if (!defined(FUNZIP) && !defined(UTIL))
 
157
 
 
158
#include "timezone.h"         /* for AMIGA-specific timezone callbacks */
 
159
 
 
160
#ifndef SUCCESS
 
161
#  define SUCCESS (-1L)
 
162
#  define FAILURE 0L
 
163
#endif
 
164
 
 
165
#define ReqVers 36L        /* required library version for SetFileDate() */
 
166
#define ENVSIZE 100        /* max space allowed for an environment var   */
 
167
 
 
168
extern struct ExecBase *SysBase;
 
169
 
 
170
#ifndef min
 
171
#  define min(a, b)  ((a) < (b) ? (a) : (b))
 
172
#  define max(a, b)  ((a) < (b) ? (b) : (a))
 
173
#endif
 
174
 
 
175
#if defined(ZIP) || defined(HAVE_MKTIME)
 
176
static const unsigned short ydays[] =
 
177
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
 
178
#else
 
179
extern const unsigned short ydays[];  /* in unzip's fileio.c */
 
180
#endif
 
181
 
 
182
#define LEAP(y)     (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
 
183
#define YDAYS(m, y) (ydays[m] + (m > 1 && LEAP(y)))
 
184
/* Number of leap years from 1978 to `y' (not including `y' itself). */
 
185
#define ANLEAP(y)   (((y) - 1977) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
 
186
#define SECSPERMIN  60
 
187
#define MINSPERHOUR 60
 
188
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
 
189
#define SECSPERDAY  86400L
 
190
 
 
191
/* prototypes */
 
192
char *getenv(const char *var);
 
193
#ifdef __SASC
 
194
/*  XXX !!  We have really got to find a way to operate without these. */
 
195
int setenv(const char *var, const char *value, int overwrite);
 
196
void set_TZ(long time_zone, int day_light);
 
197
#endif
 
198
 
 
199
LONG FileDate(char *filename, time_t u[]);
 
200
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
 
201
int Agetch(void);
 
202
 
 
203
/* =============================================================== */
 
204
 
 
205
/***********************/
 
206
/* Function filedate() */
 
207
/***********************/
 
208
 
 
209
/*  FileDate() (originally utime.c), by Paul Wells.  Modified by John Bush
 
210
 *  and others (see also sendpkt() comments, below); NewtWare SetFileDate()
 
211
 *  clone cheaply ripped off from utime().
 
212
 */
 
213
 
 
214
/* DESCRIPTION
 
215
 * This routine chooses between 2 methods to set the file date on AMIGA.
 
216
 * Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36
 
217
 * and higher).  Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate()
 
218
 * must be accomplished by constructing a message packet and sending it
 
219
 * to the file system handler of the file to be stamped.
 
220
 *
 
221
 * The system's ROM version is extracted from the external system Library
 
222
 * base.
 
223
 *
 
224
 * NOTE:  although argument passing conforms with utime(), note the
 
225
 *        following differences:
 
226
 *          - Return value is boolean success/failure.
 
227
 *          - If a structure or array is passed, only the first value
 
228
 *            is used, which *may* correspond to date accessed and not
 
229
 *            date modified.
 
230
 */
 
231
 
 
232
LONG FileDate(filename, u)
 
233
    char *filename;
 
234
    time_t u[];
 
235
{
 
236
    LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate);
 
237
    LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
 
238
    struct MsgPort *taskport;
 
239
    BPTR dirlock, lock;
 
240
    struct FileInfoBlock *fib;
 
241
    LONG pktargs[4];
 
242
    UBYTE *ptr;
 
243
    long ret;
 
244
 
 
245
    struct DateStamp pDate;
 
246
    struct tm *ltm;
 
247
    int years;
 
248
 
 
249
    tzset();
 
250
    /* Amiga file date is based on 01-Jan-1978 00:00:00 (local time):
 
251
     * 8 years and 2 leapdays difference from Unix time.
 
252
     */
 
253
    ltm = localtime(&u[0]);
 
254
    years = ltm->tm_year + 1900;
 
255
    if (years < 1978)
 
256
        pDate.ds_Days = pDate.ds_Minute = pDate.ds_Tick = 0;
 
257
    else {
 
258
        pDate.ds_Days = (years - 1978) * 365L + (ANLEAP(years)) +
 
259
                        YDAYS(ltm->tm_mon, years) + (ltm->tm_mday - 1);
 
260
        pDate.ds_Minute = ltm->tm_hour * 60 + ltm->tm_min;
 
261
        pDate.ds_Tick = ltm->tm_sec * TICKS_PER_SECOND;
 
262
    }
 
263
 
 
264
    if (SysBase->LibNode.lib_Version >= ReqVers)
 
265
    {
 
266
        return (SetFileDate(filename,&pDate));  /* native routine at 2.0+ */
 
267
    }
 
268
    else  /* !(SysBase->lib_Version >=ReqVers) */
 
269
    {
 
270
        if( !(taskport = (struct MsgPort *)DeviceProc(filename)) )
 
271
        {
 
272
            errno = ESRCH;          /* no such process */
 
273
            return FAILURE;
 
274
        }
 
275
 
 
276
        if( !(lock = Lock(filename,SHARED_LOCK)) )
 
277
        {
 
278
            errno = ENOENT;         /* no such file */
 
279
            return FAILURE;
 
280
        }
 
281
 
 
282
        if( !(fib = (struct FileInfoBlock *)AllocMem(
 
283
            (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
 
284
        {
 
285
            errno = ENOMEM;         /* insufficient memory */
 
286
            UnLock(lock);
 
287
            return FAILURE;
 
288
        }
 
289
 
 
290
        if( Examine(lock,fib)==FAILURE )
 
291
        {
 
292
            errno = EOSERR;         /* operating system error */
 
293
            UnLock(lock);
 
294
            FreeMem(fib,(long)sizeof(*fib));
 
295
            return FAILURE;
 
296
        }
 
297
 
 
298
        dirlock = ParentDir(lock);
 
299
        ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
 
300
        strcpy((ptr+1),fib->fib_FileName);
 
301
        *ptr = strlen(fib->fib_FileName);
 
302
        FreeMem(fib,(long)sizeof(*fib));
 
303
        UnLock(lock);
 
304
 
 
305
        /* now fill in argument array */
 
306
 
 
307
        pktargs[0] = 0;
 
308
        pktargs[1] = (LONG)dirlock;
 
309
        pktargs[2] = (LONG)&ptr[0] >> 2;
 
310
        pktargs[3] = (LONG)&pDate;
 
311
 
 
312
        errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L);
 
313
 
 
314
        FreeMem(ptr,64L);
 
315
        UnLock(dirlock);
 
316
 
 
317
        return SUCCESS;
 
318
    }  /* ?(SysBase->lib_Version >= ReqVers) */
 
319
} /* FileDate() */
 
320
 
 
321
 
 
322
char *getenv(const char *var)         /* not reentrant! */
 
323
{
 
324
    static char space[ENVSIZE];
 
325
    struct Process *me = (void *) FindTask(NULL);
 
326
    void *old_window = me->pr_WindowPtr;
 
327
    char *ret = NULL;
 
328
 
 
329
    me->pr_WindowPtr = (void *) -1;   /* suppress any "Please insert" popups */
 
330
    if (SysBase->LibNode.lib_Version >= ReqVers) {
 
331
        if (GetVar((char *) var, space, ENVSIZE - 1, /*GVF_GLOBAL_ONLY*/ 0) > 0)
 
332
            ret = space;
 
333
    } else {                    /* early AmigaDOS, get env var the crude way */
 
334
        BPTR hand, foot, spine;
 
335
        int z = 0;
 
336
        if (foot = Lock("ENV:", ACCESS_READ)) {
 
337
            spine = CurrentDir(foot);
 
338
            if (hand = Open((char *) var, MODE_OLDFILE)) {
 
339
                z = Read(hand, space, ENVSIZE - 1);
 
340
                Close(hand);
 
341
            }
 
342
            UnLock(CurrentDir(spine));
 
343
        }
 
344
        if (z > 0) {
 
345
            space[z] = '\0';
 
346
            ret = space;
 
347
        }
 
348
    }
 
349
    me->pr_WindowPtr = old_window;
 
350
    return ret;
 
351
}
 
352
 
 
353
#ifdef __SASC
 
354
int setenv(const char *var, const char *value, int overwrite)
 
355
{
 
356
    struct Process *me = (void *) FindTask(NULL);
 
357
    void *old_window = me->pr_WindowPtr;
 
358
    int ret = -1;
 
359
 
 
360
    me->pr_WindowPtr = (void *) -1;   /* suppress any "Please insert" popups */
 
361
    if (SysBase->LibNode.lib_Version >= ReqVers)
 
362
        ret = !SetVar((char *)var, (char *)value, -1, GVF_GLOBAL_ONLY | LV_VAR);
 
363
    else {
 
364
        BPTR hand, foot, spine;
 
365
        long len = value ? strlen(value) : 0;
 
366
        if (foot = Lock("ENV:", ACCESS_READ)) {
 
367
            spine = CurrentDir(foot);
 
368
            if (len) {
 
369
                if (hand = Open((char *) var, MODE_NEWFILE)) {
 
370
                    ret = Write(hand, (char *) value, len + 1) >= len;
 
371
                    Close(hand);
 
372
                }
 
373
            } else
 
374
                ret = DeleteFile((char *) var);
 
375
            UnLock(CurrentDir(spine));
 
376
        }
 
377
    }
 
378
    me->pr_WindowPtr = old_window;
 
379
    return ret;
 
380
}
 
381
 
 
382
/* Stores data from timezone and daylight to ENV:TZ.                  */
 
383
/* ENV:TZ is required to exist by some other SAS/C library functions, */
 
384
/* like stat() or fstat().                                            */
 
385
void set_TZ(long time_zone, int day_light)
 
386
{
 
387
    char put_tz[MAXTIMEZONELEN];  /* string for putenv: "TZ=aaabbb:bb:bbccc" */
 
388
    int offset;
 
389
    void *exists;     /* dummy ptr to see if global envvar TZ already exists */
 
390
    exists = (void *)getenv(TZ_ENVVAR);
 
391
    /* see if there is already an envvar TZ_ENVVAR. If not, create it */
 
392
    if (exists == NULL) {
 
393
        /* create TZ string by pieces: */
 
394
        sprintf(put_tz, "GMT%+ld", time_zone / 3600L);
 
395
        if (time_zone % 3600L) {
 
396
            offset = (int) labs(time_zone % 3600L);
 
397
            sprintf(put_tz + strlen(put_tz), ":%02d", offset / 60);
 
398
            if (offset % 60)
 
399
                sprintf(put_tz + strlen(put_tz), ":%02d", offset % 60);
 
400
        }
 
401
        if (day_light)
 
402
            strcat(put_tz,"DST");
 
403
        setenv(TZ_ENVVAR, put_tz, 1);
 
404
    }
 
405
}
 
406
#endif /* __SASC */
 
407
 
 
408
/* set state as well as possible from settings found in locale.library */
 
409
int GetPlatformLocalTimezone(sp, fill_tzstate_from_rules)
 
410
     register struct state * ZCONST sp;
 
411
     void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res,
 
412
                                     ZCONST struct rule * ZCONST start,
 
413
                                     ZCONST struct rule * ZCONST end);
 
414
{
 
415
    struct Library *LocaleBase;
 
416
    struct Locale *ll;
 
417
    struct Process *me = (void *) FindTask(NULL);
 
418
    void *old_window = me->pr_WindowPtr;
 
419
    BPTR eh;
 
420
    int z, valid = FALSE;
 
421
 
 
422
    /* read timezone from locale.library if TZ envvar missing */
 
423
    me->pr_WindowPtr = (void *) -1;   /* suppress any "Please insert" popups */
 
424
    if (LocaleBase = OpenLibrary("locale.library", 0)) {
 
425
        if (ll = OpenLocale(NULL)) {
 
426
            z = ll->loc_GMTOffset;    /* in minutes */
 
427
            if (z == -300) {
 
428
                if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ)) {
 
429
                    UnLock(eh);
 
430
                    valid = TRUE;
 
431
                } else
 
432
                    z = 300; /* bug: locale not initialized, default bogus! */
 
433
            } else
 
434
                valid = TRUE;
 
435
            if (valid) {
 
436
                struct rule startrule, stoprule;
 
437
 
 
438
                sp->timecnt = 0;
 
439
                sp->typecnt = 1;
 
440
                sp->charcnt = 2;
 
441
                sp->chars[0] = sp->chars[1] = '\0';
 
442
                sp->ttis[0].tt_abbrind = 0;
 
443
                sp->ttis[1].tt_abbrind = 1;
 
444
                sp->ttis[0].tt_gmtoff = -z * MINSPERHOUR;
 
445
                sp->ttis[1].tt_gmtoff = -z * MINSPERHOUR + SECSPERHOUR;
 
446
                sp->ttis[0].tt_isdst = 0;
 
447
                sp->ttis[1].tt_isdst = 1;
 
448
                stoprule.r_type = MONTH_NTH_DAY_OF_WEEK;
 
449
                stoprule.r_day = 0;
 
450
                stoprule.r_week = 5;
 
451
                stoprule.r_mon = 10;
 
452
                stoprule.r_time = 2 * SECSPERHOUR;
 
453
                startrule = stoprule;
 
454
                startrule.r_mon = 4;
 
455
                startrule.r_week = 1;
 
456
                if (z >= -180 && z < 150) {
 
457
                    /* At this point we make a really gratuitous assumption: */
 
458
                    /* if the time zone could be Europe, we use the European */
 
459
                    /* Union rules without checking what country we're in.   */
 
460
                    /* The AmigaDOS locale country codes do not, at least in */
 
461
                    /* 2.x versions of the OS, recognize very many countries */
 
462
                    /* outside of Europe and North America.                  */
 
463
                    sp->typecnt = 2;
 
464
                    startrule.r_mon = 3;   /* one week earlier than US DST */
 
465
                    startrule.r_week = 5;
 
466
                } else if (z >= 150 && z <= 480 &&
 
467
                           /* no DST in alaska, hawaii */
 
468
                           (ll->loc_CountryCode == 0x55534100 /*"USA"*/ ||
 
469
                            ll->loc_CountryCode == 0x43414E00 /*"CAN"*/))
 
470
                    sp->typecnt = 2;
 
471
                    /* We check the country code for U.S. or Canada because */
 
472
                    /* most of Latin America has no DST.  Even in these two */
 
473
                    /* countries there are some exceptions...               */
 
474
                /* else if...  Feel free to add more cases here! */
 
475
 
 
476
                if (sp->typecnt > 1)
 
477
                    (*fill_tzstate_from_rules)(sp, &startrule, &stoprule);
 
478
            }
 
479
            CloseLocale(ll);
 
480
        }
 
481
        CloseLibrary(LocaleBase);
 
482
    }
 
483
    me->pr_WindowPtr = old_window;
 
484
    return valid;
 
485
}
 
486
 
 
487
#ifdef ZIP
 
488
time_t time(time_t *tp)
 
489
{
 
490
    time_t t;
 
491
    struct DateStamp ds;
 
492
    DateStamp(&ds);
 
493
    t = ds.ds_Tick / TICKS_PER_SECOND + ds.ds_Minute * 60
 
494
                                      + (ds.ds_Days + 2922) * SECSPERDAY;
 
495
    t = mktime(gmtime(&t));
 
496
    /* gmtime leaves ds in the local timezone, mktime converts it to GMT */
 
497
    if (tp) *tp = t;
 
498
    return t;
 
499
}
 
500
#endif /* ZIP */
 
501
 
 
502
#endif /* !FUNZIP && !UTIL */
 
503
 
 
504
 
 
505
#if CRYPT || !defined(FUNZIP)
 
506
 
 
507
/*  sendpkt.c
 
508
 *  by A. Finkel, P. Lindsay, C. Sheppner
 
509
 *  returns Res1 of the reply packet
 
510
 */
 
511
/*
 
512
#include <exec/types.h>
 
513
#include <exec/memory.h>
 
514
#include <libraries/dos.h>
 
515
#include <libraries/dosextens.h>
 
516
#include <proto/exec.h>
 
517
#include <proto/dos.h>
 
518
*/
 
519
 
 
520
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
 
521
 
 
522
LONG sendpkt(pid,action,args,nargs)
 
523
struct MsgPort *pid;           /* process identifier (handler message port) */
 
524
LONG action,                   /* packet type (desired action)              */
 
525
     *args,                    /* a pointer to argument list                */
 
526
     nargs;                    /* number of arguments in list               */
 
527
{
 
528
 
 
529
    struct MsgPort *replyport, *CreatePort(UBYTE *, long);
 
530
    void DeletePort(struct MsgPort *);
 
531
    struct StandardPacket *packet;
 
532
    LONG count, *pargs, res1;
 
533
 
 
534
    replyport = CreatePort(NULL,0L);
 
535
    if( !replyport ) return(0);
 
536
 
 
537
    packet = (struct StandardPacket *)AllocMem(
 
538
            (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
 
539
    if( !packet )
 
540
    {
 
541
        DeletePort(replyport);
 
542
        return(0);
 
543
    }
 
544
 
 
545
    packet->sp_Msg.mn_Node.ln_Name  = (char *)&(packet->sp_Pkt);
 
546
    packet->sp_Pkt.dp_Link          = &(packet->sp_Msg);
 
547
    packet->sp_Pkt.dp_Port          = replyport;
 
548
    packet->sp_Pkt.dp_Type          = action;
 
549
 
 
550
    /* copy the args into the packet */
 
551
    pargs = &(packet->sp_Pkt.dp_Arg1);      /* address of 1st argument */
 
552
    for( count=0; count<nargs; count++ )
 
553
        pargs[count] = args[count];
 
554
 
 
555
    PutMsg(pid,(struct Message *)packet);   /* send packet */
 
556
 
 
557
    WaitPort(replyport);
 
558
    GetMsg(replyport);
 
559
 
 
560
    res1 = packet->sp_Pkt.dp_Res1;
 
561
 
 
562
    FreeMem((char *)packet,(long)sizeof(*packet));
 
563
    DeletePort(replyport);
 
564
 
 
565
    return(res1);
 
566
 
 
567
} /* sendpkt() */
 
568
 
 
569
#endif /* CRYPT || !FUNZIP */
 
570
 
 
571
 
 
572
#if CRYPT || (defined(UNZIP) && !defined(FUNZIP))
 
573
 
 
574
/* Agetch() reads one raw keystroke -- uses sendpkt() */
 
575
 
 
576
int Agetch(void)
 
577
{
 
578
    LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
 
579
    struct Task *me = FindTask(NULL);
 
580
    struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI);
 
581
    BPTR fh = cli->cli_StandardInput;   /* this is immune to < redirection */
 
582
    void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type;
 
583
    char longspace[8];
 
584
    long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */
 
585
    UBYTE c;
 
586
 
 
587
    *flag = 1;
 
588
    sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);         /* assume success */
 
589
    Read(fh, &c, 1);
 
590
    *flag = 0;
 
591
    sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);
 
592
    if (c == 3)                                         /* ^C in input */
 
593
        Signal(me, SIGBREAKF_CTRL_C);
 
594
    return c;
 
595
}
 
596
 
 
597
#endif /* CRYPT || (UNZIP && !FUNZIP) */
 
598
 
 
599
#endif /* __amiga_filedate_c*/