Mercurial > irccd
comparison irccdctl/main.c @ 975:5ffc8350e84b
irccdctl: add support for rule editing
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 09 Feb 2021 13:00:32 +0100 |
parents | 342fb90f2512 |
children | 489d80468925 |
comparison
equal
deleted
inserted
replaced
974:342fb90f2512 | 975:5ffc8350e84b |
---|---|
25 #include <ctype.h> | 25 #include <ctype.h> |
26 #include <err.h> | 26 #include <err.h> |
27 #include <errno.h> | 27 #include <errno.h> |
28 #include <limits.h> | 28 #include <limits.h> |
29 #include <stdarg.h> | 29 #include <stdarg.h> |
30 #include <stdio.h> | |
30 #include <stdlib.h> | 31 #include <stdlib.h> |
31 #include <stdnoreturn.h> | 32 #include <stdnoreturn.h> |
32 #include <string.h> | 33 #include <string.h> |
33 #include <unistd.h> | 34 #include <unistd.h> |
34 | 35 |
35 #include <stdio.h> | 36 #include <ketopt.h> |
36 | 37 |
37 #include <irccd/limits.h> | 38 #include <irccd/limits.h> |
38 #include <irccd/util.h> | 39 #include <irccd/util.h> |
39 | 40 |
40 static int verbose; | 41 static int verbose; |
486 | 487 |
487 ok(); | 488 ok(); |
488 } | 489 } |
489 | 490 |
490 static void | 491 static void |
492 cmd_rule_add(int argc, char **argv) | |
493 { | |
494 ketopt_t ko = KETOPT_INIT; | |
495 FILE *fp; | |
496 char out[IRC_BUF_LEN]; | |
497 | |
498 if (!(fp = fmemopen(out, sizeof (out) - 1, "w"))) | |
499 err(1, "fmemopen"); | |
500 | |
501 /* TODO: invalid option. */ | |
502 for (int ch; (ch = ketopt(&ko, argc, argv, 0, "c:e:i:o:p:s:", NULL)) != -1; ) | |
503 fprintf(fp, "%c=%s ", ch, ko.arg); | |
504 | |
505 argc -= ko.ind; | |
506 argv += ko.ind; | |
507 | |
508 if (argc < 1) | |
509 errx(1, "missing accept or drop rule action"); | |
510 | |
511 fprintf(fp, "%s", argv[0]); | |
512 | |
513 if (ferror(fp) || feof(fp)) | |
514 err(1, "fprintf"); | |
515 | |
516 fclose(fp); | |
517 req("RULE-ADD %s %s", argv[0], out); | |
518 ok(); | |
519 } | |
520 | |
521 static void | |
522 cmd_rule_edit(int argc, char **argv) | |
523 { | |
524 ketopt_t ko = KETOPT_INIT; | |
525 FILE *fp; | |
526 char out[IRC_BUF_LEN]; | |
527 | |
528 if (!(fp = fmemopen(out, sizeof (out) - 1, "w"))) | |
529 err(1, "fmemopen"); | |
530 | |
531 /* TODO: invalid option. */ | |
532 for (int ch; (ch = ketopt(&ko, argc, argv, 0, "a:C:c:E:e:O:o:P:p:S:s:", NULL)) != -1; ) { | |
533 if (ch == 'a') | |
534 fprintf(fp, "a=%s ", ko.arg); | |
535 else | |
536 fprintf(fp, "%c%c%s ", tolower(ch), isupper(ch) ? '-' : '+', ko.arg); | |
537 } | |
538 | |
539 argc -= ko.ind; | |
540 argv += ko.ind; | |
541 | |
542 if (argc < 1) | |
543 errx(1, "missing rule index"); | |
544 | |
545 if (ferror(fp) || feof(fp)) | |
546 err(1, "fprintf"); | |
547 | |
548 fclose(fp); | |
549 req("RULE-EDIT %s %s", argv[0], out); | |
550 ok(); | |
551 } | |
552 | |
553 /* | |
554 * Response: | |
555 * | |
556 * OK <n> | |
557 * accept | |
558 * server1 server2 server3 ... | |
559 * channel1 channel2 channel3 ... | |
560 * origin1 origin2 origin3 ... | |
561 * plugin1 plugin2 plugin3 ... | |
562 * event1 event2 plugin3 ... | |
563 * (repeat for every rule in <n>) | |
564 */ | |
565 static void | |
566 cmd_rule_list(int argc, char **argv) | |
567 { | |
568 (void)argc; | |
569 (void)argv; | |
570 | |
571 size_t num = 0; | |
572 | |
573 req("RULE-LIST"); | |
574 | |
575 if (sscanf(ok(), "%zu", &num) != 1) | |
576 errx(1, "could not retrieve rule list"); | |
577 | |
578 for (size_t i = 0; i < num; ++i) { | |
579 printf("%-16s: %zu\n", "index", i); | |
580 printf("%-16s: %s\n", "action", poll()); | |
581 printf("%-16s: %s\n", "servers", poll()); | |
582 printf("%-16s: %s\n", "channels", poll()); | |
583 printf("%-16s: %s\n", "origins", poll()); | |
584 printf("%-16s: %s\n", "plugins", poll()); | |
585 printf("%-16s: %s\n", "events", poll()); | |
586 printf("\n"); | |
587 } | |
588 } | |
589 | |
590 static void | |
591 cmd_rule_move(int argc, char **argv) | |
592 { | |
593 (void)argc; | |
594 | |
595 long long from, to; | |
596 const char *errstr; | |
597 | |
598 if ((from = strtonum(argv[0], 0, LLONG_MAX, &errstr)) == 0 && errstr) | |
599 err(1, "%s", argv[0]); | |
600 if ((to = strtonum(argv[1], 0, LLONG_MAX, &errstr)) == 0 && errstr) | |
601 err(1, "%s", argv[1]); | |
602 | |
603 req("RULE-MOVE %lld %lld", from, to); | |
604 ok(); | |
605 } | |
606 | |
607 static void | |
608 cmd_rule_remove(int argc, char **argv) | |
609 { | |
610 (void)argc; | |
611 | |
612 req("RULE-REMOVE %s", argv[0]); | |
613 ok(); | |
614 } | |
615 | |
616 static void | |
491 cmd_server_disconnect(int argc, char **argv) | 617 cmd_server_disconnect(int argc, char **argv) |
492 { | 618 { |
493 if (argc == 1) | 619 if (argc == 1) |
494 req("SERVER-DISCONNECT %s", argv[0]); | 620 req("SERVER-DISCONNECT %s", argv[0]); |
495 else | 621 else |
677 { "plugin-load", 1, 1, cmd_plugin_load }, | 803 { "plugin-load", 1, 1, cmd_plugin_load }, |
678 { "plugin-path", 0, 3, cmd_plugin_path }, | 804 { "plugin-path", 0, 3, cmd_plugin_path }, |
679 { "plugin-reload", 0, 1, cmd_plugin_reload }, | 805 { "plugin-reload", 0, 1, cmd_plugin_reload }, |
680 { "plugin-template", 1, 3, cmd_plugin_template }, | 806 { "plugin-template", 1, 3, cmd_plugin_template }, |
681 { "plugin-unload", 0, 1, cmd_plugin_unload }, | 807 { "plugin-unload", 0, 1, cmd_plugin_unload }, |
808 { "rule-add", -1, -1, cmd_rule_add }, | |
809 { "rule-edit", -1, -1, cmd_rule_edit }, | |
810 { "rule-list", 0, 0, cmd_rule_list }, | |
811 { "rule-move", 2, 2, cmd_rule_move }, | |
812 { "rule-remove", 1, 1, cmd_rule_remove }, | |
682 { "server-disconnect", 0, 1, cmd_server_disconnect }, | 813 { "server-disconnect", 0, 1, cmd_server_disconnect }, |
683 { "server-info", 1, 1, cmd_server_info }, | 814 { "server-info", 1, 1, cmd_server_info }, |
684 { "server-join", 2, 3, cmd_server_join }, | 815 { "server-join", 2, 3, cmd_server_join }, |
685 { "server-list", 0, 0, cmd_server_list }, | 816 { "server-list", 0, 0, cmd_server_list }, |
686 { "server-me", 3, 3, cmd_server_me }, | 817 { "server-me", 3, 3, cmd_server_me }, |
714 errx(1, "abort: command not found"); | 845 errx(1, "abort: command not found"); |
715 | 846 |
716 --argc; | 847 --argc; |
717 ++argv; | 848 ++argv; |
718 | 849 |
719 if (argc < c->minargs || argc > c->maxargs) | 850 if ((c->minargs != -1 && argc < c->minargs) || (c->minargs != -1 && argc > c->maxargs)) |
720 errx(1, "abort: invalid number of arguments"); | 851 errx(1, "abort: invalid number of arguments"); |
721 | 852 |
722 c->exec(argc, argv); | 853 c->exec(argc, argv); |
723 } | 854 } |
724 | 855 |
725 noreturn static void | 856 noreturn static void |
726 usage(void) | 857 usage(void) |
727 { | 858 { |
728 fprintf(stderr, "usage: %s [-v] [-s sock] command [arguments...]\n", getprogname()); | 859 fprintf(stderr, "usage: %s [-v] [-s sock] command [options...] [arguments...]\n", getprogname()); |
860 exit(1); | |
861 } | |
862 | |
863 noreturn static void | |
864 help(void) | |
865 { | |
866 fprintf(stderr, "usage: %s hook-add name path\n", getprogname()); | |
867 fprintf(stderr, " %s hook-list\n", getprogname()); | |
868 fprintf(stderr, " %s hook-remove id\n", getprogname()); | |
869 fprintf(stderr, " %s plugin-config id [variable [value]]\n", getprogname()); | |
870 fprintf(stderr, " %s plugin-info id\n", getprogname()); | |
871 fprintf(stderr, " %s plugin-list\n", getprogname()); | |
872 fprintf(stderr, " %s plugin-load name\n", getprogname()); | |
873 fprintf(stderr, " %s plugin-path [variable [value]]\n", getprogname()); | |
874 fprintf(stderr, " %s plugin-template [variable [value]]\n", getprogname()); | |
875 fprintf(stderr, " %s plugin-reload [plugin]\n", getprogname()); | |
876 fprintf(stderr, " %s plugin-unload [plugin]\n", getprogname()); | |
877 fprintf(stderr, " %s rule-add [-c channel] [-e event] [-i index] [-o origin] [-p plugin] [-s server] accept|drop\n", getprogname()); | |
878 fprintf(stderr, " %s rule-edit [-a accept|drop] [-c|C channel] [-e|E event] [-o|O origin] [-s|S server] index\n", getprogname()); | |
879 fprintf(stderr, " %s rule-list\n", getprogname()); | |
880 fprintf(stderr, " %s rule-move from to\n", getprogname()); | |
881 fprintf(stderr, " %s rule-remove index\n", getprogname()); | |
882 fprintf(stderr, " %s server-connect [-n nickname] [-r realname] [-u username] [-p port] id hostname\n", getprogname()); | |
883 fprintf(stderr, " %s server-disconnect [server]\n", getprogname()); | |
884 fprintf(stderr, " %s server-info server\n", getprogname()); | |
885 fprintf(stderr, " %s server-invite server target channel\n", getprogname()); | |
886 fprintf(stderr, " %s server-join server channel [password]\n", getprogname()); | |
887 fprintf(stderr, " %s server-kick server target channel [reason]\n", getprogname()); | |
888 fprintf(stderr, " %s server-list\n", getprogname()); | |
889 fprintf(stderr, " %s server-me server target message\n", getprogname()); | |
890 fprintf(stderr, " %s server-message server target message\n", getprogname()); | |
891 fprintf(stderr, " %s server-mode server target mode [limit] [user] [mask]\n", getprogname()); | |
892 fprintf(stderr, " %s server-nick server nickname\n", getprogname()); | |
893 fprintf(stderr, " %s server-notice server target message\n", getprogname()); | |
894 fprintf(stderr, " %s server-part server channel [reason]\n", getprogname()); | |
895 fprintf(stderr, " %s server-reconnect [server]\n", getprogname()); | |
896 fprintf(stderr, " %s server-topic server channel topic\n", getprogname()); | |
897 fprintf(stderr, " %s watch\n", getprogname()); | |
729 exit(1); | 898 exit(1); |
730 } | 899 } |
731 | 900 |
732 int | 901 int |
733 main(int argc, char **argv) | 902 main(int argc, char **argv) |
734 { | 903 { |
904 ketopt_t ko = KETOPT_INIT; | |
905 | |
735 setprogname("irccdctl"); | 906 setprogname("irccdctl"); |
736 | 907 |
737 for (int ch; (ch = getopt(argc, argv, "s:v")) != -1; ) { | 908 --argc; |
909 ++argv; | |
910 | |
911 for (int ch; (ch = ketopt(&ko, argc, argv, 0, "s:v", NULL)) != -1; ) { | |
738 switch (ch) { | 912 switch (ch) { |
739 case 's': | 913 case 's': |
740 strlcpy(sockaddr.sun_path, optarg, sizeof (sockaddr.sun_path)); | 914 strlcpy(sockaddr.sun_path, optarg, sizeof (sockaddr.sun_path)); |
741 break; | 915 break; |
742 case 'v': | 916 case 'v': |
743 verbose = 1; | 917 verbose = 1; |
744 break; | 918 break; |
745 default: | 919 default: |
920 usage(); | |
746 break; | 921 break; |
747 } | 922 } |
748 } | 923 } |
749 | 924 |
750 argc -= optind; | 925 argc -= ko.ind; |
751 argv += optind; | 926 argv += ko.ind; |
752 | 927 |
753 if (argc < 1) | 928 if (argc < 1) |
754 usage(); | 929 usage(); |
930 else if (strcmp(argv[0], "help") == 0) | |
931 help(); | |
755 | 932 |
756 dial(); | 933 dial(); |
757 check(); | 934 check(); |
758 run(argc, argv); | 935 run(argc, argv); |
759 } | 936 } |