]>
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 | /* | |
16 | * Talk to the SMS database to change a person's home mail machine. This may | |
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 | ||
38 | /* SMS includes */ | |
39 | #include <sms.h> | |
40 | #include <sms_app.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; | |
e2682860 | 58 | char *smsarg[3], buf[BUFSIZ]; |
0b14cdc2 | 59 | char *potype(), *index(); |
48fbc492 | 60 | char *address, *uname, *machine; |
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 | } | |
123 | smsarg[0] = uname; | |
124 | ||
9a2d61b0 | 125 | status = sms_connect(SMS_SERVER); |
48fbc492 | 126 | if (status) { |
8c5c4d26 | 127 | com_err(whoami, status, " while connecting to SMS"); |
128 | exit(1); | |
48fbc492 | 129 | } |
130 | ||
dbe34e72 | 131 | status = sms_auth("chpobox"); |
48fbc492 | 132 | if (status) { |
8c5c4d26 | 133 | com_err(whoami, status, " while authenticating -- run \"kinit\" and try again."); |
134 | sms_disconnect(); | |
135 | exit(1); | |
ccd5efe6 | 136 | } |
137 | ||
8c5c4d26 | 138 | if (setflag) { |
139 | /* Address is of form user@host. Split it up. */ | |
140 | if (!address) { | |
141 | fprintf(stderr, "%s: no address was specified.\n", whoami); | |
142 | goto show; | |
143 | } | |
48fbc492 | 144 | machine = index(address, '@'); |
145 | if (machine) { | |
8c5c4d26 | 146 | *machine++ = '\0'; /* get rid of the @ sign */ |
147 | machine = strtrim(machine); /* get rid of whitespace */ | |
148 | } else { | |
149 | fprintf(stderr, "%s: no at sign (@) in address \"%s\"\n", | |
150 | whoami, address); | |
151 | goto show; | |
48fbc492 | 152 | } |
0b14cdc2 | 153 | smsarg[2] = canonicalize_hostname(strsave(machine)); |
8c5c4d26 | 154 | smsarg[1] = potype(smsarg[2]); |
155 | if (!strcmp(smsarg[1], "POP")) { | |
156 | if (strcmp(address, uname)) { | |
157 | fprintf(stderr, | |
158 | "%s: the name on the POP box must match the username\n", | |
159 | whoami); | |
160 | goto show; | |
ccd5efe6 | 161 | } |
8c5c4d26 | 162 | } else if (!strcmp(smsarg[1], "LOCAL")) { |
0b14cdc2 | 163 | strcat(address, "@"); |
164 | strcat(address, smsarg[2]); | |
8c5c4d26 | 165 | smsarg[2] = address; |
0b14cdc2 | 166 | if ((address = index(address, '@')) && |
167 | (address = index(address, '.'))) | |
168 | *address = 0; | |
169 | strcat(smsarg[2], ".LOCAL"); | |
8c5c4d26 | 170 | smsarg[1] = "SMTP"; |
171 | } else if (smsarg[1]) { | |
0b14cdc2 | 172 | if (*machine != '"' && strcasecmp(smsarg[2], machine)) |
173 | printf("Warning: hostname %s canonicalized to %s\n", | |
174 | machine, smsarg[2]); | |
175 | strcat(address, "@"); | |
176 | strcat(address, smsarg[2]); | |
8c5c4d26 | 177 | smsarg[2] = address; |
8c5c4d26 | 178 | } else |
179 | goto show; | |
180 | status = sms_query("set_pobox", 3, smsarg, scream, NULL); | |
181 | if (status) | |
182 | com_err(whoami, status, | |
183 | " while setting pobox for %s to type %s, box %s", | |
184 | smsarg[0], smsarg[1], smsarg[2]); | |
185 | } else if (prevpop) { | |
186 | status = sms_query("set_pobox_pop", 1, smsarg, scream, NULL); | |
187 | if (status == SMS_MACHINE) { | |
188 | fprintf(stderr, | |
189 | "SMS has no record of a previous POP box for %s\n", uname); | |
190 | } else if (status != 0) | |
191 | com_err(whoami, status, " while setting pobox"); | |
48fbc492 | 192 | } |
ccd5efe6 | 193 | |
8c5c4d26 | 194 | /* |
195 | * get current box | |
196 | */ | |
197 | show: | |
198 | status = sms_query("get_pobox", 1, smsarg, get_pobox, NULL); | |
199 | if (status == SMS_NO_MATCH) | |
200 | printf("User %s has no pobox.\n", uname); | |
201 | else if (status != 0) | |
202 | com_err(whoami, status, " while retrieving current mailbox"); | |
48fbc492 | 203 | sms_disconnect(); |
204 | exit(0); | |
48fbc492 | 205 | } |
206 | ||
8c5c4d26 | 207 | |
48fbc492 | 208 | scream() |
209 | { | |
8c5c4d26 | 210 | com_err(whoami, 0, "Unexpected return value from SMS -- programmer botch"); |
48fbc492 | 211 | sms_disconnect(); |
212 | exit(1); | |
213 | } | |
214 | ||
215 | /* | |
dbe34e72 | 216 | * get_pobox gets all your poboxes and displays them. |
48fbc492 | 217 | */ |
218 | ||
219 | /* ARGSUSED */ | |
220 | int | |
dbe34e72 | 221 | get_pobox(argc, argv, callarg) |
48fbc492 | 222 | int argc; |
223 | char **argv, *callarg; | |
224 | { | |
8c5c4d26 | 225 | if (!strcmp(argv[1], "POP")) |
226 | printf("User %s, Type %s, Box: %s@%s\n", | |
227 | argv[0], argv[1], argv[0], argv[2]); | |
228 | else | |
229 | printf("User %s, Type %s, Box: %s\n", | |
230 | argv[0], argv[1], argv[2]); | |
231 | printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]); | |
48fbc492 | 232 | return (0); |
233 | } | |
234 | ||
48fbc492 | 235 | /* |
236 | * given a canonicalized machine name, ask the SMS server if it is of type | |
237 | * pop, or of type local -- if neither, we assume that it's of type foreign. | |
238 | */ | |
239 | char * | |
8c5c4d26 | 240 | potype(machine) |
48fbc492 | 241 | char *machine; |
242 | { | |
e2682860 | 243 | char *service[1]; |
8c5c4d26 | 244 | int check_match(), status; |
48fbc492 | 245 | |
246 | match = 0; | |
8c5c4d26 | 247 | service[0] = "POP"; |
48fbc492 | 248 | status = sms_query("get_server_locations", 1, service, |
249 | check_match, machine); | |
250 | if (status && (status != SMS_NO_MATCH)) { | |
8c5c4d26 | 251 | com_err(whoami, status, " while reading list of POP servers"); |
252 | return(NULL); | |
48fbc492 | 253 | } |
254 | if (match) | |
8c5c4d26 | 255 | return ("POP"); |
48fbc492 | 256 | |
8c5c4d26 | 257 | service[0] = "LOCAL"; |
48fbc492 | 258 | status = sms_query("get_server_locations", 1, service, |
259 | check_match, machine); | |
260 | if (status && (status != SMS_NO_MATCH)) { | |
8c5c4d26 | 261 | com_err(whoami, status, " while reading list of LOCAL servers"); |
262 | return(NULL); | |
48fbc492 | 263 | } |
264 | if (match) | |
8c5c4d26 | 265 | return ("LOCAL"); |
48fbc492 | 266 | else |
8c5c4d26 | 267 | return ("SMTP"); |
48fbc492 | 268 | } |
269 | ||
270 | /* ARGSUSED */ | |
271 | int | |
272 | check_match(argc, argv, callback) | |
273 | int argc; | |
274 | char **argv, *callback; | |
275 | { | |
276 | if (match) | |
277 | return (0); | |
278 | ||
8c5c4d26 | 279 | if (strcasecmp(argv[1], callback) == 0) |
48fbc492 | 280 | match = 1; |
281 | ||
282 | return (0); | |
283 | } | |
284 | ||
48fbc492 | 285 | usage() |
286 | { | |
8c5c4d26 | 287 | fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami); |
48fbc492 | 288 | exit(1); |
289 | } |