f0d81ffd1c
which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
672 lines
23 KiB
C
Executable File
672 lines
23 KiB
C
Executable File
/* Low-level Amiga routines shared between Zip and UnZip.
|
|
*
|
|
* Contains: FileDate()
|
|
* set_TZ() [SAS/C only]
|
|
* locale_TZ()
|
|
* getenv() [Aztec C only; replaces bad C library versions]
|
|
* tzset() [ditto]
|
|
* gmtime() [ditto]
|
|
* localtime() [ditto]
|
|
* time() [ditto]
|
|
* mkgmtime()
|
|
* sendpkt()
|
|
* Agetch()
|
|
*
|
|
* The first five are used by all Info-ZIP programs except fUnZip.
|
|
* The last two are used by all except the non-CRYPT version of fUnZip.
|
|
* Probably some of the stuff in here is unused by ZipNote and ZipSplit too...
|
|
* sendpkt() is used by Agetch() and FileDate(), and by windowheight() in
|
|
* amiga/amiga.c (UnZip). time() is used only by Zip.
|
|
*/
|
|
|
|
|
|
/* HISTORY/CHANGES
|
|
* 2 Sep 92, Greg Roelofs, Original coding.
|
|
* 6 Sep 92, John Bush, Incorporated into UnZip 5.1
|
|
* 6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or
|
|
* redefines SetFileDate() depending upon AMIGADOS2 definition.
|
|
* 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining
|
|
* revision via OpenLibrary() call. Now only one version of
|
|
* the program runs on both platforms (1.3.x vs. 2.x)
|
|
* 11 Oct 92, John Bush, Merged with Zip version and changed arg passing
|
|
* to take time_t input instead of struct DateStamp.
|
|
* Arg passing made to conform with utime().
|
|
* 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some
|
|
* lint-ish errors; simplified test for AmigaDOS version.
|
|
* 11 Nov 95, Paul Kienitz, added Agetch() for crypt password input and
|
|
* UnZip's "More" prompt -- simplifies crypt.h and avoids
|
|
* use of library code redundant with sendpkt(). Made it
|
|
* available to fUnZip, which does not use FileDate().
|
|
* 22 Nov 95, Paul Kienitz, created a new tzset() that gets the current
|
|
* timezone from the Locale preferences. These exist only under
|
|
* AmigaDOS 2.1 and up, but it is probably correctly set on more
|
|
* Amigas than the TZ environment variable is. We check that
|
|
* only if TZ is not validly set. We do not parse daylight
|
|
* savings syntax except to check for presence vs. absence of a
|
|
* DST part; United States rules are assumed. This is better
|
|
* than the tzset()s in the Amiga compilers' libraries do.
|
|
* 15 Jan 96, Chr. Spieler, corrected the logic when to select low level
|
|
* sendpkt() (when FileDate(), Agetch() or windowheight() is used),
|
|
* and AMIGA's Agetch() (CRYPT, and UnZip(SFX)'s UzpMorePause()).
|
|
* 10 Feb 96, Paul Kienitz, re-fiddled that selection logic again, moved
|
|
* stuff around for clarity.
|
|
* 16 Mar 96, Paul Kienitz, created a replacement localtime() to go with the
|
|
* new tzset(), because Aztec's is hopelessly broken. Also
|
|
* gmtime(), which localtime() calls.
|
|
* 12 Apr 96, Paul Kienitz, daylight savings was being handled incorrectly.
|
|
* 21 Apr 96, Paul Kienitz, had to replace time() as well, Aztec's returns
|
|
* local time instead of GMT. That's why their localtime() was bad,
|
|
* because it assumed time_t was already local, and gmtime() was
|
|
* the one that checked TZ.
|
|
* 23 Apr 96, Chr. Spieler, deactivated time() replacement for UnZip stuff.
|
|
* Currently, the UnZip sources do not make use of time() (and do
|
|
* not supply the working mktime() replacement, either!).
|
|
* 29 Apr 96, Paul Kienitz, created a replacement getenv() out of code that
|
|
* was previously embedded in tzset(), for reliable global test
|
|
* of whether TZ is set or not.
|
|
* 19 Jun 96, Haidinger Walter, re-adapted for current SAS/C compiler.
|
|
* 7 Jul 96, Paul Kienitz, smoothed together compiler-related changes.
|
|
* 4 Feb 97, Haidinger Walter, added set_TZ() for SAS/C.
|
|
* 23 Apr 97, Paul Kienitz, corrected Unix->Amiga DST error by adding
|
|
* mkgmtime() so localtime() could be used.
|
|
* 28 Apr 97, Christian Spieler, deactivated mkgmtime() definition for ZIP;
|
|
* the Zip sources supply this function as part of util.c.
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
|
|
#include <exec/types.h>
|
|
#include <exec/execbase.h>
|
|
#include <exec/memory.h>
|
|
|
|
#ifdef AZTEC_C
|
|
# include <libraries/dos.h>
|
|
# include <libraries/dosextens.h>
|
|
# include <clib/exec_protos.h>
|
|
# include <clib/dos_protos.h>
|
|
# include <clib/locale_protos.h>
|
|
# include <pragmas/exec_lib.h>
|
|
# include <pragmas/dos_lib.h>
|
|
# include <pragmas/locale_lib.h>
|
|
# define ESRCH ENOENT
|
|
# define EOSERR EIO
|
|
#endif
|
|
|
|
#ifdef __SASC
|
|
# include <stdlib.h>
|
|
# if (defined(_M68020) && (!defined(__USE_SYSBASE)))
|
|
/* on 68020 or higher processors it is faster */
|
|
# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */
|
|
# endif /* to access functions of the exec.library */
|
|
# include <proto/exec.h> /* see SAS/C manual:part 2,chapter 2,pages 6-7 */
|
|
# include <proto/dos.h>
|
|
# include <proto/locale.h>
|
|
# ifdef DEBUG
|
|
# include <sprof.h>
|
|
# endif
|
|
# ifdef MWDEBUG
|
|
# include <stdio.h> /* include both before memwatch.h again just */
|
|
# include <stdlib.h> /* to be safe */
|
|
# include "memwatch.h"
|
|
#if 0 /* remember_alloc currently unavailable */
|
|
# ifdef getenv
|
|
# undef getenv /* remove previously preprocessor symbol */
|
|
# endif
|
|
# define getenv(name) ((char *)remember_alloc((zvoid *)MWGetEnv(name, __FILE__, __LINE__)))
|
|
#endif
|
|
# endif /* MWDEBUG */
|
|
#endif
|
|
|
|
#ifndef OF
|
|
#define OF(x) x /* so crypt.h prototypes compile okay */
|
|
#endif
|
|
#if defined(ZIP) || defined(FUNZIP)
|
|
void zipwarn OF((char *, char *)); /* add zipwarn prototype from zip.h */
|
|
# define near /* likewise */
|
|
typedef unsigned long ulg; /* likewise */
|
|
typedef size_t extent; /* likewise */
|
|
typedef void zvoid; /* likewise */
|
|
#endif
|
|
#include "crypt.h" /* just so we can tell if CRYPT is supported */
|
|
|
|
int zone_is_set = FALSE; /* set by tzset() */
|
|
|
|
|
|
#ifndef FUNZIP
|
|
|
|
/***********************/
|
|
/* Function filedate() */
|
|
/***********************/
|
|
|
|
/* FileDate() (originally utime.c), by Paul Wells. Modified by John Bush
|
|
* and others (see also sendpkt() comments, below); NewtWare SetFileDate()
|
|
* clone cheaply ripped off from utime().
|
|
*/
|
|
|
|
/* DESCRIPTION
|
|
* This routine chooses between 2 methods to set the file date on AMIGA.
|
|
* Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36
|
|
* and higher). Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate()
|
|
* must be accomplished by constructing a message packet and sending it
|
|
* to the file system handler of the file to be stamped.
|
|
*
|
|
* The system's ROM version is extracted from the external system Library
|
|
* base.
|
|
*
|
|
* NOTE: although argument passing conforms with utime(), note the
|
|
* following differences:
|
|
* - Return value is boolean success/failure.
|
|
* - If a structure or array is passed, only the first value
|
|
* is used, which *may* correspond to date accessed and not
|
|
* date modified.
|
|
*/
|
|
|
|
# ifndef SUCCESS
|
|
# define SUCCESS (-1L)
|
|
# define FAILURE 0L
|
|
# endif
|
|
|
|
# define ReqVers 36L /* required library version for SetFileDate() */
|
|
# define ENVSIZE 100 /* max space allowed for an environment var */
|
|
|
|
extern struct ExecBase *SysBase;
|
|
|
|
#ifdef AZTEC_C /* should be pretty safe for reentrancy */
|
|
long timezone = 0; /* already declared SAS/C external */
|
|
int daylight = 0; /* likewise */
|
|
#endif
|
|
|
|
/* prototypes */
|
|
LONG FileDate (char *filename, time_t u[]);
|
|
int locale_TZ(void);
|
|
void tzset(void);
|
|
char *getenv(const char *var);
|
|
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
|
|
int Agetch(void);
|
|
#ifdef AZTEC_C
|
|
struct tm *gmtime(const time_t *when);
|
|
struct tm *localtime(const time_t *when);
|
|
#endif
|
|
time_t mkgmtime(struct tm *tm);
|
|
|
|
#ifdef ZIP
|
|
int is_zone_set(void); /* used by HAS_VALID_TIMEZONE macro */
|
|
time_t time(time_t *tp);
|
|
#endif
|
|
|
|
#ifdef __SASC
|
|
void set_TZ(char *TZstr);
|
|
#endif
|
|
|
|
#if 0 /* not used YET */
|
|
extern zvoid *remember_alloc OF((zvoid *memptr));
|
|
#endif
|
|
|
|
/* =============================================================== */
|
|
|
|
|
|
LONG FileDate(filename, u)
|
|
char *filename;
|
|
time_t u[];
|
|
{
|
|
LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate);
|
|
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
|
|
struct MsgPort *taskport;
|
|
BPTR dirlock, lock;
|
|
struct FileInfoBlock *fib;
|
|
LONG pktargs[4];
|
|
UBYTE *ptr;
|
|
long ret;
|
|
|
|
struct DateStamp pDate;
|
|
time_t mtime;
|
|
|
|
/* tzset(); */
|
|
/* mtime = u[0] - timezone; */
|
|
mtime = mkgmtime(localtime(&u[0]));
|
|
|
|
/* magic number = 2922 = 8 years + 2 leaps between 1970 - 1978 */
|
|
pDate.ds_Days = (mtime / 86400L) - 2922L;
|
|
mtime = mtime % 86400L;
|
|
pDate.ds_Minute = mtime / 60L;
|
|
mtime = mtime % 60L;
|
|
pDate.ds_Tick = mtime * TICKS_PER_SECOND;
|
|
|
|
if (SysBase->LibNode.lib_Version >= ReqVers)
|
|
{
|
|
return (SetFileDate(filename,&pDate)); /* native routine at 2.0+ */
|
|
}
|
|
else /* !(SysBase->lib_Version >=ReqVers) */
|
|
{
|
|
if( !(taskport = (struct MsgPort *)DeviceProc(filename)) )
|
|
{
|
|
errno = ESRCH; /* no such process */
|
|
return FAILURE;
|
|
}
|
|
|
|
if( !(lock = Lock(filename,SHARED_LOCK)) )
|
|
{
|
|
errno = ENOENT; /* no such file */
|
|
return FAILURE;
|
|
}
|
|
|
|
if( !(fib = (struct FileInfoBlock *)AllocMem(
|
|
(long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
|
|
{
|
|
errno = ENOMEM; /* insufficient memory */
|
|
UnLock(lock);
|
|
return FAILURE;
|
|
}
|
|
|
|
if( Examine(lock,fib)==FAILURE )
|
|
{
|
|
errno = EOSERR; /* operating system error */
|
|
UnLock(lock);
|
|
FreeMem(fib,(long)sizeof(*fib));
|
|
return FAILURE;
|
|
}
|
|
|
|
dirlock = ParentDir(lock);
|
|
ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
|
|
strcpy((ptr+1),fib->fib_FileName);
|
|
*ptr = strlen(fib->fib_FileName);
|
|
FreeMem(fib,(long)sizeof(*fib));
|
|
UnLock(lock);
|
|
|
|
/* now fill in argument array */
|
|
|
|
pktargs[0] = 0;
|
|
pktargs[1] = (LONG)dirlock;
|
|
pktargs[2] = (LONG)&ptr[0] >> 2;
|
|
pktargs[3] = (LONG)&pDate;
|
|
|
|
errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L);
|
|
|
|
FreeMem(ptr,64L);
|
|
UnLock(dirlock);
|
|
|
|
return SUCCESS;
|
|
} /* ?(SysBase->lib_Version >= ReqVers) */
|
|
} /* FileDate() */
|
|
|
|
|
|
#ifdef ZIP
|
|
int is_zone_set(void) /* used by HAS_VALID_TIMEZONE macro */
|
|
{
|
|
tzset(); /* sets global zone_is_set */
|
|
return zone_is_set;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* set timezone and daylight to settings found in locale.library */
|
|
int locale_TZ(void)
|
|
{
|
|
struct Library *LocaleBase;
|
|
struct Locale *ll;
|
|
struct Process *me = (void *) FindTask(NULL);
|
|
void *old_window = me->pr_WindowPtr;
|
|
BPTR eh;
|
|
int z, valid = FALSE;
|
|
|
|
/* read timezone from locale.library if TZ envvar missing */
|
|
me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */
|
|
if (LocaleBase = OpenLibrary("locale.library", 0)) {
|
|
if (ll = OpenLocale(NULL)) {
|
|
z = ll->loc_GMTOffset;
|
|
if (z == -5) {
|
|
if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ))
|
|
UnLock(eh);
|
|
else
|
|
z = 5; /* bug: locale not initialized, default is bogus! */
|
|
} else
|
|
zone_is_set = TRUE;
|
|
timezone = z * 60;
|
|
daylight = (z >= 4*60 && z <= 9*60); /* apply in the Americas */
|
|
valid = TRUE;
|
|
CloseLocale(ll);
|
|
}
|
|
CloseLibrary(LocaleBase);
|
|
}
|
|
me->pr_WindowPtr = old_window;
|
|
return valid;
|
|
}
|
|
|
|
|
|
#ifdef __SASC
|
|
/* Stores data from timezone and daylight to ENV:TZ. */
|
|
/* Only set if TZ string is absent or empty */
|
|
/* ENV:TZ is required to exist by some other SAS/C library functions, */
|
|
/* e.g. stat(), that call tzset() again rather than using already set */
|
|
/* timezone and daylight. */
|
|
void set_TZ(char *TZstr)
|
|
{
|
|
char put_tz[13]; /* string for putenv: "TZ=aaabbbccc" */
|
|
int offset;
|
|
if ((TZstr == NULL) || (TZstr && (*TZstr == '\0'))) {
|
|
offset = timezone / 3600;
|
|
/* create TZ string and make sure hours range from 0-24 */
|
|
sprintf(put_tz,"TZ=UTC%+03dDST",abs(offset)>24 ? 0 : offset);
|
|
if (daylight == 0)
|
|
put_tz[9] = '\0'; /* truncate daylight savings part */
|
|
/* Now store TZ to ENV:TZ. Will match values from locale.library */
|
|
/* or "UTC+00" if no valid information was found at all. */
|
|
putenv(put_tz);
|
|
__tzset(); /* initialize _TZ */
|
|
}
|
|
}
|
|
#endif /* __SASC */
|
|
|
|
void tzset(void) {
|
|
char *p,*TZstring;
|
|
int z,valid = FALSE;
|
|
|
|
if (zone_is_set)
|
|
return;
|
|
timezone = 0; /* default is GMT0 which means no offsets */
|
|
daylight = 0; /* from local system time */
|
|
TZstring = getenv("TZ"); /* read TZ envvar */
|
|
if (TZstring && TZstring[0]) { /* TZ exists and has contents? */
|
|
z = 3600;
|
|
for (p = TZstring; *p && !isdigit(*p) && *p != '-'; p++) ;
|
|
if (*p == '-')
|
|
z = -3600, p++;
|
|
if (*p) {
|
|
timezone = 0;
|
|
do {
|
|
while (isdigit(*p))
|
|
timezone = timezone * 10 + z * (*p++ - '0'), valid = TRUE;
|
|
if (*p == ':') p++;
|
|
} while (isdigit(*p) && (z /= 60) > 0);
|
|
}
|
|
while (isspace(*p)) p++; /* probably not needed */
|
|
if (valid)
|
|
zone_is_set = TRUE, daylight = !!*p; /* a DST name part exists */
|
|
}
|
|
if (!valid)
|
|
locale_TZ(); /* read locale.library */
|
|
#ifdef __SASC
|
|
/* Some SAS/C library functions, e.g. stat(), call library */
|
|
/* __tzset() themselves. So envvar TZ *must* exist in order */
|
|
/* to get the right offset from GMT. */
|
|
set_TZ(TZstring);
|
|
#endif /* __SASC */
|
|
}
|
|
|
|
|
|
#ifdef AZTEC_C /* SAS/C uses library getenv() */
|
|
char *getenv(const char *var) /* not reentrant! */
|
|
{
|
|
static char space[ENVSIZE];
|
|
struct Process *me = (void *) FindTask(NULL);
|
|
void *old_window = me->pr_WindowPtr;
|
|
char *ret = NULL, **varp = &var; /* <= NECESSARY to prevent "loss of" */
|
|
/* const/volatile info" errors */
|
|
me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */
|
|
if (SysBase->LibNode.lib_Version >= ReqVers) {
|
|
if (GetVar(*varp, space, ENVSIZE - 1, /* GVF_GLOBAL_ONLY */ 0) > 0)
|
|
ret = space;
|
|
} else { /* early AmigaDOS, get env var the crude way */
|
|
BPTR hand, foot, spine;
|
|
int z = 0;
|
|
if (foot = Lock("ENV:", ACCESS_READ)) {
|
|
spine = CurrentDir(foot);
|
|
if (hand = Open(*varp, MODE_OLDFILE)) {
|
|
z = Read(hand, space, ENVSIZE - 1);
|
|
Close(hand);
|
|
}
|
|
UnLock(CurrentDir(spine));
|
|
}
|
|
if (z > 0) {
|
|
space[z] = '\0';
|
|
ret = space;
|
|
}
|
|
}
|
|
me->pr_WindowPtr = old_window;
|
|
return ret;
|
|
}
|
|
#endif /* AZTEC_C */
|
|
|
|
|
|
#if (!defined(ZIP) || !defined(NO_MKTIME))
|
|
/* this mkgmtime() code is a simplified version taken from Zip's mktime.c */
|
|
|
|
/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
|
|
of the Greenwich Mean time and date in the exploded time structure `tm',
|
|
and set `tm->tm_yday' and `tm->tm_wday', but not `tm->tm_isdst'.
|
|
Return -1 if any of the other fields in `tm' has an invalid value. */
|
|
|
|
/* Nonzero if `y' is a leap year, else zero. */
|
|
#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
|
|
|
|
/* Number of leap years from 1970 to `y' (not including `y' itself). */
|
|
#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
|
|
|
|
/* Accumulated number of days from 01-Jan up to start of current month. */
|
|
extern const ush ydays[]; /* in fileio.c */
|
|
|
|
|
|
time_t mkgmtime(struct tm *tm)
|
|
{
|
|
int years, months, days, hours, minutes, seconds;
|
|
|
|
years = tm->tm_year + 1900; /* year - 1900 -> year */
|
|
months = tm->tm_mon; /* 0..11 */
|
|
days = tm->tm_mday - 1; /* 1..31 -> 0..30 */
|
|
hours = tm->tm_hour; /* 0..23 */
|
|
minutes = tm->tm_min; /* 0..59 */
|
|
seconds = tm->tm_sec; /* 0..61 in ANSI C. */
|
|
|
|
if (years < 1970
|
|
|| months < 0 || months > 11
|
|
|| days < 0
|
|
|| days >= (months == 11? 365 : ydays[months + 1]) - ydays[months]
|
|
+ (months == 1 && leap(years))
|
|
|| hours < 0 || hours > 23
|
|
|| minutes < 0 || minutes > 59
|
|
|| seconds < 0 || seconds > 61)
|
|
return -1;
|
|
|
|
/* Set `days' to the number of days into the year. */
|
|
days += ydays[months] + (months > 1 && leap(years));
|
|
tm->tm_yday = days;
|
|
|
|
/* Now set `days' to the number of days since Jan 1, 1970. */
|
|
days += 365 * (years - 1970) + nleap(years);
|
|
tm->tm_wday = (days + 4) % 7; /* Jan 1, 1970 was Thursday. */
|
|
/* tm->tm_isdst = 0; */
|
|
|
|
return (time_t)(86400L * (unsigned long)days + 3600L * (unsigned long)hours +
|
|
(unsigned long)(60 * minutes + seconds));
|
|
}
|
|
|
|
#endif /* !ZIP || !NO_MKTIME */
|
|
|
|
|
|
#ifdef AZTEC_C /* SAS/C uses library gmtime() */
|
|
struct tm *gmtime(const time_t *when)
|
|
{
|
|
static struct tm tbuf; /* this function is intrinsically non-reentrant */
|
|
static short smods[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
|
long days = *when / 86400;
|
|
long secs = *when % 86400;
|
|
short yell, yday;
|
|
|
|
tbuf.tm_wday = (days + 4) % 7; /* 1/1/70 is a Thursday */
|
|
tbuf.tm_year = 70 + 4 * (days / 1461);
|
|
yday = days % 1461;
|
|
while (yday >= (yell = (tbuf.tm_year & 3 ? 365 : 366)))
|
|
yday -= yell, tbuf.tm_year++;
|
|
smods[1] = (tbuf.tm_year & 3 ? 28 : 29);
|
|
tbuf.tm_mon = 0;
|
|
tbuf.tm_yday = yday;
|
|
while (yday >= smods[tbuf.tm_mon])
|
|
yday -= smods[tbuf.tm_mon++];
|
|
tbuf.tm_mday = yday + 1;
|
|
tbuf.tm_isdst = 0;
|
|
tbuf.tm_sec = secs % 60;
|
|
tbuf.tm_min = (secs / 60) % 60;
|
|
tbuf.tm_hour = secs / 3600;
|
|
#ifdef AZTEC_C
|
|
tbuf.tm_hsec = 0;
|
|
#endif
|
|
return &tbuf;
|
|
}
|
|
#endif /* AZTEC_C */
|
|
|
|
|
|
#ifdef AZTEC_C /* SAS/C uses library localtime() */
|
|
struct tm *localtime(const time_t *when)
|
|
{
|
|
struct tm *t;
|
|
time_t localwhen;
|
|
int dst = FALSE, sundays, lastweekday;
|
|
|
|
tzset();
|
|
localwhen = *when - timezone;
|
|
t = gmtime(&localwhen);
|
|
/* So far we support daylight savings correction by the USA rule only: */
|
|
if (daylight && t->tm_mon >= 3 && t->tm_mon <= 9) {
|
|
if (t->tm_mon > 3 && t->tm_mon < 9) /* May Jun Jul Aug Sep: yes */
|
|
dst = TRUE;
|
|
else {
|
|
sundays = (t->tm_mday + 6 - t->tm_wday) / 7;
|
|
if (t->tm_wday == 0 && t->tm_hour < 2 && sundays)
|
|
sundays--; /* a Sunday does not count until 2:00am */
|
|
if (t->tm_mon == 3 && sundays > 0) /* first sunday in April */
|
|
dst = TRUE;
|
|
else if (t->tm_mon == 9) {
|
|
lastweekday = (t->tm_wday + 31 - t->tm_mday) % 7;
|
|
if (sundays < (37 - lastweekday) / 7)
|
|
dst = TRUE; /* last sunday in October */
|
|
}
|
|
}
|
|
if (dst) {
|
|
localwhen += 3600;
|
|
t = gmtime(&localwhen); /* crude but effective */
|
|
t->tm_isdst = 1;
|
|
}
|
|
}
|
|
return t;
|
|
}
|
|
#endif /* AZTEC_C */
|
|
|
|
|
|
#ifdef AZTEC_C /* SAS/C uses library gmtime() */
|
|
#ifdef ZIP
|
|
time_t time(time_t *tp)
|
|
{
|
|
time_t t;
|
|
struct DateStamp ds;
|
|
DateStamp(&ds);
|
|
t = ds.ds_Tick / TICKS_PER_SECOND + ds.ds_Minute * 60
|
|
+ (ds.ds_Days + 2922) * 86400;
|
|
t = mktime(gmtime(&t));
|
|
/* gmtime leaves ds in the local timezone, mktime converts it to GMT */
|
|
if (tp) *tp = t;
|
|
return t;
|
|
}
|
|
#endif /* ZIP */
|
|
#endif /* AZTEC_C */
|
|
|
|
#endif /* !FUNZIP */
|
|
|
|
|
|
#if CRYPT || !defined(FUNZIP)
|
|
|
|
/* sendpkt.c
|
|
* by A. Finkel, P. Lindsay, C. Sheppner
|
|
* returns Res1 of the reply packet
|
|
*/
|
|
/*
|
|
#include <exec/types.h>
|
|
#include <exec/memory.h>
|
|
#include <libraries/dos.h>
|
|
#include <libraries/dosextens.h>
|
|
#include <proto/exec.h>
|
|
#include <proto/dos.h>
|
|
*/
|
|
|
|
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
|
|
|
|
LONG sendpkt(pid,action,args,nargs)
|
|
struct MsgPort *pid; /* process identifier (handler message port) */
|
|
LONG action, /* packet type (desired action) */
|
|
*args, /* a pointer to argument list */
|
|
nargs; /* number of arguments in list */
|
|
{
|
|
|
|
struct MsgPort *replyport, *CreatePort(UBYTE *, long);
|
|
void DeletePort(struct MsgPort *);
|
|
struct StandardPacket *packet;
|
|
LONG count, *pargs, res1;
|
|
|
|
replyport = CreatePort(NULL,0L);
|
|
if( !replyport ) return(0);
|
|
|
|
packet = (struct StandardPacket *)AllocMem(
|
|
(long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
|
|
if( !packet )
|
|
{
|
|
DeletePort(replyport);
|
|
return(0);
|
|
}
|
|
|
|
packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt);
|
|
packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
|
|
packet->sp_Pkt.dp_Port = replyport;
|
|
packet->sp_Pkt.dp_Type = action;
|
|
|
|
/* copy the args into the packet */
|
|
pargs = &(packet->sp_Pkt.dp_Arg1); /* address of 1st argument */
|
|
for( count=0; count<nargs; count++ )
|
|
pargs[count] = args[count];
|
|
|
|
PutMsg(pid,(struct Message *)packet); /* send packet */
|
|
|
|
WaitPort(replyport);
|
|
GetMsg(replyport);
|
|
|
|
res1 = packet->sp_Pkt.dp_Res1;
|
|
|
|
FreeMem((char *)packet,(long)sizeof(*packet));
|
|
DeletePort(replyport);
|
|
|
|
return(res1);
|
|
|
|
} /* sendpkt() */
|
|
|
|
#endif /* CRYPT || !FUNZIP */
|
|
|
|
|
|
#if CRYPT || (defined(UNZIP) && !defined(FUNZIP))
|
|
|
|
/* Agetch() reads one raw keystroke -- uses sendpkt() */
|
|
|
|
int Agetch(void)
|
|
{
|
|
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
|
|
struct Task *me = FindTask(NULL);
|
|
struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI);
|
|
BPTR fh = cli->cli_StandardInput; /* this is immune to < redirection */
|
|
void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type;
|
|
char longspace[8];
|
|
long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */
|
|
UBYTE c;
|
|
|
|
*flag = 1;
|
|
sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); /* assume success */
|
|
Read(fh, &c, 1);
|
|
*flag = 0;
|
|
sendpkt(conp, ACTION_SCREEN_MODE, flag, 1);
|
|
if (c == 3) /* ^C in input */
|
|
Signal(me, SIGBREAKF_CTRL_C);
|
|
return c;
|
|
}
|
|
|
|
#endif /* CRYPT || (UNZIP && !FUNZIP) */
|