Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.   Copyright (c) 1990-2000 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. /* Here we have a handmade stat() function because Aztec's c.lib stat() */
  10. /* does not support an st_mode field, which we need... also a chmod().  */
  11.  
  12. /* This stat() is by Paul Wells, modified by Paul Kienitz. */
  13. /* Originally for use with Aztec C >= 5.0 and Lattice C <= 4.01  */
  14. /* Adapted for SAS/C 6.5x by Haidinger Walter */
  15.  
  16. /* POLICY DECISION: We will not attempt to remove global variables from */
  17. /* this source file for Aztec C.  These routines are essentially just   */
  18. /* augmentations of Aztec's c.lib, which is itself not reentrant.  If   */
  19. /* we want to produce a fully reentrant UnZip, we will have to use a    */
  20. /* suitable startup module, such as purify.a for Aztec by Paul Kienitz. */
  21.  
  22. #ifndef __amiga_stat_c
  23. #define __amiga_stat_c
  24.  
  25. #include <exec/types.h>
  26. #include <exec/memory.h>
  27. #include "amiga/z-stat.h"             /* fake version of stat.h */
  28. #include <string.h>
  29.  
  30. #ifdef AZTEC_C
  31. #  include <libraries/dos.h>
  32. #  include <libraries/dosextens.h>
  33. #  include <clib/exec_protos.h>
  34. #  include <clib/dos_protos.h>
  35. #  include <pragmas/exec_lib.h>
  36. #  include <pragmas/dos_lib.h>
  37. #endif
  38. #ifdef __SASC
  39. #  include <sys/dir.h>               /* SAS/C dir function prototypes */
  40. #  include <sys/types.h>
  41. #  include <proto/exec.h>
  42. #  include <proto/dos.h>
  43. #endif
  44.  
  45. #ifndef SUCCESS
  46. #  define SUCCESS (-1)
  47. #  define FAILURE (0)
  48. #endif
  49.  
  50.  
  51. void close_leftover_open_dirs(void);    /* prototype */
  52.  
  53. static DIR *dir_cleanup_list = NULL;    /* for resource tracking */
  54.  
  55. /* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */
  56. void close_leftover_open_dirs(void)
  57. {
  58.     while (dir_cleanup_list)
  59.         closedir(dir_cleanup_list);
  60. }
  61.  
  62.  
  63. unsigned short disk_not_mounted;
  64.  
  65. extern int stat(const char *file, struct stat *buf);
  66.  
  67. stat(file,buf)
  68. const char *file;
  69. struct stat *buf;
  70. {
  71.  
  72.         struct FileInfoBlock *inf;
  73.         BPTR lock;
  74.         time_t ftime;
  75.         struct tm local_tm;
  76.  
  77.         if( (lock = Lock((char *)file,SHARED_LOCK))==0 )
  78.                 /* file not found */
  79.                 return(-1);
  80.  
  81.         if( !(inf = (struct FileInfoBlock *)AllocMem(
  82.                 (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
  83.         {
  84.                 UnLock(lock);
  85.                 return(-1);
  86.         }
  87.  
  88.         if( Examine(lock,inf)==FAILURE )
  89.         {
  90.                 FreeMem((char *)inf,(long)sizeof(*inf));
  91.                 UnLock(lock);
  92.                 return(-1);
  93.         }
  94.  
  95.         /* fill in buf */
  96.         buf->st_dev         =
  97.         buf->st_nlink       =
  98.         buf->st_uid         =
  99.         buf->st_gid         =
  100.         buf->st_rdev        = 0;
  101.         buf->st_ino         = inf->fib_DiskKey;
  102.         buf->st_blocks      = inf->fib_NumBlocks;
  103.         buf->st_size        = inf->fib_Size;
  104.  
  105.         /* now the date.  AmigaDOS has weird datestamps---
  106.          *      ds_Days is the number of days since 1-1-1978;
  107.          *      however, as Unix wants date since 1-1-1970...
  108.          */
  109.  
  110.         ftime =
  111.                 (inf->fib_Date.ds_Days * 86400 )                +
  112.                 (inf->fib_Date.ds_Minute * 60 )                 +
  113.                 (inf->fib_Date.ds_Tick / TICKS_PER_SECOND )     +
  114.                 (86400 * 8 * 365 )                              +
  115.                 (86400 * 2 );  /* two leap years */
  116.  
  117.         /* tzset(); */  /* this should be handled by mktime(), instead */
  118.         /* ftime += timezone; */
  119.         local_tm = *gmtime(&ftime);
  120.         local_tm.tm_isdst = -1;
  121.         ftime = mktime(&local_tm);
  122.  
  123.         buf->st_ctime =
  124.         buf->st_atime =
  125.         buf->st_mtime = ftime;
  126.  
  127.         buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR);
  128.  
  129.         /* lastly, throw in the protection bits */
  130.         buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF);
  131.  
  132.         FreeMem((char *)inf, (long)sizeof(*inf));
  133.         UnLock((BPTR)lock);
  134.  
  135.         return(0);
  136.  
  137. }
  138.  
  139. int fstat(int handle, struct stat *buf)
  140. {
  141.     /* fake some reasonable values for stdin */
  142.     buf->st_mode = (S_IREAD|S_IWRITE|S_IFREG);
  143.     buf->st_size = -1;
  144.     buf->st_mtime = time(&buf->st_mtime);
  145.     return 0;
  146. }
  147.  
  148.  
  149. /* opendir(), readdir(), closedir(), rmdir(), and chmod() by Paul Kienitz. */
  150.  
  151. DIR *opendir(const char *path)
  152. {
  153.     DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC);
  154.     if (!dd) return NULL;
  155.     if (!(dd->d_parentlock = Lock((char *)path, MODE_OLDFILE))) {
  156.         disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED;
  157.         FreeMem(dd, sizeof(DIR));
  158.         return NULL;
  159.     } else
  160.         disk_not_mounted = 0;
  161.     if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) {
  162.         UnLock(dd->d_parentlock);
  163.         FreeMem(dd, sizeof(DIR));
  164.         return NULL;
  165.     }
  166.     dd->d_cleanuplink = dir_cleanup_list;       /* track them resources */
  167.     if (dir_cleanup_list)
  168.         dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink;
  169.     dd->d_cleanupparent = &dir_cleanup_list;
  170.     dir_cleanup_list = dd;
  171.     return dd;
  172. }
  173.  
  174. void closedir(DIR *dd)
  175. {
  176.     if (dd) {
  177.         if (dd->d_cleanuplink)
  178.             dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent;
  179.         *(dd->d_cleanupparent) = dd->d_cleanuplink;
  180.         if (dd->d_parentlock)
  181.             UnLock(dd->d_parentlock);
  182.         FreeMem(dd, sizeof(DIR));
  183.     }
  184. }
  185.  
  186. struct dirent *readdir(DIR *dd)
  187. {
  188.     return (ExNext(dd->d_parentlock, &dd->d_fib) ? (struct dirent *)dd : NULL);
  189. }
  190.  
  191.  
  192. #ifdef AZTEC_C
  193.  
  194. int rmdir(const char *path)
  195. {
  196.     return (DeleteFile((char *)path) ? 0 : IoErr());
  197. }
  198.  
  199. int chmod(const char *filename, int bits)       /* bits are as for st_mode */
  200. {
  201.     long protmask = (bits & 0xFF) ^ 0xF;
  202.     return !SetProtection((char *)filename, protmask);
  203. }
  204.  
  205.  
  206. /* This here removes unnecessary bulk from the executable with Aztec: */
  207. void _wb_parse(void)  { }
  208.  
  209. /* fake a unix function that does not apply to amigados: */
  210. int umask(void)  { return 0; }
  211.  
  212.  
  213. #  include <signal.h>
  214.  
  215. /* C library signal() messes up debugging yet adds no actual usefulness */
  216. typedef void (*__signal_return_type)(int);
  217. __signal_return_type signal()  { return SIG_ERR; }
  218.  
  219.  
  220. /* The following replaces Aztec's argv-parsing function for compatibility with
  221. Unix-like syntax used on other platforms.  It also fixes the problem the
  222. standard _cli_parse() has of accepting only lower-ascii characters. */
  223.  
  224. int _argc, _arg_len;
  225. char **_argv, *_arg_lin;
  226.  
  227. void _cli_parse(struct Process *pp, long alen, register UBYTE *aptr)
  228. {
  229.     register UBYTE *cp;
  230.     register struct CommandLineInterface *cli;
  231.     register short c;
  232.     register short starred = 0;
  233. #  ifdef PRESTART_HOOK
  234.     void Prestart_Hook(void);
  235. #  endif
  236.  
  237.     cli = (struct CommandLineInterface *) (pp->pr_CLI << 2);
  238.     cp = (UBYTE *) (cli->cli_CommandName << 2);
  239.     _arg_len = cp[0] + alen + 2;
  240.     if (!(_arg_lin = AllocMem((long) _arg_len, 0L)))
  241.         return;
  242.     c = cp[0];
  243.     strncpy(_arg_lin, cp + 1, c);
  244.     _arg_lin[c] = 0;
  245.     for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--)
  246.         *cp++ = *aptr++;
  247.     *cp = 0;
  248.     aptr = cp = _arg_lin + c + 1;
  249.     for (_argc = 1; ; _argc++) {
  250.         while (*cp == ' ' || *cp == '\t')
  251.             cp++;
  252.         if (!*cp)
  253.             break;
  254.         if (*cp == '"') {
  255.             cp++;
  256.             while (c = *cp++) {
  257.                 if (c == '"' && !starred) {
  258.                     *aptr++ = 0;
  259.                     starred = 0;
  260.                     break;
  261.                 } else if (c == '\\' && !starred)
  262.                     starred = 1;
  263.                 else {
  264.                     *aptr++ = c;
  265.                     starred = 0;
  266.                 }
  267.             }
  268.         } else {
  269.             while ((c = *cp++) && c != ' ' && c != '\t')
  270.                 *aptr++ = c;
  271.             *aptr++ = 0;
  272.         }
  273.         if (c == 0)
  274.             --cp;
  275.     }
  276.     *aptr = 0;
  277.     if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) {
  278.         _argc = 0;
  279.         return;
  280.     }
  281.     for (c = 0, cp = _arg_lin; c < _argc; c++) {
  282.         _argv[c] = cp;
  283.         cp += strlen(cp) + 1;
  284.     }
  285.     _argv[c] = NULL;
  286. #  ifdef PRESTART_HOOK
  287.     Prestart_Hook();
  288. #  endif
  289. }
  290.  
  291. #endif /* AZTEC_C */
  292.  
  293. #endif /* __amiga_stat_c */
  294.