📄 stat.c
字号:
/* Copyright (c) 1990-2000 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2000-Apr-09 or later (the contents of which are also included in zip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html*//* 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. *//* Originally for use with Aztec C >= 5.0 and Lattice C <= 4.01 *//* Adapted for SAS/C 6.5x by Haidinger Walter *//* 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#include <exec/types.h>#include <exec/memory.h>#include "amiga/z-stat.h" /* fake version of stat.h */#include <string.h>#ifdef AZTEC_C# 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>#endif#ifdef __SASC# include <sys/dir.h> /* SAS/C dir function prototypes */# include <sys/types.h># include <proto/exec.h># include <proto/dos.h>#endif#ifndef SUCCESS# define SUCCESS (-1)# define FAILURE (0)#endifvoid 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);}unsigned short disk_not_mounted;extern int stat(const char *file, struct stat *buf);stat(file,buf)const char *file;struct stat *buf;{ struct FileInfoBlock *inf; BPTR lock; time_t ftime; struct tm local_tm; if( (lock = Lock((char *)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(); */ /* this should be handled by mktime(), instead */ /* ftime += timezone; */ local_tm = *gmtime(&ftime); local_tm.tm_isdst = -1; ftime = mktime(&local_tm); 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);}int fstat(int handle, struct stat *buf){ /* fake some reasonable values for stdin */ buf->st_mode = (S_IREAD|S_IWRITE|S_IFREG); buf->st_size = -1; buf->st_mtime = time(&buf->st_mtime); return 0;}/* opendir(), readdir(), closedir(), rmdir(), and chmod() by Paul Kienitz. */DIR *opendir(const char *path){ DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC); if (!dd) return NULL; if (!(dd->d_parentlock = Lock((char *)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);}#ifdef AZTEC_Cint rmdir(const char *path){ return (DeleteFile((char *)path) ? 0 : IoErr());}int chmod(const char *filename, int bits) /* bits are as for st_mode */{ long protmask = (bits & 0xFF) ^ 0xF; return !SetProtection((char *)filename, protmask);}/* 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 withUnix-like syntax used on other platforms. It also fixes the problem thestandard _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 */#endif /* __amiga_stat_c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -