]> andersk Git - moira.git/blob - clients/passwd/chfn.c
Win32 portability mods for Pismere.
[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   int i;
79
80   struct finger_info old_info;
81   struct finger_info new_info;
82
83   if (mrcl_connect(NULL, "chsh", 2, 1) != MRCL_SUCCESS)
84     exit(1);
85
86   /* First, do an access check. */
87
88   q_argv[F_NAME] = uname;
89   for (i = F_NAME + 1; i < F_MODTIME; i++)
90     q_argv[i] = "junk";
91   q_argc = F_MODTIME;           /* one more than the last updatable field */
92
93   if ((status = mr_access("update_finger_by_login", q_argc, q_argv)))
94     {
95       com_err(whoami, status, "; finger\ninformation not changed.");
96       exit(2);
97     }
98
99   printf("Changing finger information for %s.\n", uname);
100
101   /* Get information */
102
103   q_argv[NAME] = uname;
104   q_argc = NAME + 1;
105   if ((status = mr_query("get_finger_by_login", q_argc, q_argv,
106                          get_user_info, &old_info)))
107     {
108       com_err(whoami, status, "while getting user information.");
109       exit(2);
110     }
111
112   /* Get the new information from the user */
113
114   get_new_info(&old_info, &new_info);
115
116   /* Do the update */
117
118   printf("Changing finger information...\n");
119
120   q_argv[F_NAME] = uname;
121   q_argv[F_FULLNAME] = new_info.fullname;
122   q_argv[F_NICKNAME] = new_info.nickname;
123   q_argv[F_HOME_ADDR] = new_info.home_address;
124   q_argv[F_HOME_PHONE] = new_info.home_phone;
125   q_argv[F_OFFICE_ADDR] = new_info.office_address;
126   q_argv[F_OFFICE_PHONE] = new_info.office_phone;
127   q_argv[F_MIT_DEPT] = new_info.mit_department;
128   q_argv[F_MIT_AFFIL] = new_info.mit_year;
129   q_argc = F_MODTIME;           /* First non-update query argument */
130
131   if ((status = mr_query("update_finger_by_login", q_argc, q_argv,
132                          NULL, NULL)))
133     {
134       com_err(whoami, status, "while updating finger information.");
135       exit(1);
136     }
137
138   printf("Finger information updated succesfully.\n");
139
140   return 0;
141 }
142
143 int get_user_info(int argc, char *argv[], void *message)
144 {
145   struct finger_info *old_info = message;
146
147   if (argc != F_END)
148     {
149       fprintf(stderr, "Some internal error occurred; try again.\n");
150       exit(3);
151     }
152
153   printf("Info last changed on %s by user %s with %s.\n",
154          argv[F_MODTIME], argv[F_MODBY], argv[F_MODWITH]);
155
156   old_info->fullname = strdup(argv[F_FULLNAME]);
157   old_info->nickname = strdup(argv[F_NICKNAME]);
158   old_info->home_address = strdup(argv[F_HOME_ADDR]);
159   old_info->home_phone = strdup(argv[F_HOME_PHONE]);
160   old_info->office_address = strdup(argv[F_OFFICE_ADDR]);
161   old_info->office_phone = strdup(argv[F_OFFICE_PHONE]);
162   old_info->mit_department = strdup(argv[F_MIT_DEPT]);
163   old_info->mit_year = strdup(argv[F_MIT_AFFIL]);
164
165   /* Only pay attention to the first match since login names are
166      unique in the database. */
167   return MR_ABORT;
168 }
169
170 char *ask(char *question, char *def_val, int phone_num)
171 {
172   static char buf[BUFSIZ];
173   int ok = FALSE;
174   char *result;
175   int i;
176   int dashes = FALSE;
177   int len;
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       len = strlen(buf);
196       for (i = 0; i < len; i++)
197         {
198           switch (buf[i])
199             {
200             case '"':
201               printf("'\"' is not allowed.\n");
202               ok = FALSE;
203               break;
204             case ',':
205               printf("',' is not allowed.\n");
206               ok = FALSE;
207               break;
208             case ':':
209               printf("':' is not allowed.\n");
210               ok = FALSE;
211               break;
212             default:
213               if (iscntrl(buf[i]))
214                 {
215                   printf("Control characters are not allowed.\n");
216                   ok = FALSE;
217                   break;
218                 }
219             }
220           if (!ok)
221             break;
222         }
223
224       if (phone_num && ok)
225         {
226           len = strlen(result);
227           for (i = 0; i < len; i++)
228             {
229               if (!isdigit(result[i]) && (result[i] != '-'))
230                 {
231                   printf("Phone numbers can contain only digits.\n");
232                   ok = FALSE;
233                   break;
234                 }
235               if (result[i] == '-')
236                 dashes = TRUE;
237             }
238         }
239     }
240
241   /* Remove dashes if necessary */
242   if (dashes && result == buf)
243     {
244       char *tmp1, *tmp2;
245       tmp1 = tmp2 = (char *)buf;
246       do
247         {
248           if (*tmp1 != '-')
249             *tmp2++ = *tmp1;
250         }
251       while (*tmp1++);
252     }
253
254     return result;
255 }
256
257 void get_new_info(struct finger_info *old_info, struct finger_info *new_info)
258 {
259   printf("Default values are printed inside of '[]'.\n");
260   printf("To accept the default, type <return>.\n");
261   printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
262
263 #define GETINFO(m, v, n) new_info->v = strdup(ask(m, old_info->v, n))
264
265   GETINFO("Full name", fullname, FALSE);
266   GETINFO("Nickname", nickname, FALSE);
267   GETINFO("Home address (Ex: EC Bemis 514)", home_address, FALSE);
268   GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
269   GETINFO("Office address (Exs: E40-342 or 2-108)",
270           office_address, FALSE);
271   GETINFO("Office phone (Ex: 3-7619)", office_phone, TRUE);
272   GETINFO("MIT department (Exs: 9, Biology, Information Services)",
273           mit_department, FALSE);
274   GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
275 }
276
277 void usage(void)
278 {
279   fprintf(stderr, "Usage: %s [user]\n", whoami);
280   exit(1);
281 }
This page took 0.077852 seconds and 5 git commands to generate.