which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			286 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* Here we have a handmade stat() function because Aztec's c.lib stat() */
 | |
| /* does not support an st_mode field, which we need... also a chmod().  */
 | |
| 
 | |
| /* This stat() is by Paul Wells, modified by Paul Kienitz. */
 | |
| /* for use with Aztec C >= 5.0 and Lattice C <= 4.01  */
 | |
| 
 | |
| /* POLICY DECISION: We will not attempt to remove global variables from */
 | |
| /* this source file for Aztec C.  These routines are essentially just   */
 | |
| /* augmentations of Aztec's c.lib, which is itself not reentrant.  If   */
 | |
| /* we want to produce a fully reentrant UnZip, we will have to use a    */
 | |
| /* suitable startup module, such as purify.a for Aztec by Paul Kienitz. */
 | |
| 
 | |
| #ifndef __amiga_stat_c
 | |
| #define __amiga_stat_c
 | |
| 
 | |
| #ifdef AZTEC_C
 | |
| #  include <exec/types.h>
 | |
| #  include <exec/memory.h>
 | |
| #  include <libraries/dos.h>
 | |
| #  include <libraries/dosextens.h>
 | |
| #  include <clib/exec_protos.h>
 | |
| #  include <clib/dos_protos.h>
 | |
| #  include <pragmas/exec_lib.h>
 | |
| #  include <pragmas/dos_lib.h>
 | |
| #  include "amiga/z-stat.h"             /* fake version of stat.h */
 | |
| #  include <string.h>
 | |
| #else /* __SASC */
 | |
| /* Uncomment define of USE_REPLACEMENTS to use the directory functions below */
 | |
| /* #define USE_REPLACEMENTS */
 | |
| #  include <sys/stat.h>
 | |
| #  ifndef USE_REPLACEMENTS
 | |
| #     include <sys/dir.h>               /* SAS/C dir function prototypes */
 | |
| #     include <dos.h>
 | |
| #  else
 | |
| #     include <exec/types.h>
 | |
| #     include <exec/memory.h>
 | |
| #     include <sys/types.h>
 | |
| #     include <proto/exec.h>
 | |
| #     include <proto/dos.h>
 | |
| #     include <string.h>
 | |
| #  endif
 | |
| #endif
 | |
| 
 | |
| #ifndef SUCCESS
 | |
| #  define SUCCESS (-1)
 | |
| #  define FAILURE (0)
 | |
| #endif
 | |
| 
 | |
| 
 | |
| void close_leftover_open_dirs(void);    /* prototype */
 | |
| 
 | |
| static DIR *dir_cleanup_list = NULL;    /* for resource tracking */
 | |
| 
 | |
| /* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */
 | |
| void close_leftover_open_dirs(void)
 | |
| {
 | |
|     while (dir_cleanup_list)
 | |
|         closedir(dir_cleanup_list);
 | |
| }
 | |
| 
 | |
| #if defined(AZTEC_C) || defined(USE_REPLACEMENTS)
 | |
| 
 | |
| unsigned short disk_not_mounted;
 | |
| 
 | |
| extern int stat(char *file,struct stat *buf);
 | |
| 
 | |
| stat(file,buf)
 | |
| char *file;
 | |
| struct stat *buf;
 | |
| {
 | |
| 
 | |
|         struct FileInfoBlock *inf;
 | |
|         BPTR lock;
 | |
|         long ftime;
 | |
|         void tzset(void);
 | |
| 
 | |
|         if( (lock = Lock(file,SHARED_LOCK))==0 )
 | |
|                 /* file not found */
 | |
|                 return(-1);
 | |
| 
 | |
|         if( !(inf = (struct FileInfoBlock *)AllocMem(
 | |
|                 (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
 | |
|         {
 | |
|                 UnLock(lock);
 | |
|                 return(-1);
 | |
|         }
 | |
| 
 | |
|         if( Examine(lock,inf)==FAILURE )
 | |
|         {
 | |
|                 FreeMem((char *)inf,(long)sizeof(*inf));
 | |
|                 UnLock(lock);
 | |
|                 return(-1);
 | |
|         }
 | |
| 
 | |
|         /* fill in buf */
 | |
|         buf->st_dev         =
 | |
|         buf->st_nlink       =
 | |
|         buf->st_uid         =
 | |
|         buf->st_gid         =
 | |
|         buf->st_rdev        = 0;
 | |
|         buf->st_ino         = inf->fib_DiskKey;
 | |
|         buf->st_blocks      = inf->fib_NumBlocks;
 | |
|         buf->st_size        = inf->fib_Size;
 | |
| 
 | |
|         /* now the date.  AmigaDOS has weird datestamps---
 | |
|          *      ds_Days is the number of days since 1-1-1978;
 | |
|          *      however, as Unix wants date since 1-1-1970...
 | |
|          */
 | |
| 
 | |
|         ftime =
 | |
|                 (inf->fib_Date.ds_Days * 86400 )                +
 | |
|                 (inf->fib_Date.ds_Minute * 60 )                 +
 | |
|                 (inf->fib_Date.ds_Tick / TICKS_PER_SECOND )     +
 | |
|                 (86400 * 8 * 365 )                              +
 | |
|                 (86400 * 2 );  /* two leap years */
 | |
| 
 | |
|         tzset();
 | |
|         ftime += timezone;
 | |
| 
 | |
|         buf->st_ctime =
 | |
|         buf->st_atime =
 | |
|         buf->st_mtime = ftime;
 | |
| 
 | |
|         buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR);
 | |
| 
 | |
|         /* lastly, throw in the protection bits */
 | |
|         buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF);
 | |
| 
 | |
|         FreeMem((char *)inf, (long)sizeof(*inf));
 | |
|         UnLock((BPTR)lock);
 | |
| 
 | |
|         return(0);
 | |
| 
 | |
| }
 | |
| 
 | |
| /* opendir(), readdir(), closedir() and rmdir() by Paul Kienitz. */
 | |
| 
 | |
| DIR *opendir(char *path)
 | |
| {
 | |
|     DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC);
 | |
|     if (!dd) return NULL;
 | |
|     if (!(dd->d_parentlock = Lock(path, MODE_OLDFILE))) {
 | |
|         disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED;
 | |
|         FreeMem(dd, sizeof(DIR));
 | |
|         return NULL;
 | |
|     } else
 | |
|         disk_not_mounted = 0;
 | |
|     if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) {
 | |
|         UnLock(dd->d_parentlock);
 | |
|         FreeMem(dd, sizeof(DIR));
 | |
|         return NULL;
 | |
|     }
 | |
|     dd->d_cleanuplink = dir_cleanup_list;       /* track them resources */
 | |
|     if (dir_cleanup_list)
 | |
|         dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink;
 | |
|     dd->d_cleanupparent = &dir_cleanup_list;
 | |
|     dir_cleanup_list = dd;
 | |
|     return dd;
 | |
| }
 | |
| 
 | |
| void closedir(DIR *dd)
 | |
| {
 | |
|     if (dd) {
 | |
|         if (dd->d_cleanuplink)
 | |
|             dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent;
 | |
|         *(dd->d_cleanupparent) = dd->d_cleanuplink;
 | |
|         if (dd->d_parentlock)
 | |
|             UnLock(dd->d_parentlock);
 | |
|         FreeMem(dd, sizeof(DIR));
 | |
|     }
 | |
| }
 | |
| 
 | |
| struct dirent *readdir(DIR *dd)
 | |
| {
 | |
|     return (ExNext(dd->d_parentlock, &dd->d_fib) ? (struct dirent *)dd : NULL);
 | |
| }
 | |
| 
 | |
| 
 | |
| int rmdir(char *path)
 | |
| {
 | |
|     return (DeleteFile(path) ? 0 : IoErr());
 | |
| }
 | |
| 
 | |
| 
 | |
| int chmod(char *filename, int bits)     /* bits are as for st_mode */
 | |
| {
 | |
|     long protmask = (bits & 0xFF) ^ 0xF;
 | |
|     return !SetProtection(filename, protmask);
 | |
| }
 | |
| 
 | |
| #endif /* AZTEC_C || USE_REPLACEMENTS */
 | |
| 
 | |
| #ifdef AZTEC_C
 | |
| 
 | |
| /* This here removes unnecessary bulk from the executable with Aztec: */
 | |
| void _wb_parse(void)  { }
 | |
| 
 | |
| /* fake a unix function that does not apply to amigados: */
 | |
| int umask(void)  { return 0; }
 | |
| 
 | |
| 
 | |
| #  include <signal.h>
 | |
| 
 | |
| /* C library signal() messes up debugging yet adds no actual usefulness */
 | |
| typedef void (*__signal_return_type)(int);
 | |
| __signal_return_type signal()  { return SIG_ERR; }
 | |
| 
 | |
| 
 | |
| /* The following replaces Aztec's argv-parsing function for compatibility with
 | |
| Unix-like syntax used on other platforms.  It also fixes the problem the
 | |
| standard _cli_parse() has of accepting only lower-ascii characters. */
 | |
| 
 | |
| int _argc, _arg_len;
 | |
| char **_argv, *_arg_lin;
 | |
| 
 | |
| void _cli_parse(struct Process *pp, long alen, register UBYTE *aptr)
 | |
| {
 | |
|     register UBYTE *cp;
 | |
|     register struct CommandLineInterface *cli;
 | |
|     register short c;
 | |
|     register short starred = 0;
 | |
| #  ifdef PRESTART_HOOK
 | |
|     void Prestart_Hook(void);
 | |
| #  endif
 | |
| 
 | |
|     cli = (struct CommandLineInterface *) (pp->pr_CLI << 2);
 | |
|     cp = (UBYTE *) (cli->cli_CommandName << 2);
 | |
|     _arg_len = cp[0] + alen + 2;
 | |
|     if (!(_arg_lin = AllocMem((long) _arg_len, 0L)))
 | |
|         return;
 | |
|     c = cp[0];
 | |
|     strncpy(_arg_lin, cp + 1, c);
 | |
|     _arg_lin[c] = 0;
 | |
|     for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--)
 | |
|         *cp++ = *aptr++;
 | |
|     *cp = 0;
 | |
|     aptr = cp = _arg_lin + c + 1;
 | |
|     for (_argc = 1; ; _argc++) {
 | |
|         while (*cp == ' ' || *cp == '\t')
 | |
|             cp++;
 | |
|         if (!*cp)
 | |
|             break;
 | |
|         if (*cp == '"') {
 | |
|             cp++;
 | |
|             while (c = *cp++) {
 | |
|                 if (c == '"' && !starred) {
 | |
|                     *aptr++ = 0;
 | |
|                     starred = 0;
 | |
|                     break;
 | |
|                 } else if (c == '\\' && !starred)
 | |
|                     starred = 1;
 | |
|                 else {
 | |
|                     *aptr++ = c;
 | |
|                     starred = 0;
 | |
|                 }
 | |
|             }
 | |
|         } else {
 | |
|             while ((c = *cp++) && c != ' ' && c != '\t')
 | |
|                 *aptr++ = c;
 | |
|             *aptr++ = 0;
 | |
|         }
 | |
|         if (c == 0)
 | |
|             --cp;
 | |
|     }
 | |
|     *aptr = 0;
 | |
|     if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) {
 | |
|         _argc = 0;
 | |
|         return;
 | |
|     }
 | |
|     for (c = 0, cp = _arg_lin; c < _argc; c++) {
 | |
|         _argv[c] = cp;
 | |
|         cp += strlen(cp) + 1;
 | |
|     }
 | |
|     _argv[c] = NULL;
 | |
| #  ifdef PRESTART_HOOK
 | |
|     Prestart_Hook();
 | |
| #  endif
 | |
| }
 | |
| 
 | |
| #endif /* AZTEC_C */
 | |
| /* remove local define */
 | |
| #ifdef USE_REPLACEMENTS
 | |
| #   undef USE_REPLACEMENTS
 | |
| #endif
 | |
| #endif /* __amiga_stat_c */
 |