Made the custom memory allocator symbols hidden. This prevents
[libpwmd.git] / pwmc.c
blobd209288a1713c9622296ae3100c3ec779acbe7e0
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;
71 while ((opt = getopt(argc, argv, "Ehvap:s:S")) != EOF) {
72 switch (opt) {
73 case 'E':
74 do_exit = 1;
75 break;
76 case 'S':
77 save = 1;
78 break;
79 case 's':
80 socketpath = xstrdup(optarg);
81 break;
82 case 'p':
83 password = xstrdup(optarg);
84 break;
85 case 'a':
86 use_pinentry = 1;
87 break;
88 case 'v':
89 printf("%s (pwmc)\n%s\n", PACKAGE_STRING, PACKAGE_BUGREPORT);
90 exit(EXIT_SUCCESS);
91 case 'h':
92 default:
93 usage(argv[0]);
97 if (use_pinentry && password)
98 usage(argv[0]);
100 if (argc - optind != 1)
101 usage(argv[0]);
103 filename = argv[optind];
104 pwmd_init();
106 if ((pwm = pwmd_connect(socketpath, &error)) == NULL) {
107 if (password)
108 xfree(password);
110 errx(EXIT_FAILURE, "pwmd_connect(): %s", pwmd_strerror(error));
113 if (use_pinentry) {
114 if (pwmd_setopt(pwm, &error, PWMD_OPTION_PINENTRY, 1) != PWMD_OK) {
115 show_error(error);
116 pwmd_close(pwm);
117 exit(EXIT_FAILURE);
120 if (pwmd_setopt(pwm, &error, PWMD_OPTION_PINENTRY_TITLE, "Password Manager Daemon") != PWMD_OK) {
121 show_error(error);
122 pwmd_close(pwm);
123 exit(EXIT_FAILURE);
126 snprintf(command, sizeof(command), "A password is required for the "
127 "file \"%s\". Please\nenter the password below.", filename);
129 if (pwmd_setopt(pwm, &error, PWMD_OPTION_PINENTRY_DESC, command) != PWMD_OK) {
130 show_error(error);
131 pwmd_close(pwm);
132 exit(EXIT_FAILURE);
135 else if (password) {
136 if (pwmd_setopt(pwm, &error, PWMD_OPTION_PASSWORD, password) != PWMD_OK) {
137 xfree(password);
138 show_error(error);
139 pwmd_close(pwm);
140 exit(EXIT_FAILURE);
143 xfree(password);
146 if (pwmd_open(pwm, &error, filename) != PWMD_OK) {
147 show_error(error);
148 pwmd_close(pwm);
149 exit(EXIT_FAILURE);
152 while ((p = fgets(command, sizeof(command), stdin)) != NULL) {
153 int len = strlen(p);
154 char *t;
156 if (p[len - 1] != '\n' && feof(stdin) != 1) {
157 if ((t = (char *)xrealloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
158 if (buf)
159 xfree(buf);
161 memset(&command, 0, sizeof(command));
162 err(EXIT_FAILURE, "xrealloc()");
165 buf = t;
166 memcpy(&buf[total], p, len);
167 total += len;
168 buf[total] = 0;
169 continue;
171 else {
172 if (buf) {
173 if ((t = (char *)xrealloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
174 if (buf)
175 xfree(buf);
177 memset(&command, 0, sizeof(command));
178 err(EXIT_FAILURE, "xrealloc()");
181 buf = t;
182 memcpy(&buf[total], p, len);
183 total += len;
184 buf[total] = 0;
188 p = buf ? buf : command;
190 if (p[strlen(p) - 1] == '\n')
191 p[strlen(p) - 1] = 0;
193 if (strcasecmp(p, "BYE") == 0)
194 break;
196 if (pwmd_command(pwm, &result, &error, p) != PWMD_OK) {
197 if (buf) {
198 xfree(buf);
199 buf = NULL;
200 total = 0;
203 memset(&command, 0, sizeof(command));
204 show_error(error);
206 if (do_exit) {
207 pwmd_close(pwm);
208 exit(EXIT_FAILURE);
211 ret = EXIT_FAILURE;
213 else {
214 if (buf) {
215 xfree(buf);
216 buf = NULL;
217 total = 0;
221 memset(&command, 0, sizeof(command));
223 if (result) {
224 if (result[strlen(result) - 1] == '\n')
225 result[strlen(result) - 1] = 0;
227 fwrite(result, 1, strlen(result), stdout);
228 pwmd_free_result(result);
229 fputc('\n', stdout);
233 memset(&command, 0, sizeof(command));
235 if (save) {
236 save_again:
237 if (pwmd_save(pwm, &error) != PWMD_OK) {
238 if (error == EPWMD_BADKEY || error == EPWMD_KEY)
239 goto save_again;
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);