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