Version 3.0.0.
[libpwmd.git] / pwmc.c
blob6ca23e18bf76a6669aa67b33d0e14219053e0f8f
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 "Usage: %s [-hv] [-E] [-s <socket>] [[-a] | [-p <password>]] [-S] <filename>\n"
37 " -E exit after a command failure\n"
38 " -s socket path\n"
39 " -p password\n"
40 " -a use pinentry(1) for password retrieval\n"
41 " -S send the SAVE command after all others\n"
42 " -v version\n"
43 " -h this help text\n\n"
44 "Reads protocol commands from standard input.\n",
45 pn);
46 exit(EXIT_FAILURE);
49 static void show_error(gpg_error_t error)
51 fprintf(stderr, "ERR %i %s\n", gpg_err_code(error), pwmd_strerror(error));
54 int main(int argc, char *argv[])
56 int opt;
57 int use_pinentry = 0;
58 char *password = NULL;
59 char *filename = NULL;
60 char *socketpath = NULL;
61 char command[8196], *p;
62 int ret = EXIT_SUCCESS;
63 gpg_error_t error;
64 pwm_t *pwm;
65 char *result = NULL;
66 int save = 0;
67 char *buf = NULL;
68 int total = 0;
69 int do_exit = 0;
70 int quit = 0;
72 while ((opt = getopt(argc, argv, "Ehvap:s:S")) != EOF) {
73 switch (opt) {
74 case 'E':
75 do_exit = 1;
76 break;
77 case 'S':
78 save = 1;
79 break;
80 case 's':
81 socketpath = xstrdup(optarg);
82 break;
83 case 'p':
84 password = xstrdup(optarg);
85 break;
86 case 'a':
87 use_pinentry = 1;
88 break;
89 case 'v':
90 printf("%s (pwmc)\n%s\n", PACKAGE_STRING, PACKAGE_BUGREPORT);
91 exit(EXIT_SUCCESS);
92 case 'h':
93 default:
94 usage(argv[0]);
98 if (use_pinentry && password)
99 usage(argv[0]);
101 if (argc - optind != 1)
102 usage(argv[0]);
104 filename = argv[optind];
105 pwmd_init();
107 if ((pwm = pwmd_connect(socketpath, &error)) == NULL) {
108 if (password)
109 xfree(password);
111 errx(EXIT_FAILURE, "pwmd_connect(): %s", pwmd_strerror(error));
114 if (use_pinentry) {
115 if (pwmd_setopt(pwm, &error, PWMD_OPTION_PINENTRY, 1) != PWMD_OK) {
116 show_error(error);
117 pwmd_close(pwm);
118 exit(EXIT_FAILURE);
121 if (pwmd_setopt(pwm, &error, PWMD_OPTION_TITLE, "Password Manager Daemon") != PWMD_OK) {
122 show_error(error);
123 pwmd_close(pwm);
124 exit(EXIT_FAILURE);
127 snprintf(command, sizeof(command), "A password is required for the "
128 "file \"%s\". Please\nenter the password below.", filename);
130 if (pwmd_setopt(pwm, &error, PWMD_OPTION_DESC, command) != PWMD_OK) {
131 show_error(error);
132 pwmd_close(pwm);
133 exit(EXIT_FAILURE);
136 else if (password) {
137 if (pwmd_setopt(pwm, &error, PWMD_OPTION_PASSWORD, password) != PWMD_OK) {
138 xfree(password);
139 show_error(error);
140 pwmd_close(pwm);
141 exit(EXIT_FAILURE);
144 xfree(password);
147 if (pwmd_open(pwm, &error, filename) != PWMD_OK) {
148 show_error(error);
149 pwmd_close(pwm);
150 exit(EXIT_FAILURE);
153 while (!quit && (p = fgets(command, sizeof(command), stdin)) != NULL) {
154 int len = strlen(p);
155 char *t;
157 if (p[len - 1] != '\n') {
158 if ((t = (char *)xrealloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
159 if (buf)
160 xfree(buf);
162 memset(&command, 0, sizeof(command));
163 err(EXIT_FAILURE, "xrealloc()");
166 buf = t;
167 memcpy(&buf[total], p, len);
168 total += len;
169 buf[total] = 0;
170 continue;
172 else {
173 if (buf) {
174 if ((t = (char *)xrealloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
175 if (buf)
176 xfree(buf);
178 memset(&command, 0, sizeof(command));
179 err(EXIT_FAILURE, "xrealloc()");
182 buf = t;
183 memcpy(&buf[total], p, len);
184 total += len;
185 buf[total] = 0;
189 p = buf ? buf : command;
191 if (p[strlen(p) - 1] == '\n')
192 p[strlen(p) - 1] = 0;
194 if (strcasecmp(p, "BYE") == 0)
195 quit = 1;
197 if (pwmd_command(pwm, &result, &error, p) != PWMD_OK) {
198 if (buf) {
199 xfree(buf);
200 buf = NULL;
201 total = 0;
204 memset(&command, 0, sizeof(command));
205 show_error(error);
207 if (do_exit) {
208 pwmd_close(pwm);
209 exit(EXIT_FAILURE);
212 ret = EXIT_FAILURE;
214 else {
215 if (buf) {
216 xfree(buf);
217 buf = NULL;
218 total = 0;
222 memset(&command, 0, sizeof(command));
224 if (result) {
225 if (result[strlen(result) - 1] == '\n')
226 result[strlen(result) - 1] = 0;
228 fwrite(result, 1, strlen(result), stdout);
229 pwmd_free_result(result);
230 fputc('\n', stdout);
233 if (quit)
234 pwm->ctx = NULL;
237 memset(&command, 0, sizeof(command));
239 if (save) {
240 if (pwmd_save(pwm, &error) != PWMD_OK) {
241 show_error(error);
242 pwmd_close(pwm);
243 exit(EXIT_FAILURE);
247 pwmd_close(pwm);
249 if (socketpath)
250 xfree(socketpath);
252 exit(ret);