source: trunk/third/moira/clients/lib/pobox.c @ 24319

Revision 24319, 3.8 KB checked in by broder, 15 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: pobox.c 3956 2010-01-05 20:56:56Z zacheiss $
2 *
3 * Shared routines for pobox changing.
4 *
5 * Copyright (C) 1999 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include <mrclient.h>
13#include "mrclient-internal.h"
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#include <com_err.h>
20
21RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/clients/lib/pobox.c $ $Id: pobox.c 3956 2010-01-05 20:56:56Z zacheiss $");
22
23static int save_sloc_machine(int argc, char **argv, void *sq);
24static int save_alias_value(int argc, char **argv, void *sq);
25
26extern char *whoami;
27
28#ifdef _WIN32
29#define strtok_r(s, tokens, resume) strtok(s, tokens)
30#endif /* _WIN32 */
31
32int mrcl_validate_pobox_smtp(char *user, char *address, char **ret)
33{
34  char *addr, *retaddr, *p, *lasts = NULL;
35  char *machine = NULL, *m;
36  int oldlen, len, status = MRCL_SUCCESS;
37
38  /* Make a private copy of address that we can mangle. */
39  addr = strdup(address);
40
41  retaddr = strdup("");
42  len = 1;
43
44  /* For each comma-delimited address, canonicalize the hostname and
45   * verify that the address won't cause mail problems.
46   */
47  for (p = strtok_r(addr, ", ", &lasts); p; p = strtok_r(NULL, ",", &lasts))
48    {
49      m = strchr(p, '@');
50      if (m)
51        {
52          *m++ = '\0';          /* get rid of the @ sign */
53          m = strtrim(m);       /* get rid of whitespace */
54        }
55      else
56        {
57          mrcl_set_message("No at sign (@) in address \"%s\".", p);
58          status = MRCL_REJECT;
59          goto cleanup;
60        }
61
62      if (strlen(m) > 0)
63        {
64          machine = canonicalize_hostname(strdup(m));
65        }
66      else
67        {
68          mrcl_set_message("No hostname in address \"%s@\".", p);
69          status = MRCL_REJECT;
70          goto cleanup;
71        }
72     
73      switch (mailtype(machine))
74        {
75        case MAILTYPE_IMAP:
76          mrcl_set_message("Cannot forward mail to IMAP server %s.\n "
77                           "Use \"chpobox -p\" if you are trying to unset "
78                           "your mail forwarding.", machine);
79          status = MRCL_REJECT;
80          goto cleanup;
81
82        case MAILTYPE_POP:
83          if (strcmp(p, user))
84            {
85              mrcl_set_message("The name on the POP box (%s) must match "
86                               "the username (%s).", p, user);
87              status = MRCL_REJECT;
88              goto cleanup;
89            }
90          /* Fall through */
91
92        case MAILTYPE_LOCAL:
93          if ((m = strchr(machine, '.')))
94            *m = '\0';
95          machine = realloc(machine, strlen(machine) + 6);
96          strcat(machine, ".LOCAL");
97          break;
98
99        case MAILTYPE_MAILHUB:
100        case MAILTYPE_EXCHANGE:
101          if (!strcmp(p, user))
102            {
103              mrcl_set_message("The address \"%s@%s\" would create a mail "
104                               "loop.\nSet a POP pobox if you want local "
105                               "mail delivery.", p, machine);
106              status = MRCL_REJECT;
107              goto cleanup;
108            }
109          else
110            {
111              mrcl_set_message("Cannot forward mail to a local mailing "
112                               "address (%s@%s).", p, machine);
113              status = MRCL_REJECT;
114              goto cleanup;
115            }
116
117        case MAILTYPE_SMTP:
118          if (*m != '"' && strcasecmp(m, machine))
119            {
120              mrcl_set_message("Warning: hostname %s canonicalized to %s\n",
121                               m, machine);
122            }
123          break;
124
125        default:
126          status = MRCL_MOIRA_ERROR;
127          goto cleanup;
128        }
129
130      oldlen = len;
131      len += (oldlen > 1 ? 2 : 0) + strlen(p) + strlen(machine) + 1;
132      retaddr = realloc(retaddr, len);
133      sprintf(retaddr + oldlen - 1, "%s%s@%s", oldlen > 1 ? ", " : "",
134              p, machine);
135      free(machine);
136      machine = NULL; /* Make sure it doesn't get freed again later. */
137    }
138
139 cleanup:
140  free(addr);
141  if (status == MRCL_SUCCESS)
142    *ret = retaddr;
143  else
144    free(retaddr);
145  free(machine);
146
147  return status;
148}
149
150static int save_sloc_machine(int argc, char **argv, void *sq)
151{
152  sq_save_data(sq, strdup(argv[1]));
153  return MR_CONT;
154}
155
156static int save_alias_value(int argc, char **argv, void *sq)
157{
158  sq_save_data(sq, strdup(argv[2]));
159  return MR_CONT;
160}
Note: See TracBrowser for help on using the repository browser.