Mercurial > projects > pwm
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); |