]> andersk Git - moira.git/blob - clients/lib/pobox.c
bb4535b95cc1c0871dc77bbb87d49c9f75b02a3a
[moira.git] / clients / lib / pobox.c
1 /* $Id$
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
21 RCSID("$Header$");
22
23 static int save_sloc_machine(int argc, char **argv, void *sq);
24 static int save_alias_value(int argc, char **argv, void *sq);
25
26 extern char *whoami;
27
28 #ifdef _WIN32
29 #define strtok_r(s, tokens, resume) strtok(s, tokens)
30 #endif /* _WIN32 */
31
32 int 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           if (!strcmp(p, user))
101             {
102               mrcl_set_message("The address \"%s@%s\" would create a mail "
103                                "loop.\nSet a POP pobox if you want local "
104                                "mail delivery.", p, machine);
105               status = MRCL_REJECT;
106               goto cleanup;
107             }
108           else
109             {
110               mrcl_set_message("Cannot forward mail to a local mailing "
111                                "address (%s@%s).", p, machine);
112               status = MRCL_REJECT;
113               goto cleanup;
114             }
115
116         case MAILTYPE_SMTP:
117           if (*m != '"' && strcasecmp(m, machine))
118             {
119               mrcl_set_message("Warning: hostname %s canonicalized to %s\n",
120                                m, machine);
121             }
122           break;
123
124         default:
125           status = MRCL_MOIRA_ERROR;
126           goto cleanup;
127         }
128
129       oldlen = len;
130       len += (oldlen > 1 ? 2 : 0) + strlen(p) + strlen(machine) + 1;
131       retaddr = realloc(retaddr, len);
132       sprintf(retaddr + oldlen - 1, "%s%s@%s", oldlen > 1 ? ", " : "",
133               p, machine);
134       free(machine);
135       machine = NULL; /* Make sure it doesn't get freed again later. */
136     }
137
138  cleanup:
139   free(addr);
140   if (status == MRCL_SUCCESS)
141     *ret = retaddr;
142   else
143     free(retaddr);
144   free(machine);
145
146   return status;
147 }
148
149 static int save_sloc_machine(int argc, char **argv, void *sq)
150 {
151   sq_save_data(sq, strdup(argv[1]));
152   return MR_CONT;
153 }
154
155 static int save_alias_value(int argc, char **argv, void *sq)
156 {
157   sq_save_data(sq, strdup(argv[2]));
158   return MR_CONT;
159 }
This page took 0.877524 seconds and 3 git commands to generate.