Obsolete option --no-sig-create-check.
[gnupg.git] / util / riscos.c
index e0844a2..814ec69 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef __RISCOS__C__
@@ -23,9 +22,8 @@
 
 #include <config.h>
 #include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <string.h>
+#include <signal.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 #include "util.h"
 #include "memory.h"
 
+#include <unixlib/local.h>     /* needed for RISCOSIFY_NO_PROCESS */
 #define __UNIXLIB_INTERNALS
-#include <unixlib/unix.h>
+#include <unixlib/swiparams.h> /* needed for MMM_TYPE_* definitions */
 #undef __UNIXLIB_INTERNALS
 
-/* RISC OS specific defines that are not yet in UnixLib */
 
-#define MimeMap_Translate      0x50B00
-#define MMM_TYPE_RISCOS        0
-#define MMM_TYPE_RISCOS_STRING 1
-#define MMM_TYPE_MIME          2
-#define MMM_TYPE_DOT_EXTN      3
+/* static symbols that trigger UnixLib behaviour */
+
+int __riscosify_control = __RISCOSIFY_NO_PROCESS;
+int __feature_imagefs_is_file = 1;
+
 
 /* RISC OS file open descriptor control list */
 
@@ -53,7 +51,7 @@ struct fds_item {
     struct fds_item *next;
 };
 static struct fds_item *fds_list = NULL;
-static int initialized = 0;
+static int fdlist_initialized = 0;
 
 
 /* local RISC OS functions */
@@ -61,99 +59,125 @@ static int initialized = 0;
 static int
 is_read_only(const char *filename)
 {
-    _kernel_swi_regs r;
-    
-    r.r[0] = 17;
-    r.r[1] = (int) filename;
+    int type, attr;
     
-    if (_kernel_swi(OS_File, &r, &r))
-        log_fatal("Can't get file attributes for %s!\n", filename);
+    if (_swix(OS_File, _INR(0,1) | _OUT(0) | _OUT(5),
+              17, filename, &type, &attr))
+        log_fatal("Can't get file attributes for file \"%s\"!\n", filename);
     
-    if (r.r[0] == 0)
-        log_fatal("Can't find file %s!\n", filename);
+    if (type == 0)
+        log_fatal("Can't find file \"%s\"!\n", filename);
 
-    r.r[0] = 4;
-    if (_kernel_swi(OS_File, &r, &r))
+    if (_swix(OS_File, _INR(0,1) | _IN(5), 4, filename, attr))
         return 1;
 
     return 0;
 }
 
-static void
-riscos_set_filetype_by_number(const char *filename, int type)
+/* exported RISC OS functions */
+
+int
+riscos_load_module(const char *name, const char * const path[], int fatal)
 {
-    _kernel_swi_regs r;
+    int i;
 
-    r.r[0] = 18;
-    r.r[1] = (int) filename;
-    r.r[2] = type;
-    
-    if (_kernel_swi(OS_File, &r, &r))
-        log_fatal("Can't set filetype for file %s!\n"
-                  "Is the file on a read-only file system?\n", filename);
-}        
+    /* Is module already loaded? */
+    if (!_swix(OS_Module, _INR(0,1), 18, name))
+        return 1;
 
-/* exported RISC OS functions */
+    /* Check all the places where the module could be located */
+    for (i=0; path[i]; ++i)
+        if (!_swix(OS_Module, _INR(0,1), 1, path[i]))
+            return 1;
 
-void
-riscos_global_defaults()
+    /* Can't find module in the default locations */
+    if (fatal)
+        log_fatal("Operation cannot be performed without \"%s\" module!\n",
+                  name);
+    else
+        log_info("Can't load \"%s\" module, continuing anyway!\n", name);
+
+    return 0;
+}
+
+int
+riscos_get_filetype_from_string(const char *string, int len)
 {
-    __riscosify_control = __RISCOSIFY_NO_PROCESS;
-    __feature_imagefs_is_file = 1;
+    int result = 0xfff;
+
+    if (strlen(string) < 5 || string[len - 4] != ',')
+        return -1;
+
+    sscanf(string+len-3, "%3x", &result);
+
+    return result;
 }
 
+int
+riscos_get_filetype(const char *filename)
+{
+    int result;
+
+    if (_swix(OS_File, _INR(0,1) | _OUT(2), 17, filename, &result))
+        log_fatal("Can't get filetype for file \"%s\"!\n", filename);
+
+    if ((result & 0xfff00000) == 0xfff00000)
+        return (result & 0xfff00) >> 8;
+    else
+        return 0;
+}        
+
 void
-riscos_set_filetype(const char *filename, const char *mimetype)
+riscos_set_filetype_by_number(const char *filename, int type)
 {
-    _kernel_swi_regs r;
+    if (_swix(OS_File, _INR(0,2), 18, filename, type))
+        log_fatal("Can't set filetype for file \"%s\"!\n"
+                  "Is the file on a read-only file system?\n", filename);
+}        
 
-    r.r[0] = MMM_TYPE_MIME;
-    r.r[1] = (int) mimetype;
-    r.r[2] = MMM_TYPE_RISCOS;
-    
-    if (_kernel_swi(MimeMap_Translate, &r, &r))
-        log_fatal("Can't translate MIME type %s!\n", mimetype);
+void
+riscos_set_filetype_by_mimetype(const char *filename, const char *mimetype)
+{
+    int result;
+
+    if (_swix(MimeMap_Translate, _INR(0,2) | _OUT(3),
+              MMM_TYPE_MIME, mimetype, MMM_TYPE_RISCOS, &result))
+        log_fatal("Can't translate MIME type \"%s\"!\n", mimetype);
 
-    riscos_set_filetype_by_number(filename, r.r[3]);
+    riscos_set_filetype_by_number(filename, result);
 }        
 
 pid_t
 riscos_getpid(void)
 {
-    _kernel_swi_regs r;
+    int state;
 
-    r.r[0] = 3;
-    if (_kernel_swi(Wimp_ReadSysInfo, &r, &r))
+    if (_swix(Wimp_ReadSysInfo, _IN(0) | _OUT(0), 3, &state))
         log_fatal("Wimp_ReadSysInfo failed: Can't get WimpState (R0=3)!\n");
 
-    if (!r.r[0])
-        return (pid_t) 0;
+    if (state)
+        if (_swix(Wimp_ReadSysInfo, _IN(0) | _OUT(0), 5, &state))
+            log_fatal("Wimp_ReadSysInfo failed: "
+                      "Can't get task handle (R0=5)!\n");
 
-    r.r[0] = 5;
-    if (_kernel_swi(Wimp_ReadSysInfo, &r, &r))
-        log_fatal("Wimp_ReadSysInfo failed: Can't get task handle (R0=5)!\n");
-
-    return (pid_t) r.r[0];
+    return (pid_t) state;
 }
 
 int
 riscos_kill(pid_t pid, int sig)
 {
-    _kernel_swi_regs r;
-    int buf[4];
+    int buf[4], iter = 0;
 
     if (sig)
         kill(pid, sig);
 
-    r.r[0] = 0;
     do {
-        r.r[1] = (int) buf;
-        r.r[2] = 16;
-        if (_kernel_swi(TaskManager_EnumerateTasks, &r, &r))
+        if (_swix(TaskManager_EnumerateTasks, _INR(0,2) | _OUT(0),
+                  iter, buf, 16, &iter))
             log_fatal("TaskManager_EnumerateTasks failed!\n");
         if (buf[0] == pid)
             return 0;
-    } while (r.r[0] >= 0);
+    } while (iter >= 0);
 
     return __set_errno(ESRCH);
 }
@@ -167,9 +191,22 @@ riscos_access(const char *path, int amode)
     return access(path, amode);
 }
 
+int
+riscos_getchar(void)
+{
+    int c, flags;
+
+    if (_swix(OS_ReadC, _OUT(0) | _OUT(_FLAGS), &c, &flags))
+        log_fatal("OS_ReadC failed: Couldn't read from keyboard!\n");
+    if (flags & _C)
+        log_fatal("OS_ReadC failed: Return Code = %i!\n", c);
+
+    return c;
+}
+
 #ifdef DEBUG
 void
-dump_fdlist(void)
+riscos_dump_fdlist(void)
 {
     struct fds_item *iter = fds_list;
     printf("List of open file descriptors:\n");
@@ -181,7 +218,7 @@ dump_fdlist(void)
 #endif /* DEBUG */
 
 int
-fdopenfile(const char *filename, const int allow_write)
+riscos_fdopenfile(const char *filename, const int allow_write)
 {
     struct fds_item *h;
     int fd;
@@ -190,15 +227,18 @@ fdopenfile(const char *filename, const int allow_write)
     else
         fd = open(filename, O_RDONLY);
     if (fd == -1)
-        log_error("Can't open file %s: %i, %s!\n", filename, errno, strerror(errno));
+        log_error("Can't open file \"%s\": %i, %s!\n",
+                  filename, errno, strerror(errno));
 
-    if (!initialized) {
-        atexit (close_fds);
-        initialized = 1;
+    if (!fdlist_initialized) {
+        atexit (riscos_close_fds);
+        fdlist_initialized = 1;
     }
 
     h = fds_list;
-    fds_list = (struct fds_item *) m_alloc(sizeof(struct fds_item));
+    fds_list = (struct fds_item *) xmalloc(sizeof(struct fds_item));
+    if (!fds_list)
+        log_fatal("Can't claim memory for fdopenfile() buffer!\n");
     fds_list->fd = fd;
     fds_list->next = h;
 
@@ -206,7 +246,7 @@ fdopenfile(const char *filename, const int allow_write)
 }
 
 void
-close_fds(void)
+riscos_close_fds(void)
 {
     FILE *fp;
     struct fds_item *h = fds_list;
@@ -216,21 +256,17 @@ close_fds(void)
         if (fp)
             fflush(fp);
         close(fds_list->fd);
-        m_free(fds_list);
+        xfree(fds_list);
         fds_list = h;
     }
 }
 
 int
-renamefile(const char *old, const char *new)
+riscos_renamefile(const char *old, const char *new)
 {
-    _kernel_swi_regs r;
     _kernel_oserror *e;
 
-    r.r[0] = 25;
-    r.r[1] = (int) old;
-    r.r[2] = (int) new;
-    if (e = _kernel_swi(OS_FSControl, &r, &r)) {
+    if (e = _swix(OS_FSControl, _INR(0,2), 25, old, new)) {
         if (e->errnum == 214)
             return __set_errno(ENOENT);
         if (e->errnum == 176)
@@ -242,84 +278,155 @@ renamefile(const char *old, const char *new)
 }
 
 char *
-gstrans(const char *old)
+riscos_gstrans(const char *old)
 {
-    _kernel_swi_regs r;
-    int c = 0;
-    int size = 256;
+    int size = 256, last;
     char *buf, *tmp;
 
-    buf = (char *) m_alloc(size);
+    buf = (char *) xmalloc(size);
     if (!buf)
         log_fatal("Can't claim memory for OS_GSTrans buffer!\n");
-    do {
-        r.r[0] = (int) old;
-        r.r[1] = (int) buf;
-        r.r[2] = size;
-        _kernel_swi_c(OS_GSTrans, &r, &r, &c);
-        if (c) {
-            size += 256;
-            tmp = (char *) m_realloc(buf, size);
-            if (!tmp)
-                 log_fatal("Can't claim memory for OS_GSTrans buffer!\n");
-            buf = tmp;
-        }
-    } while (c);
+    while (_C & _swi(OS_GSTrans, _INR(0,2) | _OUT(2) | _RETURN(_FLAGS),
+                     old, buf, size, &last)) {
+        size += 256;
+        tmp = (char *) xrealloc(buf, size);
+        if (!tmp)
+             log_fatal("Can't claim memory for OS_GSTrans buffer!\n");
+        buf = tmp;
+    }
 
-    buf[r.r[2]] = '\0';
-    tmp = (char *) m_realloc(buf, r.r[2] + 1);
+    buf[last] = '\0';
+    tmp = (char *) xrealloc(buf, last + 1);
     if (!tmp)
         log_fatal("Can't realloc memory after OS_GSTrans!\n");
 
     return tmp;
 }
 
+/***************
+ * Extract from a given path the filename component.
+ * (cloned from util/fileutil.c and then heavily modified)
+ */
+char *
+riscos_make_basename(const char *filepath, const char *realfname)
+{
+    char *result, *p;
+    int i, filetype;
+
+    if ( (p = strrchr(filepath, DIRSEP_C)) )
+        p++;
+    else if ( (p = strrchr(filepath, ':')) )
+        p++;
+    else
+        p = (char*) filepath;
+
+    i = strlen(p);
+    result = xmalloc(i + 5);
+    if (!result)
+        log_fatal("Can't claim memory for riscos_make_basename() buffer!\n");
+    strcpy(result, p);
+    
+    filetype = riscos_get_filetype( realfname );
+    result[i++] = ',';
+    result[i++] = "0123456789abcdef"[(filetype >> 8) & 0xf];
+    result[i++] = "0123456789abcdef"[(filetype >> 4) & 0xf];
+    result[i++] = "0123456789abcdef"[(filetype >> 0) & 0xf];
+    result[i]   = 0;
+
+    for(i=0; i<strlen(result); ++i)
+        if(result[i] == '/')
+            result[i] = '.';
+
+    return result;
+}
+
+#define RegEx_CompilePattern         0x52AC0
+#define RegEx_Search                 0x52AC2
+#define RegEx_Free                   0x52AC7
+#define RegEx_CompileExtendedPattern 0x52AC9
+
+static const char * const regex_path[] = {
+    "GnuPG:RegEx",
+    "System:310.Modules.RegEx",
+    "System:Modules.RegEx",
+    NULL
+};
+
+int
+riscos_check_regexp(const char *exp, const char *string, int debug)
+{
+    static int regex_initialized = 0;
+    int ret;
+    char *buf;
+  
+    if (!regex_initialized)
+        regex_initialized = riscos_load_module("RegEx", regex_path, 0);
+  
+    if (!regex_initialized) {
+        log_info("Regular expressions cannot be used!\n");
+        return 0;
+    }
+  
+    if (_swix(RegEx_CompileExtendedPattern, _INR(0,2) | _OUT(0) | _OUT(3),
+              0, exp, 1<<18,
+              &buf, &ret)) {
+        log_info("RegEx could not compile pattern \"%s\".\n", exp);
+        log_info("ErrorCode = %i\n", ret);
+        return 0;
+    }
+  
+    if (_swix(RegEx_Search, _INR(0,4) | _OUT(5),
+              buf, string, -1, 0, -1,
+              &ret)) {
+        log_info("RegEx error during execution of serach pattern \"%s\"\n",
+                 exp);
+        log_info("on string \"%s\"\n", string);
+        return 0;
+    }
+  
+    _swix(RegEx_Free, _IN(0), buf);
+  
+    if(debug)
+        log_debug("regexp \"%s\" on \"%s\": %s\n",exp,string,ret>=0?"YES":"NO");
+  
+    return (ret>=0);
+}
+
 #ifdef DEBUG
 void
-list_openfiles(void)
+riscos_list_openfiles(void)
 {
-    _kernel_swi_regs r;
     char *name;
-    int i;
+    int i, len;
     
     for (i = 255; i >= 0; --i) {
-        r.r[0] = 7;
-        r.r[1] = i;
-        r.r[2] = 0;
-        r.r[5] = 0;
-        if (_kernel_swi(OS_Args, &r, &r))
+        if (_swix(OS_Args, _INR(0,2) | _IN(5) | _OUT(5), 7, i, 0, 0, &len))
             continue;
 
-        name = (char *) m_alloc(1-r.r[5]);
+        name = (char *) xmalloc(1-len);
         if (!name)
             log_fatal("Can't claim memory for OS_Args buffer!\n");
 
-        r.r[0] = 7;
-        r.r[1] = i;
-        r.r[2] = (int) name;
-        r.r[5] = 1-r.r[5];
-        if (_kernel_swi(OS_Args, &r, &r)) {
-            m_free(name);
+        if (_swix(OS_Args, _INR(0,2) | _IN(5), 7, i, name, 1-len)) {
+            xfree(name);
             log_fatal("Error when calling OS_Args(7)!\n");
         }
         
-        r.r[0] = 254;
-        r.r[1] = i;
-        if (_kernel_swi(OS_Args, &r, &r)) {
-            m_free(name);
+        if (_swix(OS_Args, _INR(0,1) | _OUT(0), 254, i, &len)) {
+            xfree(name);
             log_fatal("Error when calling OS_Args(254)!\n");
         }
         
         printf("%3i: %s (%c%c)\n", i, name,
-                                   (r.r[0] & 0x40) ? 'R' : 0,
-                                   (r.r[0] & 0x80) ? 'W' : 0);
-        m_free(name);
+                                   (len & 0x40) ? 'R' : 0,
+                                   (len & 0x80) ? 'W' : 0);
+        xfree(name);
     }
 }
 #endif
 
 void
-not_implemented(const char *feature)
+riscos_not_implemented(const char *feature)
 {
     log_info("%s is not implemented in the RISC OS version!\n", feature);
 }