]> andersk Git - moira.git/blame - clients/passwd/chpobox.c
posixify source
[moira.git] / clients / passwd / chpobox.c
CommitLineData
48fbc492 1/*
2 * Copyright 1987 by the Massachusetts Institute of Technology. For copying
3 * and distribution information, see the file "mit-copyright.h".
4 *
5 * $Source$
6 * $Header$
7 * $Author$
48fbc492 8 *
9 */
10
11#ifndef lint
67655a21 12static char *rcsid_chpobox_c = "$Header$";
48fbc492 13#endif not lint
14
15/*
8defc06b 16 * Talk to the MOIRA database to change a person's home mail machine. This may
48fbc492 17 * be an Athena machine, or a completely arbitrary address.
18 *
8c5c4d26 19 * chpobox with no modifiers reports the current mailbox.
48fbc492 20 *
8c5c4d26 21 * chpobox -s [address] means set the mailbox to this address.
48fbc492 22 *
8c5c4d26 23 * chpobox -p restores the pobox to a previous POP box, if there was one.
48fbc492 24 *
67655a21 25 * chpobox -u [user] is needed if you are logged in as one user, but
48fbc492 26 * are trying to change the email address of another. You must have
27 * Kerberos tickets as the person whose address you are trying to
28 * change, or the attempt will fail.
48fbc492 29 */
30
31#include <sys/types.h>
32#include <stdio.h>
33#include <pwd.h>
34#include <strings.h>
35#include <ctype.h>
48fbc492 36#include <errno.h>
37
8defc06b 38/* MOIRA includes */
39#include <moira.h>
40#include <moira_site.h>
67655a21 41#include "mit-copyright.h"
48fbc492 42
43char *getlogin();
44char *malloc();
48fbc492 45char *whoami;
8c5c4d26 46uid_t getuid();
48fbc492 47
48int getopt();
48fbc492 49
48fbc492 50static int match;
51
48fbc492 52
48fbc492 53main(argc, argv)
8c5c4d26 54 int argc;
48fbc492 55 char *argv[];
48fbc492 56{
57 struct passwd *pwd;
8defc06b 58 char *mrarg[3], buf[BUFSIZ];
8ba10d3d 59 char *potype();
262ca740 60 char *address, *uname, *machine, *motd;
48fbc492 61 uid_t u;
8c5c4d26 62 char *canonicalize_hostname();
dbe34e72 63 int get_pobox(), scream();
8c5c4d26 64 int c, setflag, prevpop, usageflag, status;
48fbc492 65
66 extern int optind;
67 extern char *optarg;
68
e2682860 69 c = setflag = prevpop = usageflag = 0;
48fbc492 70 address = uname = (char *) NULL;
71 u = getuid();
72
73 if ((whoami = rindex(argv[0], '/')) == NULL)
74 whoami = argv[0];
75 else
76 whoami++;
77
78 if (argc > 5) {
79 usage();
80 }
81
8c5c4d26 82 while ((c = getopt(argc, argv, "s:pu:")) != EOF)
48fbc492 83 switch (c) {
84
8c5c4d26 85 case 's':
86 if (prevpop)
48fbc492 87 usageflag++;
88 else {
8c5c4d26 89 setflag++;
e2682860 90 strcpy(buf, optarg);
91 address = buf;
48fbc492 92 }
93 break;
8c5c4d26 94 case 'p':
95 if (setflag)
48fbc492 96 usageflag++;
97 else {
8c5c4d26 98 prevpop++;
48fbc492 99 }
100 break;
101 case 'u':
dbe34e72 102 uname = strsave(optarg);
48fbc492 103 break;
104 default:
105 usageflag++;
106 break;
107 }
108 if (argc == 2 && optind == 1 && !uname) {
109 uname = argv[optind++];
110 }
111 if (usageflag || optind != argc) {
112 usage();
113 }
114 if (!uname) {
115 if ((uname = getlogin()) == NULL) {
116 usage();
117 }
118 if (uname[0] == '\0') {
119 pwd = getpwuid((int) u);
120 (void) strcpy(uname, pwd->pw_name);
121 }
122 }
8defc06b 123 mrarg[0] = uname;
48fbc492 124
8defc06b 125 status = mr_connect(NULL);
48fbc492 126 if (status) {
95cd286e 127 com_err(whoami, status, " while connecting to Moira");
8c5c4d26 128 exit(1);
48fbc492 129 }
130
8defc06b 131 status = mr_motd(&motd);
262ca740 132 if (status) {
8defc06b 133 mr_disconnect();
262ca740 134 com_err(whoami, status, " unable to check server status");
135 exit(1);
136 }
137 if (motd) {
95cd286e 138 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
8defc06b 139 mr_disconnect();
262ca740 140 exit(1);
141 }
142
8defc06b 143 status = mr_auth("chpobox");
48fbc492 144 if (status) {
8c5c4d26 145 com_err(whoami, status, " while authenticating -- run \"kinit\" and try again.");
8defc06b 146 mr_disconnect();
8c5c4d26 147 exit(1);
ccd5efe6 148 }
149
8c5c4d26 150 if (setflag) {
151 /* Address is of form user@host. Split it up. */
152 if (!address) {
153 fprintf(stderr, "%s: no address was specified.\n", whoami);
154 goto show;
155 }
48fbc492 156 machine = index(address, '@');
157 if (machine) {
8c5c4d26 158 *machine++ = '\0'; /* get rid of the @ sign */
159 machine = strtrim(machine); /* get rid of whitespace */
160 } else {
161 fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n",
162 whoami, address);
163 goto show;
48fbc492 164 }
8defc06b 165 mrarg[2] = canonicalize_hostname(strsave(machine));
166 mrarg[1] = potype(mrarg[2]);
167 if (!strcmp(mrarg[1], "POP")) {
8c5c4d26 168 if (strcmp(address, uname)) {
169 fprintf(stderr,
170 "%s: the name on the POP box must match the username\n",
171 whoami);
172 goto show;
ccd5efe6 173 }
8defc06b 174 } else if (!strcmp(mrarg[1], "LOCAL")) {
0b14cdc2 175 strcat(address, "@");
8defc06b 176 strcat(address, mrarg[2]);
177 mrarg[2] = address;
0b14cdc2 178 if ((address = index(address, '@')) &&
179 (address = index(address, '.')))
180 *address = 0;
8defc06b 181 strcat(mrarg[2], ".LOCAL");
182 mrarg[1] = "SMTP";
108a5f18 183 } else if (!strcmp(mrarg[1], "MAILHUB")) {
184 if (!strcmp(address, uname)) {
185 fprintf(stderr,
186 "Error: this will set a mail forwarding loop.\n");
187 fprintf(stderr,
188 "Use \"%s -p\" to set a local post office server.\n",
189 whoami);
190 exit(1);
191 }
192 fprintf(stderr, "Error: \"%s@%s\" is a local mail address.\n",
193 address, machine);
194 fprintf(stderr, "Your mail drop must be on a post office server or an external mail address.\n");
195 exit(1);
8defc06b 196 } else if (mrarg[1]) {
197 if (*machine != '"' && strcasecmp(mrarg[2], machine))
108a5f18 198 fprintf(stderr, "Warning: hostname %s canonicalized to %s\n",
199 machine, mrarg[2]);
0b14cdc2 200 strcat(address, "@");
8defc06b 201 strcat(address, mrarg[2]);
202 mrarg[2] = address;
8c5c4d26 203 } else
204 goto show;
8defc06b 205 status = mr_query("set_pobox", 3, mrarg, scream, NULL);
8c5c4d26 206 if (status)
207 com_err(whoami, status,
208 " while setting pobox for %s to type %s, box %s",
8defc06b 209 mrarg[0], mrarg[1], mrarg[2]);
8c5c4d26 210 } else if (prevpop) {
8defc06b 211 status = mr_query("set_pobox_pop", 1, mrarg, scream, NULL);
212 if (status == MR_MACHINE) {
8c5c4d26 213 fprintf(stderr,
95cd286e 214 "Moira has no record of a previous POP box for %s\n", uname);
8c5c4d26 215 } else if (status != 0)
216 com_err(whoami, status, " while setting pobox");
48fbc492 217 }
ccd5efe6 218
8c5c4d26 219 /*
220 * get current box
221 */
222show:
8defc06b 223 status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL);
224 if (status == MR_NO_MATCH)
8c5c4d26 225 printf("User %s has no pobox.\n", uname);
226 else if (status != 0)
227 com_err(whoami, status, " while retrieving current mailbox");
8defc06b 228 mr_disconnect();
48fbc492 229 exit(0);
48fbc492 230}
231
8c5c4d26 232
48fbc492 233scream()
234{
95cd286e 235 com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
8defc06b 236 mr_disconnect();
48fbc492 237 exit(1);
238}
239
240/*
dbe34e72 241 * get_pobox gets all your poboxes and displays them.
48fbc492 242 */
243
244/* ARGSUSED */
245int
dbe34e72 246get_pobox(argc, argv, callarg)
48fbc492 247 int argc;
248 char **argv, *callarg;
249{
8c5c4d26 250 if (!strcmp(argv[1], "POP"))
251 printf("User %s, Type %s, Box: %s@%s\n",
252 argv[0], argv[1], argv[0], argv[2]);
253 else
254 printf("User %s, Type %s, Box: %s\n",
255 argv[0], argv[1], argv[2]);
256 printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]);
48fbc492 257 return (0);
258}
259
48fbc492 260/*
8defc06b 261 * given a canonicalized machine name, ask the MR server if it is of type
48fbc492 262 * pop, or of type local -- if neither, we assume that it's of type foreign.
263 */
264char *
8c5c4d26 265potype(machine)
48fbc492 266 char *machine;
267{
108a5f18 268 char *service[1], *argv[3];
269 int check_match(), check_match3(), status;
48fbc492 270
271 match = 0;
8c5c4d26 272 service[0] = "POP";
8defc06b 273 status = mr_query("get_server_locations", 1, service,
48fbc492 274 check_match, machine);
8defc06b 275 if (status && (status != MR_NO_MATCH)) {
8c5c4d26 276 com_err(whoami, status, " while reading list of POP servers");
277 return(NULL);
48fbc492 278 }
279 if (match)
8c5c4d26 280 return ("POP");
48fbc492 281
8c5c4d26 282 service[0] = "LOCAL";
8defc06b 283 status = mr_query("get_server_locations", 1, service,
48fbc492 284 check_match, machine);
8defc06b 285 if (status && (status != MR_NO_MATCH)) {
8c5c4d26 286 com_err(whoami, status, " while reading list of LOCAL servers");
287 return(NULL);
48fbc492 288 }
289 if (match)
8c5c4d26 290 return ("LOCAL");
108a5f18 291
292 argv[0] = "mailhub";
293 argv[1] = "TYPE";
294 argv[2] = "*";
295 status = mr_query("get_alias", 3, argv, check_match3, machine);
296 if (status && (status != MR_NO_MATCH)) {
297 com_err(whoami, status, " while reading list of MAILHUB servers");
298 return(NULL);
299 }
300 if (match)
301 return ("MAILHUB");
48fbc492 302 else
8c5c4d26 303 return ("SMTP");
48fbc492 304}
305
306/* ARGSUSED */
307int
308check_match(argc, argv, callback)
309 int argc;
310 char **argv, *callback;
311{
312 if (match)
313 return (0);
314
8c5c4d26 315 if (strcasecmp(argv[1], callback) == 0)
48fbc492 316 match = 1;
317
318 return (0);
319}
320
108a5f18 321/* ARGSUSED */
322int
323check_match3(argc, argv, callback)
324 int argc;
325 char **argv, *callback;
326{
327 if (match)
328 return (0);
329
330 if (strcasecmp(argv[2], callback) == 0)
331 match = 1;
332
333 return (0);
334}
335
48fbc492 336usage()
337{
8c5c4d26 338 fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
48fbc492 339 exit(1);
340}
This page took 0.144014 seconds and 5 git commands to generate.