summaryrefslogtreecommitdiff
path: root/acorn/riscos.c
diff options
context:
space:
mode:
Diffstat (limited to 'acorn/riscos.c')
-rw-r--r--acorn/riscos.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/acorn/riscos.c b/acorn/riscos.c
new file mode 100644
index 0000000..84dd2d3
--- /dev/null
+++ b/acorn/riscos.c
@@ -0,0 +1,394 @@
+/*
+ Copyright (c) 1990-2002 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
+*/
+/* riscos.c */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zip.h"
+#include "riscos.h"
+
+#define MAXEXT 256
+
+/* External globals */
+extern int scanimage;
+
+/* Local globals (!?!?) */
+char *exts2swap = NULL; /* Extensions to swap (actually, directory names) */
+
+int stat(char *filename,struct stat *res)
+{
+ int attr; /* object attributes */
+ unsigned int load; /* load address */
+ unsigned int exec; /* exec address */
+ int type; /* type: 0 not found, 1 file, 2 dir, 3 image */
+
+ if (!res)
+ return -1;
+
+ if (SWI_OS_File_5(filename,&type,&load,&exec,(int *)&res->st_size,&attr)!=NULL)
+ return -1;
+
+ if (type==0)
+ return -1;
+
+ res->st_dev=0;
+ res->st_ino=0;
+ res->st_nlink=0;
+ res->st_uid=1;
+ res->st_gid=1;
+ res->st_rdev=0;
+ res->st_blksize=1024;
+
+ res->st_mode = ((attr & 0001) << 8) | ((attr & 0002) << 6) |
+ ((attr & 0020) >> 2) | ((attr & 0040) >> 4);
+
+ switch (type) {
+ case 1: /* File */
+ res->st_mode |= S_IFREG;
+ break;
+ case 2: /* Directory */
+ res->st_mode |= S_IFDIR | 0700;
+ break;
+ case 3: /* Image file */
+ if (scanimage)
+ res->st_mode |= S_IFDIR | 0700;
+ else
+ res->st_mode |= S_IFREG;
+ break;
+ }
+
+ if ((((unsigned int) load) >> 20) == 0xfff) { /* date stamped file */
+ unsigned int t1, t2, tc;
+
+ t1 = (unsigned int) (exec);
+ t2 = (unsigned int) (load & 0xff);
+
+ tc = 0x6e996a00U;
+ if (t1 < tc)
+ t2--;
+ t1 -= tc;
+ t2 -= 0x33; /* 00:00:00 Jan. 1 1970 = 0x336e996a00 */
+
+ t1 = (t1 / 100) + (t2 * 42949673U); /* 0x100000000 / 100 = 42949672.96 */
+ t1 -= (t2 / 25); /* compensate for .04 error */
+
+ res->st_atime = res->st_mtime = res->st_ctime = t1;
+ }
+ else
+ res->st_atime = res->st_mtime = res->st_ctime = 0;
+
+ return 0;
+}
+
+#ifndef SFX
+
+DIR *opendir(char *dirname)
+{
+ DIR *thisdir;
+ int type;
+ int attr;
+ os_error *er;
+
+ thisdir=(DIR *)malloc(sizeof(DIR));
+ if (thisdir==NULL)
+ return NULL;
+
+ thisdir->dirname=(char *)malloc(strlen(dirname)+1);
+ if (thisdir->dirname==NULL) {
+ free(thisdir);
+ return NULL;
+ }
+
+ strcpy(thisdir->dirname,dirname);
+ if (thisdir->dirname[strlen(thisdir->dirname)-1]=='.')
+ thisdir->dirname[strlen(thisdir->dirname)-1]=0;
+
+ if (er=SWI_OS_File_5(thisdir->dirname,&type,NULL,NULL,NULL,&attr),er!=NULL ||
+ type<=1 || (type==3 && !scanimage))
+ {
+ free(thisdir->dirname);
+ free(thisdir);
+ return NULL;
+ }
+
+ thisdir->buf=malloc(DIR_BUFSIZE);
+ if (thisdir->buf==NULL) {
+ free(thisdir->dirname);
+ free(thisdir);
+ return NULL;
+ }
+
+ thisdir->size=DIR_BUFSIZE;
+ thisdir->offset=0;
+ thisdir->read=0;
+
+ return thisdir;
+}
+
+struct dirent *readdir(DIR *d)
+{
+ static struct dirent dent;
+
+ if (d->read==0) { /* no more objects read in the buffer */
+ if (d->offset==-1) { /* no more objects to read */
+ return NULL;
+ }
+
+ d->read=255;
+ if (SWI_OS_GBPB_9(d->dirname,d->buf,&d->read,&d->offset,DIR_BUFSIZE,NULL)!=NULL)
+ return NULL;
+
+ if (d->read==0) {
+ d->offset=-1;
+ return NULL;
+ }
+ d->read--;
+ d->act=(char *)d->buf;
+ }
+ else { /* some object is ready in buffer */
+ d->read--;
+ d->act=(char *)(d->act+strlen(d->act)+1);
+ }
+
+ strcpy(dent.d_name,d->act);
+ dent.d_namlen=strlen(dent.d_name);
+
+ return &dent;
+}
+
+void closedir(DIR *d)
+{
+ if (d->buf!=NULL)
+ free(d->buf);
+ if (d->dirname!=NULL)
+ free(d->dirname);
+ free(d);
+}
+
+int unlink(f)
+char *f; /* file to delete */
+/* Delete the file *f, returning non-zero on failure. */
+{
+ os_error *er;
+ char canon[256];
+ int size=255;
+
+ er=SWI_OS_FSControl_37(f,canon,&size);
+ if (er==NULL) {
+ er=SWI_OS_FSControl_27(canon,0x100);
+ }
+ else {
+ er=SWI_OS_FSControl_27(f,0x100);
+ }
+ return (int)er;
+}
+
+int deletedir(char *d)
+{
+ int objtype;
+ char *s;
+ int len;
+ os_error *er;
+
+ len = strlen(d);
+ if ((s = malloc(len + 1)) == NULL)
+ return -1;
+
+ strcpy(s,d);
+ if (s[len-1]=='.')
+ s[len-1]=0;
+
+ if (er=SWI_OS_File_5(s,&objtype,NULL,NULL,NULL,NULL),er!=NULL) {
+ free(s);
+ return -1;
+ }
+ if (objtype<2 || (!scanimage && objtype==3)) {
+ /* this is a file or it doesn't exist */
+ free(s);
+ return -1;
+ }
+
+ if (er=SWI_OS_File_6(s),er!=NULL) {
+ /* maybe this is a problem with the DDEUtils module, try to canonicalise the path */
+ char canon[256];
+ int size=255;
+
+ if (er=SWI_OS_FSControl_37(s,canon,&size),er!=NULL) {
+ free(s);
+ return -1;
+ }
+ if (er=SWI_OS_File_6(canon),er!=NULL) {
+ free(s);
+ return -1;
+ }
+ }
+ free(s);
+ return 0;
+}
+
+#endif /* !SFX */
+
+int chmod(char *file, int mode)
+{
+/*************** NOT YET IMPLEMENTED!!!!!! ******************/
+/* I don't know if this will be needed or not... */
+ file=file;
+ mode=mode;
+ return 0;
+}
+
+void setfiletype(char *fname,int ftype)
+{
+ char str[256];
+ sprintf(str,"SetType %s &%3.3X",fname,ftype);
+ SWI_OS_CLI(str);
+}
+
+void getRISCOSexts(char *envstr)
+{
+ char *envptr; /* value returned by getenv */
+
+ envptr = getenv(envstr);
+ if (envptr == NULL || *envptr == 0) return;
+
+ exts2swap=malloc(1+strlen(envptr));
+ if (exts2swap == NULL)
+ return;
+
+ strcpy(exts2swap, envptr);
+}
+
+int checkext(char *suff)
+{
+ register char *extptr=exts2swap;
+ register char *suffptr;
+ register int e,s;
+
+ if (extptr != NULL) while(*extptr) {
+ suffptr=suff;
+ e=*extptr; s=*suffptr;
+ while (e && e!=':' && s && s!='.' && s!='/' && e==s) {
+ e=*++extptr; s=*++suffptr;
+ }
+ if (e==':') e=0;
+ if (s=='.' || s=='/') s=0;
+ if (!e && !s) {
+ return 1;
+ }
+ while(*extptr!=':' && *extptr!='\0') /* skip to next extension */
+ extptr++;
+ if (*extptr!='\0')
+ extptr++;
+ }
+ return 0;
+}
+
+int swapext(char *name, char *exptr)
+{
+ char *ext;
+ char *p1=exptr;
+ char *p2;
+ int extchar=*exptr;
+ unsigned int i=0;
+
+ while(*++p1 && *p1!='.' && *p1!='/')
+ ;
+ ext=malloc(i=p1-exptr);
+ if (!ext)
+ return 1;
+ memcpy(ext, exptr+1, i);
+ p2=exptr-1;
+ p1=exptr+i-1;
+ while(p2 >= name)
+ *p1--=*p2--;
+ strcpy(name,ext);
+ *p1=(extchar=='/'?'.':'/');
+ free(ext);
+ return 0;
+}
+
+void remove_prefix(void)
+{
+ SWI_DDEUtils_Prefix(NULL);
+}
+
+void set_prefix(void)
+{
+ char *pref;
+ int size=0;
+
+ if (SWI_OS_FSControl_37("@",pref,&size)!=NULL)
+ return;
+
+ size=1-size;
+
+ if (pref=malloc(size),pref!=NULL) {
+ if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) {
+ free(pref);
+ return;
+ }
+
+ if (SWI_DDEUtils_Prefix(pref)==NULL) {
+ atexit(remove_prefix);
+ }
+
+ free(pref);
+ }
+}
+
+#ifdef localtime
+# undef localtime
+#endif
+
+#ifdef gmtime
+# undef gmtime
+#endif
+
+/* Acorn's implementation of localtime() and gmtime()
+ * doesn't consider the timezone offset, so we have to
+ * add it before calling the library functions
+ */
+
+struct tm *riscos_localtime(const time_t *timer)
+{
+ time_t localt=*timer;
+
+ localt+=SWI_Read_Timezone()/100;
+
+ return localtime(&localt);
+}
+
+struct tm *riscos_gmtime(const time_t *timer)
+{
+ time_t localt=*timer;
+
+ localt+=SWI_Read_Timezone()/100;
+
+ return gmtime(&localt);
+}
+
+
+int riscos_fseek(FILE *fd, long offset, int whence)
+{
+ int ret;
+ switch (whence)
+ {
+ case SEEK_END:
+ ret = (fseek) (fd, 0, SEEK_END);
+ if (ret)
+ return ret;
+ /* fall through */
+ case SEEK_CUR:
+ offset += ftell (fd);
+ /* fall through */
+ default: /* SEEK_SET */
+ return (fseek) (fd, offset < 0 ? 0 : offset, SEEK_SET);
+ }
+}