]> andersk Git - moira.git/blobdiff - server/mr_scall.c
use read(), not streams to read motd file
[moira.git] / server / mr_scall.c
index 5aac2566f4805a0900c43d9ce5545dc8ec7a7138..574ced8ec272526b9ba72103f1bd9b711dd7d23b 100644 (file)
@@ -4,47 +4,28 @@
  *     $Header$
  *
  *     Copyright (C) 1987 by the Massachusetts Institute of Technology
+ *     For copying and distribution information, please see the file
+ *     <mit-copyright.h>.
  *
- *     $Log$
- *     Revision 1.8  1987-07-16 15:43:19  wesommer
- *     Fixed bug where the argv was not copied to private storage
- *     (it got changed out from under us before it got sent..).
- *
- * Revision 1.7  87/07/14  00:39:01  wesommer
- * Rearranged loggin.
- * 
- * Revision 1.6  87/06/30  20:04:43  wesommer
- * Free returned tuples when possible.
- * 
- * Revision 1.5  87/06/26  10:55:53  wesommer
- * Added sms_access, now paiys attention to return code from 
- * sms_process_query, sms_check_access.
- * 
- * Revision 1.4  87/06/21  16:42:00  wesommer
- * Performance work, rearrangement of include files.
- * 
- * Revision 1.3  87/06/04  01:35:01  wesommer
- * Added a working query request handler.
- * 
- * Revision 1.2  87/06/03  16:07:50  wesommer
- * Fixes for lint.
- * 
- * Revision 1.1  87/06/02  20:07:10  wesommer
- * Initial revision
- * 
  */
 
 #ifndef lint
 static char *rcsid_sms_scall_c = "$Header$";
 #endif lint
 
+#include <mit-copyright.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
 #include <krb.h>
 #include <errno.h>
+#include "query.h"
 #include "sms_server.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();
@@ -56,13 +37,24 @@ void
 do_client(cp)
        client *cp;
 {
+       struct stat stbuf;
+
        free_rtn_tuples(cp);
        if (OP_STATUS(cp->pending_op) == OP_CANCELLED) {
-               (void) sprintf(buf1, "Closed connection (now %d client%s)",
-                              nclients-1,
-                              nclients!=2?"s":"");
-               com_err(whoami, 0, buf1);
+               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(SMS_MOTD_FILE, &stbuf) == 0)) {
+                   com_err(whoami, 0, "motd file exists, slumbertime");
+                   dormant = SLEEPY;
+               }
                return;
        }
        switch (cp->action) {
@@ -77,6 +69,8 @@ do_client(cp)
        case CL_RECEIVE:
                /* Data is here. Process it & start it heading back */
                do_call(cp); /* This may block for a while. */
+               sms_destroy_reply(cp->args);
+               cp->args = NULL;
                initialize_operation(cp->pending_op, sms_start_send,
                                     (char *)&cp->reply, (int (*)())NULL);
                queue_operation(cp->con, CON_OUTPUT, cp->pending_op);
@@ -91,6 +85,8 @@ char *procnames[] = {
         "shutdown",
         "query",
         "access",
+        "dcm",
+        "motd",
 };
 
 
@@ -101,6 +97,7 @@ do_call(cl)
        int pn;
        cl->reply.sms_argc = 0;
        cl->reply.sms_status = 0;
+       cl->reply.sms_version_no = cl->args->sms_version_no;
        if (((pn = cl->args->sms_procno) < 0) ||
            (pn > SMS_MAX_PROC)) {
                com_err(whoami, 0, "procno out of range");
@@ -108,10 +105,18 @@ do_call(cl)
                return;
        }
        if (log_flags & LOG_ARGS)
-               log_args(procnames[pn], cl->args->sms_argc,
-                        cl->args->sms_argv);
+               log_args(procnames[pn], cl->args->sms_version_no,
+                        cl->args->sms_argc, cl->args->sms_argv);
        else if (log_flags & LOG_REQUESTS)
-               com_err(whoami, 0, procnames[pn]);
+               com_err(whoami, 0, "%s", procnames[pn]);
+
+       if ((dormant == ASLEEP || dormant == GROGGY) &&
+           pn != SMS_NOOP && pn != SMS_MOTD) {
+           cl->reply.sms_status = SMS_DOWN;
+           if (log_flags & LOG_RES)
+             com_err(whoami, SMS_DOWN, "(query refused)");
+           return;
+       }
 
        switch(pn) {
        case SMS_NOOP:
@@ -133,6 +138,14 @@ do_call(cl)
        case SMS_SHUTDOWN:
                do_shutdown(cl);
                return;
+
+       case SMS_DO_UPDATE:
+               trigger_dcm(0, 0, cl);
+               return;
+
+       case SMS_MOTD:
+               get_motd(cl);
+               return;
        }
 }
 
@@ -146,16 +159,6 @@ free_rtn_tuples(cp)
                if (t1 == cp->last) cp->last = NULL;
 
                sms_destroy_reply(t1->retval);
-#ifdef notdef
-               if (t1->retval) {
-                       register sms_params *p = t1->retval;
-                       if (p->sms_flattened)
-                               free(p->sms_flattened);
-                       if (p->sms_argl)
-                               free(p->sms_argl);
-                       free(p);
-               }
-#endif notdef
                delete_operation(t1->op);
                free(t1);
        }
@@ -180,14 +183,18 @@ retr_callback(argc, argv, p_cp)
        
        OPERATION op_tmp = create_operation();
 
+       if (sms_trim_args(argc, argv) == SMS_NO_MEM) {
+           com_err(whoami, SMS_NO_MEM, "while trimming args");
+       }
        if (log_flags & LOG_RESP)
-               log_args("return: ", argc, argv);
+               log_args("return: ", cp->args->sms_version_no, argc, argv);
 
        tp->op = op_tmp;
        tp->retval = arg_tmp;
        tp->next = NULL;
        
        arg_tmp->sms_status = SMS_MORE_DATA;
+       arg_tmp->sms_version_no = cp->args->sms_version_no;
        arg_tmp->sms_argc = argc;
        arg_tmp->sms_argv = nargv;
        for (i = 0; i < argc; i++) {
@@ -211,20 +218,65 @@ retr_callback(argc, argv, p_cp)
        queue_operation(cp->con, CON_OUTPUT, op_tmp);
 }
 
+list_users(callbk, callarg)
+       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;
+}
 
 do_retr(cl)
-       client *cl;
+       register client *cl;
 {
+       register char *queryname;
+
        cl->reply.sms_argc = 0;
        cl->reply.sms_status = 0;
 
-       cl->reply.sms_status = 
-         sms_process_query(cl,
-                           cl->args->sms_argv[0],
-                           cl->args->sms_argc-1,
-                           cl->args->sms_argv+1,
-                           retr_callback,
-                           (char *)cl);
+       queryname = cl->args->sms_argv[0];
+       
+       if (cl->args->sms_version_no == SMS_VERSION_2)
+         newqueries++;
+       else
+         oldqueries++;
+
+       if (strcmp(queryname, "_list_users") == 0)
+               cl->reply.sms_status = list_users(retr_callback, (char *)cl);
+       else {
+               cl->reply.sms_status = 
+                       sms_process_query(cl,
+                                         cl->args->sms_argv[0],
+                                         cl->args->sms_argc-1,
+                                         cl->args->sms_argv+1,
+                                         retr_callback,
+                                         (char *)cl);
+       }
        if (log_flags & LOG_RES)
                com_err(whoami, 0, "Query complete.");
 }
@@ -242,3 +294,60 @@ do_access(cl)
        
        com_err(whoami, 0, "Access check complete.");
 }
+
+
+/* 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(dummy0, dummy1, cl)
+       int dummy0, dummy1;
+       client *cl;
+{
+       register int pid;
+       
+       cl->reply.sms_argc = 0;
+
+       if (cl->reply.sms_status = check_query_access(&pseudo_query, 0, cl) )
+               return(cl->reply.sms_status);
+
+       pid = vfork();
+       switch (pid) {
+       case 0:
+               for (dummy0 = getdtablesize() - 1; dummy0 > 2; dummy0--)
+                 close(dummy0);
+               execl("/u1/sms/bin/startdcm", "startdcm", 0);
+               exit(1);
+               
+       case -1:
+               cl->reply.sms_status = errno;
+               return(0);
+
+       default:
+               return(0);
+       }
+}
+
+
+get_motd(cl)
+client *cl;
+{
+    int motd, len;
+    char buffer[1024];
+    char *arg[1];
+
+    arg[0] = buffer;
+    cl->reply.sms_status = 0;
+    motd = open(SMS_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.sms_status = 0;
+}
This page took 0.044888 seconds and 4 git commands to generate.