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>
34 int get_pobox(int argc, char **argv, void *callarg);
35 char *potype(char *machine);
36 int check_match(int argc, char **argv, void *callback);
37 int check_match3(int argc, char **argv, void *callback);
44 int main(int argc, char *argv[])
47 char *mrarg[3], buf[BUFSIZ];
48 char *address, *uname, *machine, *motd;
50 int c, setflag, prevpop, usageflag, status;
55 c = setflag = prevpop = usageflag = 0;
56 address = uname = NULL;
59 if ((whoami = strrchr(argv[0], '/')) == NULL)
67 while ((c = getopt(argc, argv, "s:pu:")) != -1)
87 uname = strdup(optarg);
93 if (argc == 2 && optind == 1 && !uname)
94 uname = argv[optind++];
96 if (usageflag || optind != argc)
101 if (!(uname = getlogin()))
104 if (uname[0] == '\0')
107 strcpy(uname, pwd->pw_name);
112 status = mr_connect(NULL);
115 com_err(whoami, status, " while connecting to Moira");
119 status = mr_motd(&motd);
123 com_err(whoami, status, " unable to check server status");
128 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
134 status = mr_auth("chpobox");
137 com_err(whoami, status, " while authenticating -- "
138 "run \"kinit\" and try again.");
145 /* Address is of form user@host. Split it up. */
148 fprintf(stderr, "%s: no address was specified.\n", whoami);
151 machine = strchr(address, '@');
154 *machine++ = '\0'; /* get rid of the @ sign */
155 machine = strtrim(machine); /* get rid of whitespace */
159 fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n",
163 mrarg[2] = canonicalize_hostname(strdup(machine));
164 mrarg[1] = potype(mrarg[2]);
165 if (!strcmp(mrarg[1], "POP"))
167 if (strcmp(address, uname))
170 "%s: the name on the POP box must match the username\n",
175 else if (!strcmp(mrarg[1], "LOCAL"))
177 strcat(address, "@");
178 strcat(address, mrarg[2]);
180 if ((address = strchr(address, '@')) &&
181 (address = strchr(address, '.')))
183 strcat(mrarg[2], ".LOCAL");
186 else if (!strcmp(mrarg[1], "MAILHUB"))
188 if (!strcmp(address, uname))
191 "Error: this will set a mail forwarding loop.\n");
193 "Use \"%s -p\" to set a local post office server.\n",
197 fprintf(stderr, "Error: \"%s@%s\" is a local mail address.\n",
199 fprintf(stderr, "Your mail drop must be on a post office server "
200 "or an external mail address.\n");
205 if (*machine != '"' && strcasecmp(mrarg[2], machine))
207 fprintf(stderr, "Warning: hostname %s canonicalized to %s\n",
210 strcat(address, "@");
211 strcat(address, mrarg[2]);
215 status = mr_query("set_pobox", 3, mrarg, NULL, NULL);
217 com_err(whoami, status,
218 " while setting pobox for %s to type %s, box %s",
219 mrarg[0], mrarg[1], mrarg[2]);
223 status = mr_query("set_pobox_pop", 1, mrarg, NULL, NULL);
224 if (status == MR_MACHINE)
227 "Moira has no record of a previous POP box for %s\n", uname);
229 else if (status != 0)
230 com_err(whoami, status, " while setting pobox");
237 status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL);
238 if (status == MR_NO_MATCH)
239 printf("User %s has no pobox.\n", uname);
240 else if (status != 0)
241 com_err(whoami, status, " while retrieving current mailbox");
248 * get_pobox gets all your poboxes and displays them.
251 int get_pobox(int argc, char **argv, void *callarg)
253 if (!strcmp(argv[1], "POP"))
254 printf("User %s, Type %s, Box: %s@%s\n",
255 argv[0], argv[1], argv[0], argv[2]);
257 printf("User %s, Type %s, Box: %s\n",
258 argv[0], argv[1], argv[2]);
259 printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]);
264 * given a canonicalized machine name, ask the Moira server if it is of type
265 * pop, or of type local -- if neither, we assume that it's of type foreign.
267 char *potype(char *machine)
269 char *service[1], *argv[3];
274 status = mr_query("get_server_locations", 1, service, check_match, machine);
275 if (status && (status != MR_NO_MATCH))
277 com_err(whoami, status, " while reading list of POP servers");
283 service[0] = "LOCAL";
284 status = mr_query("get_server_locations", 1, service, check_match, machine);
285 if (status && (status != MR_NO_MATCH))
287 com_err(whoami, status, " while reading list of LOCAL servers");
296 status = mr_query("get_alias", 3, argv, check_match3, machine);
297 if (status && (status != MR_NO_MATCH))
299 com_err(whoami, status, " while reading list of MAILHUB servers");
308 int check_match(int argc, char **argv, void *callback)
313 if (!strcasecmp(argv[1], callback))
319 int check_match3(int argc, char **argv, void *callback)
324 if (!strcasecmp(argv[2], callback))
332 fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);