Update.
[pwmd.git] / libpwmd / pwmc.c
blob85c30602402ee0a670159e3d555e2be0d983540d
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 static void usage(const char *pn)
33 fprintf(stderr,
34 "Usage: %s [-hv] [-E] [-s <socket>] [[-a] | [-p <password>]] [-S] <filename>\n"
35 " -E exit after a command failure\n"
36 " -s socket path\n"
37 " -p password\n"
38 " -a use gpg-agent\n"
39 " -S send the SAVE command after all others\n"
40 " -v version\n"
41 " -h this help text\n",
42 pn);
43 exit(EXIT_FAILURE);
46 static void pwmd_show_error(int ret, int error)
48 if (ret == PWMD_PERROR)
49 fprintf(stderr, "ERR %03i %s\n", error, pwmd_strerror(error));
50 else if (ret == PWMD_ERROR)
51 fprintf(stderr, "ERR 000 %s\n", strerror(error));
52 else
53 fprintf(stderr, "ERR 000 Is gpg-agent running? Is GPG_AGENT_INFO set?\n");
56 int main(int argc, char *argv[])
58 int opt;
59 int use_agent = 0;
60 char *password = NULL;
61 char *filename = NULL;
62 char *socketpath = NULL;
63 char command[8196], *p;
64 int ret, 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;
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 = strdup(optarg);
82 break;
83 case 'p':
84 password = strdup(optarg);
85 break;
86 case 'a':
87 use_agent = 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_agent && password)
99 usage(argv[0]);
101 if (argc - optind != 1)
102 usage(argv[0]);
104 filename = argv[optind];
106 if ((pwm = pwmd_connect(socketpath, &error)) == NULL) {
107 errno = error;
109 if (password) {
110 memset(password, 0, strlen(password));
111 free(password);
114 err(EXIT_FAILURE, "pwmd_connect()");
117 if (use_agent) {
118 if ((ret = pwmd_command(pwm, &result, &error, PWMD_SETOPT, PWMD_OPTION_USEAGENT, 1))
119 != PWMD_OK) {
120 pwmd_show_error(ret, error);
121 pwmd_close(pwm);
122 exit(EXIT_FAILURE);
125 if ((ret = pwmd_command(pwm, &result, &error, PWMD_SETOPT, PWMD_OPTION_TITLE,
126 "Password Manager Daemon")) != PWMD_OK) {
127 pwmd_show_error(ret, error);
128 pwmd_close(pwm);
129 exit(EXIT_FAILURE);
132 snprintf(command, sizeof(command), "A password is required for the "
133 "file \"%s\". Please\nenter the password below.", filename);
135 if ((ret = pwmd_command(pwm, &result, &error, PWMD_SETOPT, PWMD_OPTION_DESC,
136 command)) != PWMD_OK) {
137 pwmd_show_error(ret, error);
138 pwmd_close(pwm);
139 exit(EXIT_FAILURE);
142 else if (password) {
143 if ((ret = pwmd_command(pwm, &result, &error, PWMD_SETOPT,
144 PWMD_OPTION_PASSWORD, password)) != PWMD_OK) {
145 memset(password, 0, strlen(password));
146 free(password);
147 pwmd_show_error(ret, error);
148 pwmd_close(pwm);
149 exit(EXIT_FAILURE);
152 memset(password, 0, strlen(password));
153 free(password);
156 if ((ret = pwmd_command(pwm, &result, &error, PWMD_OPEN, filename)) != PWMD_OK) {
157 pwmd_show_error(ret, error);
158 pwmd_close(pwm);
159 exit(EXIT_FAILURE);
162 while ((p = fgets(command, sizeof(command), stdin)) != NULL) {
163 int len = strlen(p);
164 char *t;
166 if (p[len - 1] != '\n') {
167 if ((t = (char *)realloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
168 if (buf) {
169 memset(buf, 0, total);
170 free(buf);
173 err(EXIT_FAILURE, "realloc()");
176 buf = t;
177 memcpy(&buf[total], p, len);
178 total += len;
179 buf[total] = 0;
180 continue;
182 else {
183 if (buf) {
184 if ((t = (char *)realloc(buf, (total + len + 1) * sizeof(char))) == NULL) {
185 if (buf) {
186 memset(buf, 0, total);
187 free(buf);
190 err(EXIT_FAILURE, "realloc()");
193 buf = t;
194 memcpy(&buf[total], p, len);
195 total += len;
196 buf[total] = 0;
200 if ((ret = pwmd_command(pwm, &result, &error, PWMD_COMMAND,
201 (buf) ? buf : command)) != PWMD_OK) {
202 if (buf) {
203 memset(buf, 0, total);
204 free(buf);
207 memset(&command, 0, sizeof(command));
208 pwmd_show_error(ret, error);
210 if (do_exit) {
211 pwmd_close(pwm);
212 exit(EXIT_FAILURE);
216 if (buf) {
217 memset(buf, 0, total);
218 free(buf);
219 buf = NULL;
220 total = 0;
223 if (result) {
224 printf("%s\n", (char *)result);
225 free(result);
229 if (save) {
230 if ((ret = pwmd_command(pwm, &result, &error, PWMD_SAVE)) != PWMD_OK) {
231 memset(&command, 0, sizeof(command));
232 pwmd_show_error(ret, error);
233 pwmd_close(pwm);
234 exit(EXIT_FAILURE);
238 pwmd_close(pwm);
240 if (socketpath)
241 free(socketpath);
243 exit(EXIT_SUCCESS);