home *** CD-ROM | disk | FTP | other *** search
- /* rn -- new readnews program
- *
- * Original Author: lwall@sdcrdcf.UUCP (Larry Wall)
- * Organization: System Development Corporation, Santa Monica
- *
- * begun: 01/14/83
- * 1.0: 04/08/83
- * 2.0: 09/01/83
- * RRN/RN: 11/01/89
- */
-
- static char rnid[] = "@(#)$Header: E:\SRC\UUPC\RN\RCS/RN.C 1.1 1992/11/21 06:14:58 ahd Exp $";
- static char patchlevel[] = "Patch #: 47";
-
- /* $Log: RN.C $
- * Revision 1.1 1992/11/21 06:14:58 ahd
- * Initial
- *
- *
- * Rev 1.0 18 Nov 1990 0:22:04
- * Initial revision.
- * Revision 4.3.2.4 90/04/03 23:11:33 sob
- * Added more information to the version command.
- *
- * Revision 4.3.2.3 90/03/22 23:05:23 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.2 89/11/28 01:51:25 sob
- * Removed redundant #include directive.
- *
- * Revision 4.3.2.1 89/11/08 02:27:38 sob
- * Release of RN 4.3 with RRN that can be compiled from the same
- * sources as either version of the program.
- *
- * Revision 4.3.1.4 85/09/10 11:05:13 lwall
- * Improved %m in in_char().
- *
- * Revision 4.3.1.3 85/05/16 16:47:10 lwall
- * Catchup confirmation didn't grok -t.
- *
- * Revision 4.3.1.2 85/05/13 09:34:53 lwall
- * Fixed default after do_newsgroup() returns from Q command.
- *
- * Revision 4.3.1.1 85/05/10 11:38:08 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:47:56 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "importng.h"
-
- #include "INTERN.h"
- #include "common.h"
- #include "rn.h"
- #include "EXTERN.h"
- #include "rcstuff.h"
- #include "term.h"
- #include "final.h"
- #include "ngdata.h"
- #include "util.h"
- #include "only.h"
- #include "ngsrch.h"
- #include "help.h"
- #include "last.h"
- #include "init.h"
- #include "intrp.h"
- #include "rcln.h"
- #include "sw.h"
- #include "addng.h"
- #include "ng.h"
-
- void rn_init(void);
- void set_ngname(char *what);
- char *getngdir(char *ngnam);
-
- void
- rn_init()
- {
- ;
- }
-
- void
- main(argc, argv)
- int argc;
- char *argv[];
- {
- bool foundany = initialize(argc, argv);
- register char *s;
- bool oh_for_the_good_old_days = FALSE;
-
- if (maxngtodo)
- starthere = 0;
- else if (!foundany)
- { /* nothing to do? */
-
- #ifdef VERBOSE
- if (verbose)
- fputs("\
- No unread news in subscribed-to newsgroups. To subscribe to a new\n\
- newsgroup use the g<newsgroup> command.\n\
- ", stdout) FLUSH;
- #endif
-
- starthere = nextrcline;
- }
-
- /* loop through all unread news */
-
- {
- char promptbuf[80];
- bool special = FALSE; /* temporarily allow
- * newsgroup */
-
- /* with no unread news? */
- bool retry; /* cycle back to top of
- * list? */
- NG_NUM recent_ng = 0;
-
- current_ng = 0;
- do
- {
- retry = FALSE;
- if (findlast)
- {
- findlast = FALSE;
- starthere = 0;
- if (*lastngname)
- {
- if ((ng = find_ng(lastngname)) == nextrcline)
- ng = 0;
- else
- {
- set_ngname(lastngname);
- set_toread(ng);
- if (toread[ng] <= TR_NONE)
- ng = 0;
- }
- }
- }
- else
- {
- ng = starthere;
- starthere = 0;
- }
- while (ng <= nextrcline)
- { /* for each newsgroup */
- mode = 'n';
- if (ng >= nextrcline)
- { /* after the last
- * newsgroup? */
- ng = nextrcline; /* force it to 1 after */
-
- #ifdef ONLY
- if (maxngtodo)
- {
- if (retry)
-
- #ifdef VERBOSE
- IF(verbose)
- printf("\nRestriction %s%s still in effect.\n",
- ngtodo[0],
- maxngtodo > 1 ? ", etc." : nullstr) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("\n(\"Only\" mode.)\n", stdout) FLUSH;
- #endif
-
- else
- {
-
- #ifdef VERBOSE
- IF(verbose)
- fputs("\nNo articles under restriction.",
- stdout) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("\nNo \"only\" articles.", stdout) FLUSH;
- #endif
-
- end_only(); /* release the
- * restriction */
- retry = TRUE;
- }
- }
- #endif
-
- dfltcmd = (retry ? "npq" : "qnp");
-
- #ifdef VERBOSE
- IF(verbose)
- sprintf(promptbuf,
- "\n******** End of newsgroups--what next? [%s] ",
- dfltcmd);
- ELSE
- #endif
-
- #ifdef TERSE
- sprintf(promptbuf,
- "\n**** End--next? [%s] ", dfltcmd);
- #endif
- }
- else
- {
- bool shoe_fits; /* newsgroup matches
- * restriction? */
-
- if (toread[ng] >= TR_NONE)
- { /* recalc toread? */
- set_ngname(rcline[ng]);
- if ((shoe_fits = (special || inlist(ngname))) != 0)
- set_toread(ng);
- if (paranoid)
- {
- recent_ng = current_ng;
- current_ng = ng;
- cleanup_rc();
- /* this may move newsgroups around */
- ng = current_ng;
- set_ngname(rcline[ng]);
- }
- }
- if (toread[ng] < (maxngtodo || special ? TR_NONE : TR_ONE) || !shoe_fits)
- {
- /* unwanted newsgroup? */
- ng++; /* then skip it */
- continue;
- }
- reprompt_newsgroup:
- dfltcmd = "ynq";
-
- #ifdef VERBOSE
- IF(verbose)
- sprintf(promptbuf,
- "\n******** %3ld unread article%c in %s--read now? [%s] ",
- (long) toread[ng], (toread[ng] == TR_ONE ? ' ' : 's'),
- ngname, dfltcmd); /* format prompt string */
- ELSE
- #endif
-
- #ifdef TERSE
- sprintf(promptbuf,
- "\n**** %3ld in %s--read? [%s] ",
- (long) toread[ng],
- ngname, dfltcmd); /* format prompt string */
- #endif
- }
- special = FALSE; /* go back to normal
- * mode */
- if (ng != current_ng)
- {
- recent_ng = current_ng;
- /* remember previous newsgroup */
- current_ng = ng; /* remember current
- * newsgroup */
- }
- reask_newsgroup:
- unflush_output();/* disable any ^O in
- * effect */
- fputs(promptbuf, stdout) FLUSH; /* print prompt */
- fflush(stdout);
- reinp_newsgroup:
- eat_typeahead();
- getcmd(buf);
- if (errno || *buf == '\f')
- {
- putchar('\n') FLUSH; /* if return from stop
- * signal */
- goto reask_newsgroup; /* give them a prompt
- * again */
- }
- setdef(buf, dfltcmd);
-
- #ifdef VERIFY
- printcmd();
- #endif
-
- switch (*buf)
- {
- case 'p': /* find previous unread
- * newsgroup */
- do
- {
- if (ng <= 0)
- break;
- ng--;
- if (toread[ng] == TR_NONE)
- set_toread(ng);
- } while (toread[ng] <= TR_NONE);
- break;
- case 'P': /* goto previous
- * newsgroup */
- do
- {
- if (ng <= 0)
- break;
- ng--;
- } while (toread[ng] < TR_NONE);
- special = TRUE; /* don't skip it if
- * toread==0 */
- break;
- case '-':
- ng = recent_ng; /* recall previous
- * newsgroup */
- special = TRUE; /* don't skip it if
- * toread==0 */
- break;
- case 'q':
- case 'Q':
- case 'x': /* quit? */
- oh_for_the_good_old_days = (*buf == 'x');
- putchar('\n') FLUSH;
- ng = nextrcline + 1; /* satisfy */
- retry = FALSE;/* loop conditions */
- break;
- case '^':
- putchar('\n') FLUSH;
- ng = 0;
- break;
- case 'n':
- case '+': /* find next unread
- * newsgroup */
- if (ng == nextrcline)
- {
- putchar('\n') FLUSH;
- retry = TRUE;
- }
- else if (toread[ng] > TR_NONE)
- retry = TRUE;
- ng++;
- break;
- case 'N': /* goto next newsgroup */
- ng++;
- special = TRUE; /* and don't skip it if
- * toread==0 */
- break;
- case '1': /* goto 1st newsgroup */
- ng = 0;
- special = TRUE; /* and don't skip it if
- * toread==0 */
- break;
- case '$':
- ng = nextrcline; /* goto last newsgroup */
- retry = TRUE;
- break;
- case 'L':
- list_newsgroups();
- goto reask_newsgroup;
- case '/':
- case '?': /* scan for newsgroup
- * pattern */
-
- #ifdef NGSEARCH
- switch (ng_search(buf, TRUE))
- {
- case NGS_ABORT:
- goto reinp_newsgroup;
- case NGS_INTR:
-
- #ifdef VERBOSE
- IF(verbose)
- fputs("\n(Interrupted)\n", stdout) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("\n(Intr)\n", stdout) FLUSH;
- #endif
-
- ng = current_ng;
- goto reask_newsgroup;
- case NGS_FOUND:
- special = TRUE; /* don't skip it if
- * toread==0 */
- break;
- case NGS_NOTFOUND:
-
- #ifdef VERBOSE
- IF(verbose)
- fputs("\n\nNot found--use g to add newsgroups\n",
- stdout) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("\n\nNot found\n", stdout) FLUSH;
- #endif
-
- goto reask_newsgroup;
- }
- #else
- notincl("/");
- #endif
-
- break;
- case 'm':
-
- #ifndef RELOCATE
- notincl("m");
- break;
- #endif
-
- case 'g': /* goto named newsgroup */
- if (!finish_command(FALSE))
- /* if they didn't finish command */
- goto reinp_newsgroup; /* go try something else */
- for (s = buf + 1; *s == ' '; s++);
- /* skip leading spaces */
- if (!*s)
- strcpy(s, ngname);
-
- #ifdef RELOCATE
- if (!get_ng(s, *buf == 'm')) /* try to find newsgroup */
- #else
- if (!get_ng(s, FALSE)) /* try to find newsgroup */
- #endif
-
- ng = current_ng; /* if not found, go nowhere */
- special = TRUE; /* don't skip it if toread==0 */
- break;
-
- #ifdef DEBUGGING
- case 'D':
- printf("\nTries: %d Hits: %d\n",
- softtries, softtries - softmisses) FLUSH;
- goto reask_newsgroup;
- #endif
-
- case '!': /* shell escape */
- if (escapade()) /* do command */
- goto reinp_newsgroup;
- /* if rubbed out, re input */
- goto reask_newsgroup;
- case Ctl('k'): /* edit global KILL file */
- edit_kfile();
- goto reask_newsgroup;
- case 'c': /* catch up */
-
- #ifdef CATCHUP
- reask_catchup:
-
- #ifdef VERBOSE
- IF(verbose)
- in_char("\nDo you really want to mark everything as read? [yn] ", 'C');
- ELSE
- #endif
-
- #ifdef TERSE
- in_char("\nReally? [ynh] ", 'C');
- #endif
-
- putchar('\n') FLUSH;
- setdef(buf, "y");
- if (*buf == 'h')
- {
-
- #ifdef VERBOSE
- printf("Type y or SP to mark all articles as read.\n");
- printf("Type n to leave articles marked as they are.\n");
- #else
- printf("y or SP to mark all read.\n");
- printf("n to forget it.\n");
- #endif
-
- goto reask_catchup;
- }
- else if (*buf != ' ' && *buf != 'y' && *buf != 'n' && *buf != 'q')
- {
- printf(hforhelp);
- settle_down();
- goto reask_catchup;
- }
- else if ((*buf == ' ' || *buf == 'y') && ng < nextrcline)
- catch_up(ng);
- else
- retry = TRUE;
- ng++;
- #else
- notincl("c");
- #endif
-
- break;
- case 'u': /* unsubscribe */
- if (ng < nextrcline && toread[ng] >= TR_NONE)
- {
- /* unsubscribable? */
- printf(unsubto, rcline[ng]) FLUSH;
- rcchar[ng] = NEGCHAR;
- /* unsubscribe to (from?) it */
- toread[ng] = TR_UNSUB;
- /* and make line invisible */
- ng++; /* do an automatic 'n' */
- }
- break;
- case 'h':
- { /* help */
- int cmd;
-
- if ((cmd = help_ng()) > 0)
- pushchar(cmd);
- goto reask_newsgroup;
- }
- case 'a':
-
- #ifndef FINDNEWNG
- notincl("a");
- goto reask_newsgroup;
- #else
- /* FALL THROUGH */
- #endif
-
- case 'o':
-
- #ifdef ONLY
- {
-
- #ifdef FINDNEWNG
- bool doscan = (*buf == 'a');
-
- #endif
-
- if (!finish_command(TRUE)) /* get rest of command */
- goto reinp_newsgroup; /* if rubbed out, try
- * something else */
- end_only();
- if (buf[1])
- {
- sw_list(buf + 1);
- cwd_check(FALSE);
- putchar('\n') FLUSH;
-
- #ifdef FINDNEWNG
- if (doscan && maxngtodo)
- scanactive();
- #endif
- }
- ng = 0; /* simulate ^ */
- retry = FALSE;
- break;
- }
- #else
- notincl("o");
- goto reask_newsgroup;
- #endif
-
- case '&':
- if (switcheroo()) /* get rest of command */
- goto reinp_newsgroup; /* if rubbed out, try
- * something else */
- goto reask_newsgroup;
- case 'l':
- { /* list other newsgroups */
- if (!finish_command(TRUE)) /* get rest of command */
- goto reinp_newsgroup; /* if rubbed out, try
- * something else */
- for (s = buf + 1; *s == ' '; s++);
- /* skip leading spaces */
- sprintf(cmd_buf, "%s '%s'", filexp(NEWSGROUPS), s);
- resetty();
- if (doshell(sh, cmd_buf))
-
- #ifdef VERBOSE
- IF(verbose)
- fputs(" (Error from newsgroups program)\n",
- stdout) FLUSH;
- ELSE
- #endif
-
- #ifdef TERSE
- fputs("(Error)\n", stdout) FLUSH;
- #endif
-
- noecho();
- crmode();
- goto reask_newsgroup;
- }
- case '.':
- case '=':
- case 'y':
- case 'Y': /* do normal thing */
- if (ng >= nextrcline)
- {
- fputs("\nNot on a newsgroup.", stdout) FLUSH;
- goto reask_newsgroup;
- }
- if (*buf == '=')
- s = savestr("=");
- else if (*buf == '.')
- { /* start command? */
- if (!finish_command(FALSE)) /* get rest of command */
- goto reinp_newsgroup;
- s = savestr(buf + 1);
- /* do_newsgroup will free it */
- }
- else
- s = Nullch;
- if (toread[ng])
- retry = TRUE;
- switch (do_newsgroup(s))
- {
- case NG_ERROR:
- case NG_NORM:
- ng++;
- break;
- case NG_ASK:
- goto reprompt_newsgroup;
- case NG_MINUS:
- ng = recent_ng; /* recall previous
- * newsgroup */
- special = TRUE; /* don't skip it if
- * toread==0 */
- break;
- }
- break;
-
- #ifdef STRICTCR
- case '\n':
- fputs(badcr, stdout) FLUSH;
- goto reask_newsgroup;
- #endif
-
- case 'v':
- printf("\n%s", rnid);
- printf("\n%s", patchlevel);
- printf("\nSend bugs to rrn@lib.tmc.edu\n") FLUSH;
- goto reask_newsgroup;
- default:
- printf("\n%s", hforhelp) FLUSH;
- settle_down();
- goto reask_newsgroup;
- }
- }
- } while (retry);
- }
-
- /* now write .newsrc back out */
-
- write_rc();
-
- if (oh_for_the_good_old_days)
- get_old_rc();
-
- finalize(0); /* and exit */
- }
-
- /*--------------------------------------------------------------------*/
- /* s e t _ n g n a m e */
- /* */
- /* S e t c u r r e n t n e w s g r o u p */
- /*--------------------------------------------------------------------*/
-
- void set_ngname(char *what)
- {
- strcpy(ngname, what);
- strcpy(ngdir, getngdir(what));
- }
-
- /*--------------------------------------------------------------------*/
- /* g e t n g d i r */
- /* */
- /* Set the news group directory from the news group name */
- /*--------------------------------------------------------------------*/
-
- char *getngdir(char *ngnam)
- {
- static char myngdir[FILENAME_MAX];
- register char *s;
- ImportNewsGroup( myngdir, ngnam, 0 );
- return myngdir;
- }
-