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;