]> andersk Git - moira.git/blame - clients/passwd/chfn.c
make "none" delete a phone number
[moira.git] / clients / passwd / chfn.c
CommitLineData
7283d000 1/*
2 * Copyright 1988 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
12static char *rcsid_chfn_c = "$Header$";
13#endif not lint
14
15/*
16 * Talk to the SMS database to change a person's GECOS information.
17 *
18 * chfn with no modifiers changes the information of the user who is
19 * running the program.
20 *
21 * If a commandline argument is given, it is taken to be the username
22 * of the user whose information is to be changed.
23 *
24 */
25
26#define FALSE 0
27#define TRUE 1
28
29#include <sys/types.h>
30#include <stdio.h>
31#include <strings.h>
32#include <ctype.h>
33#include <sys/file.h>
34#include <krb.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
43char *whoami;
44
45extern char *krb_err_txt[];
46
47struct finger_info {
48 char *fullname;
49 char *nickname;
50 char *home_address;
51 char *home_phone;
52 char *office_address;
53 char *office_phone;
54 char *mit_department;
55 char *mit_year;
56};
57
58main(argc, argv)
59 int argc;
60 char *argv[];
61{
62 char pname[ANAME_SZ];
63 char *uname = pname;
64 int k_errno;
65 char *whoami;
66
67 if ((whoami = rindex(argv[0], '/')) == NULL)
68 whoami = argv[0];
69 else
70 whoami++;
71
72 if (argc > 2) {
73 usage();
74 }
75
76 if (argc == 2)
77 uname = argv[1];
78 else
79 {
80 /* Do it right; get name from kerberos ticket file rather than
81 from passord file. */
82
83 if (k_errno = tf_init(TKT_FILE, R_TKT_FIL)) {
84 fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
85 exit(1);
86 }
87
88 if (k_errno = tf_get_pname(pname)) {
89 fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
90 exit(1);
91 }
92
93 tf_close();
94 }
95
96 exit(chfn(uname));
97}
98
99leave(status)
100 int status;
101 /* This should be called rather than exit once connection to sms server
102 has been established. */
103{
104 sms_disconnect();
105 exit(status);
106}
107
108scream()
109{
95cd286e 110 com_err(whoami, 0, "Unexpected return value from Moira -- programmer botch");
7283d000 111 leave(1);
112}
113
114chfn(uname)
115 char *uname;
116{
117 int status; /* general purpose exit status */
118 int q_argc; /* argc for sms_query */
119 char *q_argv[F_END]; /* argv for sms_query */
262ca740 120 char *motd; /* for SMS server status */
7283d000 121 int i;
122
123 int get_user_info();
124 void get_new_info();
125
126 struct finger_info old_info;
127 struct finger_info new_info;
128
129 /* Try each query. If we ever fail, print error message and exit. */
130
131 status = sms_connect(SMS_SERVER);
132 if (status) {
95cd286e 133 com_err(whoami, status, " while connecting to Moira");
7283d000 134 exit(1);
135 }
136
262ca740 137 status = sms_motd(&motd);
138 if (status) {
139 com_err(whoami, status, " unable to check server status");
140 leave(1);
141 }
142 if (motd) {
95cd286e 143 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
262ca740 144 leave(1);
145 }
146
7283d000 147 status = sms_auth("chfn"); /* Don't use argv[0] - too easy to fake */
148 if (status) {
149 com_err(whoami, status,
150 " while authenticating -- run \"kinit\" and try again.");
151 leave(1);
152 }
153
154 /* First, do an access check. */
155
156 q_argv[F_NAME] = uname;
157 for (i = F_NAME + 1; i < F_MODTIME; i++)
158 q_argv[i] = "junk";
159 q_argc = F_MODTIME; /* one more than the last updatable field */
160
161 if (status = sms_access("update_finger_by_login", q_argc, q_argv)) {
162 com_err(whoami, status, "; finger\ninformation not changed.");
163 leave(2);
164 }
165
166 printf("Changing finger information for %s.\n", uname);
167
168 /* Get information */
169
170 q_argv[NAME] = uname;
171 q_argc = NAME + 1;
172 if (status = sms_query("get_finger_by_login", q_argc, q_argv,
173 get_user_info, (char *) &old_info))
174 {
175 com_err(whoami, status, " while getting user information.");
176 leave(2);
177 }
178
179 /* Get the new information from the user */
180
181 get_new_info(&old_info, &new_info);
182
183 /* Do the update */
184
185 printf("Changing finger information...\n");
186
187 q_argv[F_NAME] = uname;
188 q_argv[F_FULLNAME] = new_info.fullname;
189 q_argv[F_NICKNAME] = new_info.nickname;
190 q_argv[F_HOME_ADDR] = new_info.home_address;
191 q_argv[F_HOME_PHONE] = new_info.home_phone;
192 q_argv[F_OFFICE_ADDR] = new_info.office_address;
193 q_argv[F_OFFICE_PHONE] = new_info.office_phone;
194 q_argv[F_MIT_DEPT] = new_info.mit_department;
195 q_argv[F_MIT_AFFIL] = new_info.mit_year;
196 q_argc = F_MODTIME; /* First non-update query argument */
197
198 if (status = sms_query("update_finger_by_login", q_argc, q_argv,
199 scream, (char *)NULL))
200 {
201 com_err(whoami, status, " while updating finger information.");
202 leave(1);
203 }
204
205 printf("Finger information updated succesfully.\n");
206
207 return(0);
208}
209
210get_user_info(argc, argv, message)
211 int argc;
212 char *argv[];
213 char *message;
214{
215 struct finger_info *old_info = (struct finger_info *) message;
216
217 if (argc != F_END) {
218 fprintf(stderr, "Some internal error occurred; try again.\n");
219 leave(3);
220 }
221
222 printf("Info last changed on %s by user %s with %s.\n",
223 argv[F_MODTIME], argv[F_MODBY], argv[F_MODWITH]);
224
225 old_info->fullname = strsave(argv[F_FULLNAME]);
226 old_info->nickname = strsave(argv[F_NICKNAME]);
227 old_info->home_address = strsave(argv[F_HOME_ADDR]);
228 old_info->home_phone = strsave(argv[F_HOME_PHONE]);
229 old_info->office_address = strsave(argv[F_OFFICE_ADDR]);
230 old_info->office_phone = strsave(argv[F_OFFICE_PHONE]);
231 old_info->mit_department = strsave(argv[F_MIT_DEPT]);
232 old_info->mit_year = strsave(argv[F_MIT_AFFIL]);
233
234 /* Only pay attention to the first match since login names are
235 unique in the database. */
236 return(SMS_ABORT);
237}
238
239char *ask(question, def_val, phone_num)
240 char *question;
241 char *def_val;
242 int phone_num; /* True if this must contain only digits */
243{
12487417 244 static char buf[BUFSIZ];
7283d000 245 int ok = FALSE;
246 char *result;
247 int i;
248 int dashes = FALSE;
249
250#define BLANK "none"
251
252 while (!ok)
253 {
254 ok = TRUE;
255 printf("%s [%s]: ", question, def_val);
12487417 256 if (fgets(buf, sizeof(buf), stdin) == NULL)
257 leave(0);
7283d000 258 buf[strlen(buf) - 1] = NULL;
259 if (strlen(buf) == 0)
260 result = def_val;
261 else if (strcasecmp(buf, BLANK) == NULL)
262 result = "";
263 else
264 result = buf;
265
266 for (i = 0; i < strlen(buf); i++)
267 {
268 switch (buf[i])
269 {
270 case '"':
271 printf("'\"' is not allowed.\n");
272 ok = FALSE;
273 break;
274 case ',':
275 printf("',' is not allowed.\n");
276 ok = FALSE;
277 break;
278 case ':':
279 printf("':' is not allowed.\n");
280 ok = FALSE;
281 break;
282 default:
283 if (iscntrl(buf[i])) {
284 printf("Control characters are not allowed.\n");
285 ok = FALSE;
286 break;
287 }
288 }
289 if (!ok)
290 break;
291 }
292
293 if (phone_num && ok) {
1603d7ed 294 for (i = 0; i < strlen(result); i++) {
295 if (!isdigit(result[i]) && (result[i] != '-')) {
7283d000 296 printf("Phone numbers can contain only digits.\n");
297 ok = FALSE;
298 break;
299 }
1603d7ed 300 if (result[i] == '-')
7283d000 301 dashes = TRUE;
302 }
303 }
304 }
305
306 /* Remove dashes if necessary */
12487417 307 if (dashes && result == buf) {
7283d000 308 char *tmp1, *tmp2;
12487417 309 tmp1 = tmp2 = (char *)buf;
7283d000 310 do {
311 if (*(tmp1) != '-')
312 *(tmp2++) = *(tmp1);
313 }
314 while (*(tmp1++));
315 }
316
317 return(result);
318}
319
320void get_new_info(old_info, new_info)
321 struct finger_info *old_info;
322 struct finger_info *new_info;
323{
324 printf("Default values are printed inside of '[]'.\n");
325 printf("To accept the default, type <return>.\n");
326 printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
327
328#define GETINFO(m,v,n) \
329 new_info->v = strsave(ask(m, old_info->v, n))
330
331 GETINFO("Full name", fullname, FALSE);
332 GETINFO("Nickname", nickname, FALSE);
333 GETINFO("Home address (Ex: Atkinson 304)", home_address, FALSE);
334 GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
335 GETINFO("Office address (Exs: E40-342 or 2-108)",
336 office_address, FALSE);
337 GETINFO("Office phone (Ex: 3-1300)", office_phone, TRUE);
338 GETINFO("MIT department (Exs: 9, Biology, Information Services",
339 mit_department, FALSE);
340 GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
341}
342
343usage()
344{
345 fprintf(stderr, "Usage: %s [user]\n", whoami);
346 exit(1);
347}
This page took 0.093024 seconds and 5 git commands to generate.