riscos.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. Copyright (c) 1990-2002 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. /* riscos.c */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "zip.h"
  13. #include "riscos.h"
  14. #define MAXEXT 256
  15. /* External globals */
  16. extern int scanimage;
  17. /* Local globals (!?!?) */
  18. char *exts2swap = NULL; /* Extensions to swap (actually, directory names) */
  19. int stat(char *filename,struct stat *res)
  20. {
  21. int attr; /* object attributes */
  22. unsigned int load; /* load address */
  23. unsigned int exec; /* exec address */
  24. int type; /* type: 0 not found, 1 file, 2 dir, 3 image */
  25. if (!res)
  26. return -1;
  27. if (SWI_OS_File_5(filename,&type,&load,&exec,(int *)&res->st_size,&attr)!=NULL)
  28. return -1;
  29. if (type==0)
  30. return -1;
  31. res->st_dev=0;
  32. res->st_ino=0;
  33. res->st_nlink=0;
  34. res->st_uid=1;
  35. res->st_gid=1;
  36. res->st_rdev=0;
  37. res->st_blksize=1024;
  38. res->st_mode = ((attr & 0001) << 8) | ((attr & 0002) << 6) |
  39. ((attr & 0020) >> 2) | ((attr & 0040) >> 4);
  40. switch (type) {
  41. case 1: /* File */
  42. res->st_mode |= S_IFREG;
  43. break;
  44. case 2: /* Directory */
  45. res->st_mode |= S_IFDIR | 0700;
  46. break;
  47. case 3: /* Image file */
  48. if (scanimage)
  49. res->st_mode |= S_IFDIR | 0700;
  50. else
  51. res->st_mode |= S_IFREG;
  52. break;
  53. }
  54. if ((((unsigned int) load) >> 20) == 0xfff) { /* date stamped file */
  55. unsigned int t1, t2, tc;
  56. t1 = (unsigned int) (exec);
  57. t2 = (unsigned int) (load & 0xff);
  58. tc = 0x6e996a00U;
  59. if (t1 < tc)
  60. t2--;
  61. t1 -= tc;
  62. t2 -= 0x33; /* 00:00:00 Jan. 1 1970 = 0x336e996a00 */
  63. t1 = (t1 / 100) + (t2 * 42949673U); /* 0x100000000 / 100 = 42949672.96 */
  64. t1 -= (t2 / 25); /* compensate for .04 error */
  65. res->st_atime = res->st_mtime = res->st_ctime = t1;
  66. }
  67. else
  68. res->st_atime = res->st_mtime = res->st_ctime = 0;
  69. return 0;
  70. }
  71. #ifndef SFX
  72. DIR *opendir(char *dirname)
  73. {
  74. DIR *thisdir;
  75. int type;
  76. int attr;
  77. os_error *er;
  78. thisdir=(DIR *)malloc(sizeof(DIR));
  79. if (thisdir==NULL)
  80. return NULL;
  81. thisdir->dirname=(char *)malloc(strlen(dirname)+1);
  82. if (thisdir->dirname==NULL) {
  83. free(thisdir);
  84. return NULL;
  85. }
  86. strcpy(thisdir->dirname,dirname);
  87. if (thisdir->dirname[strlen(thisdir->dirname)-1]=='.')
  88. thisdir->dirname[strlen(thisdir->dirname)-1]=0;
  89. if (er=SWI_OS_File_5(thisdir->dirname,&type,NULL,NULL,NULL,&attr),er!=NULL ||
  90. type<=1 || (type==3 && !scanimage))
  91. {
  92. free(thisdir->dirname);
  93. free(thisdir);
  94. return NULL;
  95. }
  96. thisdir->buf=malloc(DIR_BUFSIZE);
  97. if (thisdir->buf==NULL) {
  98. free(thisdir->dirname);
  99. free(thisdir);
  100. return NULL;
  101. }
  102. thisdir->size=DIR_BUFSIZE;
  103. thisdir->offset=0;
  104. thisdir->read=0;
  105. return thisdir;
  106. }
  107. struct dirent *readdir(DIR *d)
  108. {
  109. static struct dirent dent;
  110. if (d->read==0) { /* no more objects read in the buffer */
  111. if (d->offset==-1) { /* no more objects to read */
  112. return NULL;
  113. }
  114. d->read=255;
  115. if (SWI_OS_GBPB_9(d->dirname,d->buf,&d->read,&d->offset,DIR_BUFSIZE,NULL)!=NULL)
  116. return NULL;
  117. if (d->read==0) {
  118. d->offset=-1;
  119. return NULL;
  120. }
  121. d->read--;
  122. d->act=(char *)d->buf;
  123. }
  124. else { /* some object is ready in buffer */
  125. d->read--;
  126. d->act=(char *)(d->act+strlen(d->act)+1);
  127. }
  128. strcpy(dent.d_name,d->act);
  129. dent.d_namlen=strlen(dent.d_name);
  130. return &dent;
  131. }
  132. void closedir(DIR *d)
  133. {
  134. if (d->buf!=NULL)
  135. free(d->buf);
  136. if (d->dirname!=NULL)
  137. free(d->dirname);
  138. free(d);
  139. }
  140. int unlink(f)
  141. char *f; /* file to delete */
  142. /* Delete the file *f, returning non-zero on failure. */
  143. {
  144. os_error *er;
  145. char canon[256];
  146. int size=255;
  147. er=SWI_OS_FSControl_37(f,canon,&size);
  148. if (er==NULL) {
  149. er=SWI_OS_FSControl_27(canon,0x100);
  150. }
  151. else {
  152. er=SWI_OS_FSControl_27(f,0x100);
  153. }
  154. return (int)er;
  155. }
  156. int deletedir(char *d)
  157. {
  158. int objtype;
  159. char *s;
  160. int len;
  161. os_error *er;
  162. len = strlen(d);
  163. if ((s = malloc(len + 1)) == NULL)
  164. return -1;
  165. strcpy(s,d);
  166. if (s[len-1]=='.')
  167. s[len-1]=0;
  168. if (er=SWI_OS_File_5(s,&objtype,NULL,NULL,NULL,NULL),er!=NULL) {
  169. free(s);
  170. return -1;
  171. }
  172. if (objtype<2 || (!scanimage && objtype==3)) {
  173. /* this is a file or it doesn't exist */
  174. free(s);
  175. return -1;
  176. }
  177. if (er=SWI_OS_File_6(s),er!=NULL) {
  178. /* maybe this is a problem with the DDEUtils module, try to canonicalise the path */
  179. char canon[256];
  180. int size=255;
  181. if (er=SWI_OS_FSControl_37(s,canon,&size),er!=NULL) {
  182. free(s);
  183. return -1;
  184. }
  185. if (er=SWI_OS_File_6(canon),er!=NULL) {
  186. free(s);
  187. return -1;
  188. }
  189. }
  190. free(s);
  191. return 0;
  192. }
  193. #endif /* !SFX */
  194. int chmod(char *file, int mode)
  195. {
  196. /*************** NOT YET IMPLEMENTED!!!!!! ******************/
  197. /* I don't know if this will be needed or not... */
  198. file=file;
  199. mode=mode;
  200. return 0;
  201. }
  202. void setfiletype(char *fname,int ftype)
  203. {
  204. char str[256];
  205. sprintf(str,"SetType %s &%3.3X",fname,ftype);
  206. SWI_OS_CLI(str);
  207. }
  208. void getRISCOSexts(char *envstr)
  209. {
  210. char *envptr; /* value returned by getenv */
  211. envptr = getenv(envstr);
  212. if (envptr == NULL || *envptr == 0) return;
  213. exts2swap=malloc(1+strlen(envptr));
  214. if (exts2swap == NULL)
  215. return;
  216. strcpy(exts2swap, envptr);
  217. }
  218. int checkext(char *suff)
  219. {
  220. register char *extptr=exts2swap;
  221. register char *suffptr;
  222. register int e,s;
  223. if (extptr != NULL) while(*extptr) {
  224. suffptr=suff;
  225. e=*extptr; s=*suffptr;
  226. while (e && e!=':' && s && s!='.' && s!='/' && e==s) {
  227. e=*++extptr; s=*++suffptr;
  228. }
  229. if (e==':') e=0;
  230. if (s=='.' || s=='/') s=0;
  231. if (!e && !s) {
  232. return 1;
  233. }
  234. while(*extptr!=':' && *extptr!='\0') /* skip to next extension */
  235. extptr++;
  236. if (*extptr!='\0')
  237. extptr++;
  238. }
  239. return 0;
  240. }
  241. int swapext(char *name, char *exptr)
  242. {
  243. char *ext;
  244. char *p1=exptr;
  245. char *p2;
  246. int extchar=*exptr;
  247. unsigned int i=0;
  248. while(*++p1 && *p1!='.' && *p1!='/')
  249. ;
  250. ext=malloc(i=p1-exptr);
  251. if (!ext)
  252. return 1;
  253. memcpy(ext, exptr+1, i);
  254. p2=exptr-1;
  255. p1=exptr+i-1;
  256. while(p2 >= name)
  257. *p1--=*p2--;
  258. strcpy(name,ext);
  259. *p1=(extchar=='/'?'.':'/');
  260. free(ext);
  261. return 0;
  262. }
  263. void remove_prefix(void)
  264. {
  265. SWI_DDEUtils_Prefix(NULL);
  266. }
  267. void set_prefix(void)
  268. {
  269. char *pref;
  270. int size=0;
  271. if (SWI_OS_FSControl_37("@",pref,&size)!=NULL)
  272. return;
  273. size=1-size;
  274. if (pref=malloc(size),pref!=NULL) {
  275. if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) {
  276. free(pref);
  277. return;
  278. }
  279. if (SWI_DDEUtils_Prefix(pref)==NULL) {
  280. atexit(remove_prefix);
  281. }
  282. free(pref);
  283. }
  284. }
  285. #ifdef localtime
  286. # undef localtime
  287. #endif
  288. #ifdef gmtime
  289. # undef gmtime
  290. #endif
  291. /* Acorn's implementation of localtime() and gmtime()
  292. * doesn't consider the timezone offset, so we have to
  293. * add it before calling the library functions
  294. */
  295. struct tm *riscos_localtime(const time_t *timer)
  296. {
  297. time_t localt=*timer;
  298. localt+=SWI_Read_Timezone()/100;
  299. return localtime(&localt);
  300. }
  301. struct tm *riscos_gmtime(const time_t *timer)
  302. {
  303. time_t localt=*timer;
  304. localt+=SWI_Read_Timezone()/100;
  305. return gmtime(&localt);
  306. }
  307. int riscos_fseek(FILE *fd, long offset, int whence)
  308. {
  309. int ret;
  310. switch (whence)
  311. {
  312. case SEEK_END:
  313. ret = (fseek) (fd, 0, SEEK_END);
  314. if (ret)
  315. return ret;
  316. /* fall through */
  317. case SEEK_CUR:
  318. offset += ftell (fd);
  319. /* fall through */
  320. default: /* SEEK_SET */
  321. return (fseek) (fd, offset < 0 ? 0 : offset, SEEK_SET);
  322. }
  323. }