]>
Commit | Line | Data |
---|---|---|
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 | 12 | static 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 | |
43 | char *getlogin(); | |
44 | char *malloc(); | |
48fbc492 | 45 | char *whoami; |
8c5c4d26 | 46 | uid_t getuid(); |
48fbc492 | 47 | |
48 | int getopt(); | |
48fbc492 | 49 | |
48fbc492 | 50 | static int match; |
51 | ||
48fbc492 | 52 | |
48fbc492 | 53 | main(argc, argv) |
8c5c4d26 | 54 | int argc; |
48fbc492 | 55 | char *argv[]; |
48fbc492 | 56 | { |
57 | struct passwd *pwd; | |
8defc06b | 58 | char *mrarg[3], buf[BUFSIZ]; |
0b14cdc2 | 59 | char *potype(), *index(); |
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"; | |
183 | } else if (mrarg[1]) { | |
184 | if (*machine != '"' && strcasecmp(mrarg[2], machine)) | |
0b14cdc2 | 185 | printf("Warning: hostname %s canonicalized to %s\n", |
8defc06b | 186 | machine, mrarg[2]); |
0b14cdc2 | 187 | strcat(address, "@"); |
8defc06b | 188 | strcat(address, mrarg[2]); |
189 | mrarg[2] = address; | |
8c5c4d26 | 190 | } else |
191 | goto show; | |
8defc06b | 192 | status = mr_query("set_pobox", 3, mrarg, scream, NULL); |
8c5c4d26 | 193 | if (status) |
194 | com_err(whoami, status, | |
195 | " while setting pobox for %s to type %s, box %s", | |
8defc06b | 196 | mrarg[0], mrarg[1], mrarg[2]); |
8c5c4d26 | 197 | } else if (prevpop) { |
8defc06b | 198 | status = mr_query("set_pobox_pop", 1, mrarg, scream, NULL); |
199 | if (status == MR_MACHINE) { | |
8c5c4d26 | 200 | fprintf(stderr, |
95cd286e | 201 | "Moira has no record of a previous POP box for %s\n", uname); |
8c5c4d26 | 202 | } else if (status != 0) |
203 | com_err(whoami, status, " while setting pobox"); | |
48fbc492 | 204 | } |
ccd5efe6 | 205 | |
8c5c4d26 | 206 | /* |
207 | * get current box | |
208 | */ | |
209 | show: | |
8defc06b | 210 | status = mr_query("get_pobox", 1, mrarg, get_pobox, NULL); |
211 | if (status == MR_NO_MATCH) | |
8c5c4d26 | 212 | printf("User %s has no pobox.\n", uname); |
213 | else if (status != 0) | |
214 | com_err(whoami, status, " while retrieving current mailbox"); | |
8defc06b | 215 | mr_disconnect(); |
48fbc492 | 216 | exit(0); |
48fbc492 | 217 | } |
218 | ||
8c5c4d26 | 219 | |
48fbc492 | 220 | scream() |
221 | { | |
95cd286e | 222 | com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch"); |
8defc06b | 223 | mr_disconnect(); |
48fbc492 | 224 | exit(1); |
225 | } | |
226 | ||
227 | /* | |
dbe34e72 | 228 | * get_pobox gets all your poboxes and displays them. |
48fbc492 | 229 | */ |
230 | ||
231 | /* ARGSUSED */ | |
232 | int | |
dbe34e72 | 233 | get_pobox(argc, argv, callarg) |
48fbc492 | 234 | int argc; |
235 | char **argv, *callarg; | |
236 | { | |
8c5c4d26 | 237 | if (!strcmp(argv[1], "POP")) |
238 | printf("User %s, Type %s, Box: %s@%s\n", | |
239 | argv[0], argv[1], argv[0], argv[2]); | |
240 | else | |
241 | printf("User %s, Type %s, Box: %s\n", | |
242 | argv[0], argv[1], argv[2]); | |
243 | printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]); | |
48fbc492 | 244 | return (0); |
245 | } | |
246 | ||
48fbc492 | 247 | /* |
8defc06b | 248 | * given a canonicalized machine name, ask the MR server if it is of type |
48fbc492 | 249 | * pop, or of type local -- if neither, we assume that it's of type foreign. |
250 | */ | |
251 | char * | |
8c5c4d26 | 252 | potype(machine) |
48fbc492 | 253 | char *machine; |
254 | { | |
e2682860 | 255 | char *service[1]; |
8c5c4d26 | 256 | int check_match(), status; |
48fbc492 | 257 | |
258 | match = 0; | |
8c5c4d26 | 259 | service[0] = "POP"; |
8defc06b | 260 | status = mr_query("get_server_locations", 1, service, |
48fbc492 | 261 | check_match, machine); |
8defc06b | 262 | if (status && (status != MR_NO_MATCH)) { |
8c5c4d26 | 263 | com_err(whoami, status, " while reading list of POP servers"); |
264 | return(NULL); | |
48fbc492 | 265 | } |
266 | if (match) | |
8c5c4d26 | 267 | return ("POP"); |
48fbc492 | 268 | |
8c5c4d26 | 269 | service[0] = "LOCAL"; |
8defc06b | 270 | status = mr_query("get_server_locations", 1, service, |
48fbc492 | 271 | check_match, machine); |
8defc06b | 272 | if (status && (status != MR_NO_MATCH)) { |
8c5c4d26 | 273 | com_err(whoami, status, " while reading list of LOCAL servers"); |
274 | return(NULL); | |
48fbc492 | 275 | } |
276 | if (match) | |
8c5c4d26 | 277 | return ("LOCAL"); |
48fbc492 | 278 | else |
8c5c4d26 | 279 | return ("SMTP"); |
48fbc492 | 280 | } |
281 | ||
282 | /* ARGSUSED */ | |
283 | int | |
284 | check_match(argc, argv, callback) | |
285 | int argc; | |
286 | char **argv, *callback; | |
287 | { | |
288 | if (match) | |
289 | return (0); | |
290 | ||
8c5c4d26 | 291 | if (strcasecmp(argv[1], callback) == 0) |
48fbc492 | 292 | match = 1; |
293 | ||
294 | return (0); | |
295 | } | |
296 | ||
48fbc492 | 297 | usage() |
298 | { | |
8c5c4d26 | 299 | fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami); |
48fbc492 | 300 | exit(1); |
301 | } |