filedate.c 22 KB

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