]> andersk Git - moira.git/blobdiff - server/qrtn.qc
added codes for new user statuses
[moira.git] / server / qrtn.qc
index 07d02d848f59569763c9b2cf4569ae793b2b4d1e..ec7a0818ec4b451e8ac7160c1d60c9496168d58f 100644 (file)
@@ -4,6 +4,8 @@
  *     $Header$
  *
  *     Copyright (C) 1987, 1988 by the Massachusetts Institute of Technology
+ *     For copying and distribution information, please see the file
+ *     <mit-copyright.h>.
  * 
  */
 
 static char *rcsid_qrtn_qc = "$Header$";
 #endif lint
 
+#include <mit-copyright.h>
 #include "query.h"
 #include "sms_server.h"
 
 char *Argv[16];
 
-static int ingres_errno = 0;
+int ingres_errno = 0;
+int sms_errcode = 0;
+## int query_timeout = 30;
 extern char *whoami;
 extern FILE *journal;
 
 #define INGRES_BAD_INT 4111
 #define INGRES_BAD_DATE 4302
 #define INGRES_DEADLOCK 4700
+#define INGRES_TIMEOUT 4702
 
 /*
  * ingerr: (supposedly) called when Ingres indicates an error.
@@ -33,20 +39,25 @@ extern FILE *journal;
 static int ingerr(num)
     int *num;
 {
-    char buf[256];
+    ingres_errno = *num;
 
     switch (*num) {
     case INGRES_BAD_INT:
-       ingres_errno = SMS_INTEGER;
+       sms_errcode = SMS_INTEGER;
        break;
     case INGRES_BAD_DATE:
-       ingres_errno = SMS_DATE;
+       sms_errcode = SMS_DATE;
        break;
     case INGRES_DEADLOCK:
-       ingres_errno = SMS_DEADLOCK;
+       sms_errcode = SMS_DEADLOCK;
+       com_err(whoami, 0, "INGRES deadlock detected");
+       break;
+    case INGRES_TIMEOUT:
+       sms_errcode = SMS_BUSY;
+       com_err(whoami, 0, "timed out getting lock");
        break;
     default:
-       ingres_errno = SMS_INGRES_ERR;
+       sms_errcode = SMS_INGRES_ERR;
        com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
        critical_alert("SMS", "SMS server encountered INGRES ERROR %d", *num);
        return (*num);
@@ -69,6 +80,9 @@ int sms_open_database()
        
     /* open the database */
 ##  ingres sms
+##  set lockmode session where level = table, timeout = query_timeout
+##  set lockmode on capacls where readlock = shared
+##  set lockmode on alias where readlock = shared
     return ingres_errno;
 }
 
@@ -86,6 +100,8 @@ sms_check_access(cl, name, argc, argv_ro)
     struct query *q;
     struct query *get_query_by_name();
 
+    ingres_errno = 0;
+
     q = get_query_by_name(name, cl->args->sms_version_no);
     if (q == (struct query *)0)
        return(SMS_NO_HANDLE);
@@ -115,6 +131,8 @@ sms_process_query(cl, name, argc, argv_ro, action, actarg)
     struct save_queue *sq_create();
     char *build_sort();
 
+    ingres_errno = 0;
+
     /* list queries command */
     if (!strcmp(name, "_list_queries")) {
        list_queries(cl->args->sms_version_no, action, actarg);
@@ -136,8 +154,10 @@ sms_process_query(cl, name, argc, argv_ro, action, actarg)
     if (q == (struct query *)0) return(SMS_NO_HANDLE);
     v = q->validate;
 
-    if (q->type != RETRIEVE)
+    if (q->type != RETRIEVE) {
+##     set lockmode session where readlock = exclusive
 ##      begin transaction
+    }
 
     /* setup argument vector, verify access and arguments */
     if ((status = sms_verify_query(cl, q, argc, argv_ro)) != SMS_SUCCESS)
@@ -307,12 +327,26 @@ out:
                fflush(journal);
            }
        } else {
-##          abort              /* it never happened */
+           if (ingres_errno != INGRES_DEADLOCK) {
+##             abort           /* it never happened */
+           }
        }
+##      set lockmode session where readlock = system
+    }
+
+    if (status == SMS_SUCCESS && ingres_errno != 0) {
+       critical_alert("SMS", "Server didn't notice INGRES ERROR %d",
+                      ingres_errno);
+       status = SMS_INTERNAL;
     }
 
     if (status != SMS_SUCCESS && log_flags & LOG_RES)
        com_err(whoami, status, " (Query failed)");
+    /* until all the clients know about SMS_BUSY, convert this error
+     * to one they will recognize.
+     */
+    if (status == SMS_BUSY)
+      status = SMS_DEADLOCK;
     return(status);
 }
 
@@ -402,13 +436,18 @@ sms_verify_query(cl, q, argc, argv_ro)
     register struct validate *v = q->validate;
     register int i;
     register int privileged = 0;
+    int len;
 
     /* copy the arguments into a local argv that we can modify */
+    if (argc >= QMAXARGS)
+      return(SMS_ARGS);
     for (i = 0; i < argc; i++) {
-       if (strlen(argv_ro[i]) < ARGLEN)
+       if ((len = strlen(argv_ro[i])) < ARGLEN)
            strcpy(Argv[i], argv_ro[i]);
        else
            return(SMS_ARG_TOO_LONG);
+       if (Argv[i][len-1] == '\\')
+         return(SMS_BAD_CHAR);
     }
 
     /* check initial query access */
@@ -469,7 +508,7 @@ check_query_access(q, argv, cl)
     }
 
     /* check for default access */
-##  range of m is members
+##  range of m is imembers
 ##  repeat retrieve (exists = any(m.#member_id where m.list_id = @acl_id and
 ##                   m.member_type = "USER" and m.#member_id = def_uid))
     if (exists) return(SMS_SUCCESS);
@@ -520,60 +559,29 @@ get_client(cl, client_type, client_id)
     return(SMS_SUCCESS);
 ##}
 
-##find_member(list_type, list_id, member_type, member_id, sq)
+##find_member(list_type, list_id, member_type, member_id)
     char *list_type;
 ##  int list_id;
 ##  char *member_type;
 ##  int member_id;
-    struct save_queue *sq;
 ##{
-##  int exists;
-##  int sublist;
-    int child;
-    struct save_queue *sq_create();
+##  int exists, errorno;
+
+    if (!strcmp(strtrim(list_type), strtrim(member_type)) &&
+       list_id == member_id)
+       return(1);
 
     /* see if client is a direct member of list */
+##  range of m is imembers
 ##  repeat retrieve (exists = any(m.#member_id where 
 ##                               m.#list_id = @list_id and
 ##                               m.#member_type = @member_type and 
 ##                               m.#member_id = @member_id))
-    if (exists) return(1);
-
-    /* are there any sub-lists? */
-##  repeat retrieve (exists = any(m.#member_id where m.#list_id = @list_id and
-##                   m.#member_type = "LIST"))
-    if (!exists) return(0);
-
-    /* yes; now recurse through sublists */
-
-    /* create a save queue */
-    if (sq == (struct save_queue *)0) {
-       sq = sq_create();
-       child = 0;
-    } else {
-       child = 1;
-    }
-
-    /* save all sublist ids */
-##  range of m is members
-##  retrieve (sublist = m.#member_id) 
-##      where m.#list_id = list_id and m.#member_type = "LIST"
-##  {
-        sq_save_unique_data(sq, sublist);
-##  }
-
-    if (child) return(0);
-
-    /* at top-level, check sub-lists for client (breadth-first search) */
-    while (sq_get_data(sq, &sublist)) {
-       exists = find_member(list_type, sublist, member_type, member_id, sq);
-       if (exists) {
-           sq_destroy(sq);
-           return(1);
-       }
-    }
-    sq_destroy(sq);
-    return(0);
+##  inquire_equel(errorno = "errorno")
+    if (errorno == 0)
+      return(exists);
+    else
+      return(0);
 ##}
 
 
@@ -785,14 +793,22 @@ sanity_check_queries()
 {
     register int i;
     int maxv = 0, maxa = 0;
+#ifdef MULTIPROTOCOLS
     extern int QueryCount1, QueryCount2;
     extern struct query Queries1[], Queries2[];
+#else
+    extern int QueryCount2;
+    extern struct query Queries2[];
+#endif MULTIPROTOCOLS
+
 #define MAX(x,y) ((x) > (y) ? (x) : (y))
 
+#ifdef MULTIPROTOCOLS
     for (i = 0; i < QueryCount1; i++) {
        maxv = MAX(maxv, Queries1[i].vcnt);
        maxa = MAX(maxa, Queries1[i].argc);
     }
+#endif MULTIPROTOCOLS
     for (i = 0; i < QueryCount2; i++) {
        maxv = MAX(maxv, Queries2[i].vcnt);
        maxa = MAX(maxa, Queries2[i].argc);
@@ -802,16 +818,3 @@ sanity_check_queries()
        exit(1);
     }
 }
-
-
-/*
- * Local Variables:
- * mode: c
- * c-indent-level: 4
- * c-continued-statement-offset: 4
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * End:
- */
-
This page took 0.060755 seconds and 4 git commands to generate.