3 * Talk to the Moira database to change a person's home mail machine. This may
4 * be an Athena machine, or a completely arbitrary address.
6 * chpobox with no modifiers reports the current mailbox.
8 * chpobox -s [address] means set the mailbox to this address.
10 * chpobox -p restores the pobox to a previous POP box, if there was one.
12 * chpobox -u [user] is needed if you are logged in as one user, but
13 * are trying to change the email address of another. You must have
14 * Kerberos tickets as the person whose address you are trying to
15 * change, or the attempt will fail.
17 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
18 * For copying and distribution information, please see the file
22 #include <mit-copyright.h>
24 #include <moira_site.h>
36 int get_pobox(int argc, char **argv, void *callarg);
37 char *potype(char *machine);
38 int check_match(int argc, char **argv, void *callback);
39 int check_match3(int argc, char **argv, void *callback);
46 int main(int argc, char *argv[])
49 char *mrarg[3], buf[BUFSIZ], pname[ANAME_SZ];
50 char *address, *uname, *machine, *motd;
52 int c, setflag, prevpop, usageflag, status;
57 c = setflag = prevpop = usageflag = 0;
58 address = uname = NULL;
61 if ((whoami = strrchr(argv[0], '/')) == NULL)
69 while ((c = getopt(argc, argv, "s:pu:")) != -1)
89 uname = strdup(optarg);
95 if (argc == 2 && optind == 1 && !uname)
96 uname = argv[optind++];
98 if (usageflag || optind != argc)
103 if ((status = tf_init(TKT_FILE, R_TKT_FIL)) ||
104 (status = tf_get_pname(pname)))
106 com_err(whoami, status, "reading Kerberos ticket file");
114 status = mr_connect(NULL);
117 com_err(whoami, status, " while connecting to Moira");
121 status = mr_motd(&motd);
125 com_err(whoami, status, " unable to check server status");
130 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
136 status = mr_auth("chpobox");
139 com_err(whoami, status, " while authenticating -- "
140 "run \"kinit\" and try again.");
147 /* Address is of form user@host. Split it up. */
150 fprintf(stderr, "%s: no address was specified.\n", whoami);
153 machine = strchr(address, '@');
156 *machine++ = '\0'; /* get rid of the @ sign */
157 machine = strtrim(machine); /* get rid of whitespace */
161 fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n",
165 mrarg[2] = canonicalize_hostname(strdup(machine));
166 mrarg[1] = potype(mrarg[2]);
167 if (!strcmp(mrarg[1], "POP"))
169 if (strcmp(address, uname))
172 "%s: the name on the POP box must match the username\n",
177 else if (!strcmp(mrarg[1], "LOCAL"))
179 strcat(address, "@");
180 strcat(address, mrarg[2]);
182 if ((address = strchr(address, '@')) &&
183 (address = strchr(address, '.')))
185 strcat(mrarg[2], ".LOCAL");
188 else if (!strcmp(mrarg[1], "MAILHUB"))
190 if (!strcmp(address, uname))
193 "Error: this will set a mail forwarding loop.\n");
195 "Use \"%s -p\" to set a local post office server.\n",
199 fprintf(stderr, "Error: \"%s@%s\" is a local mail address.\n",
201 fprintf(stderr, "Your mail drop must be on a post office server "
202 "or an external mail address.\n");
207 if (*machine != '"' && strcasecmp(mrarg[2], machine))
209 fprintf(stderr, "Warning: hostname %s canonicalized to %s\n",
212 strcat(address, "@");
213 strcat(address, mrarg[2]);
217 status = mr_query("set_pobox", 3, mrarg, NULL, NULL);
219 com_err(whoami, status,
220 " while setting pobox for %s to type %s, box %s",
221 mrarg[0], mrarg[1], mrarg[2]);
225 status = mr_query("set_pobox_pop", 1, mrarg, NULL, NULL);
226 if (status == MR_MACHINE)
229 "Moira has no record of a previous POP box for %s\n", uname);
231 else if (status != 0)
232 com_err(whoami, status, " while setting pobox");
239 status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL);
240 if (status == MR_NO_MATCH)
241 printf("User %s has no pobox.\n", uname);
242 else if (status != 0)
243 com_err(whoami, status, " while retrieving current mailbox");
250 * get_pobox gets all your poboxes and displays them.
253 int get_pobox(int argc, char **argv, void *callarg)
255 if (!strcmp(argv[1], "POP"))
256 printf("User %s, Type %s, Box: %s@%s\n",
257 argv[0], argv[1], argv[0], argv[2]);
259 printf("User %s, Type %s, Box: %s\n",
260 argv[0], argv[1], argv[2]);
261 printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]);
266 * given a canonicalized machine name, ask the Moira server if it is of type
267 * pop, or of type local -- if neither, we assume that it's of type foreign.
269 char *potype(char *machine)
271 char *service[1], *argv[3];
276 status = mr_query("get_server_locations", 1, service, check_match, machine);
277 if (status && (status != MR_NO_MATCH))
279 com_err(whoami, status, " while reading list of POP servers");
285 service[0] = "LOCAL";
286 status = mr_query("get_server_locations", 1, service, check_match, machine);
287 if (status && (status != MR_NO_MATCH))
289 com_err(whoami, status, " while reading list of LOCAL servers");
298 status = mr_query("get_alias", 3, argv, check_match3, machine);
299 if (status && (status != MR_NO_MATCH))
301 com_err(whoami, status, " while reading list of MAILHUB servers");
310 int check_match(int argc, char **argv, void *callback)
315 if (!strcasecmp(argv[1], callback))
321 int check_match3(int argc, char **argv, void *callback)
326 if (!strcasecmp(argv[2], callback))
334 fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);