]> andersk Git - moira.git/blob - clients/passwd/chpobox.c
changes for HC compiler
[moira.git] / clients / passwd / chpobox.c
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$
8  *
9  */
10
11 #ifndef lint
12 static char *rcsid_chpobox_c = "$Header$";
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  * 
19  * chpobox with no modifiers reports the current mailbox.
20  * 
21  * chpobox -s [address] means set the mailbox to this address.
22  *
23  * chpobox -p restores the pobox to a previous POP box, if there was one.
24  *
25  * chpobox -u [user] is needed if you are logged in as one user, but
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.
29  */
30
31 #include <sys/types.h>
32 #include <stdio.h>
33 #include <pwd.h>
34 #include <strings.h>
35 #include <ctype.h>
36 #include <errno.h>
37
38 /* SMS includes */
39 #include <sms.h>
40 #include <sms_app.h>
41 #include "mit-copyright.h"
42
43 char *getlogin();
44 char *malloc();
45 char *whoami;
46 uid_t getuid();
47
48 int getopt();
49
50 static int match;
51
52
53 main(argc, argv)
54     int argc;
55     char *argv[];
56 {
57     struct passwd *pwd;
58     char *smsarg[3], buf[BUFSIZ];
59     char *potype();
60     char *address, *uname, *machine;
61     uid_t u;
62     char *canonicalize_hostname();
63     int get_pobox(), scream();
64     int c, setflag, prevpop, usageflag, status;
65
66     extern int optind;
67     extern char *optarg;
68
69     c = setflag = prevpop = usageflag = 0;
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
82     while ((c = getopt(argc, argv, "s:pu:")) != EOF)
83         switch (c) {
84
85         case 's':
86             if (prevpop)
87                 usageflag++;
88             else {
89                 setflag++;
90                 strcpy(buf, optarg);
91                 address = buf;
92             }
93             break;
94         case 'p':
95             if (setflag)
96                 usageflag++;
97             else {
98                 prevpop++;
99             }
100             break;
101         case 'u':
102             uname = strsave(optarg);
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) {
127         com_err(whoami, status, " while connecting to SMS");
128         exit(1);
129     }
130
131     status = sms_auth("chpobox");
132     if (status) {
133         com_err(whoami, status, " while authenticating -- run \"kinit\" and try again.");
134         sms_disconnect();
135         exit(1);
136     }
137
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         }
144         machine = index(address, '@');
145         if (machine) {
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;
152         }
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;
161             }
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");
187     }
188
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");
198     sms_disconnect();
199     exit(0);
200 }
201
202
203 scream()
204 {
205     com_err(whoami, 0, "Unexpected return value from SMS -- programmer botch");
206     sms_disconnect();
207     exit(1);
208 }
209
210 /*
211  * get_pobox gets all your poboxes and displays them.
212  */
213
214 /* ARGSUSED */
215 int
216 get_pobox(argc, argv, callarg)
217     int argc;
218     char **argv, *callarg;
219 {
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]);
227     return (0);
228 }
229
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 *
235 potype(machine)
236     char *machine;
237 {
238     char *service[1];
239     int check_match(), status;
240
241     match = 0;
242     service[0] = "POP";
243     status = sms_query("get_server_locations", 1, service,
244                        check_match, machine);
245     if (status && (status != SMS_NO_MATCH)) {
246         com_err(whoami, status, " while reading list of POP servers");
247         return(NULL);
248     }
249     if (match)
250         return ("POP");
251
252     service[0] = "LOCAL";
253     status = sms_query("get_server_locations", 1, service,
254                        check_match, machine);
255     if (status && (status != SMS_NO_MATCH)) {
256         com_err(whoami, status, " while reading list of LOCAL servers");
257         return(NULL);
258     }
259     if (match)
260         return ("LOCAL");
261     else
262         return ("SMTP");
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
274     if (strcasecmp(argv[1], callback) == 0)
275         match = 1;
276
277     return (0);
278 }
279
280 usage()
281 {
282     fprintf(stderr, "Usage: %s [-s address] [-p] [-u user]\n", whoami);
283     exit(1);
284 }
This page took 0.149645 seconds and 5 git commands to generate.