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