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