* mpi.h (gcry_mpi, mpi_get_opaque, mpi_set_opaque): Make nbits and the
[gnupg.git] / util / riscos.c
index c64da37..70ec98f 100644 (file)
@@ -23,9 +23,7 @@
 
 #include <config.h>
 #include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <signal.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 #include "memory.h"
 
 #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
 
 /* RISC OS file open descriptor control list */
 
@@ -53,7 +44,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 */
@@ -65,10 +56,10 @@ is_read_only(const char *filename)
     
     if (_swix(OS_File, _INR(0,1) | _OUT(0) | _OUT(5),
               17, filename, &type, &attr))
-        log_fatal("Can't get file attributes for %s!\n", filename);
+        log_fatal("Can't get file attributes for file \"%s\"!\n", filename);
     
     if (type == 0)
-        log_fatal("Can't find file %s!\n", filename);
+        log_fatal("Can't find file \"%s\"!\n", filename);
 
     if (_swix(OS_File, _INR(0,1) | _IN(5), 4, filename, attr))
         return 1;
@@ -76,14 +67,6 @@ is_read_only(const char *filename)
     return 0;
 }
 
-static void
-riscos_set_filetype_by_number(const char *filename, int type)
-{
-    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);
-}        
-
 /* exported RISC OS functions */
 
 void
@@ -93,14 +76,70 @@ riscos_global_defaults(void)
     __feature_imagefs_is_file = 1;
 }
 
+int
+riscos_load_module(const char *name, const char * const path[], int fatal)
+{
+    int i;
+
+    /* Is module already loaded? */
+    if (!_swix(OS_Module, _INR(0,1), 18, name))
+        return 1;
+
+    /* 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;
+
+    /* 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)
+{
+    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(6), 23, filename, &result))
+        log_fatal("Can't get filetype for file \"%s\"!\n", filename);
+
+    return result;
+}        
+
+void
+riscos_set_filetype_by_number(const char *filename, int type)
+{
+    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);
+}        
+
 void
-riscos_set_filetype(const char *filename, const char *mimetype)
+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);
+        log_fatal("Can't translate MIME type \"%s\"!\n", mimetype);
 
     riscos_set_filetype_by_number(filename, result);
 }        
@@ -115,7 +154,8 @@ riscos_getpid(void)
 
     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");
+            log_fatal("Wimp_ReadSysInfo failed: "
+                      "Can't get task handle (R0=5)!\n");
 
     return (pid_t) state;
 }
@@ -163,7 +203,7 @@ riscos_getchar(void)
 
 #ifdef DEBUG
 void
-dump_fdlist(void)
+riscos_dump_fdlist(void)
 {
     struct fds_item *iter = fds_list;
     printf("List of open file descriptors:\n");
@@ -175,7 +215,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;
@@ -184,15 +224,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));
+    if (!fds_list)
+        log_fatal("Can't claim memory for fdopenfile() buffer!\n");
     fds_list->fd = fd;
     fds_list->next = h;
 
@@ -200,7 +243,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,7 +259,7 @@ close_fds(void)
 }
 
 int
-renamefile(const char *old, const char *new)
+riscos_renamefile(const char *old, const char *new)
 {
     _kernel_oserror *e;
 
@@ -232,7 +275,7 @@ renamefile(const char *old, const char *new)
 }
 
 char *
-gstrans(const char *old)
+riscos_gstrans(const char *old)
 {
     int size = 256, last;
     char *buf, *tmp;
@@ -257,9 +300,95 @@ gstrans(const char *old)
     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 = (char*)filepath-1;
+    int i, filetype;
+
+    if ( !(p=strrchr(filepath, DIRSEP_C)) )
+        if ( !(p=strrchr(filepath, ':')) )
+            ;
+
+    i = strlen(p+1);
+    result = m_alloc(i + 5);
+    if (!result)
+        log_fatal("Can't claim memory for riscos_make_basename() buffer!\n");
+    strcpy(result, p+1);
+    
+    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)
 {
     char *name;
     int i, len;
@@ -291,7 +420,7 @@ list_openfiles(void)
 #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);
 }