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 }