annotate pwm.c @ 39:131c35592054

Allow keybinding customizations in ~/.teclarc
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Thu, 08 Aug 2019 22:48:09 +0200
parents 2a8298bafec2
children
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>
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
30 #include <fcntl.h>
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
31 #include <langinfo.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
32 #include <locale.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
33 #include <pwd.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
34 #include <stdlib.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
35 #include <stdio.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
36 #include <string.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
37 #include <pwd.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
38 #include <sys/stat.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
39 #include <time.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
40 #include <unistd.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
41
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
42 #include "pwm.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
43 #include "cmd.h"
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
44 #include "io.h"
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
45 #include "macro.h"
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
46 #include "pwfile.h"
29
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
47 #include "pwmrc.h"
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
48 #include "tok.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
49 #include "util.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
50
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
51 static void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
52 usage(void)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
53 {
23
1b89066d992c Add read-only mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 22
diff changeset
54 fprintf(stderr, "usage: %s [-P file] [-R] [filename]\n", getprogname());
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
55 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
56
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
57 void
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
58 pwm_err(struct pwm_ctx *ctx, char *fmt, ...)
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
59 {
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
60 va_list args;
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
61
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
62 free(ctx->errmsg);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
63
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
64 if (fmt != NULL) {
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
65 va_start(args, fmt);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
66 xvasprintf(&ctx->errmsg, fmt, args);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
67 va_end(args);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
68
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
69 fprintf(stderr, "%s\n", ctx->errmsg);
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
70 } else {
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
71 ctx->errmsg = NULL;
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
72 }
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
73 }
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
74
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
75 void
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
76 pwm_block_signals(void)
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
77 {
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
78 sigset_t set;
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
79
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
80 sigemptyset(&set);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
81 sigaddset(&set, SIGINT);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
82 sigaddset(&set, SIGTERM);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
83 sigaddset(&set, SIGHUP);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
84 sigaddset(&set, SIGQUIT);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
85 if (sigprocmask(SIG_BLOCK, &set, NULL) != 0) {
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
86 err(1, "sigprocmask");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
87 }
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
88 }
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
89
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
90 void
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
91 pwm_unblock_signals(void)
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
92 {
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
93 sigset_t set;
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
94
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
95 sigemptyset(&set);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
96 sigaddset(&set, SIGINT);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
97 sigaddset(&set, SIGTERM);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
98 sigaddset(&set, SIGHUP);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
99 sigaddset(&set, SIGQUIT);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
100 if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) {
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
101 err(1, "sigprocmask");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
102 }
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
103 }
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
104
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
105 static int
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
106 run_input_loop(struct pwm_ctx *ctx)
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
107 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
108 int retval = -1;
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
109 char prompt[8 + 2 + 1];
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
110 GetLine *gl = NULL;
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
111 char buf[PWM_LINE_MAX + 1];
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
112 int io_retval;
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
113 size_t tokenc = 0;
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
114 union tok **tokenv = NULL;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
115 int argc = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
116 char **argv = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
117 struct cmd *cmd;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
118 int i;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
119
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
120 snprintf(prompt, sizeof (prompt), "%.*s> ", 8, getprogname());
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
121
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
122 pwm_block_signals();
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
123
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
124 /* initialize libtecla */
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
125 gl = new_GetLine(PWM_LINE_MAX, PWM_HISTORY_MAX);
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
126 if (gl == NULL) {
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
127 err(1, "new_GetLine");
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
128 }
39
131c35592054 Allow keybinding customizations in ~/.teclarc
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 35
diff changeset
129 gl_configure_getline(gl, NULL, NULL, "~/.teclarc");
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
130 gl_catch_blocked(gl);
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
131 gl_limit_history(gl, PWM_HISTORY_LINES_MAX);
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
132 /* disable default filename completion */
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
133 gl_customize_completion(gl, NULL, io_gl_complete_nothing);
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
134
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
135 for (;;) {
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
136 /* read next line */
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
137 cmd = NULL;
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
138 buf[0] = '\0';
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
139 io_retval = io_get_line(gl, prompt, 1, NULL, 0,
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
140 sizeof (buf), buf);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
141 switch (io_retval) {
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
142 case IO_OK:
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
143 break;
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
144 case IO_TRUNCATED:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
145 /* line was truncated in non-interactive mode */
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
146 fprintf(stderr, "line too long\n");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
147 goto out;
21
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
148 case IO_EOF:
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
149 if (ctx->is_interactive) {
21
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
150 /* treat as "q" command */
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
151 strcpy(buf, "q\n");
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
152 io_retval = IO_OK;
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
153 break;
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
154 }
ee4d36c85287 Make EOF in interactive mode equivalent to the q command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
155 /* FALLTHORUGH */
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
156 case IO_SIGNAL:
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
157 if (ctx->unsaved_changes) {
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
158 pwfile_write_autosave_file(ctx);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
159 }
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
160 goto quit;
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
161 default:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
162 fprintf(stderr, "unknown error\n");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
163 goto quit;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
164 }
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 /* tokenize line */
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
167 switch (tok_tokenize(buf, &tokenc, &tokenv)) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
168 case TOK_ERR_UNTERMINATED_QUOTE:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
169 fprintf(stderr, "unterminated quote\n");
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
170 if (!ctx->is_interactive) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
171 goto out;
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 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
174 case TOK_ERR_TRAILING_BACKSLASH:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
175 fprintf(stderr, "trailing backslash\n");
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
176 if (!ctx->is_interactive) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
177 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
178 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
179 goto next;
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
180 case TOK_ERR_INVALID_MACRO_NAME:
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
181 fprintf(stderr, "invalid macro name\n");
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
182 if (!ctx->is_interactive) {
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
183 goto out;
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
184 }
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
185 goto next;
30
2552eec9b913 Explicitly handle all cases in switch statements
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 29
diff changeset
186 case TOK_ERR_OK:
2552eec9b913 Explicitly handle all cases in switch statements
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 29
diff changeset
187 break;
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
188 }
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
189
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
190 /* expand macros */
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
191 if (macro_expand_macros(ctx->macro_head, tokenc, tokenv, &argc,
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
192 &argv) != 0) {
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
193 fprintf(stderr, "undefined macro\n");
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
194 if (!ctx->is_interactive) {
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
195 goto out;
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
196 }
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
197 goto next;
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
200 if (argc == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
201 /* empty line */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
202 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
203 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
204
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
205 /* find and execute the command */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
206 cmd = cmd_match(argv[0]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
207 if (cmd == NULL) {
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
208 pwm_err(ctx, "unknown command: %s", argv[0]);
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
209 if (ctx->is_interactive) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
210 goto next;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
211 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
212 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
213 }
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 switch (cmd->cmd_func(ctx, argc, argv)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
216 case CMD_OK:
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
217 pwm_err(ctx, NULL); /* clear error */
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
218 break;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
219 case CMD_USAGE:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
220 fprintf(stderr, "usage: %s\n", cmd->usage);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
221 case CMD_ERR: /* FALLTHROUGH */
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
222 if (!ctx->is_interactive) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
223 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
224 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
225 break;
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
226 case CMD_SIGNAL:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
227 fprintf(stderr, "received signal, quitting\n");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
228 case CMD_QUIT: /* FALLTHROUGH */
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
229 goto quit;
30
2552eec9b913 Explicitly handle all cases in switch statements
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 29
diff changeset
230 default:
2552eec9b913 Explicitly handle all cases in switch statements
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 29
diff changeset
231 break;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
232 }
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
233 ctx->prev_cmd = cmd->full_cmd;
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 next:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
236 for (i = 0; i < argc; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
237 free(argv[i]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
238 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
239 free(argv);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
240 argc = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
241 argv = NULL;
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
242 tok_free(tokenv);
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
243 tokenc = 0;
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
244 tokenv = NULL;
0
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
247 quit:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
248 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
249
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
250 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
251 for (i = 0; i < argc; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
252 free(argv[i]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
253 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
254 free(argv);
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
255 tok_free(tokenv);
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
256 del_GetLine(gl);
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
257
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
258 return (retval);
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
259 }
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
260
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
261 int
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
262 pwm_read_password(struct pwm_ctx *ctx, int is_new_password)
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
263 {
19
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
264 switch (io_get_password(is_new_password ? "New Password:" :
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
265 "Password:", is_new_password ? "Confirm Password:" : NULL,
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
266 sizeof (ctx->password), ctx->password)) {
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
267 case IO_OK:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
268 return (0);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
269 case IO_SIGNAL:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
270 return (-2);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
271 case IO_PASSWORD_EMPTY:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
272 pwm_err(ctx, "password must not be empty");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
273 return (-1);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
274 case IO_PASSWORD_MISMATCH:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
275 pwm_err(ctx, "passwords do not match");
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
276 return (-1);
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
277 default:
5c6155c8e9b6 Handle signals
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 18
diff changeset
278 return (-1);
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
279 }
0
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
282 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
283 read_password_from_file(const char *filename, char *password,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
284 size_t password_size)
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 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
287 char *buf = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
288 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
289 size_t password_len = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
290
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
291 buf = xmalloc(password_size);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
292
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
293 fp = fopen(filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
294 if (fp == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
295 warn("failed to open master password file \"%s\"", filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
296 goto out;
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 (fgets(buf, password_size, fp) == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
299 /* read error or empty file */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
300 if (ferror(fp)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
301 /* read error */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
302 warn("failed to read master password from \"%s\"",
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
303 filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
304 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
305 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
306 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
307 password_len = strlen(buf);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
308 if (buf[password_len - 1] == '\n') {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
309 /* strip trailing newline */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
310 password_len--;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
311 if (password_len == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
312 /* first line is empty */
5
0b1bce8db371 Prevent misleading double error message
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 0
diff changeset
313 fprintf(stderr, "malformed password file\n");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
314 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
315 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
316 } else if (!feof(fp)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
317 /* 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
318 fprintf(stderr, "malformed password file\n");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
319 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
320 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
321 memcpy(password, buf, password_size);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
322 retval = 0;
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 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
325 password[password_len] = '\0';
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
326
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
327 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
328 fclose(fp);
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 free(buf);
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 return (retval);
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
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
335 int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
336 main(int argc, char *argv[])
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
337 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
338 int status = EXIT_FAILURE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
339 char *locale;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
340 int errflag = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
341 int c;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
342 const char *master_password_filename = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
343 struct pwm_ctx ctx = { 0 };
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
344 struct passwd *passwd;
35
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
345 char *home;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
346 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
347
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
348 setprogname(argv[0]);
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 /* set up locale and check for UTF-8 codeset */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
351 locale = setlocale(LC_ALL, "");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
352 if (locale == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
353 errx(1, "invalid locale");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
354 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
355 if ((strcasecmp(nl_langinfo(CODESET), "UTF-8") != 0) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
356 (strcasecmp(nl_langinfo(CODESET), "UTF8") != 0)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
357 fprintf(stderr, "pwm requires a locale with UTF-8 character "
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
358 "encoding.\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
359 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
360 }
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 /* timestamps are processed as UTC */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
363 if (setenv("TZ", "", 1) != 0) {
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 tzset();
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 /* initialize libpws */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
369 if (pws_init() != 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
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
373 ctx.is_interactive = isatty(STDIN_FILENO);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
374
29
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
375 macro_init(&ctx.macro_head);
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
376
23
1b89066d992c Add read-only mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 22
diff changeset
377 while (!errflag && (c = getopt(argc, argv, "P:Rh")) != -1) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
378 switch (c) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
379 case 'P':
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
380 master_password_filename = optarg;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
381 break;
23
1b89066d992c Add read-only mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 22
diff changeset
382 case 'R':
1b89066d992c Add read-only mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 22
diff changeset
383 ctx.is_readonly = 1;
1b89066d992c Add read-only mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 22
diff changeset
384 break;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
385 case 'h':
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
386 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
387 status = EXIT_SUCCESS;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
388 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
389 default:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
390 errflag = 1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
391 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
392 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
393 if (errflag || (optind + 1 < argc)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
394 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
395 status = EXIT_USAGE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
396 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
397 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
398
35
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
399 home = getenv("HOME");
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
400 if (home == NULL) {
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
401 passwd = getpwuid(getuid());
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
402 if (passwd == NULL) {
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
403 err(1, "getpwuid");
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
404 }
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
405 home = passwd->pw_dir;
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
406 }
35
2a8298bafec2 Try to use $HOME for the user's home directory
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 30
diff changeset
407 xasprintf(&ctx.dirname, "%s/.pwm", home);
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
408
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
409 /* create ~/.pwm directory if necessary */
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
410 if ((mkdir(ctx.dirname, S_IRWXU) != 0) && (errno != EEXIST)) {
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
411 warn("failed to create directory \"%s\"", ctx.dirname);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
412 goto out;
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
413 }
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
414
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
415 if (optind == argc) {
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
416 xasprintf(&ctx.filename, "%s/pwm.psafe3", ctx.dirname);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
417 } else if (optind + 1 == argc) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
418 ctx.filename = xstrdup(argv[optind++]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
419 } else {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
420 usage();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
421 status = EXIT_USAGE;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
422 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
423 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
424
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
425 if (ctx.is_interactive) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
426 printf("pwm version %s\n", VERSION);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
427 } else if (master_password_filename == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
428 fprintf(stderr, "master password file must be specified when "
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
429 "running non-interactively\n");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
430 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
431 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
432
29
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
433 /* read ~/.pwm/pwmrc */
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
434 if (pwmrc_read(&ctx) != 0) {
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
435 goto out;
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
436 }
00d782cb45fa Read configuration file on startup
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 28
diff changeset
437
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
438 pwfile_init(&ctx);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
439 fp = fopen(ctx.filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
440 if ((fp == NULL) && (errno != ENOENT)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
441 warn("failed to open password database");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
442 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
443 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
444 /* obtain master password */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
445 if (master_password_filename != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
446 if (read_password_from_file(master_password_filename,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
447 ctx.password, sizeof (ctx.password)) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
448 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
449 }
18
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
450 } else if (pwm_read_password(&ctx, (fp == NULL)) != 0) {
1e39a251cbe9 Use libtecla for interactive input
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 16
diff changeset
451 goto out;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
452 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
453 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
454 if (pwfile_read_file(&ctx, fp) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
455 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
456 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
457 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
458 fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
459 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
460
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
461 /* run main input loop */
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 21
diff changeset
462 status = (run_input_loop(&ctx) != 0);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
463
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
464 out:
27
722a45b4028b Add define command for defining macros
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 23
diff changeset
465 macro_destroy(ctx.macro_head);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
466 pwfile_destroy(&ctx);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
467 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
468 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
469 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
470 free(ctx.filename);
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 19
diff changeset
471 free(ctx.dirname);
16
a07665727c19 Add status command
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
472 free(ctx.errmsg);
28
e3db02d7f1f4 Add set command for setting or retrieving option values
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 27
diff changeset
473 free(ctx.pipecmd);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
474
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
475 exit(status);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
476 }