home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip532.zip / amiga / stat.c < prev    next >
C/C++ Source or Header  |  1997-10-24  |  8KB  |  300 lines

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