Removed the pwmd_error_t data type. Functions that returned this type
[libpwmd.git] / pwmc.c
blob25d545cb4efedf31eccbf25c99522af6505a052e
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2007 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <err.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <libpwmd.h>
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
31 #include "mem.h"
33 static void usage(const char *pn)
35 fprintf(stderr,
36 "Reads PWMD protocol commands from standard input.\n\n"
37 "Usage: %s [-hv] [-E] [-s <socket>] [[-a [-P pinentry]] | [-p <password>]] [-S] [filename]\n"
38 " -E exit after a command failure\n"
39 " -s socket path\n"
40 " -p password\n"
41 " -a use pinentry(1) for password retrieval\n"
42 " -P path to the pinentry binary (/usr/bin/pinentry)\n"
43 " -S send the SAVE command after all others\n"
44 " -v version\n"
45 " -h this help text\n",
46 pn);
47 exit(EXIT_FAILURE);
50 static void show_error(gpg_error_t error)
52 fprintf(stderr, "ERR %i %s\n", gpg_err_code(error), pwmd_strerror(error));
55 int main(int argc, char *argv[])
57 int opt;
58 int use_pinentry = 0;
59 char *password = NULL;
60 char *filename = NULL;
61 char *socketpath = NULL;
62 char command[8196], *p;
63 int ret = EXIT_SUCCESS;
64 gpg_error_t error;
65 pwm_t *pwm;
66 char *result = NULL;
67 int save = 0;
68 char *buf = NULL;
69 int total = 0;
70 int do_exit = 0;
71 char *pinentry_path = NULL;
73 while ((opt = getopt(argc, argv, "EhvaP:p:s:S")) != EOF) {
74 switch (opt) {
75 case 'E':
76 do_exit = 1;
77 break;
78 case 'S':
79 save = 1;
80 break;
81 case 's':
82 socketpath = xstrdup(optarg);
83 break;
84 case 'p':
85 password = xstrdup(optarg);
86 break;
87 case 'a':
88 use_pinentry = 1;
89 break;
90 case 'P':
91 pinentry_path = xstrdup(optarg);
92 break;
93 case 'v':
94 printf("%s (pwmc)\n%s\n", PACKAGE_STRING, PACKAGE_BUGREPORT);
95 exit(EXIT_SUCCESS);
96 case 'h':
97 default:
98 usage(argv[0]);
102 if (use_pinentry && password) {
103 xfree(password);
104 usage(argv[0]);
107 if (argc - optind == 1)
108 filename = argv[optind];
110 pwmd_init();
112 if ((pwm = pwmd_connect(socketpath, &error)) == NULL) {
113 xfree(password);
114 errx(EXIT_FAILURE, "pwmd_connect(): %s", pwmd_strerror(error));
117 if (use_pinentry) {
118 error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY, 1);
120 if (error) {
121 xfree(password);
122 show_error(error);
123 pwmd_close(pwm);
124 exit(EXIT_FAILURE);
127 if (pinentry_path) {
128 error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_PATH, pinentry_path);
130 if (error) {
131 xfree(password);
132 show_error(error);
133 pwmd_close(pwm);
134 exit(EXIT_FAILURE);
138 error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_TITLE, "Password Manager Daemon");
140 if (error) {
141 xfree(password);
142 show_error(error);
143 pwmd_close(pwm);
144 exit(EXIT_FAILURE);
147 snprintf(command, sizeof(command), "A password is required for the "
148 "file \"%s\". Please\nenter the password below.", filename);
150 error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_DESC, command);
152 if (error) {
153 xfree(password);
154 show_error(error);
155 pwmd_close(pwm);
156 exit(EXIT_FAILURE);
159 else if (password) {
160 error = pwmd_setopt(pwm, PWMD_OPTION_PASSWORD, password);
162 if (error) {
163 xfree(password);
164 show_error(error);
165 pwmd_close(pwm);
166 exit(EXIT_FAILURE);
169 xfree(password);
172 if (filename) {
173 error = pwmd_open(pwm, filename);
175 if (error) {
176 show_error(error);
177 pwmd_close(pwm);
178 exit(EXIT_FAILURE);
182 while ((p = fgets(command, sizeof(command), stdin)) != NULL) {
183 int len = strlen(p);
184 char *t;
186 if (p[len - 1] != '\n' && feof(stdin) != 1) {
187 if ((t = (char *)xrealloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
188 if (buf)
189 xfree(buf);
191 memset(&command, 0, sizeof(command));
192 err(EXIT_FAILURE, "xrealloc()");
195 buf = t;
196 memcpy(&buf[total], p, len);
197 total += len;
198 buf[total] = 0;
199 continue;
201 else {
202 if (buf) {
203 if ((t = (char *)xrealloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
204 if (buf)
205 xfree(buf);
207 memset(&command, 0, sizeof(command));
208 err(EXIT_FAILURE, "xrealloc()");
211 buf = t;
212 memcpy(&buf[total], p, len);
213 total += len;
214 buf[total] = 0;
218 p = buf ? buf : command;
220 if (p[strlen(p) - 1] == '\n')
221 p[strlen(p) - 1] = 0;
223 if (strcasecmp(p, "BYE") == 0)
224 break;
226 error = pwmd_command(pwm, &result, p);
228 if (error) {
229 if (buf) {
230 xfree(buf);
231 buf = NULL;
232 total = 0;
235 memset(&command, 0, sizeof(command));
236 show_error(error);
238 if (do_exit) {
239 pwmd_close(pwm);
240 exit(EXIT_FAILURE);
243 ret = EXIT_FAILURE;
245 else {
246 if (buf) {
247 xfree(buf);
248 buf = NULL;
249 total = 0;
253 memset(&command, 0, sizeof(command));
255 if (result) {
256 if (result[strlen(result) - 1] == '\n')
257 result[strlen(result) - 1] = 0;
259 fwrite(result, 1, strlen(result), stdout);
260 pwmd_free_result(result);
261 fputc('\n', stdout);
265 if (buf)
266 xfree(buf);
268 memset(&command, 0, sizeof(command));
270 if (save) {
271 save_again:
272 error = pwmd_save(pwm);
274 if (error) {
275 if (error == EPWMD_BADKEY || error == EPWMD_KEY)
276 goto save_again;
278 show_error(error);
279 pwmd_close(pwm);
280 exit(EXIT_FAILURE);
284 pwmd_close(pwm);
286 if (socketpath)
287 xfree(socketpath);
289 exit(ret);