📄 filedate.c
字号:
/* Low-level Amiga routines shared between Zip and UnZip. * * Contains: FileDate() * locale_TZ() * getenv() [Aztec C only; replaces bad C library versions] * setenv() [ditto] * 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. * 24 May 97, Haidinger Walter, added time_lib support for SAS/C and moved * set_TZ() to time_lib.c * 12 Jul 97, Paul Kienitz, adapted time_lib stuff for Aztec. * 26 Jul 97, Chr. Spieler, old mkgmtime() fixed (ydays[] def, sign vs unsign). */#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 */ /* define USE_TIME_LIB if replacement functions of time_lib are available */ /* replaced are: tzset(), time(), localtime() and gmtime() */#endif /* __SASC */#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# 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 */#ifdef AZTEC_C char *getenv(const char *var); int setenv(const char *var, const char *value, int overwrite);#endifLONG FileDate (char *filename, time_t u[]);LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);int Agetch(void);#if (!defined(ZIP) || !defined(NO_MKTIME)) && !defined(USE_TIME_LIB) time_t mkgmtime(struct tm *tm); /* use mkgmtime() from here */#else extern time_t mkgmtime(struct tm *tm); /* from mktime.c or time_lib.c */#endif/* prototypes for time replacement functions */#ifndef USE_TIME_LIB void tzset(void); int locale_TZ(void); struct tm *gmtime(const time_t *when); struct tm *localtime(const time_t *when); extern void set_TZ(long time_zone, int day_light); /* in time_lib.c */# ifdef ZIP time_t time(time_t *tp);# endif#endif /* !USE_TIME_LIB */#if 0 /* not used YET */ extern zvoid *remember_alloc OF((zvoid *memptr));#endif/* =============================================================== *//***********************//* 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. */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 AZTEC_C /* SAS/C uses library getenv() & putenv() */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; me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ if (SysBase->LibNode.lib_Version >= ReqVers) { if (GetVar((char *) var, 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((char *) var, 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -