]> andersk Git - moira.git/blob - clients/passwd/chfn.c
Fix uninitialized queue element pointer in CreateImapBox().
[moira.git] / clients / passwd / chfn.c
1 /* $Id$
2  *
3  * Talk to the Moira database to change a person's GECOS information.
4  *
5  * chfn with no modifiers changes the information of the user who is
6  * running the program.
7  *
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  *
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>.
14  */
15
16 #include <mit-copyright.h>
17 #include <moira.h>
18 #include <moira_site.h>
19 #include <mrclient.h>
20
21 #include <ctype.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 RCSID("$Header$");
26
27 #define FALSE 0
28 #define TRUE 1
29
30 char *whoami;
31
32 struct finger_info {
33   char *fullname;
34   char *nickname;
35   char *home_address;
36   char *home_phone;
37   char *office_address;
38   char *office_phone;
39   char *mit_department;
40   char *mit_year;
41 };
42
43 void usage(void);
44 int chfn(char *uname);
45 int get_user_info(int argc, char *argv[], void *message);
46 char *ask(char *question, char *def_val, int phone_num);
47 void get_new_info(struct finger_info *old_info, struct finger_info *new_info);
48
49 int main(int argc, char *argv[])
50 {
51   char *uname;
52
53   if ((whoami = strrchr(argv[0], '/')) == NULL)
54     whoami = argv[0];
55   else
56     whoami++;
57
58   if (argc > 2)
59     usage();
60
61   if (argc == 2)
62     uname = argv[1];
63   else
64     {
65       uname = mrcl_krb_user();
66       if (!uname)
67         exit(1);
68     }
69
70   exit(chfn(uname));
71 }
72
73 int chfn(char *uname)
74 {
75   int status;                   /* general purpose exit status */
76   int q_argc;                   /* argc for mr_query */
77   char *q_argv[F_END];          /* argv for mr_query */
78   char *motd;                   /* for Moira server status */
79   int i;
80
81   struct finger_info old_info;
82   struct finger_info new_info;
83
84   if (mrcl_connect(NULL, "chsh", 2, 1) != MRCL_SUCCESS)
85     exit(1);
86
87   /* First, do an access check. */
88
89   q_argv[F_NAME] = uname;
90   for (i = F_NAME + 1; i < F_MODTIME; i++)
91     q_argv[i] = "junk";
92   q_argc = F_MODTIME;           /* one more than the last updatable field */
93
94   if ((status = mr_access("update_finger_by_login", q_argc, q_argv)))
95     {
96       com_err(whoami, status, "; finger\ninformation not changed.");
97       exit(2);
98     }
99
100   printf("Changing finger information for %s.\n", uname);
101
102   /* Get information */
103
104   q_argv[NAME] = uname;
105   q_argc = NAME + 1;
106   if ((status = mr_query("get_finger_by_login", q_argc, q_argv,
107                          get_user_info, &old_info)))
108     {
109       com_err(whoami, status, "while getting user information.");
110       exit(2);
111     }
112
113   /* Get the new information from the user */
114
115   get_new_info(&old_info, &new_info);
116
117   /* Do the update */
118
119   printf("Changing finger information...\n");
120
121   q_argv[F_NAME] = uname;
122   q_argv[F_FULLNAME] = new_info.fullname;
123   q_argv[F_NICKNAME] = new_info.nickname;
124   q_argv[F_HOME_ADDR] = new_info.home_address;
125   q_argv[F_HOME_PHONE] = new_info.home_phone;
126   q_argv[F_OFFICE_ADDR] = new_info.office_address;
127   q_argv[F_OFFICE_PHONE] = new_info.office_phone;
128   q_argv[F_MIT_DEPT] = new_info.mit_department;
129   q_argv[F_MIT_AFFIL] = new_info.mit_year;
130   q_argc = F_MODTIME;           /* First non-update query argument */
131
132   if ((status = mr_query("update_finger_by_login", q_argc, q_argv,
133                          NULL, NULL)))
134     {
135       com_err(whoami, status, "while updating finger information.");
136       exit(1);
137     }
138
139   printf("Finger information updated succesfully.\n");
140
141   return 0;
142 }
143
144 int get_user_info(int argc, char *argv[], void *message)
145 {
146   struct finger_info *old_info = message;
147
148   if (argc != F_END)
149     {
150       fprintf(stderr, "Some internal error occurred; try again.\n");
151       exit(3);
152     }
153
154   printf("Info last changed on %s by user %s with %s.\n",
155          argv[F_MODTIME], argv[F_MODBY], argv[F_MODWITH]);
156
157   old_info->fullname = strdup(argv[F_FULLNAME]);
158   old_info->nickname = strdup(argv[F_NICKNAME]);
159   old_info->home_address = strdup(argv[F_HOME_ADDR]);
160   old_info->home_phone = strdup(argv[F_HOME_PHONE]);
161   old_info->office_address = strdup(argv[F_OFFICE_ADDR]);
162   old_info->office_phone = strdup(argv[F_OFFICE_PHONE]);
163   old_info->mit_department = strdup(argv[F_MIT_DEPT]);
164   old_info->mit_year = strdup(argv[F_MIT_AFFIL]);
165
166   /* Only pay attention to the first match since login names are
167      unique in the database. */
168   return MR_ABORT;
169 }
170
171 char *ask(char *question, char *def_val, int phone_num)
172 {
173   static char buf[BUFSIZ];
174   int ok = FALSE;
175   char *result;
176   int i;
177   int dashes = FALSE;
178
179 #define BLANK "none"
180
181   while (!ok)
182     {
183       ok = TRUE;
184       printf("%s [%s]: ", question, def_val);
185       if (!fgets(buf, sizeof(buf), stdin))
186         exit(0);
187       buf[strlen(buf) - 1] = '\0';
188       if (strlen(buf) == 0)
189         result = def_val;
190       else if (!strcasecmp(buf, BLANK))
191         result = "";
192       else
193         result = buf;
194
195       for (i = 0; i < strlen(buf); i++)
196         {
197           switch (buf[i])
198             {
199             case '"':
200               printf("'\"' is not allowed.\n");
201               ok = FALSE;
202               break;
203             case ',':
204               printf("',' is not allowed.\n");
205               ok = FALSE;
206               break;
207             case ':':
208               printf("':' is not allowed.\n");
209               ok = FALSE;
210               break;
211             default:
212               if (iscntrl(buf[i]))
213                 {
214                   printf("Control characters are not allowed.\n");
215                   ok = FALSE;
216                   break;
217                 }
218             }
219           if (!ok)
220             break;
221         }
222
223       if (phone_num && ok)
224         {
225           for (i = 0; i < strlen(result); i++)
226             {
227               if (!isdigit(result[i]) && (result[i] != '-'))
228                 {
229                   printf("Phone numbers can contain only digits.\n");
230                   ok = FALSE;
231                   break;
232                 }
233               if (result[i] == '-')
234                 dashes = TRUE;
235             }
236         }
237     }
238
239   /* Remove dashes if necessary */
240   if (dashes && result == buf)
241     {
242       char *tmp1, *tmp2;
243       tmp1 = tmp2 = (char *)buf;
244       do
245         {
246           if (*tmp1 != '-')
247             *tmp2++ = *tmp1;
248         }
249       while (*tmp1++);
250     }
251
252     return result;
253 }
254
255 void get_new_info(struct finger_info *old_info, struct finger_info *new_info)
256 {
257   printf("Default values are printed inside of '[]'.\n");
258   printf("To accept the default, type <return>.\n");
259   printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
260
261 #define GETINFO(m, v, n) new_info->v = strdup(ask(m, old_info->v, n))
262
263   GETINFO("Full name", fullname, FALSE);
264   GETINFO("Nickname", nickname, FALSE);
265   GETINFO("Home address (Ex: EC Bemis 514)", home_address, FALSE);
266   GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
267   GETINFO("Office address (Exs: E40-342 or 2-108)",
268           office_address, FALSE);
269   GETINFO("Office phone (Ex: 3-7619)", office_phone, TRUE);
270   GETINFO("MIT department (Exs: 9, Biology, Information Services)",
271           mit_department, FALSE);
272   GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
273 }
274
275 void usage(void)
276 {
277   fprintf(stderr, "Usage: %s [user]\n", whoami);
278   exit(1);
279 }
This page took 0.283411 seconds and 5 git commands to generate.