⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ng.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: ng.c,v 3.0 1992/02/01 03:09:32 davison Trn $ *//* This software is Copyright 1991 by Stan Barber.  * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made.  * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk.  */#include "EXTERN.h"#include "common.h"#include "trn.h"#include "term.h"#include "final.h"#include "util.h"#include "cache.h"#include "bits.h"#include "artsrch.h"#include "help.h"#include "kfile.h"#include "rcstuff.h"#include "head.h"#include "art.h"#include "artio.h"#include "ngstuff.h"#include "intrp.h"#include "respond.h"#include "ngdata.h"#include "backpage.h"#include "rcln.h"#include "last.h"#include "search.h"#include "nntp.h"#include "rthread.h"#include "rt-select.h"#include "rt-wumpus.h"#include "decode.h"#include "INTERN.h"#include "ng.h"#include "artstate.h"			/* somebody has to do it *//* art_switch() return values */#define AS_NORM 0#define AS_INP 1#define AS_ASK 2#define AS_CLEAN 3int exit_code = NG_NORM;voidng_init(){#ifdef KILLFILES    open_kfile(KF_GLOBAL);#endif#ifdef CUSTOMLINES    init_compex(&hide_compex);    init_compex(&page_compex);#endif}/* do newsgroup on line ng with name ngname *//* assumes that we are chdir'ed to NEWSSPOOL, and assures that that is * still true upon return, but chdirs to NEWSSPOOL/ngname in between * * If you can understand this routine, you understand most of the program. * The basic structure is: *	for each desired article *		for each desired page *			for each line on page *				if we need another line from file *					get it *					if it's a header line *						do special things *				for each column on page *					put out a character *				end loop *			end loop *		end loop *	end loop * *	(Actually, the pager is in another routine.) * * The chief problem is deciding what is meant by "desired".  Most of * the messiness of this routine is due to the fact that people want * to do unstructured things all the time.  I have used a few judicious * goto's where I thought it improved readability.  The rest of the messiness * arises from trying to be both space and time efficient.  Have fun. */intdo_newsgroup(start_command)char *start_command;			/* command to fake up first */{    char oldmode = mode;    char *whatnext = "%sWhat next? [%s]";#ifdef ARTSEARCH    srchahead = (scanon && !ThreadedGroup	/* did they say -S? */	      && ((ART_NUM)toread[ng]) >= scanon ? -1 : 0);#endif        exit_code = NG_NORM;    save_ids = FALSE;    killfirst = 0;    if (extractdest) {	free(extractdest);	extractdest = Nullch;    }    if (extractprog) {	free(extractprog);	extractprog = Nullch;    }    /* initialize the newsgroup data structures */    if (!access_ng())	return -1;    /* FROM HERE ON, RETURN THRU CLEANUP OR WE ARE SCREWED */    in_ng = TRUE;			/* tell the world we are here */    forcelast = TRUE;			/* if 0 unread, do not bomb out */    recent_artp = curr_artp = Nullart;    recent_art = curr_art = lastart+1;    prompt = whatnext;    /* remember what newsgroup we were in for sake of posterity */    writelast();    /* see if there are any special searches to do */    has_normal_kills = FALSE;#ifdef KILLFILES    open_kfile(KF_LOCAL);# ifdef VERBOSE    IF(verbose)	kill_unwanted(firstart,"Processing memorized commands...\n\n",TRUE);    ELSE# endif# ifdef TERSE	kill_unwanted(firstart,"Auto-processing...\n\n",TRUE);# endif#endif    if (!selected_count)	selected_only = FALSE;    top_article();    /* do they want a special top line? */    firstline = getval("FIRSTLINE",Nullch);    /* custom line suppression, custom page ending */#ifdef CUSTOMLINES    if (hideline = getval("HIDELINE",Nullch))	compile(&hide_compex,hideline,TRUE,TRUE);    if (pagestop = getval("PAGESTOP",Nullch))	compile(&page_compex,pagestop,TRUE,TRUE);#endif    /* now read each unread article */    rc_changed = doing_ng = TRUE;	/* enter the twilight zone */    checkcount = 0;			/* do not checkpoint for a while */    do_fseek = FALSE;			/* start 1st article at top */    for (; art<=lastart+1; ) {		/* for each article */	mode = 'a';	/* do we need to "grow" the newsgroup? */	if (art > lastart || forcegrow) {	    ART_NUM oldlast = lastart;#ifdef USE_NNTP	    ART_NUM newlast = lastart;	    while (nntp_stat(newlast+1))		newlast++;	    if (newlast > oldlast) {		ngmax[ng] = newlast;		grow_ng(newlast);	    }#else	    grow_ng(getngsize(ng));#endif	    if (forcelast && art > oldlast)		art = lastart+1;	}	find_article(art);		/* sets artp */	if (start_command) {		/* do we have an initial command? */	    pushstring(start_command, 0);	    free(start_command);	    start_command = Nullch;	    art = curr_art = lastart+1;	    artp = curr_artp = Nullart;	    if (input_pending())		goto reinp_article;	}	if (art>lastart) {		/* are we off the end still? */	    ARTICLE *ap;	    ART_NUM i;	    art = lastart + 1;		/* keep pointer references sane */	    if (!forcelast && toread[ng] && selected_only && !selected_count) {		art = curr_art;		artp = curr_artp;		strcpy(buf, "+");		goto article_level;	    }	    count_subjects(CS_NORM);	    for (i=last_cached+1, ap=article_ptr(i); i<=lastart; i++, ap++)		if (!(ap->flags & AF_READ))		    article_count++;	    toread[ng] = (ART_UNREAD)article_count;	    if (artp != curr_artp) {		recent_art = curr_art;	/* remember last article # (for '-') */		curr_art = art;		/* set current article # */		recent_artp = curr_artp;		curr_artp = artp;	    }	    if (erase_screen)		clear();			/* clear the screen */	    else		fputs("\n\n",stdout) FLUSH;#ifdef VERBOSE	    IF(verbose)		printf("End of newsgroup %s.",ngname);					/* print pseudo-article */	    ELSE#endif#ifdef TERSE		printf("End of %s",ngname);#endif	    if (article_count) {		if (selected_only)		    printf("  (%ld + %ld articles still unread)",			(long)selected_count,			(long)article_count-selected_count);		else		    printf("  (%ld article%s still unread)",			(long)article_count,article_count==1?nullstr:"s");	    }	    else if (!forcelast)		goto cleanup;		/* actually exit newsgroup */	    mode = 'e';	    prompt = whatnext;#ifdef ARTSEARCH	    srchahead = 0;		/* no more subject search mode */#endif	    fputs("\n\n",stdout) FLUSH;	}	else if (!reread && (was_read(art) || (artp->flags & AF_MISSING)		|| (selected_only && !(artp->flags & AF_SEL)))) {					/* has this article been read? */	    inc_art(selected_only,FALSE);/* then skip it */	    continue;	}	else if (!reread && !parseheader(art)) {	    oneless(artp);		/* mark deleted as read */	    ng_skip();	}	else {				/* we have a real live article */	    if (artp != curr_artp) {		recent_art = curr_art;	/* remember last article # (for '-') */		curr_art = art;		/* set current article # */		recent_artp = curr_artp;		curr_artp = artp;	    }	    if (!do_fseek) {		/* starting at top of article? */		artline = 0;		/* start at the beginning */		topline = -1;		/* and remember top line of screen */					/*  (line # within article file) */	    }	    clear();			/* clear screen */	    if (!artopen(art)) {	/* make sure article is found & open */		char tmpbuf[256];		/* see if we have tree data for this article anyway */		init_tree();		sprintf(tmpbuf,"%s: article is not available.",ngname);		if (artp && !(artp->flags & AF_CACHED)) {		    if (absfirst < first_cached || last_cached < lastart		     || !cached_all_in_range)			sprintf(tmpbuf,"%s: article may show up in a moment.",				ngname);		}		tree_puts(tmpbuf,0,0);		vwtary((ART_LINE)0,(ART_POS)0);		finish_tree(1);		prompt = whatnext;#ifdef ARTSEARCH		srchahead = 0;#endif	    }	    else {			/* found it, so print it */		switch (do_article()) {		case DA_CLEAN:		/* quit newsgroup */		    goto cleanup;		case DA_TOEND:		/* do not mark as read */		    goto reask_article; 		case DA_RAISE:		/* reparse command at end of art */		    goto article_level;		case DA_NORM:		/* normal end of article */		    break;		}	    }	    if (art >= absfirst)	/* don't mark non-existant articles */		mark_as_read();		/* mark current article as read */	    do_hiding = TRUE;#ifdef ROTATION	    rotate = FALSE;#endif	}/* if these gotos bother you, think of this as a little state machine */reask_article:#ifdef MAILCALL	setmail(FALSE);#endif	setdfltcmd();#ifdef CLEAREOL	if (erase_screen && can_home_clear)	    clear_rest();#endif /* CLEAREOL */	unflush_output();		/* disable any ^O in effect */	standout();			/* enter standout mode */	printf(prompt,mailcall,dfltcmd);/* print prompt, whatever it is */	un_standout();			/* leave standout mode */	putchar(' ');	fflush(stdout);reinp_article:	reread = FALSE;	forcelast = FALSE;	eat_typeahead();#ifdef PENDING	look_ahead();			/* see what we can do in advance */	cache_until_key();#endif	art = curr_art;	artp = curr_artp;	getcmd(buf);	if (errno || *buf == '\f') {	    if (LINES < 100 && !int_count)		*buf = '\f';		/* on CONT fake up refresh */	    else {		putchar('\n') FLUSH;		/* but only on a crt */		goto reask_article;	    }	}article_level:	output_chase_phrase = TRUE;	/* parse and process article level command */	switch (art_switch()) {	case AS_INP:			/* multichar command rubbed out */	    goto reinp_article;	case AS_ASK:			/* reprompt "End of article..." */	    goto reask_article;	case AS_CLEAN:			/* exit newsgroup */	    goto cleanup;	case AS_NORM:			/* display article art */	    break;	}    }					/* end of article selection loop */    /* shut down newsgroup */cleanup:    decode_end();#ifdef KILLFILES    kill_unwanted(firstart,"\nCleaning up...\n\n",FALSE);					/* do cleanup from KILL file, if any */#endif    in_ng = FALSE;			/* leave newsgroup state */    if (artfp != Nullfp) {		/* article still open? */	fclose(artfp);			/* close it */	artfp = Nullfp;			/* and tell the world */	openart = 0;    }    putchar('\n') FLUSH;    deselect_all();    yankback();				/* do a Y command */    bits_to_rc();			/* reconstitute .newsrc line */    doing_ng = FALSE;			/* tell sig_catcher to cool it */    write_rc();				/* and update .newsrc */    rc_changed = FALSE;			/* tell sig_catcher it is ok */    if (chdir(spool)) {	printf(nocd,spool) FLUSH;	sig_catcher(0);    }#ifdef KILLFILES    if (localkfp) {	fclose(localkfp);	localkfp = Nullfp;    }#endif    mode = oldmode;    return exit_code;}					/* Whew! *//* decide what to do at the end of an article */intart_switch(){    register ART_NUM i;          setdef(buf,dfltcmd);#ifdef VERIFY    printcmd();#endif    switch (*buf) {    case '<':			/* goto previous subject/thread */	prev_subject();	return AS_NORM;    case '>':			/* goto next subject/thread */	next_subject();	return AS_NORM;    case 'U': {			/* unread some articles */	char *u_prompt, *u_help_thread;	dfltcmd = "+";	if (!artp) {	    u_help_thread = nullstr;#ifdef VERBOSE	    IF(verbose)		u_prompt = "\nSet unread: +select or all? [+an] ";	    ELSE#endif#ifdef TERSE		u_prompt = "\nSet unread? [+an] ";#endif	}	else {#ifdef VERBOSE	    IF(verbose) {		u_prompt = "\n\Set unread: +select, thread, subthread, or all? [+tsan] ";		u_help_thread = "\Type t or SP to mark this thread's articles as unread.\n\Type s to mark the current article and its descendants as unread.\n";	    }	    ELSE#endif#ifdef TERSE	    {		u_prompt = "\nSet unread? [+tsan] ";		u_help_thread = "\t or SP to mark thread unread.\n\s to mark subthread unread.\n";	    }#endif	}      reask_unread:	in_char(u_prompt,'u');	setdef(buf,dfltcmd);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -