]>
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]; |
8c5c4d26 | 59 | char *potype(); |
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 | ||
125 | status = sms_connect(); | |
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 | } |
8c5c4d26 | 153 | smsarg[2] = canonicalize_hostname(machine); |
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")) { |
163 | smsarg[2] = address; | |
164 | *(--machine) = '@'; | |
165 | address = index(machine, '.'); | |
166 | if (address == NULL) | |
167 | address = &machine[strlen(machine)]; | |
168 | sprintf(address, ".LOCAL"); | |
169 | smsarg[1] = "SMTP"; | |
170 | } else if (smsarg[1]) { | |
171 | smsarg[2] = address; | |
172 | *(--machine) = '@'; | |
173 | } else | |
174 | goto show; | |
175 | status = sms_query("set_pobox", 3, smsarg, scream, NULL); | |
176 | if (status) | |
177 | com_err(whoami, status, | |
178 | " while setting pobox for %s to type %s, box %s", | |
179 | smsarg[0], smsarg[1], smsarg[2]); | |
180 | } else if (prevpop) { | |
181 | status = sms_query("set_pobox_pop", 1, smsarg, scream, NULL); | |
182 | if (status == SMS_MACHINE) { | |
183 | fprintf(stderr, | |
184 | "SMS has no record of a previous POP box for %s\n", uname); | |
185 | } else if (status != 0) | |
186 | com_err(whoami, status, " while setting pobox"); | |
48fbc492 | 187 | } |
ccd5efe6 | 188 | |
8c5c4d26 | 189 | /* |
190 | * get current box | |
191 | */ | |
192 | show: | |
193 | status = sms_query("get_pobox", 1, smsarg, get_pobox, NULL); | |
194 | if (status == SMS_NO_MATCH) | |
195 | printf("User %s has no pobox.\n", uname); | |
196 | else if (status != 0) | |
197 | com_err(whoami, status, " while retrieving current mailbox"); | |
48fbc492 | 198 | sms_disconnect(); |
199 | exit(0); | |
48fbc492 | 200 | } |
201 | ||
8c5c4d26 | 202 | |
48fbc492 | 203 | scream() |
204 | { | |
8c5c4d26 | 205 | com_err(whoami, 0, "Unexpected return value from SMS -- programmer botch"); |
48fbc492 | 206 | sms_disconnect(); |
207 | exit(1); | |
208 | } | |
209 | ||
210 | /* | |
dbe34e72 | 211 | * get_pobox gets all your poboxes and displays them. |
48fbc492 | 212 | */ |
213 | ||
214 | /* ARGSUSED */ | |
215 | int | |
dbe34e72 | 216 | get_pobox(argc, argv, callarg) |
48fbc492 | 217 | int argc; |
218 | char **argv, *callarg; | |
219 | { | |
8c5c4d26 | 220 | if (!strcmp(argv[1], "POP")) |
221 | printf("User %s, Type %s, Box: %s@%s\n", | |
222 | argv[0], argv[1], argv[0], argv[2]); | |
223 | else | |
224 | printf("User %s, Type %s, Box: %s\n", | |
225 | argv[0], argv[1], argv[2]); | |
226 | printf(" Modified by %s on %s with %s\n", argv[4], argv[3], argv[5]); | |
48fbc492 | 227 | return (0); |
228 | } | |
229 | ||
48fbc492 | 230 | /* |
231 | * given a canonicalized machine name, ask the SMS server if it is of type | |
232 | * pop, or of type local -- if neither, we assume that it's of type foreign. | |
233 | */ | |
234 | char * | |
8c5c4d26 | 235 | potype(machine) |
48fbc492 | 236 | char *machine; |
237 | { | |
e2682860 | 238 | char *service[1]; |
8c5c4d26 | 239 | int check_match(), status; |
48fbc492 | 240 | |
241 | match = 0; | |
8c5c4d26 | 242 | service[0] = "POP"; |
48fbc492 | 243 | status = sms_query("get_server_locations", 1, service, |
244 | check_match, machine); | |
245 | if (status && (status != SMS_NO_MATCH)) { | |
8c5c4d26 | 246 | com_err(whoami, status, " while reading list of POP servers"); |
247 | return(NULL); | |
48fbc492 | 248 | } |
249 | if (match) | |
8c5c4d26 | 250 | return ("POP"); |
48fbc492 | 251 | |
8c5c4d26 | 252 | service[0] = "LOCAL"; |
48fbc492 | 253 | status = sms_query("get_server_locations", 1, service, |
254 | check_match, machine); | |
255 | if (status && (status != SMS_NO_MATCH)) { | |
8c5c4d26 | 256 | com_err(whoami, status, " while reading list of LOCAL servers"); |
257 | return(NULL); | |
48fbc492 | 258 | } |
259 | if (match) | |
8c5c4d26 | 260 | return ("LOCAL"); |
48fbc492 | 261 | else |
8c5c4d26 | 262 | return ("SMTP"); |
48fbc492 | 263 | } |
264 | ||
265 | /* ARGSUSED */ | |
266 | int | |
267 | check_match(argc, argv, callback) | |
268 | int argc; | |
269 | char **argv, *callback; | |
270 | { | |
271 | if (match) | |
272 | return (0); | |
273 | ||
8c5c4d26 | 274 | if (strcasecmp(argv[1], callback) == 0) |
48fbc492 | 275 | match = 1; |
276 | ||
277 | return (0); | |
278 | } | |
279 | ||
48fbc492 | 280 | usage() |
281 | { | |
8c5c4d26 | 282 | fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami); |
48fbc492 | 283 | exit(1); |
284 | } |