Mercurial > noffle
comparison src/noffle.c @ 150:1c7303c71f66 noffle
[svn] * src/protocol.c: Fix bug in Prt_getLn if we should read a line
starting with '\0' - according to the leafnode mailing list,
this has been seen in the wild.
* docs/inews.1,docs/noffle.1,docs/noffle.conf.5,
packages/redhat/noffle.spec,src/configfile.h,src/configfile.c,
src/noffle.c,src/post.h,src/post.c: Removed use of getopt_long,
and added inews mode - the Noffle executable behaves
as inews is invoked as inews. This includes adding From: and
Organization: headers if necessary - add configs to override
defaults for the From: domain and specify the organization.
For all my fellow trn-heads out there, and users of any other
ageing newsreader that expects inews. Updated RPM spec to create
inews link to noffle on install.
author | bears |
---|---|
date | Thu, 26 Oct 2000 22:21:13 +0100 |
parents | a740dac296bc |
children | 8ea6b5ddc5a5 |
comparison
equal
deleted
inserted
replaced
149:bfeea2bc09b6 | 150:1c7303c71f66 |
---|---|
8 not as server. If noffle runs as server, locking is performed while | 8 not as server. If noffle runs as server, locking is performed while |
9 executing NNTP commands, but temporarily released if no new command is | 9 executing NNTP commands, but temporarily released if no new command is |
10 received for some seconds (to allow multiple clients connect at the same | 10 received for some seconds (to allow multiple clients connect at the same |
11 time). | 11 time). |
12 | 12 |
13 $Id: noffle.c 197 2000-08-14 19:49:56Z bears $ | 13 $Id: noffle.c 227 2000-10-26 21:21:13Z bears $ |
14 */ | 14 */ |
15 | 15 |
16 #if HAVE_CONFIG_H | 16 #if HAVE_CONFIG_H |
17 #include <config.h> | 17 #include <config.h> |
18 #endif | 18 #endif |
19 | 19 |
20 #include <ctype.h> | 20 #include <ctype.h> |
21 #include <errno.h> | 21 #include <errno.h> |
22 #include <getopt.h> | |
23 #include <signal.h> | 22 #include <signal.h> |
24 #include <sys/time.h> | 23 #include <sys/time.h> |
25 #include <sys/resource.h> | 24 #include <sys/resource.h> |
26 #include <syslog.h> | 25 #include <syslog.h> |
27 #include <unistd.h> | 26 #include <unistd.h> |
180 | 179 |
181 Lock_releaseFetchLock(); | 180 Lock_releaseFetchLock(); |
182 } | 181 } |
183 | 182 |
184 static Bool | 183 static Bool |
185 doPost( void ) | 184 doPost( FILE *f, unsigned flags ) |
186 { | 185 { |
187 Str line; | 186 Str line; |
188 DynStr *s; | 187 DynStr *s; |
189 Bool res; | 188 Bool res; |
190 | 189 |
191 s = new_DynStr( 10000 ); | 190 s = new_DynStr( 10000 ); |
192 while ( fgets( line, MAXCHAR, stdin ) != NULL ) | 191 while ( fgets( line, MAXCHAR, f ) != NULL ) |
193 DynStr_app( s, line ); | 192 DynStr_app( s, line ); |
194 | 193 |
195 res = TRUE; | 194 res = TRUE; |
196 if ( ! Post_open( DynStr_str( s ) ) ) | 195 if ( ! Post_open( DynStr_str( s ), flags ) ) |
197 { | 196 { |
198 fprintf( stderr, "Post failed: Malformed article.\n" ); | 197 fprintf( stderr, "Post failed: Malformed article.\n" ); |
199 res = FALSE; | 198 res = FALSE; |
200 } | 199 } |
201 else if ( ! Post_post() ) | 200 else if ( ! Post_post() ) |
638 Log_inf( "Received signal %i (%s). Aborting.", sig, name ); | 637 Log_inf( "Received signal %i (%s). Aborting.", sig, name ); |
639 signal( sig, SIG_DFL ); | 638 signal( sig, SIG_DFL ); |
640 raise( sig ); | 639 raise( sig ); |
641 } | 640 } |
642 | 641 |
642 static void | |
643 printInewsUsage( void ) | |
644 { | |
645 static const char *msg = | |
646 "Usage: inews [-D] [-O] [-S] [input]\n" | |
647 " -D Debug - send article to stdout and don't post\n" | |
648 " -O Don't add Organization header\n" | |
649 " -S Don't add .signature\n" | |
650 " input File containing message, standard input if none specified.\n" | |
651 "For compatability, -h, -A, -V, -W are ignored and -N is\n" | |
652 "equivalent to -D.\n"; | |
653 fprintf( stderr, "%s", msg ); | |
654 } | |
655 | |
656 static int | |
657 doInews( int argc, char **argv ) | |
658 { | |
659 int result; | |
660 int flags; | |
661 FILE *f; | |
662 | |
663 UNUSED( argc ); | |
664 | |
665 noffle.lockAtStartup = TRUE; | |
666 | |
667 /* Process options */ | |
668 flags = POST_ADD_ORG | POST_ADD_SIG | POST_ADD_FROM; | |
669 for ( ; argv[0] != NULL && argv[0][0] == '-' ; argv++ ) | |
670 { | |
671 if ( argv[0][2] != '\0' ) | |
672 { | |
673 printInewsUsage(); | |
674 return EXIT_FAILURE; | |
675 } | |
676 | |
677 switch( argv[0][1] ) | |
678 { | |
679 case 'h': | |
680 case 'A': | |
681 case 'V': | |
682 case 'W': | |
683 break; | |
684 case 'N': | |
685 case 'D': | |
686 flags |= POST_DEBUG; | |
687 break; | |
688 case 'O': | |
689 flags &= ~POST_ADD_ORG; | |
690 break; | |
691 case 'S': | |
692 flags &= ~POST_ADD_SIG; | |
693 break; | |
694 default: | |
695 printInewsUsage(); | |
696 return EXIT_FAILURE; | |
697 } | |
698 } | |
699 | |
700 if ( argv[0] == NULL ) | |
701 f = stdin; | |
702 else | |
703 { | |
704 f = fopen( argv[0], "r" ); | |
705 if ( f == NULL ) | |
706 { | |
707 Log_err( "Can't access %s (%s).", argv[0], strerror( errno ) ); | |
708 return EXIT_FAILURE; | |
709 } | |
710 } | |
711 | |
712 if ( ! initNoffle() ) | |
713 return EXIT_FAILURE; | |
714 result = EXIT_SUCCESS; | |
715 | |
716 if ( ! doPost( f, flags ) ) | |
717 result = EXIT_FAILURE; | |
718 | |
719 if ( f != stdin ) | |
720 fclose( f ); | |
721 | |
722 closeNoffle(); | |
723 return result; | |
724 } | |
725 | |
726 static int | |
727 getArgLetter(const char *arg) | |
728 { | |
729 int res; | |
730 struct option | |
731 { | |
732 const char *longOpt; | |
733 const char *opt; | |
734 } options[] = | |
735 { | |
736 { "--article", "-a" }, | |
737 { "--cancel", "-c" }, | |
738 { "--create", "-C" }, | |
739 { "--database", "-d" }, | |
740 { "--delete", "-D" }, | |
741 { "--expire", "-e" }, | |
742 { "--fetch", "-f" }, | |
743 { "--groups", "-g" }, | |
744 { "--help", "-h" }, | |
745 { "--list", "-l" }, | |
746 { "--modify", "-m" }, | |
747 { "--offline", "-o" }, | |
748 { "--online", "-n" }, | |
749 { "--post", "-p" }, | |
750 { "--query", "-q" }, | |
751 { "--server", "-r" }, | |
752 { "--requested", "-R" }, | |
753 { "--subscribe-over", "-s" }, | |
754 { "--subscribe-full", "-S" }, | |
755 { "--subscribe-thread", "-t" }, | |
756 { "--unsubscribe", "-u" }, | |
757 { "--version", "-v" }, | |
758 { NULL, NULL } | |
759 | |
760 }; | |
761 struct option *opt; | |
762 | |
763 res = -1; | |
764 for ( opt = options; opt->opt != NULL; opt++ ) | |
765 if ( strcmp( arg, opt->longOpt ) == 0 || | |
766 strcmp( arg, opt->opt ) == 0 ) | |
767 { | |
768 res = opt->opt[1]; | |
769 break; | |
770 } | |
771 | |
772 return res; | |
773 } | |
774 | |
643 int main ( int argc, char **argv ) | 775 int main ( int argc, char **argv ) |
644 { | 776 { |
645 int c, result; | 777 int c, result; |
646 struct option longOptions[] = | 778 const char *cmdname, *p; |
647 { | 779 |
648 { "article", required_argument, NULL, 'a' }, | |
649 { "cancel", required_argument, NULL, 'c' }, | |
650 { "create", required_argument, NULL, 'C' }, | |
651 { "database", no_argument, NULL, 'd' }, | |
652 { "delete", required_argument, NULL, 'D' }, | |
653 { "expire", no_argument, NULL, 'e' }, | |
654 { "fetch", no_argument, NULL, 'f' }, | |
655 { "groups", no_argument, NULL, 'g' }, | |
656 { "help", no_argument, NULL, 'h' }, | |
657 { "list", no_argument, NULL, 'l' }, | |
658 { "modify", required_argument, NULL, 'm' }, | |
659 { "offline", no_argument, NULL, 'o' }, | |
660 { "online", no_argument, NULL, 'n' }, | |
661 { "post", no_argument, NULL, 'p' }, | |
662 { "query", required_argument, NULL, 'q' }, | |
663 { "server", no_argument, NULL, 'r' }, | |
664 { "requested", no_argument, NULL, 'R' }, | |
665 { "subscribe-over", required_argument, NULL, 's' }, | |
666 { "subscribe-full", required_argument, NULL, 'S' }, | |
667 { "subscribe-thread", required_argument, NULL, 't' }, | |
668 { "unsubscribe", required_argument, NULL, 'u' }, | |
669 { "version", no_argument, NULL, 'v' }, | |
670 { NULL, 0, NULL, 0 } | |
671 }; | |
672 | |
673 signal( SIGSEGV, bugReport ); | 780 signal( SIGSEGV, bugReport ); |
674 signal( SIGABRT, logSignal ); | 781 signal( SIGABRT, logSignal ); |
675 signal( SIGFPE, logSignal ); | 782 signal( SIGFPE, logSignal ); |
676 signal( SIGILL, logSignal ); | 783 signal( SIGILL, logSignal ); |
677 signal( SIGINT, logSignal ); | 784 signal( SIGINT, logSignal ); |
678 signal( SIGTERM, logSignal ); | 785 signal( SIGTERM, logSignal ); |
679 signal( SIGPIPE, logSignal ); | 786 signal( SIGPIPE, logSignal ); |
680 c = getopt_long( argc, argv, "a:c:C:dD:efghlm:onpq:rRs:S:t:u:v", | 787 |
681 longOptions, NULL ); | 788 /* Find last component of command name. */ |
789 cmdname = argv[0]; | |
790 p = strrchr( cmdname, '/' ); | |
791 if ( p != NULL ) | |
792 cmdname = ++p; | |
793 | |
794 argv++; | |
795 argc--; | |
796 | |
797 /* Were we invoked as inews? */ | |
798 if ( strcmp( cmdname, "inews" ) == 0 ) | |
799 return doInews( argc, argv ); | |
800 | |
801 c = -1; | |
802 if ( *argv != NULL ) | |
803 { | |
804 c = getArgLetter( *argv ); | |
805 argv++; | |
806 argc--; | |
807 } | |
808 | |
682 noffle.lockAtStartup = ! ( c == 'r' || c == 'h' ); | 809 noffle.lockAtStartup = ! ( c == 'r' || c == 'h' ); |
683 if ( ! initNoffle() ) | 810 if ( ! initNoffle() ) |
684 return EXIT_FAILURE; | 811 return EXIT_FAILURE; |
685 result = EXIT_SUCCESS; | 812 result = EXIT_SUCCESS; |
686 switch ( c ) | 813 switch ( c ) |
687 { | 814 { |
688 case 0: | |
689 /* Options that set a flag. */ | |
690 break; | |
691 case 'a': | 815 case 'a': |
692 if ( ! optarg ) | 816 if ( *argv == NULL ) |
693 { | 817 { |
694 fprintf( stderr, "Option -a needs argument.\n" ); | 818 fprintf( stderr, "Option -a needs argument.\n" ); |
695 result = EXIT_FAILURE; | 819 result = EXIT_FAILURE; |
696 } | 820 } |
697 else | 821 else |
698 doArt( optarg ); | 822 doArt( *argv ); |
699 break; | 823 break; |
700 case 'c': | 824 case 'c': |
701 if ( ! optarg ) | 825 if ( *argv == NULL ) |
702 { | 826 { |
703 fprintf( stderr, "Option -c needs argument.\n" ); | 827 fprintf( stderr, "Option -c needs argument.\n" ); |
704 result = EXIT_FAILURE; | 828 result = EXIT_FAILURE; |
705 } | 829 } |
706 else | 830 else |
707 doCancel( optarg ); | 831 doCancel( *argv ); |
708 break; | 832 break; |
709 case 'C': | 833 case 'C': |
710 if ( ! optarg ) | 834 if ( *argv == NULL ) |
711 { | 835 { |
712 fprintf( stderr, "Option -C needs argument.\n" ); | 836 fprintf( stderr, "Option -C needs argument.\n" ); |
713 result = EXIT_FAILURE; | 837 result = EXIT_FAILURE; |
714 } | 838 } |
715 else | 839 else |
716 doCreateLocalGroup( optarg ); | 840 doCreateLocalGroup( *argv ); |
717 break; | 841 break; |
718 case 'd': | 842 case 'd': |
719 doDb(); | 843 doDb(); |
720 break; | 844 break; |
721 case 'D': | 845 case 'D': |
722 if ( ! optarg ) | 846 if ( *argv == NULL ) |
723 { | 847 { |
724 fprintf( stderr, "Option -D needs argument.\n" ); | 848 fprintf( stderr, "Option -D needs argument.\n" ); |
725 result = EXIT_FAILURE; | 849 result = EXIT_FAILURE; |
726 } | 850 } |
727 else | 851 else |
728 doDeleteLocalGroup( optarg ); | 852 doDeleteLocalGroup( *argv ); |
729 break; | 853 break; |
730 case 'e': | 854 case 'e': |
731 doExpire(); | 855 doExpire(); |
732 break; | 856 break; |
733 case 'f': | 857 case 'f': |
742 break; | 866 break; |
743 case 'l': | 867 case 'l': |
744 doList(); | 868 doList(); |
745 break; | 869 break; |
746 case 'm': | 870 case 'm': |
747 if ( ! optarg ) | 871 if ( *argv == NULL ) |
748 { | 872 { |
749 fprintf( stderr, "Option -m needs argument.\n" ); | 873 fprintf( stderr, "Option -m needs argument.\n" ); |
750 result = EXIT_FAILURE; | 874 result = EXIT_FAILURE; |
751 } | 875 } |
752 else | 876 else |
753 if ( ! doModify( optarg, argc - optind, &argv[ optind ] ) ) | 877 if ( ! doModify( *argv, --argc, ++argv ) ) |
754 result = EXIT_FAILURE; | 878 result = EXIT_FAILURE; |
755 break; | 879 break; |
756 case 'n': | 880 case 'n': |
757 if ( Online_true() ) | 881 if ( Online_true() ) |
758 fprintf( stderr, "NOFFLE is already online\n" ); | 882 fprintf( stderr, "NOFFLE is already online\n" ); |
764 fprintf( stderr, "NOFFLE is already offline\n" ); | 888 fprintf( stderr, "NOFFLE is already offline\n" ); |
765 else | 889 else |
766 Online_set( FALSE ); | 890 Online_set( FALSE ); |
767 break; | 891 break; |
768 case 'p': | 892 case 'p': |
769 if ( ! doPost() ) | 893 if ( ! doPost( stdin, 0 ) ) |
770 result = EXIT_FAILURE; | 894 result = EXIT_FAILURE; |
771 break; | 895 break; |
772 case 'q': | 896 case 'q': |
773 if ( ! optarg ) | 897 if ( *argv == NULL ) |
774 { | 898 { |
775 fprintf( stderr, "Option -q needs argument.\n" ); | 899 fprintf( stderr, "Option -q needs argument.\n" ); |
776 result = EXIT_FAILURE; | 900 result = EXIT_FAILURE; |
777 } | 901 } |
778 else | 902 else |
779 { | 903 { |
780 if ( strcmp( optarg, "groups" ) == 0 ) | 904 if ( strcmp( *argv, "groups" ) == 0 ) |
781 noffle.queryGrps = TRUE; | 905 noffle.queryGrps = TRUE; |
782 else if ( strcmp( optarg, "desc" ) == 0 ) | 906 else if ( strcmp( *argv, "desc" ) == 0 ) |
783 noffle.queryDsc = TRUE; | 907 noffle.queryDsc = TRUE; |
784 else | 908 else |
785 { | 909 { |
786 fprintf( stderr, "Unknown argument -q %s\n", optarg ); | 910 fprintf( stderr, "Unknown argument -q %s\n", *argv ); |
787 result = EXIT_FAILURE; | 911 result = EXIT_FAILURE; |
788 } | 912 } |
789 doQuery(); | 913 doQuery(); |
790 } | 914 } |
791 break; | 915 break; |
792 case 'r': | 916 case 'r': |
793 Log_inf( "Starting as server" ); | 917 Log_inf( "Starting as server" ); |
794 Server_run(); | 918 Server_run(); |
795 break; | 919 break; |
796 case 'R': | 920 case 'R': |
797 doRequested( optarg ); | 921 doRequested( *argv ); |
798 break; | 922 break; |
799 case 's': | 923 case 's': |
800 if ( ! optarg ) | 924 if ( *argv == NULL ) |
801 { | 925 { |
802 fprintf( stderr, "Option -s needs argument.\n" ); | 926 fprintf( stderr, "Option -s needs argument.\n" ); |
803 result = EXIT_FAILURE; | 927 result = EXIT_FAILURE; |
804 } | 928 } |
805 else | 929 else |
806 result = doSubscribe( optarg, OVER ); | 930 result = doSubscribe( *argv, OVER ); |
807 break; | 931 break; |
808 case 'S': | 932 case 'S': |
809 if ( ! optarg ) | 933 if ( *argv == NULL ) |
810 { | 934 { |
811 fprintf( stderr, "Option -S needs argument.\n" ); | 935 fprintf( stderr, "Option -S needs argument.\n" ); |
812 result = EXIT_FAILURE; | 936 result = EXIT_FAILURE; |
813 } | 937 } |
814 else | 938 else |
815 doSubscribe( optarg, FULL ); | 939 doSubscribe( *argv, FULL ); |
816 break; | 940 break; |
817 case 't': | 941 case 't': |
818 if ( ! optarg ) | 942 if ( *argv == NULL ) |
819 { | 943 { |
820 fprintf( stderr, "Option -t needs argument.\n" ); | 944 fprintf( stderr, "Option -t needs argument.\n" ); |
821 result = EXIT_FAILURE; | 945 result = EXIT_FAILURE; |
822 } | 946 } |
823 else | 947 else |
824 result = doSubscribe( optarg, THREAD ); | 948 result = doSubscribe( *argv, THREAD ); |
825 break; | 949 break; |
826 case 'u': | 950 case 'u': |
827 if ( ! optarg ) | 951 if ( *argv == NULL ) |
828 { | 952 { |
829 fprintf( stderr, "Option -u needs argument.\n" ); | 953 fprintf( stderr, "Option -u needs argument.\n" ); |
830 result = EXIT_FAILURE; | 954 result = EXIT_FAILURE; |
831 } | 955 } |
832 else | 956 else |
833 doUnsubscribe( optarg ); | 957 doUnsubscribe( *argv ); |
834 break; | 958 break; |
835 case '?': | 959 case '?': |
836 /* Error message already printed by getopt_long */ | 960 /* Error message already printed by getopt_long */ |
837 result = EXIT_FAILURE; | 961 result = EXIT_FAILURE; |
838 break; | 962 break; |