comparison pwm.c @ 22:ec01c579024a

Add fully interactive mode
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Thu, 07 Sep 2017 12:40:50 +0200
parents ee4d36c85287
children 1b89066d992c
comparison
equal deleted inserted replaced
21:ee4d36c85287 22:ec01c579024a
99 err(1, "sigprocmask"); 99 err(1, "sigprocmask");
100 } 100 }
101 } 101 }
102 102
103 static int 103 static int
104 run_input_loop(struct pwm_ctx *ctx, int is_interactive) 104 run_input_loop(struct pwm_ctx *ctx)
105 { 105 {
106 int retval = -1; 106 int retval = -1;
107 char prompt[8 + 2 + 1]; 107 char prompt[8 + 2 + 1];
108 GetLine *gl = NULL; 108 GetLine *gl = NULL;
109 char buf[PWM_LINE_MAX + 1]; 109 char buf[PWM_LINE_MAX + 1];
139 case IO_TRUNCATED: 139 case IO_TRUNCATED:
140 /* line was truncated in non-interactive mode */ 140 /* line was truncated in non-interactive mode */
141 fprintf(stderr, "line too long\n"); 141 fprintf(stderr, "line too long\n");
142 goto out; 142 goto out;
143 case IO_EOF: 143 case IO_EOF:
144 if (is_interactive) { 144 if (ctx->is_interactive) {
145 /* treat as "q" command */ 145 /* treat as "q" command */
146 strcpy(buf, "q\n"); 146 strcpy(buf, "q\n");
147 io_retval = IO_OK; 147 io_retval = IO_OK;
148 break; 148 break;
149 } 149 }
162 switch (tok_tokenize(buf, &argc, &argv)) { 162 switch (tok_tokenize(buf, &argc, &argv)) {
163 case TOK_ERR_SYSTEM_ERROR: 163 case TOK_ERR_SYSTEM_ERROR:
164 err(1, "tok_tokenize"); 164 err(1, "tok_tokenize");
165 case TOK_ERR_UNTERMINATED_QUOTE: 165 case TOK_ERR_UNTERMINATED_QUOTE:
166 fprintf(stderr, "unterminated quote\n"); 166 fprintf(stderr, "unterminated quote\n");
167 if (!is_interactive) { 167 if (!ctx->is_interactive) {
168 goto out; 168 goto out;
169 } 169 }
170 goto next; 170 goto next;
171 case TOK_ERR_TRAILING_BACKSLASH: 171 case TOK_ERR_TRAILING_BACKSLASH:
172 fprintf(stderr, "trailing backslash\n"); 172 fprintf(stderr, "trailing backslash\n");
173 if (!is_interactive) { 173 if (!ctx->is_interactive) {
174 goto out; 174 goto out;
175 } 175 }
176 goto next; 176 goto next;
177 } 177 }
178 178
183 183
184 /* find and execute the command */ 184 /* find and execute the command */
185 cmd = cmd_match(argv[0]); 185 cmd = cmd_match(argv[0]);
186 if (cmd == NULL) { 186 if (cmd == NULL) {
187 pwm_err(ctx, "unknown command: %s", argv[0]); 187 pwm_err(ctx, "unknown command: %s", argv[0]);
188 if (is_interactive) { 188 if (ctx->is_interactive) {
189 goto next; 189 goto next;
190 } else { 190 } else {
191 goto out; 191 goto out;
192 } 192 }
193 } 193 }
196 pwm_err(ctx, NULL); /* clear error */ 196 pwm_err(ctx, NULL); /* clear error */
197 break; 197 break;
198 case CMD_USAGE: 198 case CMD_USAGE:
199 fprintf(stderr, "usage: %s\n", cmd->usage); 199 fprintf(stderr, "usage: %s\n", cmd->usage);
200 case CMD_ERR: /* FALLTHROUGH */ 200 case CMD_ERR: /* FALLTHROUGH */
201 if (!is_interactive) { 201 if (!ctx->is_interactive) {
202 goto out; 202 goto out;
203 } 203 }
204 break; 204 break;
205 case CMD_SIGNAL: 205 case CMD_SIGNAL:
206 fprintf(stderr, "received signal, quitting\n"); 206 fprintf(stderr, "received signal, quitting\n");
308 int 308 int
309 main(int argc, char *argv[]) 309 main(int argc, char *argv[])
310 { 310 {
311 int status = EXIT_FAILURE; 311 int status = EXIT_FAILURE;
312 char *locale; 312 char *locale;
313 int is_interactive;
314 int errflag = 0; 313 int errflag = 0;
315 int c; 314 int c;
316 const char *master_password_filename = NULL; 315 const char *master_password_filename = NULL;
317 struct pwm_ctx ctx = { 0 }; 316 struct pwm_ctx ctx = { 0 };
318 struct passwd *passwd; 317 struct passwd *passwd;
341 /* initialize libpws */ 340 /* initialize libpws */
342 if (pws_init() != 0) { 341 if (pws_init() != 0) {
343 goto out; 342 goto out;
344 } 343 }
345 344
346 is_interactive = isatty(STDIN_FILENO); 345 ctx.is_interactive = isatty(STDIN_FILENO);
347 346
348 while (!errflag && (c = getopt(argc, argv, "P:h")) != -1) { 347 while (!errflag && (c = getopt(argc, argv, "P:h")) != -1) {
349 switch (c) { 348 switch (c) {
350 case 'P': 349 case 'P':
351 master_password_filename = optarg; 350 master_password_filename = optarg;
384 usage(); 383 usage();
385 status = EXIT_USAGE; 384 status = EXIT_USAGE;
386 goto out; 385 goto out;
387 } 386 }
388 387
389 if (is_interactive) { 388 if (ctx.is_interactive) {
390 printf("pwm version %s\n", VERSION); 389 printf("pwm version %s\n", VERSION);
391 } else if (master_password_filename == NULL) { 390 } else if (master_password_filename == NULL) {
392 fprintf(stderr, "master password file must be specified when " 391 fprintf(stderr, "master password file must be specified when "
393 "running non-interactively\n"); 392 "running non-interactively\n");
394 goto out; 393 goto out;
417 fclose(fp); 416 fclose(fp);
418 fp = NULL; 417 fp = NULL;
419 } 418 }
420 419
421 /* run main input loop */ 420 /* run main input loop */
422 status = (run_input_loop(&ctx, is_interactive) != 0); 421 status = (run_input_loop(&ctx) != 0);
423 422
424 out: 423 out:
425 pwfile_destroy(&ctx); 424 pwfile_destroy(&ctx);
426 if (fp != NULL) { 425 if (fp != NULL) {
427 fclose(fp); 426 fclose(fp);