Commit 07d50280 07d50280d3a8493c9cc988a541373ba4a5aec81d by Sergey Poznyakoff

Convert popauth to mu_cli

1 parent 01adf04c
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ 16 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
17 17
18 #include "pop3d.h" 18 #include "pop3d.h"
19 #include "mailutils/libargp.h" 19 #include "mailutils/opt.h"
20 20
21 int db_list (char *input_name, char *output_name); 21 int db_list (char *input_name, char *output_name);
22 int db_make (char *input_name, char *output_name); 22 int db_make (char *input_name, char *output_name);
23 23
24 #define ACT_DEFAULT -1
24 #define ACT_CREATE 0 25 #define ACT_CREATE 0
25 #define ACT_ADD 1 26 #define ACT_ADD 1
26 #define ACT_DELETE 2 27 #define ACT_DELETE 2
...@@ -29,23 +30,19 @@ int db_make (char *input_name, char *output_name); ...@@ -29,23 +30,19 @@ int db_make (char *input_name, char *output_name);
29 30
30 static int permissions = 0600; 31 static int permissions = 0600;
31 static int compatibility_option = 0; 32 static int compatibility_option = 0;
32 33 static int action = ACT_DEFAULT;
33 struct action_data { 34 static char *input_name;
34 int action; 35 static char *output_name;
35 char *input_name; 36 static char *user_name;
36 char *output_name; 37 static char *user_password;
37 char *username; 38
38 char *passwd; 39 int action_create (void);
39 }; 40 int action_add (void);
40 41 int action_delete (void);
41 void check_action(int action); 42 int action_list (void);
42 int action_create (struct action_data *ap); 43 int action_chpass (void);
43 int action_add (struct action_data *ap); 44
44 int action_delete (struct action_data *ap); 45 int (*ftab[]) (void) = {
45 int action_list (struct action_data *ap);
46 int action_chpass (struct action_data *ap);
47
48 int (*ftab[]) (struct action_data *) = {
49 action_create, 46 action_create,
50 action_add, 47 action_add,
51 action_delete, 48 action_delete,
...@@ -53,178 +50,200 @@ int (*ftab[]) (struct action_data *) = { ...@@ -53,178 +50,200 @@ int (*ftab[]) (struct action_data *) = {
53 action_chpass 50 action_chpass
54 }; 51 };
55 52
56 static char doc[] = N_("GNU popauth -- manage pop3 authentication database");
57 static error_t popauth_parse_opt (int key, char *arg,
58 struct argp_state *astate);
59
60 void popauth_version (FILE *stream, struct argp_state *state);
61
62 #define COMPATIBILITY_OPTION 256
63
64 static struct argp_option options[] =
65 {
66 { NULL, 0, NULL, 0, N_("Actions are:"), 1 },
67 { "add", 'a', 0, 0, N_("add user"), 1 },
68 { "modify", 'm', 0, 0, N_("modify user's record (change password)"), 1 },
69 { "delete", 'd', 0, 0, N_("delete user's record"), 1 },
70 { "list", 'l', 0, 0, N_("list the contents of DBM file"), 1 },
71 { "create", 'c', 0, 0, N_("create the DBM from a plaintext file"), 1 },
72
73 { NULL, 0, NULL, 0,
74 N_("Default action is:\n"
75 " For root: --list\n"
76 " For a user: --modify --user <username>\n"), 2 },
77
78 { NULL, 0, NULL, 0, N_("Options are:"), 3 },
79 { "file", 'f', N_("FILE"), 0, N_("read input from FILE (default stdin)"), 3 },
80 { "output", 'o', N_("FILE"), 0, N_("direct output to file"), 3 },
81 { "password", 'p', N_("STRING"), 0, N_("specify user's password"), 3 },
82 { "user", 'u', N_("USERNAME"), 0, N_("specify user name"), 3 },
83 { "permissions", 'P', N_("PERM"), 0, N_("force given permissions on the database"), 3 },
84 { "compatibility", COMPATIBILITY_OPTION, NULL, 0,
85 N_("backward compatibility mode") },
86 { NULL, }
87 };
88
89 static struct argp argp = {
90 options,
91 popauth_parse_opt,
92 NULL,
93 doc,
94 NULL,
95 NULL, NULL
96 };
97
98 static const char *popauth_argp_capa[] = {
99 "mailutils",
100 "common",
101 NULL
102 };
103
104 static void 53 static void
105 set_db_perms (struct argp_state *astate, char *opt, int *pperm) 54 set_action (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
106 { 55 {
107 int perm = 0; 56 if (action != -1)
108
109 if (mu_isdigit (opt[0]))
110 {
111 char *p;
112 perm = strtoul (opt, &p, 8);
113 if (*p)
114 { 57 {
115 argp_error (astate, _("invalid octal number: %s"), opt); 58 mu_parseopt_error (po,
116 exit (EX_USAGE); 59 _("You may not specify more than one `-aldp' option"));
117 } 60 exit (po->po_exit_error);
118 } 61 }
119 *pperm = perm;
120 }
121 62
122 static error_t 63 switch (opt->opt_short)
123 popauth_parse_opt (int key, char *arg, struct argp_state *astate)
124 {
125 struct action_data *ap = astate->input;
126 switch (key)
127 { 64 {
128 case ARGP_KEY_INIT:
129 memset (ap, 0, sizeof(*ap));
130 ap->action = -1;
131 break;
132
133 case 'a': 65 case 'a':
134 check_action (ap->action); 66 action = ACT_ADD;
135 ap->action = ACT_ADD;
136 break; 67 break;
137 68
138 case 'c': 69 case 'c':
139 check_action (ap->action); 70 action = ACT_CREATE;
140 ap->action = ACT_CREATE;
141 break; 71 break;
142 72
143 case 'l': 73 case 'l':
144 check_action (ap->action); 74 action = ACT_LIST;
145 ap->action = ACT_LIST;
146 break; 75 break;
147 76
148 case 'd': 77 case 'd':
149 check_action (ap->action); 78 action = ACT_DELETE;
150 ap->action = ACT_DELETE;
151 break;
152
153 case 'p':
154 ap->passwd = arg;
155 break; 79 break;
156 80
157 case 'm': 81 case 'm':
158 check_action (ap->action); 82 action = ACT_CHPASS;
159 ap->action = ACT_CHPASS;
160 break; 83 break;
161 84
162 case 'f': 85 default:
163 ap->input_name = arg; 86 abort ();
164 break; 87 }
88 }
165 89
166 case 'o': 90 static void
167 ap->output_name = arg; 91 set_permissions (struct mu_parseopt *po, struct mu_option *opt,
168 break; 92 char const *arg)
93 {
94 if (mu_isdigit (arg[0]))
95 {
96 char *p;
97 permissions = strtoul (arg, &p, 8);
98 if (*p == 0)
99 return;
100 }
169 101
170 case 'u': 102 mu_parseopt_error (po, _("invalid octal number: %s"), arg);
171 ap->username = arg; 103 exit (EX_USAGE);
172 break; 104 }
173 105
174 case 'P': 106 static struct mu_option popauth_options[] = {
175 set_db_perms (astate, arg, &permissions); 107 MU_OPTION_GROUP (N_("Actions are:")),
176 break; 108 { "add", 'a', NULL, MU_OPTION_DEFAULT,
109 N_("add user"),
110 mu_c_string, NULL, set_action },
111 { "modify", 'm', NULL, MU_OPTION_DEFAULT,
112 N_("modify user's record (change password)"),
113 mu_c_string, NULL, set_action },
114 { "delete", 'd', NULL, MU_OPTION_DEFAULT,
115 N_("delete user's record"),
116 mu_c_string, NULL, set_action },
117 { "list", 'l', NULL, MU_OPTION_DEFAULT,
118 N_("list the contents of DBM file"),
119 mu_c_string, NULL, set_action },
120 { "create", 'c', NULL, MU_OPTION_DEFAULT,
121 N_("create the DBM from a plaintext file"),
122 mu_c_string, NULL, set_action },
123
124 MU_OPTION_GROUP (N_("Options are:")),
125 { "file", 'f', N_("FILE"), MU_OPTION_DEFAULT,
126 N_("read input from FILE (default stdin)"),
127 mu_c_string, &input_name },
128 { "output", 'o', N_("FILE"), MU_OPTION_DEFAULT,
129 N_("direct output to file"),
130 mu_c_string, &output_name },
131 { "password", 'p', N_("STRING"), MU_OPTION_DEFAULT,
132 N_("specify user's password"),
133 mu_c_string, &user_password },
134 { "user", 'u', N_("USERNAME"), MU_OPTION_DEFAULT,
135 N_("specify user name"),
136 mu_c_string, &user_name },
137 { "permissions", 'P', N_("PERM"), MU_OPTION_DEFAULT,
138 N_("force given permissions on the database"),
139 mu_c_string, NULL, set_permissions },
140 { "compatibility", 0, NULL, MU_OPTION_DEFAULT,
141 N_("compatibility mode"),
142 mu_c_bool, &compatibility_option },
143 MU_OPTION_END
144 }, *options[] = { popauth_options, NULL };
177 145
178 case COMPATIBILITY_OPTION: 146 void
179 compatibility_option = 1; 147 popauth_version (struct mu_parseopt *po, mu_stream_t stream)
180 break; 148 {
149 mu_iterator_t itr;
150 int rc;
151
152 mu_version_func (po, stream);
153 mu_stream_printf (stream, _("Database formats: "));
181 154
182 case ARGP_KEY_FINI: 155 rc = mu_dbm_impl_iterator (&itr);
183 if (ap->action == -1) 156 if (rc)
184 { 157 {
185 /* Deduce the default action */ 158 mu_stream_printf (stream, "%s\n", _("unknown"));
186 if (getuid () == 0) 159 mu_error ("%s", mu_strerror (rc));
187 ap->action = ACT_LIST;
188 else
189 ap->action = ACT_CHPASS;
190 } 160 }
191 break; 161 else
162 {
163 int i;
164 for (mu_iterator_first (itr), i = 0; !mu_iterator_is_done (itr);
165 mu_iterator_next (itr), i++)
166 {
167 struct mu_dbm_impl *impl;
192 168
193 default: 169 mu_iterator_current (itr, (void**)&impl);
194 return ARGP_ERR_UNKNOWN; 170 if (i)
171 mu_stream_printf (stream, ", ");
172 mu_stream_printf (stream, "%s", impl->_dbm_name);
195 } 173 }
196 return 0; 174 mu_stream_printf (stream, "\n");
175 mu_iterator_destroy (&itr);
176 }
177 mu_stream_printf (stream, _("Default database location: %s\n"),
178 APOP_PASSFILE);
179 exit (EX_OK);
180 }
181
182 void
183 popauth_help_hook (struct mu_parseopt *po, mu_stream_t stream)
184 {
185 unsigned margin = 2;
186
187 mu_stream_printf (stream, "%s", _("Default action is:\n"));
188 mu_stream_ioctl (stream, MU_IOCTL_WORDWRAPSTREAM,
189 MU_IOCTL_WORDWRAP_SET_MARGIN, &margin);
190 mu_stream_printf (stream, "%s\n", _("For root: --list"));
191 mu_stream_printf (stream, "%s\n",
192 _("For a user: --modify --user <username>"));
197 } 193 }
198 194
199 int 195 int
200 main (int argc, char **argv) 196 main (int argc, char **argv)
201 { 197 {
202 struct action_data adata; 198 struct mu_parseopt po;
199 int flags;
203 200
204 /* Native Language Support */ 201 /* Native Language Support */
205 MU_APP_INIT_NLS (); 202 MU_APP_INIT_NLS ();
206 203
207 mu_argp_init (NULL, NULL); 204 mu_set_program_name (argv[0]);
208 argp_program_version_hook = popauth_version;
209 if (mu_app_init (&argp, popauth_argp_capa, NULL,
210 argc, argv, 0, NULL, &adata))
211 exit (EX_USAGE);
212 205
213 return (*ftab[adata.action]) (&adata); 206 po.po_prog_doc = N_("GNU popauth -- manage pop3 authentication database");
214 } 207 po.po_package_name = PACKAGE_NAME;
208 po.po_package_url = PACKAGE_URL;
209 po.po_bug_address = PACKAGE_BUGREPORT;
210 po.po_extra_info =
211 N_("General help using GNU software: <http://www.gnu.org/gethelp/>");
212 po.po_version_hook = popauth_version;
213 po.po_help_hook = popauth_help_hook;
215 214
216 void 215 flags = MU_PARSEOPT_IMMEDIATE
217 check_action (int action) 216 | MU_PARSEOPT_DATA
218 { 217 | MU_PARSEOPT_PROG_DOC
219 if (action != -1) 218 | MU_PARSEOPT_PACKAGE_NAME
219 | MU_PARSEOPT_PACKAGE_URL
220 | MU_PARSEOPT_BUG_ADDRESS
221 | MU_PARSEOPT_EXTRA_INFO
222 | MU_PARSEOPT_VERSION_HOOK
223 | MU_PARSEOPT_HELP_HOOK;
224
225 if (mu_parseopt (&po, argc, argv, options, flags))
226 exit (po.po_exit_error);
227
228 if (argc > po.po_arg_start)
220 { 229 {
221 mu_error (_("You may not specify more than one `-aldp' option")); 230 mu_parseopt_error (&po, _("too many arguments"));
222 exit (EX_USAGE); 231 exit (po.po_exit_error);
223 } 232 }
233 mu_parseopt_free (&po);
234
235 if (action == ACT_DEFAULT)
236 {
237 if (getuid () == 0)
238 action = ACT_LIST;
239 else
240 action = ACT_CHPASS;
241 }
242 return (*ftab[action]) ();
224 } 243 }
225 244
226 mu_dbm_file_t 245 mu_dbm_file_t
227 open_db_file (int action, struct action_data *ap, int *my_file) 246 open_db_file (int action, int *my_file)
228 { 247 {
229 mu_dbm_file_t db; 248 mu_dbm_file_t db;
230 struct passwd *pw; 249 struct passwd *pw;
...@@ -241,30 +260,30 @@ open_db_file (int action, struct action_data *ap, int *my_file) ...@@ -241,30 +260,30 @@ open_db_file (int action, struct action_data *ap, int *my_file)
241 case ACT_CREATE: 260 case ACT_CREATE:
242 flags = MU_STREAM_CREAT; 261 flags = MU_STREAM_CREAT;
243 safety_flags = MU_FILE_SAFETY_NONE; 262 safety_flags = MU_FILE_SAFETY_NONE;
244 db_name = ap->output_name; 263 db_name = output_name;
245 break; 264 break;
246 265
247 case ACT_ADD: 266 case ACT_ADD:
248 case ACT_DELETE: 267 case ACT_DELETE:
249 if (!ap->input_name) 268 if (!input_name)
250 ap->input_name = APOP_PASSFILE; 269 input_name = APOP_PASSFILE;
251 flags = MU_STREAM_RDWR; 270 flags = MU_STREAM_RDWR;
252 db_name = ap->input_name; 271 db_name = input_name;
253 break; 272 break;
254 273
255 case ACT_LIST: 274 case ACT_LIST:
256 if (!ap->input_name) 275 if (!input_name)
257 ap->input_name = APOP_PASSFILE; 276 input_name = APOP_PASSFILE;
258 flags = MU_STREAM_READ; 277 flags = MU_STREAM_READ;
259 safety_flags = MU_FILE_SAFETY_NONE; 278 safety_flags = MU_FILE_SAFETY_NONE;
260 db_name = ap->input_name; 279 db_name = input_name;
261 break; 280 break;
262 281
263 case ACT_CHPASS: 282 case ACT_CHPASS:
264 if (!ap->input_name) 283 if (!input_name)
265 ap->input_name = APOP_PASSFILE; 284 input_name = APOP_PASSFILE;
266 flags = MU_STREAM_RDWR; 285 flags = MU_STREAM_RDWR;
267 db_name = ap->input_name; 286 db_name = input_name;
268 break; 287 break;
269 288
270 default: 289 default:
...@@ -336,7 +355,7 @@ open_db_file (int action, struct action_data *ap, int *my_file) ...@@ -336,7 +355,7 @@ open_db_file (int action, struct action_data *ap, int *my_file)
336 if (my_file) 355 if (my_file)
337 *my_file = 0; 356 *my_file = 0;
338 357
339 if (ap->username) 358 if (user_name)
340 { 359 {
341 mu_error (_("Only the file owner can use --username")); 360 mu_error (_("Only the file owner can use --username"));
342 exit (EX_USAGE); 361 exit (EX_USAGE);
...@@ -350,7 +369,7 @@ open_db_file (int action, struct action_data *ap, int *my_file) ...@@ -350,7 +369,7 @@ open_db_file (int action, struct action_data *ap, int *my_file)
350 pw = getpwuid (uid); 369 pw = getpwuid (uid);
351 if (!pw) 370 if (!pw)
352 exit (EX_OSERR); 371 exit (EX_OSERR);
353 ap->username = pw->pw_name; 372 user_name = pw->pw_name;
354 return db; 373 return db;
355 } 374 }
356 375
...@@ -373,23 +392,23 @@ print_entry (mu_stream_t str, struct mu_dbm_datum const *key, ...@@ -373,23 +392,23 @@ print_entry (mu_stream_t str, struct mu_dbm_datum const *key,
373 } 392 }
374 393
375 int 394 int
376 action_list (struct action_data *ap) 395 action_list (void)
377 { 396 {
378 mu_stream_t str; 397 mu_stream_t str;
379 mu_dbm_file_t db; 398 mu_dbm_file_t db;
380 struct mu_dbm_datum key, contents; 399 struct mu_dbm_datum key, contents;
381 int rc; 400 int rc;
382 401
383 db = open_db_file (ACT_LIST, ap, NULL); 402 db = open_db_file (ACT_LIST, NULL);
384 403
385 if (ap->output_name) 404 if (output_name)
386 { 405 {
387 int rc = mu_file_stream_create (&str, ap->output_name, 406 int rc = mu_file_stream_create (&str, output_name,
388 MU_STREAM_WRITE|MU_STREAM_CREAT); 407 MU_STREAM_WRITE|MU_STREAM_CREAT);
389 if (rc) 408 if (rc)
390 { 409 {
391 mu_error (_("cannot create file %s: %s"), 410 mu_error (_("cannot create file %s: %s"),
392 ap->output_name, mu_strerror (rc)); 411 output_name, mu_strerror (rc));
393 return 1; 412 return 1;
394 } 413 }
395 mu_stream_truncate (str, 0); 414 mu_stream_truncate (str, 0);
...@@ -400,16 +419,16 @@ action_list (struct action_data *ap) ...@@ -400,16 +419,16 @@ action_list (struct action_data *ap)
400 mu_stream_ref (str); 419 mu_stream_ref (str);
401 } 420 }
402 421
403 if (ap->username) 422 if (user_name)
404 { 423 {
405 memset (&key, 0, sizeof key); 424 memset (&key, 0, sizeof key);
406 memset (&contents, 0, sizeof contents); 425 memset (&contents, 0, sizeof contents);
407 key.mu_dptr = ap->username; 426 key.mu_dptr = user_name;
408 key.mu_dsize = strlen (ap->username); 427 key.mu_dsize = strlen (user_name);
409 rc = mu_dbm_fetch (db, &key, &contents); 428 rc = mu_dbm_fetch (db, &key, &contents);
410 if (rc == MU_ERR_NOENT) 429 if (rc == MU_ERR_NOENT)
411 { 430 {
412 mu_error (_("no such user: %s"), ap->username); 431 mu_error (_("no such user: %s"), user_name);
413 } 432 }
414 else if (rc) 433 else if (rc)
415 { 434 {
...@@ -449,7 +468,7 @@ action_list (struct action_data *ap) ...@@ -449,7 +468,7 @@ action_list (struct action_data *ap)
449 } 468 }
450 469
451 int 470 int
452 action_create (struct action_data *ap) 471 action_create (void)
453 { 472 {
454 int rc; 473 int rc;
455 mu_stream_t in; 474 mu_stream_t in;
...@@ -462,19 +481,19 @@ action_create (struct action_data *ap) ...@@ -462,19 +481,19 @@ action_create (struct action_data *ap)
462 /* Make sure we have proper privileges if popauth is setuid */ 481 /* Make sure we have proper privileges if popauth is setuid */
463 setuid (getuid ()); 482 setuid (getuid ());
464 483
465 if (ap->input_name) 484 if (input_name)
466 { 485 {
467 rc = mu_file_stream_create (&in, ap->input_name, MU_STREAM_READ); 486 rc = mu_file_stream_create (&in, input_name, MU_STREAM_READ);
468 if (rc) 487 if (rc)
469 { 488 {
470 mu_error (_("cannot open file %s: %s"), 489 mu_error (_("cannot open file %s: %s"),
471 ap->input_name, mu_strerror (rc)); 490 input_name, mu_strerror (rc));
472 return 1; 491 return 1;
473 } 492 }
474 } 493 }
475 else 494 else
476 { 495 {
477 ap->input_name = ""; 496 input_name = "";
478 rc = mu_stdio_stream_create (&in, MU_STDIN_FD, MU_STREAM_READ); 497 rc = mu_stdio_stream_create (&in, MU_STDIN_FD, MU_STREAM_READ);
479 if (rc) 498 if (rc)
480 { 499 {
...@@ -484,10 +503,10 @@ action_create (struct action_data *ap) ...@@ -484,10 +503,10 @@ action_create (struct action_data *ap)
484 } 503 }
485 } 504 }
486 505
487 if (!ap->output_name) 506 if (!output_name)
488 ap->output_name = APOP_PASSFILE; 507 output_name = APOP_PASSFILE;
489 508
490 db = open_db_file (ACT_CREATE, ap, NULL); 509 db = open_db_file (ACT_CREATE, NULL);
491 510
492 line = 0; 511 line = 0;
493 while ((rc = mu_stream_getline (in, &buf, &size, &len)) == 0 512 while ((rc = mu_stream_getline (in, &buf, &size, &len)) == 0
...@@ -502,7 +521,7 @@ action_create (struct action_data *ap) ...@@ -502,7 +521,7 @@ action_create (struct action_data *ap)
502 pass = mu_str_skip_class_comp (str, MU_CTYPE_SPACE); 521 pass = mu_str_skip_class_comp (str, MU_CTYPE_SPACE);
503 if (*pass == 0) 522 if (*pass == 0)
504 { 523 {
505 mu_error (_("%s:%d: malformed line"), ap->input_name, line); 524 mu_error (_("%s:%d: malformed line"), input_name, line);
506 continue; 525 continue;
507 } 526 }
508 /* Strip trailing semicolon, when in compatibility mode. */ 527 /* Strip trailing semicolon, when in compatibility mode. */
...@@ -512,7 +531,7 @@ action_create (struct action_data *ap) ...@@ -512,7 +531,7 @@ action_create (struct action_data *ap)
512 pass = mu_str_skip_class (pass, MU_CTYPE_SPACE); 531 pass = mu_str_skip_class (pass, MU_CTYPE_SPACE);
513 if (*pass == 0) 532 if (*pass == 0)
514 { 533 {
515 mu_error (_("%s:%d: malformed line"), ap->input_name, line); 534 mu_error (_("%s:%d: malformed line"), input_name, line);
516 continue; 535 continue;
517 } 536 }
518 537
...@@ -526,7 +545,7 @@ action_create (struct action_data *ap) ...@@ -526,7 +545,7 @@ action_create (struct action_data *ap)
526 rc = mu_dbm_store (db, &key, &contents, 1); 545 rc = mu_dbm_store (db, &key, &contents, 1);
527 if (rc) 546 if (rc)
528 mu_error (_("%s:%d: cannot store datum: %s"), 547 mu_error (_("%s:%d: cannot store datum: %s"),
529 ap->input_name, line, 548 input_name, line,
530 rc == MU_ERR_FAILURE ? 549 rc == MU_ERR_FAILURE ?
531 mu_dbm_strerror (db) : mu_strerror (rc)); 550 mu_dbm_strerror (db) : mu_strerror (rc));
532 } 551 }
...@@ -543,10 +562,10 @@ open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner) ...@@ -543,10 +562,10 @@ open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner)
543 int rc = check_user_perm (action, ap); 562 int rc = check_user_perm (action, ap);
544 if (not_owner) 563 if (not_owner)
545 *not_owner = rc; 564 *not_owner = rc;
546 if (mu_dbm_open (ap->input_name, db, MU_STREAM_RDWR, permissions)) 565 if (mu_dbm_open (input_name, db, MU_STREAM_RDWR, permissions))
547 { 566 {
548 mu_error (_("cannot open file %s: %s"), 567 mu_error (_("cannot open file %s: %s"),
549 ap->input_name, mu_strerror (errno)); 568 input_name, mu_strerror (errno));
550 return 1; 569 return 1;
551 } 570 }
552 return 0; 571 return 0;
...@@ -554,9 +573,9 @@ open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner) ...@@ -554,9 +573,9 @@ open_io (int action, struct action_data *ap, DBM_FILE *db, int *not_owner)
554 */ 573 */
555 574
556 void 575 void
557 fill_pass (struct action_data *ap) 576 fill_pass (void)
558 { 577 {
559 if (!ap->passwd) 578 if (!user_password)
560 { 579 {
561 char *p; 580 char *p;
562 mu_stream_t in, out; 581 mu_stream_t in, out;
...@@ -580,8 +599,8 @@ fill_pass (struct action_data *ap) ...@@ -580,8 +599,8 @@ fill_pass (struct action_data *ap)
580 599
581 while (1) 600 while (1)
582 { 601 {
583 if (ap->passwd) 602 if (user_password)
584 free (ap->passwd); 603 free (user_password);
585 rc = mu_getpass (in, out, _("Password:"), &p); 604 rc = mu_getpass (in, out, _("Password:"), &p);
586 if (rc) 605 if (rc)
587 { 606 {
...@@ -592,7 +611,7 @@ fill_pass (struct action_data *ap) ...@@ -592,7 +611,7 @@ fill_pass (struct action_data *ap)
592 if (!p) 611 if (!p)
593 exit (EX_DATAERR); 612 exit (EX_DATAERR);
594 613
595 ap->passwd = mu_strdup (p); 614 user_password = mu_strdup (p);
596 /* TRANSLATORS: Please try to format this string so that it has 615 /* TRANSLATORS: Please try to format this string so that it has
597 the same length as the translation of 'Password:' above */ 616 the same length as the translation of 'Password:' above */
598 rc = mu_getpass (in, out, _("Confirm :"), &p); 617 rc = mu_getpass (in, out, _("Confirm :"), &p);
...@@ -604,7 +623,7 @@ fill_pass (struct action_data *ap) ...@@ -604,7 +623,7 @@ fill_pass (struct action_data *ap)
604 623
605 if (!p) 624 if (!p)
606 exit (EX_DATAERR); 625 exit (EX_DATAERR);
607 if (strcmp (ap->passwd, p) == 0) 626 if (strcmp (user_password, p) == 0)
608 break; 627 break;
609 mu_error (_("Passwords differ. Please retry.")); 628 mu_error (_("Passwords differ. Please retry."));
610 } 629 }
...@@ -614,28 +633,28 @@ fill_pass (struct action_data *ap) ...@@ -614,28 +633,28 @@ fill_pass (struct action_data *ap)
614 } 633 }
615 634
616 int 635 int
617 action_add (struct action_data *ap) 636 action_add (void)
618 { 637 {
619 mu_dbm_file_t db; 638 mu_dbm_file_t db;
620 struct mu_dbm_datum key, contents; 639 struct mu_dbm_datum key, contents;
621 int rc; 640 int rc;
622 641
623 if (!ap->username) 642 if (!user_name)
624 { 643 {
625 mu_error (_("missing username to add")); 644 mu_error (_("missing user name to add"));
626 return 1; 645 return 1;
627 } 646 }
628 647
629 db = open_db_file (ACT_ADD, ap, NULL); 648 db = open_db_file (ACT_ADD, NULL);
630 649
631 fill_pass (ap); 650 fill_pass ();
632 651
633 memset (&key, 0, sizeof key); 652 memset (&key, 0, sizeof key);
634 memset (&contents, 0, sizeof contents); 653 memset (&contents, 0, sizeof contents);
635 key.mu_dptr = ap->username; 654 key.mu_dptr = user_name;
636 key.mu_dsize = strlen (ap->username); 655 key.mu_dsize = strlen (user_name);
637 contents.mu_dptr = ap->passwd; 656 contents.mu_dptr = user_password;
638 contents.mu_dsize = strlen (ap->passwd); 657 contents.mu_dsize = strlen (user_password);
639 658
640 rc = mu_dbm_store (db, &key, &contents, 1); 659 rc = mu_dbm_store (db, &key, &contents, 1);
641 if (rc) 660 if (rc)
...@@ -648,28 +667,28 @@ action_add (struct action_data *ap) ...@@ -648,28 +667,28 @@ action_add (struct action_data *ap)
648 } 667 }
649 668
650 int 669 int
651 action_delete (struct action_data *ap) 670 action_delete (void)
652 { 671 {
653 mu_dbm_file_t db; 672 mu_dbm_file_t db;
654 struct mu_dbm_datum key; 673 struct mu_dbm_datum key;
655 int rc; 674 int rc;
656 675
657 if (!ap->username) 676 if (!user_name)
658 { 677 {
659 mu_error (_("missing username to delete")); 678 mu_error (_("missing username to delete"));
660 return 1; 679 return 1;
661 } 680 }
662 681
663 db = open_db_file (ACT_DELETE, ap, NULL); 682 db = open_db_file (ACT_DELETE, NULL);
664 683
665 memset (&key, 0, sizeof key); 684 memset (&key, 0, sizeof key);
666 key.mu_dptr = ap->username; 685 key.mu_dptr = user_name;
667 key.mu_dsize = strlen (ap->username); 686 key.mu_dsize = strlen (user_name);
668 687
669 rc = mu_dbm_delete (db, &key); 688 rc = mu_dbm_delete (db, &key);
670 if (rc) 689 if (rc)
671 mu_error (_("cannot remove record for %s: %s"), 690 mu_error (_("cannot remove record for %s: %s"),
672 ap->username, 691 user_name,
673 rc == MU_ERR_FAILURE ? 692 rc == MU_ERR_FAILURE ?
674 mu_dbm_strerror (db) : mu_strerror (rc)); 693 mu_dbm_strerror (db) : mu_strerror (rc));
675 694
...@@ -678,31 +697,31 @@ action_delete (struct action_data *ap) ...@@ -678,31 +697,31 @@ action_delete (struct action_data *ap)
678 } 697 }
679 698
680 int 699 int
681 action_chpass (struct action_data *ap) 700 action_chpass (void)
682 { 701 {
683 mu_dbm_file_t db; 702 mu_dbm_file_t db;
684 struct mu_dbm_datum key, contents; 703 struct mu_dbm_datum key, contents;
685 int rc; 704 int rc;
686 int my_file; 705 int my_file;
687 706
688 db = open_db_file (ACT_CHPASS, ap, &my_file); 707 db = open_db_file (ACT_CHPASS, &my_file);
689 708
690 if (!ap->username) 709 if (!user_name)
691 { 710 {
692 struct passwd *pw = getpwuid (getuid ()); 711 struct passwd *pw = getpwuid (getuid ());
693 ap->username = pw->pw_name; 712 user_name = pw->pw_name;
694 printf ("Changing password for %s\n", ap->username); 713 printf ("Changing password for %s\n", user_name);
695 } 714 }
696 715
697 memset (&key, 0, sizeof key); 716 memset (&key, 0, sizeof key);
698 memset (&contents, 0, sizeof contents); 717 memset (&contents, 0, sizeof contents);
699 718
700 key.mu_dptr = ap->username; 719 key.mu_dptr = user_name;
701 key.mu_dsize = strlen (ap->username); 720 key.mu_dsize = strlen (user_name);
702 rc = mu_dbm_fetch (db, &key, &contents); 721 rc = mu_dbm_fetch (db, &key, &contents);
703 if (rc == MU_ERR_NOENT) 722 if (rc == MU_ERR_NOENT)
704 { 723 {
705 mu_error (_("no such user: %s"), ap->username); 724 mu_error (_("no such user: %s"), user_name);
706 return 1; 725 return 1;
707 } 726 }
708 else if (rc) 727 else if (rc)
...@@ -728,11 +747,11 @@ action_chpass (struct action_data *ap) ...@@ -728,11 +747,11 @@ action_chpass (struct action_data *ap)
728 } 747 }
729 } 748 }
730 749
731 fill_pass (ap); 750 fill_pass ();
732 751
733 mu_dbm_datum_free (&contents); 752 mu_dbm_datum_free (&contents);
734 contents.mu_dptr = ap->passwd; 753 contents.mu_dptr = user_password;
735 contents.mu_dsize = strlen (ap->passwd); 754 contents.mu_dsize = strlen (user_password);
736 rc = mu_dbm_store (db, &key, &contents, 1); 755 rc = mu_dbm_store (db, &key, &contents, 1);
737 if (rc) 756 if (rc)
738 mu_error (_("cannot replace datum: %s"), 757 mu_error (_("cannot replace datum: %s"),
...@@ -743,37 +762,3 @@ action_chpass (struct action_data *ap) ...@@ -743,37 +762,3 @@ action_chpass (struct action_data *ap)
743 return rc; 762 return rc;
744 } 763 }
745 764
746 void
747 popauth_version (FILE *stream, struct argp_state *state)
748 {
749 mu_iterator_t itr;
750 int rc;
751
752 mu_program_version_hook (stream, state);
753 fprintf (stream, _("Database formats: "));
754
755 rc = mu_dbm_impl_iterator (&itr);
756 if (rc)
757 {
758 fprintf (stream, "%s\n", _("unknown"));
759 mu_error ("%s", mu_strerror (rc));
760 }
761 else
762 {
763 int i;
764 for (mu_iterator_first (itr), i = 0; !mu_iterator_is_done (itr);
765 mu_iterator_next (itr), i++)
766 {
767 struct mu_dbm_impl *impl;
768
769 mu_iterator_current (itr, (void**)&impl);
770 if (i)
771 fprintf (stream, ", ");
772 fprintf (stream, "%s", impl->_dbm_name);
773 }
774 fputc ('\n', stream);
775 mu_iterator_destroy (&itr);
776 }
777 fprintf (stream, _("Default database location: %s\n"), APOP_PASSFILE);
778 exit (EX_OK);
779 }
......