]> andersk Git - moira.git/commitdiff
Heap o' new functionality. Specifically:
authorzacheiss <zacheiss>
Thu, 10 Aug 2000 02:05:35 +0000 (02:05 +0000)
committerzacheiss <zacheiss>
Thu, 10 Aug 2000 02:05:35 +0000 (02:05 +0000)
* better checking of STRING members of lists.

* support for canonicalizing KERBEROS members of lists.

* new error reporting interface, for clients that don't want to use
  com_err.

* remove potype(), and replace it with mailtype() in mail.c

clients/lib/Makefile.in
clients/lib/error.c [new file with mode: 0644]
clients/lib/mail.c [new file with mode: 0644]
clients/lib/member.c [new file with mode: 0644]
clients/lib/mrclient-internal.h [new file with mode: 0644]
clients/lib/pobox.c

index 2fce070b797480761cf0dd9a81d955be91fa30c3..66f43c16aea23e0baad427ab282b1c83cdaa8be1 100644 (file)
@@ -14,7 +14,7 @@ VPATH=@srcdir@
 SRCTOP=@top_srcdir@
 BUILDTOP=../..
 
-OBJS=pobox.o utils.o
+OBJS=error.o mail.o member.o pobox.o utils.o
 
 .c.o:
        $(CC) -c $(ALL_CFLAGS) $<
diff --git a/clients/lib/error.c b/clients/lib/error.c
new file mode 100644 (file)
index 0000000..7fb0c7d
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id$
+ *
+ * mrcl error interface
+ *
+ * Copyright (C) 1999 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <moira.h>
+#include <mrclient.h>
+#include "mrclient-internal.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <com_err.h>
+
+RCSID("$Header$");
+
+static char *mrcl_message = NULL;
+
+void mrcl_set_message(char *fmt, ...)
+{
+  int args, len;
+  char *p;
+  va_list ap;
+
+  free(mrcl_message);
+
+  /* Count "%s"s */
+  for (args = 0, p = strstr(fmt, "%s"); p; p = strstr(p + 2, "%s"))
+    args++;
+
+  /* Measure the output string. */
+  len = strlen(fmt) + 1;
+  va_start(ap, fmt);
+  while (args--)
+    {
+      p = va_arg(ap, char *);
+      len += strlen(p);
+    }
+  va_end(ap);
+
+  /* Malloc and print */
+  mrcl_message = malloc(len);
+  if (mrcl_message)
+    {
+      va_start(ap, fmt);
+      vsprintf(mrcl_message, fmt, ap);
+      va_end(ap);
+    }
+}
+
+char *mrcl_get_message(void)
+{
+  return mrcl_message;
+}
+
+void mrcl_clear_message(void)
+{
+  free(mrcl_message);
+  mrcl_message = NULL;
+}
+
+void mrcl_com_err(char *whoami)
+{
+  if (mrcl_message)
+    com_err(whoami, 0, "%s", mrcl_message);
+}
diff --git a/clients/lib/mail.c b/clients/lib/mail.c
new file mode 100644 (file)
index 0000000..ee91fa2
--- /dev/null
@@ -0,0 +1,189 @@
+/* $Id$
+ *
+ * Library-internal routines for categorizing machines in terms
+ * of email.
+ *
+ * Copyright (C) 1999 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <moira.h>
+#include <mrclient.h>
+#include "mrclient-internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+RCSID("$Header$");
+
+static int save_sloc_machine(int argc, char **argv, void *sq);
+static int save_alias_value(int argc, char **argv, void *sq);
+
+/* Given a canonicalized machine name, ask the Moira server if it is of type
+ * POP, LOCAL, or MAILHUB -- if none of those, we assume it's FOREIGN.
+ */
+int mailtype(char *machine)
+{
+  char *name;
+  int status, match = 0;
+  static struct save_queue *pop = NULL, *local = NULL;
+  static struct save_queue *mailhub = NULL, *mailhub_name = NULL;
+  static struct save_queue *imap = NULL,
+
+  mrcl_clear_message();
+
+  /* 1. Check if the machine is an IMAP server. */
+  if (!imap)
+    {
+      char *service = "POSTOFFICE";
+      imap = sq_create();
+      status = mr_query("get_server_locations", 1, &service,
+                       save_sloc_machine, imap);
+      if (status && (status != MR_NO_MATCH))
+       {
+         mrcl_set_message("Could not read list of IMAP servers: %s",
+                          error_message(status));
+         return MAILTYPE_ERROR;
+       }
+    }
+
+  /* Because of how sq_get_data works, we need to go through the entire
+   * queue even if we find a match, so that it gets reset for the next
+   * call.
+   */
+  while (sq_get_data(imap, &name))
+    {
+      if (!match && !strcasecmp(name, machine))
+       match = 1;
+    }
+
+  if (match)
+    return MAILTYPE_IMAP;
+
+
+  /* 2. Check if the machine is a POP server. */
+  if (!pop)
+    {
+      char *service = "POP";
+      pop = sq_create();
+      status = mr_query("get_server_locations", 1, &service,
+                       save_sloc_machine, pop);
+      if (status && (status != MR_NO_MATCH))
+       {
+         mrcl_set_message("Could not read list of POP servers: %s",
+                          error_message(status));
+         return MAILTYPE_ERROR;
+       }
+    }
+  
+  /* Because of how sq_get_data works, we need to go through the entire
+   * queue even if we find a match, so that it gets reset for the next
+   * call.
+   */
+  while (sq_get_data(pop, &name))
+    {
+      if (!match && !strcasecmp(name, machine))
+       match = 1;
+    }
+  if (match)
+    return MAILTYPE_POP;
+
+
+  /* 3. Check if the machine is "LOCAL". */
+  if (!local)
+    {
+      char *service = "LOCAL";
+      local = sq_create();
+      status = mr_query("get_server_locations", 1, &service,
+                       save_sloc_machine, local);
+      if (status && (status != MR_NO_MATCH))
+       {
+         mrcl_set_message("Could not read list of LOCAL servers: %s",
+                          error_message(status));
+         return MAILTYPE_ERROR;
+       }
+    }
+
+  while (sq_get_data(local, &name))
+    {
+      if (!match && !strcasecmp(name, machine))
+       match = 1;
+    }
+  if (match)
+    return MAILTYPE_LOCAL;
+
+  
+  /* 4. Check if the machine is one of the mailhubs. */
+  if (!mailhub)
+    {
+      char *service = "MAILHUB";
+      mailhub = sq_create();
+      status = mr_query("get_server_locations", 1, &service,
+                       save_sloc_machine, mailhub);
+      if (!status || status == MR_NO_MATCH)
+       {
+         service = "NMAILHUB";
+         status = mr_query("get_server_locations", 1, &service,
+                           save_sloc_machine, mailhub);
+       }
+
+      if (status && (status != MR_NO_MATCH))
+       {
+         mrcl_set_message("Could not read list of MAILHUB servers: %s",
+                          error_message(status));
+         return MAILTYPE_ERROR;
+       }
+
+    }
+
+  while (sq_get_data(mailhub, &name))
+    {
+      if (!match && !strcasecmp(name, machine))
+       match = 1;
+    }
+  if (match)
+    return MAILTYPE_MAILHUB;
+
+
+  /* 5. Check if the machine is one of the external names of the mailhubs. */
+  if (!mailhub_name)
+    {
+      char *argv[3];
+      mailhub_name = sq_create();
+      argv[0] = "mailhub";
+      argv[1] = "TYPE";
+      argv[2] = "*";
+      status = mr_query("get_alias", 3, argv, save_alias_value, mailhub_name);
+      if (status && (status != MR_NO_MATCH))
+       {
+         mrcl_set_message("Could not read list of mailhub names: %s",
+                          error_message(status));
+         return MAILTYPE_ERROR;
+       }
+    }
+
+  while (sq_get_data(mailhub_name, &name))
+    {
+      if (!match && !strcasecmp(name, machine))
+       match = 1;
+    }
+  if (match)
+    return MAILTYPE_MAILHUB;
+
+  return MAILTYPE_SMTP;
+}
+
+static int save_sloc_machine(int argc, char **argv, void *sq)
+{
+  sq_save_data(sq, strdup(argv[1]));
+  return MR_CONT;
+}
+
+static int save_alias_value(int argc, char **argv, void *sq)
+{
+  sq_save_data(sq, canonicalize_hostname(strdup(argv[2])));
+  return MR_CONT;
+}
diff --git a/clients/lib/member.c b/clients/lib/member.c
new file mode 100644 (file)
index 0000000..a3beadc
--- /dev/null
@@ -0,0 +1,103 @@
+/* $Id$
+ *
+ * Shared routines for playing with list membership.
+ *
+ * Copyright (C) 1999 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <moira.h>
+#include <mrclient.h>
+#include "mrclient-internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <krb.h>
+
+RCSID("$Header$");
+
+static char default_realm[REALM_SZ];
+
+int mrcl_validate_string_member(char *str)
+{
+  char *p, *lname;
+
+  p = strchr(str, '@');
+  if (p)
+    {
+      char *host = canonicalize_hostname(strdup(++p));
+
+      if (mailtype(host) != MAILTYPE_SMTP)
+       {
+         free(host);
+         lname = strdup(str);
+         *strchr(str, '@') = '\0';
+         mrcl_set_message("STRING \"%s\" should be USER or LIST \"%s\" "
+                          "because it is a local name.", lname, str);
+         free(lname);
+         return MRCL_REJECT;
+       }
+      free(host);
+    }
+  else if (!strpbrk(str, "%!"))
+    {
+      mrcl_set_message("STRING \"%s\" is not a foreign mail address.\nAdding "
+                      "it to a mailing list may cause the list to break.",
+                      lname);
+      return MRCL_REJECT;
+    }
+
+  mrcl_clear_message();
+  return MRCL_SUCCESS;
+}
+
+int mrcl_validate_kerberos_member(char *str, char **ret)
+{
+  char *p;
+
+  mrcl_clear_message();
+
+  p = strchr(str, '@');
+  if (!p)
+    {
+      /* An IP address is not a Kerberos principal, but we allow it
+       * for AFS purposes.
+       */
+      if (strtoul(str, &p, 10) < 256 && (*p == '.') &&
+         strtoul(p + 1, &p, 10) < 256 && (*p == '.') &&
+         strtoul(p + 1, &p, 10) < 256 && (*p == '.') &&
+         strtoul(p + 1, &p, 10) < 256 && !*p)
+       {
+         *ret = strdup(str);
+         return MRCL_SUCCESS;
+       }
+
+      if (!*default_realm)
+       krb_get_lrealm(default_realm, 1);
+
+      *ret = malloc(strlen(str) + strlen(default_realm) + 2);
+      sprintf(*ret, "%s@%s", str, default_realm);
+
+      mrcl_set_message("Warning: default realm \"%s\" added to principal "
+                      "\"%s\"", default_realm, str);
+      return MRCL_SUCCESS;
+    }
+
+  /* Check capitalization. */
+  *ret = strdup(str);
+  p = strchr(*ret, '@');
+  while (*++p)
+    {
+      if (islower(*p))
+       {
+         *p = toupper(*p);
+         mrcl_set_message("Warning: set realm in \"%s\" to all caps.", *ret);
+       }
+    }
+
+  return MRCL_SUCCESS;
+}
diff --git a/clients/lib/mrclient-internal.h b/clients/lib/mrclient-internal.h
new file mode 100644 (file)
index 0000000..b0afcec
--- /dev/null
@@ -0,0 +1,17 @@
+/* $Id$
+ *
+ * Copyright (C) 1999 by the Massachusetts Institute of Technology
+ *
+ */
+
+#ifndef _mrclient_internal_h_
+#define _mrclient_internal_h_
+
+void mrcl_set_message(char *, ...);
+void mrcl_clear_message(void);
+
+enum { MAILTYPE_ERROR, MAILTYPE_IMAP, MAILTYPE_POP, 
+       MAILTYPE_LOCAL, MAILTYPE_MAILHUB, MAILTYPE_SMTP };
+int mailtype(char *machine);
+
+#endif /* _mrclient_internal_h_ */
index b8c9475920cef0cfacafacc85b8fb509a8062d84..247647f52af26af40eb31804958cbe62c6b8eca4 100644 (file)
@@ -10,6 +10,7 @@
 #include <mit-copyright.h>
 #include <moira.h>
 #include <mrclient.h>
+#include "mrclient-internal.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -19,8 +20,6 @@
 
 RCSID("$Header$");
 
-enum { POTYPE_ERROR, POTYPE_POP, POTYPE_LOCAL, POTYPE_MAILHUB, POTYPE_SMTP, POTYPE_IMAP };
-static int potype(char *machine);
 static int save_sloc_machine(int argc, char **argv, void *sq);
 static int save_alias_value(int argc, char **argv, void *sq);
 
@@ -55,7 +54,7 @@ int mrcl_validate_pobox_smtp(char *user, char *address, char **ret)
        }
       else
        {
-         com_err(whoami, 0, "No at sign (@) in address \"%s\".", p);
+         mrcl_set_message("No at sign (@) in address \"%s\".", p);
          status = MRCL_REJECT;
          goto cleanup;
        }
@@ -66,61 +65,59 @@ int mrcl_validate_pobox_smtp(char *user, char *address, char **ret)
        }
       else
        {
-         com_err(whoami, 0, "No hostname in address \"%s@\".", p);
+         mrcl_set_message("No hostname in address \"%s@\".", p);
          status = MRCL_REJECT;
          goto cleanup;
        }
       
-      switch (potype(machine))
+      switch (mailtype(machine))
        {
-       case POTYPE_IMAP:
-         com_err(whoami, 0, "Cannot forward mail to IMAP server %s", 
-                 machine);
-         com_err(NULL, 0, "Use \"chpobox -p\" if you are trying to unset "
-                 "your mail forwarding.");
+       case MAILTYPE_IMAP:
+         mrcl_set_message("Cannot forward mail to IMAP server %s.\n " 
+                          "Use \"chpobox -p\" if you are trying to unset "
+                          "your mail forwarding.", machine);
          status = MRCL_REJECT;
          goto cleanup;
 
-       case POTYPE_POP:
+       case MAILTYPE_POP:
          if (strcmp(p, user))
            {
-             com_err(whoami, 0, "The name on the POP box (%s) must match "
-                     "the username (%s).", p, user);
+             mrcl_set_message("The name on the POP box (%s) must match "
+                              "the username (%s).", p, user);
              status = MRCL_REJECT;
              goto cleanup;
            }
          /* Fall through */
 
-       case POTYPE_LOCAL:
+       case MAILTYPE_LOCAL:
          if ((m = strchr(machine, '.')))
            *m = '\0';
          machine = realloc(machine, strlen(machine) + 6);
          strcat(machine, ".LOCAL");
          break;
 
-       case POTYPE_MAILHUB:
+       case MAILTYPE_MAILHUB:
          if (!strcmp(p, user))
            {
-             com_err(whoami, 0, "The address \"%s@%s\" would create a mail "
-                     "loop.", p, machine);
-             com_err(NULL, 0, "Set a POP pobox if you want local mail "
-                     "delivery.");
+             mrcl_set_message("The address \"%s@%s\" would create a mail "
+                              "loop.\nSet a POP pobox if you want local "
+                              "mail delivery.", p, machine);
              status = MRCL_REJECT;
              goto cleanup;
            }
          else
            {
-             com_err(whoami, 0, "Cannot forward mail to a local mailing "
-                     "address (%s@%s).", p, machine);
+             mrcl_set_message("Cannot forward mail to a local mailing "
+                              "address (%s@%s).", p, machine);
              status = MRCL_REJECT;
              goto cleanup;
            }
 
-       case POTYPE_SMTP:
+       case MAILTYPE_SMTP:
          if (*m != '"' && strcasecmp(m, machine))
            {
-             com_err(whoami, 0, "Warning: hostname %s canonicalized to %s\n",
-                     m, machine);
+             mrcl_set_message("Warning: hostname %s canonicalized to %s\n",
+                              m, machine);
            }
          break;
 
@@ -141,7 +138,10 @@ int mrcl_validate_pobox_smtp(char *user, char *address, char **ret)
  cleanup:
   free(addr);
   if (status == MRCL_SUCCESS)
-    *ret = retaddr;
+    {
+      *ret = retaddr;
+      mrcl_clear_message();
+    }
   else
     free(retaddr);
   free(machine);
@@ -149,142 +149,6 @@ int mrcl_validate_pobox_smtp(char *user, char *address, char **ret)
   return status;
 }
 
-/* Given a canonicalized machine name, ask the Moira server if it is
- * of type IMAP, POP, LOCAL, or MAILHUB -- if none of those, we assume
- * it's foreign.  
- */
-static int potype(char *machine)
-{
-  char *name;
-  int status, match = 0;
-  static struct save_queue *pop = NULL, *local = NULL;
-  static struct save_queue *mailhub = NULL, *mailhub_name = NULL;
-  static struct save_queue *imap = NULL;
-
-  /* 0. Check if the machine is an IMAP server. */
-  if (!imap)
-    {
-      char *service = "POSTOFFICE";
-      imap = sq_create();
-      status = mr_query("get_server_locations", 1, &service,
-                       save_sloc_machine, imap);
-      if (status && (status != MR_NO_MATCH))
-       {
-         com_err(whoami, status, "while reading list of IMAP servers");
-         return POTYPE_ERROR;
-       }
-    }
-
-  /* Because of how sq_get_data works, we need to go through the entire
-   * queue even if we find a match, so that it gets reset for the next
-   * call.
-   */
-  while (sq_get_data(imap, &name))
-    {
-      if (!match && !strcasecmp(name, machine))
-       match = 1;
-    }
-
-  if (match)
-    return POTYPE_IMAP;
-
-
-  /* 1. Check if the machine is a POP server. */
-  if (!pop)
-    {
-      char *service = "POP";
-      pop = sq_create();
-      status = mr_query("get_server_locations", 1, &service,
-                       save_sloc_machine, pop);
-      if (status && (status != MR_NO_MATCH))
-       {
-         com_err(whoami, status, "while reading list of POP servers");
-         return POTYPE_ERROR;
-       }
-    }
-
-  while (sq_get_data(pop, &name))
-    {
-      if (!match && !strcasecmp(name, machine))
-       match = 1;
-    }
-  if (match)
-    return POTYPE_POP;
-
-
-  /* 2. Check if the machine is "LOCAL". */
-  if (!local)
-    {
-      char *service = "LOCAL";
-      local = sq_create();
-      status = mr_query("get_server_locations", 1, &service,
-                       save_sloc_machine, local);
-      if (status && (status != MR_NO_MATCH))
-       {
-         com_err(whoami, status, "while reading list of LOCAL servers");
-         return POTYPE_ERROR;
-       }
-    }
-
-  while (sq_get_data(local, &name))
-    {
-      if (!match && !strcasecmp(name, machine))
-       match = 1;
-    }
-  if (match)
-    return POTYPE_LOCAL;
-
-  
-  /* 3. Check if the machine is one of the mailhubs. */
-  if (!mailhub)
-    {
-      char *service = "MAILHUB";
-      mailhub = sq_create();
-      status = mr_query("get_server_locations", 1, &service,
-                       save_sloc_machine, mailhub);
-      if (status && (status != MR_NO_MATCH))
-       {
-         com_err(whoami, status, "while reading list of MAILHUB servers");
-         return POTYPE_ERROR;
-       }
-    }
-
-  while (sq_get_data(mailhub, &name))
-    {
-      if (!match && !strcasecmp(name, machine))
-       match = 1;
-    }
-  if (match)
-    return POTYPE_MAILHUB;
-
-
-  /* 4. Check if the machine is one of the external names of the mailhubs. */
-  if (!mailhub_name)
-    {
-      char *argv[3];
-      mailhub_name = sq_create();
-      argv[0] = "mailhub";
-      argv[1] = "TYPE";
-      argv[2] = "*";
-      status = mr_query("get_alias", 3, argv, save_alias_value, mailhub_name);
-      if (status && (status != MR_NO_MATCH))
-       {
-         com_err(whoami, status, "while reading list of mailhub names");
-         return POTYPE_ERROR;
-       }
-    }
-
-  while (sq_get_data(mailhub_name, &name))
-    {
-      if (!match && !strcasecmp(name, machine))
-       match = 1;
-    }
-  if (match)
-    return POTYPE_MAILHUB;
-
-  return POTYPE_SMTP;
-}
-
 static int save_sloc_machine(int argc, char **argv, void *sq)
 {
   sq_save_data(sq, strdup(argv[1]));
This page took 0.085375 seconds and 5 git commands to generate.