home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / zip21.zip / amiga / stat.c < prev    next >
C/C++ Source or Header  |  1996-04-18  |  8KB  |  268 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. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <libraries/dos.h>
  16. #include <libraries/dosextens.h>
  17. #ifdef AZTEC_C
  18. #  include <clib/exec_protos.h>
  19. #  include <clib/dos_protos.h>
  20. #  include <pragmas/exec_lib.h>
  21. #  include <pragmas/dos_lib.h>
  22. #  include "amiga/z-stat.h"             /* fake version of stat.h */
  23. #else
  24. #  include <sys/types.h>
  25. #  include <sys/stat.h>
  26. #  include <proto/exec.h>
  27. #  include <proto/dos.h>
  28. #endif
  29. #include <string.h>
  30.  
  31. #ifndef SUCCESS
  32. #  define SUCCESS (-1)
  33. #  define FAILURE (0)
  34. #endif
  35.  
  36. extern int stat(char *file,struct stat *buf);
  37.  
  38. stat(file,buf)
  39. char *file;
  40. struct stat *buf;
  41. {
  42.  
  43.         struct FileInfoBlock *inf;
  44.         BPTR lock;
  45.         long ftime;
  46.         void tzset(void);
  47.  
  48.         if( (lock = Lock(file,SHARED_LOCK))==0 )
  49.                 /* file not found */
  50.                 return(-1);
  51.  
  52.         if( !(inf = (struct FileInfoBlock *)AllocMem(
  53.                 (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
  54.         {
  55.                 UnLock(lock);
  56.                 return(-1);
  57.         }
  58.  
  59.         if( Examine(lock,inf)==FAILURE )
  60.         {
  61.                 FreeMem((char *)inf,(long)sizeof(*inf));
  62.                 UnLock(lock);
  63.                 return(-1);
  64.         }
  65.  
  66.         /* fill in buf */
  67.         buf->st_dev         =
  68.         buf->st_nlink       =
  69.         buf->st_uid         =
  70.         buf->st_gid         =
  71.         buf->st_rdev        = 0;
  72.         
  73.         buf->st_ino         = inf->fib_DiskKey;
  74.         buf->st_blocks      = inf->fib_NumBlocks;
  75.         buf->st_size        = inf->fib_Size;
  76.  
  77.         /* now the date.  AmigaDOS has weird datestamps---
  78.          *      ds_Days is the number of days since 1-1-1978;
  79.          *      however, as Unix wants date since 1-1-1970...
  80.          */
  81.  
  82.         ftime =
  83.                 (inf->fib_Date.ds_Days * 86400 )                +
  84.                 (inf->fib_Date.ds_Minute * 60 )                 +
  85.                 (inf->fib_Date.ds_Tick / TICKS_PER_SECOND )     +
  86.                 (86400 * 8 * 365 )                              +
  87.                 (86400 * 2 );  /* two leap years */
  88.  
  89.         tzset();
  90.         ftime += timezone;
  91.  
  92.         buf->st_ctime =
  93.         buf->st_atime =
  94.         buf->st_mtime = ftime;
  95.  
  96.         buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR);
  97.  
  98.         /* lastly, throw in the protection bits */
  99.         buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF);
  100.  
  101.         FreeMem((char *)inf, (long)sizeof(*inf));
  102.         UnLock((BPTR)lock);
  103.  
  104.         return(0);
  105.  
  106. }
  107.  
  108.  
  109. /* opendir(), readdir(), closedir() and rmdir() by Paul Kienitz. */
  110.  
  111. unsigned short disk_not_mounted;
  112. static DIR *dir_cleanup_list = NULL;    /* for resource tracking */
  113.  
  114.  
  115. DIR *opendir(char *path)
  116. {
  117.     DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC);
  118.     if (!dd) return NULL;
  119.     if (!(dd->d_parentlock = Lock(path, MODE_OLDFILE))) {
  120.         disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED;
  121.         FreeMem(dd, sizeof(DIR));
  122.         return NULL;
  123.     } else
  124.         disk_not_mounted = 0;
  125.     if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) {
  126.         UnLock(dd->d_parentlock);
  127.         FreeMem(dd, sizeof(DIR));
  128.         return NULL;
  129.     }
  130.     dd->d_cleanuplink = dir_cleanup_list;       /* track them resources */
  131.     if (dir_cleanup_list)
  132.         dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink;
  133.     dd->d_cleanupparent = &dir_cleanup_list;
  134.     dir_cleanup_list = dd;
  135.     return dd;
  136. }
  137.  
  138. void closedir(DIR *dd)
  139. {
  140.     if (dd) {
  141.         if (dd->d_cleanuplink)
  142.             dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent;
  143.         *(dd->d_cleanupparent) = dd->d_cleanuplink;
  144.         if (dd->d_parentlock)
  145.             UnLock(dd->d_parentlock);
  146.         FreeMem(dd, sizeof(DIR));
  147.     }
  148. }
  149.  
  150. /* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */
  151. void close_leftover_open_dirs(void)
  152. {
  153.     while (dir_cleanup_list)
  154.         closedir(dir_cleanup_list);
  155. }
  156.  
  157. struct dirent *readdir(DIR *dd)
  158. {
  159.     return (ExNext(dd->d_parentlock, &dd->d_fib) ? (struct dirent *)dd : NULL);
  160. }
  161.  
  162. int rmdir(char *path)
  163. {
  164.     return (DeleteFile(path) ? 0 : IoErr());
  165. }
  166.  
  167.  
  168. int chmod(char *filename, int bits)     /* bits are as for st_mode */
  169. {
  170.     long protmask = (bits & 0xFF) ^ 0xF;
  171.     return !SetProtection(filename, protmask);
  172. }
  173.  
  174.  
  175. #ifdef AZTEC_C
  176.  
  177. /* This here removes unnecessary bulk from the executable with Aztec: */
  178. void _wb_parse(void)  { }
  179.  
  180. /* fake a unix function that does not apply to amigados: */
  181. int umask(void)  { return 0; }
  182.  
  183.  
  184. #  include <signal.h>
  185.  
  186. /* C library signal() messes up debugging yet adds no actual usefulness */
  187. typedef void (*__signal_return_type)(int);
  188. __signal_return_type signal()  { return SIG_ERR; }
  189.  
  190.  
  191. /* The following replaces Aztec's argv-parsing function for compatibility with
  192. the standard AmigaDOS handling of *E, *N, and *".  It also fixes the problem
  193. the standard _cli_parse() has of accepting only lower-ascii characters. */
  194.  
  195. int _argc, _arg_len;
  196. char **_argv, *_arg_lin;
  197.  
  198. void _cli_parse(struct Process *pp, long alen, register UBYTE *aptr)
  199. {
  200.     register UBYTE *cp;
  201.     register struct CommandLineInterface *cli;
  202.     register short c;
  203.     register short starred = 0;
  204. #  ifdef PRESTART_HOOK
  205.     void Prestart_Hook(void);
  206. #  endif
  207.  
  208.     cli = (struct CommandLineInterface *) (pp->pr_CLI << 2);
  209.     cp = (UBYTE *) (cli->cli_CommandName << 2);
  210.     _arg_len = cp[0] + alen + 2;
  211.     if (!(_arg_lin = AllocMem((long) _arg_len, 0L)))
  212.         return;
  213.     c = cp[0];
  214.     strncpy(_arg_lin, cp + 1, c);
  215.     _arg_lin[c] = 0;
  216.     for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--)
  217.         *cp++ = *aptr++;
  218.     *cp = 0;
  219.     aptr = cp = _arg_lin + c + 1;
  220.     for (_argc = 1; ; _argc++) {
  221.         while (*cp == ' ' || *cp == '\t')
  222.             cp++;
  223.         if (!*cp)
  224.             break;
  225.         if (*cp == '"') {
  226.             cp++;
  227.             while (c = *cp++) {
  228.                 if (starred) {
  229.                     if (c | 0x20 == 'n')
  230.                         *aptr++ = '\n';
  231.                     else if (c | 0x20 == 'e')
  232.                         *aptr++ = 27;
  233.                     else
  234.                         *aptr++ = c;
  235.                     starred = 0;
  236.                 } else if (c == '"') {  
  237.                     *aptr++ = 0;
  238.                     break;
  239.                 } else if (c == '*')
  240.                     starred = 1;
  241.                 else
  242.                     *aptr++ = c;
  243.             }
  244.         } else {
  245.             while ((c = *cp++) && c != ' ' && c != '\t')
  246.                 *aptr++ = c;
  247.             *aptr++ = 0;
  248.         }
  249.         if (c == 0)
  250.             --cp;
  251.     }
  252.     *aptr = 0;
  253.     if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) {
  254.         _argc = 0;
  255.         return;
  256.     }
  257.     for (c = 0, cp = _arg_lin; c < _argc; c++) {
  258.         _argv[c] = cp;
  259.         cp += strlen(cp) + 1;
  260.     }
  261.     _argv[c] = NULL;
  262. #  ifdef PRESTART_HOOK
  263.     Prestart_Hook();
  264. #  endif
  265. }
  266.  
  267. #endif /* AZTEC_C */
  268.