annotate pwm.c @ 16:a07665727c19

Add status command Add status command to redisplay an error message of the previous command and unsaved changes. Add pwm_err function to display and save error messages.
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Tue, 08 Aug 2017 10:47:04 +0200
parents cf81eb0c2d5a
children 1e39a251cbe9
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 /*
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
2 * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name>
0
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
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
60 void
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
61 pwm_err(struct pwm_ctx *ctx, char *fmt, ...)
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
62 {
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
63 va_list args;
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
64
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
65 free(ctx->errmsg);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
66
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
67 if (fmt != NULL) {
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
68 va_start(args, fmt);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
69 xvasprintf(&ctx->errmsg, fmt, args);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
70 va_end(args);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
71
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
72 fprintf(stderr, "%s\n", ctx->errmsg);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
73 } else {
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
74 ctx->errmsg = NULL;
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
75 }
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
76 }
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
77
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
78 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
79 run_input_loop(struct pwm_ctx *ctx, int is_interactive)
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 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
82 char buf[PWM_LINE_MAX];
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
83 int c;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
84 int argc = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
85 char **argv = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
86 struct cmd *cmd;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
87 int i;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
88
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
89 for (;;) {
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
90 cmd = NULL;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
91 if (fgets(buf, (int)sizeof (buf), stdin) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
92 if (ferror(stdin)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
93 /* error */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
94 warn("failed to read command");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
95 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
96 } else if (feof(stdin)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
97 /* EOF */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
98 break;
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 if ((buf[strlen(buf) - 1] != '\n') && !feof(stdin)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
102 /* line was truncated */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
103 fprintf(stderr, "line too long\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
104 if (is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
105 /* skip input to next newline */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
106 do {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
107 errno = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
108 c = fgetc(stdin);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
109 if ((c == EOF) && (errno != 0)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
110 warn("failed to read command");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
111 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
112 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
113 } while ((c != '\n') && (c != EOF));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
114 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
115 /* fatal error in non-interactive mode */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
116 goto out;
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
120 /* tokenize line */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
121 switch(tok_tokenize(buf, &argc, &argv)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
122 case TOK_ERR_SYSTEM_ERROR:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
123 err(1, "tok_tokenize");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
124 case TOK_ERR_UNTERMINATED_QUOTE:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
125 fprintf(stderr, "unterminated quote\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
126 if (!is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
127 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
128 }
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 case TOK_ERR_TRAILING_BACKSLASH:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
131 fprintf(stderr, "trailing backslash\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
132 if (!is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
133 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
134 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
135 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
136 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
137
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
138 if (argc == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
139 /* empty line */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
140 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
141 }
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 /* find and execute the command */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
144 cmd = cmd_match(argv[0]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
145 if (cmd == NULL) {
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
146 pwm_err(ctx, "unknown command: %s", argv[0]);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
147 if (is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
148 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
149 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
150 goto out;
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 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
153 switch (cmd->cmd_func(ctx, argc, argv)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
154 case CMD_OK:
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
155 pwm_err(ctx, NULL); /* clear error */
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
156 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
157 case CMD_USAGE:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
158 fprintf(stderr, "usage: %s\n", cmd->usage);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
159 case CMD_ERR: /* FALLTHROUGH */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
160 if (!is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
161 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
162 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
163 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
164 case CMD_QUIT:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
165 goto quit;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
166 }
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
167 ctx->prev_cmd = cmd->full_cmd;
0
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 next:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
170 for (i = 0; i < argc; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
171 free(argv[i]);
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 free(argv);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
174 argc = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
175 argv = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
176 }
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 quit:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
179 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
180
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
181 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
182 for (i = 0; i < argc; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
183 free(argv[i]);
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 free(argv);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
186
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
187 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
188 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
189
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
190 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
191 read_password_from_file(const char *filename, char *password,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
192 size_t password_size)
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 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
195 char *buf = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
196 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
197 size_t password_len = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
198
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
199 buf = xmalloc(password_size);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
200
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
201 fp = fopen(filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
202 if (fp == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
203 warn("failed to open master password file \"%s\"", filename);
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 if (fgets(buf, password_size, fp) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
207 /* read error or empty file */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
208 if (ferror(fp)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
209 /* read error */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
210 warn("failed to read master password from \"%s\"",
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
211 filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
212 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
213 goto out;
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 password_len = strlen(buf);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
216 if (buf[password_len - 1] == '\n') {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
217 /* strip trailing newline */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
218 password_len--;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
219 if (password_len == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
220 /* first line is empty */
5
0b1bce8db371 Prevent misleading double error message
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 0
diff changeset
221 fprintf(stderr, "malformed password file\n");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
222 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
223 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
224 } else if (!feof(fp)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
225 /* the first line was truncated, password is too long */
5
0b1bce8db371 Prevent misleading double error message
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 0
diff changeset
226 fprintf(stderr, "malformed password file\n");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
227 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
228 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
229 memcpy(password, buf, password_size);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
230 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
231
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
232 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
233 password[password_len] = '\0';
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 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
236 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
237 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
238 free(buf);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
239
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
240 return (retval);
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
243 int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
244 main(int argc, char *argv[])
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
245 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
246 int status = EXIT_FAILURE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
247 char *locale;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
248 int is_interactive;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
249 int errflag = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
250 int c;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
251 const char *master_password_filename = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
252 struct pwm_ctx ctx = { 0 };
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
253 struct passwd *passwd;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
254 char *pwm_dirname = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
255 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
256 char password_buf[PWS3_MAX_PASSWORD_LEN + 1];
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
257
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
258 setprogname(argv[0]);
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 /* set up locale and check for UTF-8 codeset */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
261 locale = setlocale(LC_ALL, "");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
262 if (locale == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
263 errx(1, "invalid locale");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
264 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
265 if ((strcasecmp(nl_langinfo(CODESET), "UTF-8") != 0) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
266 (strcasecmp(nl_langinfo(CODESET), "UTF8") != 0)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
267 fprintf(stderr, "pwm requires a locale with UTF-8 character "
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
268 "encoding.\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
269 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
270 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
271
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
272 /* timestamps are processed as UTC */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
273 if (setenv("TZ", "", 1) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
274 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
275 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
276 tzset();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
277
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
278 /* initialize libpws */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
279 if (pws_init() != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
280 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
281 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
282
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
283 is_interactive = isatty(STDIN_FILENO);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
284
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
285 while (!errflag && (c = getopt(argc, argv, "P:h")) != -1) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
286 switch (c) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
287 case 'P':
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
288 master_password_filename = optarg;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
289 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
290 case 'h':
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
291 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
292 status = EXIT_SUCCESS;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
293 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
294 default:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
295 errflag = 1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
296 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
297 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
298 if (errflag || (optind + 1 < argc)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
299 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
300 status = EXIT_USAGE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
301 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
302 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
303
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
304 if (optind == argc) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
305 passwd = getpwuid(getuid());
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
306 if (passwd == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
307 err(1, "getpwuid");
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 xasprintf(&pwm_dirname, "%s/.pwm", passwd->pw_dir);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
310 xasprintf(&ctx.filename, "%s/pwm.psafe3", pwm_dirname);
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 /* create ~/.pwm directory if necessary */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
313 if ((mkdir(pwm_dirname, S_IRWXU) != 0) && (errno != EEXIST)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
314 warn("failed to create directory \"%s\"", pwm_dirname);
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 } else if (optind + 1 == argc) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
318 ctx.filename = xstrdup(argv[optind++]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
319 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
320 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
321 status = EXIT_USAGE;
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
325 if (is_interactive) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
326 printf("pwm version %s\n", VERSION);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
327 } else if (master_password_filename == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
328 fprintf(stderr, "master password file must be specified when "
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
329 "running non-interactively\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
330 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
331 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
332
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
333 pwfile_init(&ctx);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
334
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
335 fp = fopen(ctx.filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
336 if ((fp == NULL) && (errno != ENOENT)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
337 warn("failed to open password database");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
338 goto out;
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 /* obtain master password */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
341 if (master_password_filename != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
342 if (read_password_from_file(master_password_filename,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
343 ctx.password, sizeof (ctx.password)) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
344 goto out;
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 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
347 if (readpassphrase("Enter password: ", ctx.password,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
348 sizeof (ctx.password), RPP_ECHO_OFF | RPP_REQUIRE_TTY) ==
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
349 NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
350 err(1, "readpassphrase");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
351 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
352 if (ctx.password[0] == '\0') {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
353 fprintf(stderr, "password must not be empty\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
354 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
355 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
356 if (fp == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
357 if (readpassphrase("Confirm password: ", password_buf,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
358 sizeof (password_buf),
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
359 RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
360 err(1, "readpassphrase");
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 if (strcmp(ctx.password, password_buf) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
363 fprintf(stderr, "passwords do not match\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
364 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
365 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
366 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
367 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
368 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
369 if (pwfile_read_file(&ctx, fp) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
370 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
371 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
372 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
373 fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
374 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
375
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
376 /* run main input loop */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
377 status = (run_input_loop(&ctx, is_interactive) != 0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
378
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
379 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
380 pwfile_destroy(&ctx);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
381 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
382 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
383 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
384 free(ctx.filename);
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
385 free(ctx.errmsg);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
386 free(pwm_dirname);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
387
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
388 exit(status);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
389 }