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