home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip540.zip / amiga / filedate.c < prev    next >
C/C++ Source or Header  |  1998-09-02  |  22KB  |  629 lines

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