annotate pwm.c @ 0:a7e41e1a79c8

Initial revision
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Thu, 19 Jan 2017 22:39:51 +0100
parents
children 0b1bce8db371
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1 /*
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
2 * Copyright (C) 2016 Guido Berhoerster <guido+pwm@berhoerster.name>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
3 *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
5 * a copy of this software and associated documentation files (the
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
6 * "Software"), to deal in the Software without restriction, including
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
7 * without limitation the rights to use, copy, modify, merge, publish,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
8 * distribute, sublicense, and/or sell copies of the Software, and to
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
9 * permit persons to whom the Software is furnished to do so, subject to
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
10 * the following conditions:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
11 *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
12 * The above copyright notice and this permission notice shall be included
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
13 * in all copies or substantial portions of the Software.
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
14 *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
22 */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
23
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
24 #include "compat.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
25
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
26 #ifdef HAVE_ERR_H
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
27 #include <err.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
28 #endif /* HAVE_ERR_H */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
29 #include <errno.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
30 #include <langinfo.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
31 #include <locale.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
32 #include <pwd.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
33 #ifdef HAVE_READPASSPHRASE_H
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
34 #include <readpassphrase.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
35 #endif /* READPASSPHRASE_H */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
36 #include <stdlib.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
37 #include <stdio.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
38 #include <string.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
39 #include <pwd.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
40 #include <sys/stat.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
41 #include <time.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
42 #include <unistd.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
43
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
44 #include "pwm.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
45 #include "cmd.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
46 #include "pwfile.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
47 #include "tok.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
48 #include "util.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
49
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
50 #ifndef PWM_LINE_MAX
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
51 #define PWM_LINE_MAX 16384
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
52 #endif /* !PWM_LINE_MAX */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
53
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
54 static void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
55 usage(void)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
56 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
57 fprintf(stderr, "usage: %s [-P file] [filename]\n", getprogname());
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
58 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
59
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
60 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
61 run_input_loop(struct pwm_ctx *ctx, int is_interactive)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
62 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
63 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
64 char buf[PWM_LINE_MAX];
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
65 int c;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
66 int argc = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
67 char **argv = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
68 struct cmd *cmd;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
69 int i;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
70
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
71 for (;;) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
72 if (fgets(buf, (int)sizeof (buf), stdin) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
73 if (ferror(stdin)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
74 /* error */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
75 warn("failed to read command");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
76 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
77 } else if (feof(stdin)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
78 /* EOF */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
79 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
80 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
81 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
82 if ((buf[strlen(buf) - 1] != '\n') && !feof(stdin)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
83 /* line was truncated */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
84 fprintf(stderr, "line too long\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
85 if (is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
86 /* skip input to next newline */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
87 do {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
88 errno = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
89 c = fgetc(stdin);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
90 if ((c == EOF) && (errno != 0)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
91 warn("failed to read command");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
92 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
93 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
94 } while ((c != '\n') && (c != EOF));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
95 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
96 /* fatal error in non-interactive mode */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
97 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
98 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
99 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
100
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
101 /* tokenize line */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
102 switch(tok_tokenize(buf, &argc, &argv)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
103 case TOK_ERR_SYSTEM_ERROR:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
104 err(1, "tok_tokenize");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
105 case TOK_ERR_UNTERMINATED_QUOTE:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
106 fprintf(stderr, "unterminated quote\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
107 if (!is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
108 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
109 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
110 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
111 case TOK_ERR_TRAILING_BACKSLASH:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
112 fprintf(stderr, "trailing backslash\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
113 if (!is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
114 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
115 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
116 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
117 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
118
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
119 if (argc == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
120 /* empty line */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
121 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
122 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
123
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
124 /* find and execute the command */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
125 cmd = cmd_match(argv[0]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
126 if (cmd == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
127 fprintf(stderr, "unknown command: %s\n", argv[0]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
128 if (is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
129 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
130 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
131 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
132 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
133 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
134 switch (cmd->cmd_func(ctx, argc, argv)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
135 case CMD_OK:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
136 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
137 case CMD_USAGE:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
138 fprintf(stderr, "usage: %s\n", cmd->usage);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
139 case CMD_ERR: /* FALLTHROUGH */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
140 if (!is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
141 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
142 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
143 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
144 case CMD_QUIT:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
145 goto quit;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
146 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
147
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
148 next:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
149 for (i = 0; i < argc; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
150 free(argv[i]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
151 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
152 free(argv);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
153 argc = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
154 argv = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
155 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
156
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
157 quit:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
158 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
159
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
160 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
161 for (i = 0; i < argc; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
162 free(argv[i]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
163 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
164 free(argv);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
165
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
166 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
167 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
168
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
169 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
170 read_password_from_file(const char *filename, char *password,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
171 size_t password_size)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
172 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
173 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
174 char *buf = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
175 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
176 size_t password_len = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
177
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
178 buf = xmalloc(password_size);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
179
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
180 fp = fopen(filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
181 if (fp == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
182 warn("failed to open master password file \"%s\"", filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
183 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
184 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
185 if (fgets(buf, password_size, fp) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
186 /* read error or empty file */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
187 if (ferror(fp)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
188 /* read error */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
189 warn("failed to read master password from \"%s\"",
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
190 filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
191 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
192 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
193 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
194 password_len = strlen(buf);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
195 if (buf[password_len - 1] == '\n') {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
196 /* strip trailing newline */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
197 password_len--;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
198 if (password_len == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
199 /* first line is empty */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
200 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
201 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
202 } else if (!feof(fp)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
203 /* the first line was truncated, password is too long */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
204 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
205 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
206 memcpy(password, buf, password_size);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
207 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
208
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
209 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
210 password[password_len] = '\0';
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
211
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
212 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
213 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
214 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
215 free(buf);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
216
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
217 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
218 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
219
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
220 int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
221 main(int argc, char *argv[])
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
222 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
223 int status = EXIT_FAILURE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
224 char *locale;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
225 int is_interactive;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
226 int errflag = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
227 int c;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
228 const char *master_password_filename = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
229 struct pwm_ctx ctx = { 0 };
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
230 struct passwd *passwd;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
231 char *pwm_dirname = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
232 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
233 char password_buf[PWS3_MAX_PASSWORD_LEN + 1];
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
234
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
235 setprogname(argv[0]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
236
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
237 /* set up locale and check for UTF-8 codeset */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
238 locale = setlocale(LC_ALL, "");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
239 if (locale == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
240 errx(1, "invalid locale");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
241 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
242 if ((strcasecmp(nl_langinfo(CODESET), "UTF-8") != 0) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
243 (strcasecmp(nl_langinfo(CODESET), "UTF8") != 0)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
244 fprintf(stderr, "pwm requires a locale with UTF-8 character "
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
245 "encoding.\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
246 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
247 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
248
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
249 /* timestamps are processed as UTC */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
250 if (setenv("TZ", "", 1) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
251 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
252 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
253 tzset();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
254
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
255 /* initialize libpws */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
256 if (pws_init() != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
257 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
258 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
259
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
260 is_interactive = isatty(STDIN_FILENO);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
261
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
262 while (!errflag && (c = getopt(argc, argv, "P:h")) != -1) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
263 switch (c) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
264 case 'P':
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
265 master_password_filename = optarg;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
266 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
267 case 'h':
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
268 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
269 status = EXIT_SUCCESS;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
270 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
271 default:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
272 errflag = 1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
273 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
274 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
275 if (errflag || (optind + 1 < argc)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
276 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
277 status = EXIT_USAGE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
278 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
279 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
280
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
281 if (optind == argc) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
282 passwd = getpwuid(getuid());
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
283 if (passwd == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
284 err(1, "getpwuid");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
285 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
286 xasprintf(&pwm_dirname, "%s/.pwm", passwd->pw_dir);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
287 xasprintf(&ctx.filename, "%s/pwm.psafe3", pwm_dirname);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
288
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
289 /* create ~/.pwm directory if necessary */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
290 if ((mkdir(pwm_dirname, S_IRWXU) != 0) && (errno != EEXIST)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
291 warn("failed to create directory \"%s\"", pwm_dirname);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
292 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
293 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
294 } else if (optind + 1 == argc) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
295 ctx.filename = xstrdup(argv[optind++]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
296 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
297 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
298 status = EXIT_USAGE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
299 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
300 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
301
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
302 if (is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
303 printf("pwm version %s\n", VERSION);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
304 } else if (master_password_filename == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
305 fprintf(stderr, "master password file must be specified when "
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
306 "running non-interactively\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
307 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
308 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
309
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
310 pwfile_init(&ctx);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
311
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
312 fp = fopen(ctx.filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
313 if ((fp == NULL) && (errno != ENOENT)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
314 warn("failed to open password database");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
315 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
316 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
317 /* obtain master password */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
318 if (master_password_filename != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
319 if (read_password_from_file(master_password_filename,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
320 ctx.password, sizeof (ctx.password)) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
321 fprintf(stderr, "malformed password database\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
322 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
323 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
324 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
325 if (readpassphrase("Enter password: ", ctx.password,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
326 sizeof (ctx.password), RPP_ECHO_OFF | RPP_REQUIRE_TTY) ==
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
327 NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
328 err(1, "readpassphrase");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
329 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
330 if (ctx.password[0] == '\0') {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
331 fprintf(stderr, "password must not be empty\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
332 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
333 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
334 if (fp == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
335 if (readpassphrase("Confirm password: ", password_buf,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
336 sizeof (password_buf),
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
337 RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
338 err(1, "readpassphrase");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
339 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
340 if (strcmp(ctx.password, password_buf) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
341 fprintf(stderr, "passwords do not match\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
342 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
343 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
344 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
345 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
346 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
347 if (pwfile_read_file(&ctx, fp) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
348 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
349 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
350 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
351 fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
352 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
353
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
354 /* run main input loop */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
355 status = (run_input_loop(&ctx, is_interactive) != 0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
356
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
357 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
358 pwfile_destroy(&ctx);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
359 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
360 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
361 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
362 free(ctx.filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
363 free(pwm_dirname);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
364
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
365 exit(status);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
366 }