source: trunk/third/moira/clients/chfn/chfn.c @ 24319

Revision 24319, 6.5 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/* $Id: chfn.c 3956 2010-01-05 20:56:56Z zacheiss $
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
25RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/clients/chfn/chfn.c $ $Id: chfn.c 3956 2010-01-05 20:56:56Z zacheiss $");
26
27#define FALSE 0
28#define TRUE 1
29
30char *whoami;
31char *username;
32
33struct 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
46void usage(void);
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
51int 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
158int 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
185char *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
242void 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
262void usage(void)
263{
264  fprintf(stderr, "Usage: %s [user]\n", whoami);
265  exit(1);
266}
Note: See TracBrowser for help on using the repository browser.