stat.c 8.2 KB

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