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