]> andersk Git - moira.git/blobdiff - server/mr_scall.c
Change `SMS' to `Moira' where possible.
[moira.git] / server / mr_scall.c
index a3671b9770090aa8d88cddacdd9f2f268c3318bf..2b4a7c4dc583e5c493b53be9619b39c3436b7c70 100644 (file)
  */
 
 #ifndef lint
-static char *rcsid_sms_scall_c = "$Header$";
+static char *rcsid_mr_scall_c = "$Header$";
 #endif lint
 
 #include <mit-copyright.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
+#include <fcntl.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <krb.h>
 #include <errno.h>
-#include "query.h"
 #include "mr_server.h"
+#include "query.h"
 extern char buf1[];
 extern int nclients;
 extern char *whoami;
-extern char *malloc();
 extern int errno;
 
 extern void clist_delete(), do_auth(), do_shutdown();
 void do_call();
+extern int dbms_errno, mr_errcode;
+static int row_count;
+
+/* Put this in a variable so that we can patch it if necessary */
+int max_row_count = 4096;
 
 /*
  * Welcome to the (finite state) machine (highest level).
  */
-void
-do_client(cp)
-       client *cp;
+void do_client(client *cp)
 {
-       struct stat stbuf;
-
-       free_rtn_tuples(cp);
-       if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
-               com_err(whoami, 0, "Closed connection (now %d client%s, %d new queries, %d old)",
-                       nclients-1,
-                       nclients!=2?"s":"",
-                       newqueries,
-                       oldqueries);
-               clist_delete(cp);
-               /* if we no longer have any clients, and we're supposed to
-                * go down, then go down now.
-                */
-               if ((dormant == AWAKE) && (nclients == 0) &&
-                   (stat(MOIRA_MOTD_FILE, &stbuf) == 0)) {
-                   com_err(whoami, 0, "motd file exists, slumbertime");
-                   dormant = SLEEPY;
-               }
-               return;
+  struct stat stbuf;
+
+  free_rtn_tuples(cp);
+  if (OP_STATUS(cp->pending_op) == OP_CANCELLED)
+    {
+      com_err(whoami, 0,
+             "Closed connection (now %d client%s, %d new queries, %d old)",
+             nclients - 1, nclients != 2 ? "s" : "", newqueries, oldqueries);
+      clist_delete(cp);
+      /* if we no longer have any clients, and we're supposed to
+       * go down, then go down now.
+       */
+      if ((dormant == AWAKE) && (nclients == 0) &&
+         (stat(MOIRA_MOTD_FILE, &stbuf) == 0))
+       {
+         com_err(whoami, 0, "motd file exists, slumbertime");
+         dormant = SLEEPY;
        }
-       switch (cp->action) {
-       case CL_ACCEPT:
-       case CL_SEND:
-               /* Start recieving next request */
-               initialize_operation(cp->pending_op, mr_start_recv,
-                                    (char *)&cp->args, (int (*)())NULL);
-               queue_operation(cp->con, CON_INPUT, cp->pending_op);
-               cp->action = CL_RECEIVE;
-               break;
-       case CL_RECEIVE:
-               /* Data is here. Process it & start it heading back */
-               do_call(cp); /* This may block for a while. */
-               mr_destroy_reply(cp->args);
-               cp->args = NULL;
-               initialize_operation(cp->pending_op, mr_start_send,
-                                    (char *)&cp->reply, (int (*)())NULL);
-               queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
-               cp->action = CL_SEND;
-               break;
-       }
-}              
+      return;
+    }
+  switch (cp->action)
+    {
+    case CL_ACCEPT:
+    case CL_SEND:
+      /* Start recieving next request */
+      initialize_operation(cp->pending_op, mr_start_recv,
+                          (char *)&cp->args, NULL);
+      queue_operation(cp->con, CON_INPUT, cp->pending_op);
+      cp->action = CL_RECEIVE;
+      break;
+    case CL_RECEIVE:
+      /* Data is here. Process it & start it heading back */
+      do_call(cp); /* This may block for a while. */
+      mr_destroy_reply(cp->args);
+      cp->args = NULL;
+      initialize_operation(cp->pending_op, mr_start_send,
+                          (char *)&cp->reply, NULL);
+      queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
+      cp->action = CL_SEND;
+      break;
+    }
+}
 
 char *procnames[] = {
-        "noop",
-        "auth",
-        "shutdown",
-        "query",
-        "access",
-        "dcm",
-        "motd",
+  "noop",
+  "auth",
+  "shutdown",
+  "query",
+  "access",
+  "dcm",
+  "motd",
 };
 
 
-void
-do_call(cl)
-       client *cl;
+void do_call(client *cl)
 {
-       int pn;
-       extern int ingres_errno;
-       cl->reply.mr_argc = 0;
-       cl->reply.mr_status = 0;
-       cl->reply.mr_version_no = cl->args->mr_version_no;
-       if (((pn = cl->args->mr_procno) < 0) ||
-           (pn > MR_MAX_PROC)) {
-               com_err(whoami, 0, "procno out of range");
-               cl->reply.mr_status = MR_UNKNOWN_PROC;
-               return;
-       }
-       if (log_flags & LOG_ARGS)
-               log_args(procnames[pn], cl->args->mr_version_no,
-                        cl->args->mr_argc, cl->args->mr_argv);
-       else if (log_flags & LOG_REQUESTS)
-               com_err(whoami, 0, "%s", procnames[pn]);
-
-       if ((dormant == ASLEEP || dormant == GROGGY) &&
-           pn != MR_NOOP && pn != MR_MOTD) {
-           cl->reply.mr_status = MR_DOWN;
-           if (log_flags & LOG_RES)
-             com_err(whoami, MR_DOWN, "(query refused)");
-           return;
-       }
-
-       /* make sure this gets cleared before every operation */
-       ingres_errno = 0;
-
-       switch(pn) {
-       case MR_NOOP:
-               cl->reply.mr_status = 0;
-               return;
-
-       case MR_AUTH:
-               do_auth(cl);
-               return;
-
-       case MR_QUERY:
-               do_retr(cl);
-               return;
-
-       case MR_ACCESS:
-               do_access(cl);
-               return;
-               
-       case MR_SHUTDOWN:
-               do_shutdown(cl);
-               return;
-
-       case MR_DO_UPDATE:
-               trigger_dcm(0, 0, cl);
-               return;
-
-       case MR_MOTD:
-               get_motd(cl);
-               return;
-       }
+  int pn;
+  cl->reply.mr_argc = 0;
+  cl->reply.mr_status = 0;
+  cl->reply.mr_version_no = cl->args->mr_version_no;
+  if (((pn = cl->args->mr_procno) < 0) || (pn > MR_MAX_PROC))
+    {
+      com_err(whoami, 0, "procno out of range");
+      cl->reply.mr_status = MR_UNKNOWN_PROC;
+      return;
+    }
+  if (log_flags & LOG_ARGS)
+    {
+      log_args(procnames[pn], cl->args->mr_version_no,
+              cl->args->mr_argc, cl->args->mr_argv);
+    }
+  else if (log_flags & LOG_REQUESTS)
+    com_err(whoami, 0, "%s", procnames[pn]);
+
+  if ((dormant == ASLEEP || dormant == GROGGY) &&
+      pn != MR_NOOP && pn != MR_MOTD)
+    {
+      cl->reply.mr_status = MR_DOWN;
+      if (log_flags & LOG_RES)
+       com_err(whoami, MR_DOWN, "(query refused)");
+      return;
+    }
+
+  /* make sure this gets cleared before every operation */
+  dbms_errno = 0;
+
+  switch (pn)
+    {
+    case MR_NOOP:
+      cl->reply.mr_status = 0;
+      return;
+
+    case MR_AUTH:
+      do_auth(cl);
+      return;
+
+    case MR_QUERY:
+      do_retr(cl);
+      return;
+
+    case MR_ACCESS:
+      do_access(cl);
+      return;
+
+    case MR_SHUTDOWN:
+      do_shutdown(cl);
+      return;
+
+    case MR_DO_UPDATE:
+      trigger_dcm(0, 0, cl);
+      return;
+
+    case MR_MOTD:
+      get_motd(cl);
+      return;
+    }
 }
 
-free_rtn_tuples(cp)
-       client *cp;
+free_rtn_tuples(client *cp)
 {
-       register returned_tuples *temp;
-       for (temp=cp->first; temp && OP_DONE(temp->op); ) {
-               register returned_tuples *t1=temp;
-               temp = t1->next;
-               if (t1 == cp->last) cp->last = NULL;
-
-               mr_destroy_reply(t1->retval);
-               delete_operation(t1->op);
-               free(t1);
-       }
-       cp->first = temp;
-}      
+  returned_tuples *temp;
+  for (temp = cp->first; temp && OP_DONE(temp->op); )
+    {
+      returned_tuples *t1 = temp;
+      temp = t1->next;
+      if (t1 == cp->last)
+       cp->last = NULL;
+
+      mr_destroy_reply(t1->retval);
+      delete_operation(t1->op);
+      free(t1);
+    }
+  cp->first = temp;
+}
 
-retr_callback(argc, argv, p_cp)
-       register int argc;
-       register char **argv;
-       char *p_cp;
+retr_callback(int argc, char **argv, char *p_cp)
 {
-       register client *cp = (client *)p_cp;
-       /*
-        * This takes too much advantage of the fact that
-        * serialization of the data happens during the queue operation.
-        */
-       mr_params *arg_tmp = (mr_params *)db_alloc(sizeof(mr_params));
-       returned_tuples *tp = (returned_tuples *)
-               db_alloc(sizeof(returned_tuples));
-       register char **nargv = (char **)malloc(argc * sizeof(char *));
-       register int i;
-       
-       OPERATION op_tmp = create_operation();
-
-       if (mr_trim_args(argc, argv) == MR_NO_MEM) {
-           com_err(whoami, MR_NO_MEM, "while trimming args");
-       }
-       if (log_flags & LOG_RESP)
-               log_args("return: ", cp->args->mr_version_no, argc, argv);
-
-       tp->op = op_tmp;
-       tp->retval = arg_tmp;
-       tp->next = NULL;
-       
-       arg_tmp->mr_status = MR_MORE_DATA;
-       arg_tmp->mr_version_no = cp->args->mr_version_no;
-       arg_tmp->mr_argc = argc;
-       arg_tmp->mr_argv = nargv;
-       for (i = 0; i < argc; i++) {
-               register int len = strlen(argv[i]) + 1;
-               nargv[i] = malloc(len);
-               bcopy(argv[i], nargv[i], len);
-       }
-       arg_tmp->mr_flattened = (char *)NULL;
-       arg_tmp->mr_argl = (int *)NULL;
-
-       if (cp->last) {
-               cp->last->next = tp;
-               cp->last = tp;
-       } else {
-               cp->last = cp->first = tp;
-       }
-       
-       reset_operation(op_tmp);
-       initialize_operation(op_tmp, mr_start_send, (char *)arg_tmp,
-                            (int (*)())NULL);
-       queue_operation(cp->con, CON_OUTPUT, op_tmp);
+  client *cp = (client *)p_cp;
+  mr_params *arg_tmp;
+  returned_tuples *tp;
+  OPERATION op_tmp;
+  char **nargv;
+  int i;
+
+  if (row_count++ >= max_row_count)
+    {
+      dbms_errno = mr_errcode = MR_NO_MEM;
+      return;
+    }
+
+  /*
+   * This takes too much advantage of the fact that
+   * serialization of the data happens during the queue operation.
+   */
+  arg_tmp = db_alloc(sizeof(mr_params));
+  tp = db_alloc(sizeof(returned_tuples));
+  nargv = malloc(argc * sizeof(char *));
+
+  op_tmp = create_operation();
+
+  if (mr_trim_args(argc, argv) == MR_NO_MEM)
+    com_err(whoami, MR_NO_MEM, "while trimming args");
+  if (log_flags & LOG_RESP)
+    log_args("return: ", cp->args->mr_version_no, argc, argv);
+
+  tp->op = op_tmp;
+  tp->retval = arg_tmp;
+  tp->next = NULL;
+
+  arg_tmp->mr_status = MR_MORE_DATA;
+  arg_tmp->mr_version_no = cp->args->mr_version_no;
+  arg_tmp->mr_argc = argc;
+  arg_tmp->mr_argv = nargv;
+  for (i = 0; i < argc; i++)
+    {
+      int len = strlen(argv[i]) + 1;
+      nargv[i] = malloc(len);
+      memcpy(nargv[i], argv[i], len);
+    }
+  arg_tmp->mr_flattened = NULL;
+  arg_tmp->mr_argl = NULL;
+
+  if (cp->last)
+    {
+      cp->last->next = tp;
+      cp->last = tp;
+    } else
+      cp->last = cp->first = tp;
+
+  reset_operation(op_tmp);
+  initialize_operation(op_tmp, mr_start_send, (char *)arg_tmp, NULL);
+  queue_operation(cp->con, CON_OUTPUT, op_tmp);
 }
 
-list_users(callbk, callarg)
-       int (*callbk)();
-       char *callarg;
+int list_users(int (*callbk)(), char *callarg)
 {
-       char *argv[6];
-       char buf[30];
-       char buf1[30];
-       int i;
-       extern client **clients;
-       extern char *inet_ntoa();
-       char *cp;
-       char *index();
-       char *ctime();
-
-       for (i = 0; i < nclients; i++) {
-               register client *cl = clients[i];
-               if (cl->clname) 
-                       argv[0] = cl->clname;
-               else argv[0] = "unauthenticated";
-               
-               argv[1] = inet_ntoa(cl->haddr.sin_addr);
-               argv[2] = buf;
-               sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
-               argv[3] = ctime(&cl->last_time_used);
-               cp = index(argv[3], '\n');
-               if (cp) *cp = '\0';
-               argv[4] = buf1;
-               sprintf(buf1, "[#%d]", cl->id);
-               (*callbk)(5, argv, callarg);
-       }
-       return 0;
+  char *argv[6];
+  char buf[30];
+  char buf1[30];
+  int i;
+  extern client **clients;
+  char *cp;
+  char *ctime();
+
+  for (i = 0; i < nclients; i++)
+    {
+      client *cl = clients[i];
+      if (cl->clname)
+       argv[0] = cl->clname;
+      else argv[0] = "unauthenticated";
+
+      argv[1] = inet_ntoa(cl->haddr.sin_addr);
+      argv[2] = buf;
+      sprintf(buf, "port %d", ntohs(cl->haddr.sin_port));
+      argv[3] = ctime(&cl->last_time_used);
+      cp = strchr(argv[3], '\n');
+      if (cp)
+       *cp = '\0';
+      argv[4] = buf1;
+      sprintf(buf1, "[#%d]", cl->id);
+      (*callbk)(5, argv, callarg);
+    }
+  return 0;
 }
 
-do_retr(cl)
-       register client *cl;
+do_retr(client *cl)
 {
-       register char *queryname;
-
-       cl->reply.mr_argc = 0;
-       cl->reply.mr_status = 0;
-
-       queryname = cl->args->mr_argv[0];
-       
-       if (cl->args->mr_version_no == MR_VERSION_2)
-         newqueries++;
-       else
-         oldqueries++;
-
-       if (strcmp(queryname, "_list_users") == 0)
-               cl->reply.mr_status = list_users(retr_callback, (char *)cl);
-       else {
-               cl->reply.mr_status = 
-                       mr_process_query(cl,
-                                         cl->args->mr_argv[0],
-                                         cl->args->mr_argc-1,
-                                         cl->args->mr_argv+1,
-                                         retr_callback,
-                                         (char *)cl);
-       }
-       if (log_flags & LOG_RES)
-               com_err(whoami, 0, "Query complete.");
+  char *queryname;
+
+  cl->reply.mr_argc = 0;
+  cl->reply.mr_status = 0;
+  row_count = 0;
+
+  if (cl->args->mr_argc < 1)
+    {
+      cl->reply.mr_status = MR_ARGS;
+      com_err(whoami, MR_ARGS, "got nameless query");
+      return;
+    }
+  queryname = cl->args->mr_argv[0];
+
+  if (cl->args->mr_version_no == MR_VERSION_2)
+    newqueries++;
+  else
+    oldqueries++;
+
+  if (!strcmp(queryname, "_list_users"))
+    cl->reply.mr_status = list_users(retr_callback, (char *)cl);
+  else
+    {
+      cl->reply.mr_status = mr_process_query(cl, queryname,
+                                            cl->args->mr_argc - 1,
+                                            cl->args->mr_argv + 1,
+                                            retr_callback, (char *)cl);
+    }
+  if (row_count >= max_row_count)
+    {
+      critical_alert("moirad", "attempted query %s with %d rows\n",
+                    queryname, row_count);
+    }
+
+  if (log_flags & LOG_RES)
+    com_err(whoami, 0, "Query complete.");
 }
 
-do_access(cl)
-       client *cl;
+do_access(client *cl)
 {
-       cl->reply.mr_argc = 0;
-
-       cl->reply.mr_status = 
-         mr_check_access(cl,
-                          cl->args->mr_argv[0],
-                          cl->args->mr_argc-1,
-                          cl->args->mr_argv+1);
-       
-       com_err(whoami, 0, "Access check complete.");
+  if (cl->args->mr_argc < 1)
+    {
+      cl->reply.mr_status = MR_ARGS;
+      com_err(whoami, MR_ARGS, "got nameless access");
+      return;
+    }
+  cl->reply.mr_argc = 0;
+
+  cl->reply.mr_status = mr_check_access(cl, cl->args->mr_argv[0],
+                                       cl->args->mr_argc - 1,
+                                       cl->args->mr_argv + 1);
+
+  com_err(whoami, 0, "Access check complete.");
 }
 
 
-/* trigger_dcm is also used as a followup routine to the 
+/* trigger_dcm is also used as a followup routine to the
  * set_server_host_override query, hence the two dummy arguments.
  */
 
 struct query pseudo_query = {
-       "trigger_dcm",
-       "tdcm",
+  "trigger_dcm",
+  "tdcm",
 };
 
-trigger_dcm(dummy0, dummy1, cl)
-       int dummy0, dummy1;
-       client *cl;
+int trigger_dcm(int dummy0, int dummy1, client *cl)
 {
-       register int pid;
-       char prog[128];
-
-       cl->reply.mr_argc = 0;
-
-       if (cl->reply.mr_status = check_query_access(&pseudo_query, 0, cl) )
-               return(cl->reply.mr_status);
-
-       sprintf(prog, "%s/startdcm", BIN_DIR);
-       pid = vfork();
-       switch (pid) {
-       case 0:
-               for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
-                 close(dummy0);
-               execl(prog, "startdcm", 0);
-               exit(1);
-               
-       case -1:
-               cl->reply.mr_status = errno;
-               return(0);
-
-       default:
-               return(0);
-       }
+  int pid;
+  char prog[128];
+
+  cl->reply.mr_argc = 0;
+
+  if ((cl->reply.mr_status = check_query_access(&pseudo_query, 0, cl)))
+    return cl->reply.mr_status;
+
+  sprintf(prog, "%s/startdcm", BIN_DIR);
+  pid = vfork();
+  switch (pid)
+    {
+    case 0:
+      execl(prog, "startdcm", 0);
+      exit(1);
+
+    case -1:
+      cl->reply.mr_status = errno;
+      return 0;
+
+    default:
+      return 0;
+    }
 }
 
 
-get_motd(cl)
-client *cl;
+get_motd(client *cl)
 {
-    int motd, len;
-    char buffer[1024];
-    char *arg[1];
-
-    arg[0] = buffer;
-    cl->reply.mr_status = 0;
-    motd = open(MOIRA_MOTD_FILE, 0, O_RDONLY);
-    if (motd < 0) return;
-    len = read(motd, buffer, sizeof(buffer) - 1);
-    close(motd);
-    buffer[len] = 0;
-    retr_callback(1, arg, cl);
-    cl->reply.mr_status = 0;
+  int motd, len;
+  char buffer[1024];
+  char *arg[1];
+
+  arg[0] = buffer;
+  cl->reply.mr_status = 0;
+  motd = open(MOIRA_MOTD_FILE, 0, O_RDONLY);
+  if (motd < 0)
+    return;
+  len = read(motd, buffer, sizeof(buffer) - 1);
+  close(motd);
+  buffer[len] = 0;
+  row_count = 0;
+  retr_callback(1, arg, cl);
+  cl->reply.mr_status = 0;
 }
This page took 0.070628 seconds and 4 git commands to generate.