home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / trn_12.zip / src / rn.c < prev    next >
C/C++ Source or Header  |  1993-12-05  |  18KB  |  705 lines

  1. /*  trn -- threaded readnews program based on rn 4.4
  2.  *
  3.  *  Author/Maintainer of trn: davison@borland.com (Wayne Davison)
  4.  *  Organization: Borland International
  5.  *  Author/Maintainer of rn: sob@bcm.tmc.edu (Stan Barber)
  6.  *  Organization: Baylor College of Medicine, Houston,Tx
  7.  *  Original Author: lwall@sdcrdcf.UUCP (Larry Wall)
  8.  *  Organization: System Development Corporation, Santa Monica
  9.  *
  10.  *  History:
  11.  *    01/14/83 - rn begun
  12.  *    04/08/83 - rn 1.0
  13.  *    09/01/83 - rn 2.0
  14.  *    05/01/85 - rn 4.3
  15.  *    11/01/89 - rn/rrn integration
  16.  *    11/25/89 - trn begun
  17.  *    07/21/90 - trn 1.0
  18.  *    07/04/91 - rn 4.4
  19.  *    11/25/91 - trn 2.0
  20.  */
  21. /* This software is Copyright 1991 by Stan Barber. 
  22.  *
  23.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  24.  * use this software as long as: there is no monetary profit gained
  25.  * specifically from the use or reproduction of this software, it is not
  26.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  27.  * included prominently in any copy made. 
  28.  *
  29.  * The author make no claims as to the fitness or correctness of this software
  30.  * for any use whatsoever, and it is provided as is. Any use of this software
  31.  * is at the user's own risk. 
  32.  */
  33.  
  34. static char rnid[] = "@(#)$Id: rn.c,v 4.4.3.1 1991/11/22 04:12:14 davison Trn $";
  35. static char patchlevelos2[] = "TRN 1.2 for OS/2 based on Trn 2.5";
  36. static char patchlevel[] = "Trn-2.5 based on rn-4.4PL4";
  37.  
  38. /* $Log: rn.c,v $
  39.  * Revision 4.4.2.1  1991/12/01  18:05:42  sob
  40.  * Patchlevel 2 changes
  41.  *
  42.  * Revision 4.4.1.1  1991/09/25  19:38:08  sob
  43.  * Updated patchlevel message
  44.  *
  45.  * Revision 4.4  1991/09/09  20:27:37  sob
  46.  * release 4.4
  47.  *
  48.  *
  49.  *
  50.  * 
  51.  */
  52.  
  53. #include "INTERN.h"
  54. #include "common.h"
  55. #include "rn.h"
  56. #ifdef SERVER
  57. #include "server.h"
  58. #endif
  59. #include "EXTERN.h"
  60. #include "rcstuff.h"
  61. #include "term.h"
  62. #include "final.h"
  63. #include "search.h"
  64. #include "ngdata.h"
  65. #include "util.h"
  66. #include "only.h"
  67. #include "ngsrch.h"
  68. #include "help.h"
  69. #include "last.h"
  70. #include "init.h"
  71. #include "intrp.h"
  72. #include "rcln.h"
  73. #include "sw.h"
  74. #include "addng.h"
  75. #include "ng.h"
  76.  
  77.  
  78. void
  79. rn_init()
  80. {
  81.     ;
  82. }
  83.  
  84. void
  85. main(argc,argv)
  86. int argc;
  87. char *argv[];
  88. {
  89.     bool foundany;
  90.     register char *s;
  91.     bool oh_for_the_good_old_days = FALSE;
  92.     int direction = 1;
  93.  
  94. /*** OS2: Now we load the settings out of the uupc-rc-files.
  95.           This settings contain the information, which was
  96.           previously hardcoded in the config.h-file by
  97.           the Configure-shell-script.       ***/
  98.  
  99.     if (!load_uupc_rc())
  100.     {  fprintf(stderr,"An error occurred while reading the uupc-rc-files!\n\
  101. The following settings must be defined in the UUPCSYSRC-file:\n\
  102.        MailServ, NodeName, NewsDir, Domain, TempDir, MailDir, rmail\n");
  103.        fprintf(stderr,"These settings must be defined in the UUPCUSRRC-file:\n\
  104.        Mailbox, Signature, Name, Home, Organization, Editor\n");
  105.        fprintf(stderr,"And these settings must be defined in the UUPCTRNRC-file:\n\
  106.        Newsadmin, TrnLib, LocalDist, OrganizationDist, CityDist,\n\
  107.        StateDist, Countrydist, ContinentDist\n");
  108.        fprintf(stderr,"\nDon't forget, these settings are required, not optional!\n");
  109.        fflush(stderr);
  110.        exit(1);
  111.     }
  112.     
  113.     setvbuf(stdout, NULL, _IOFBF, BUFSIZ);
  114.     
  115.     
  116. #if defined(USETHREADS) && !THREAD_INIT
  117.     /* Default to threaded operation if our name starts with a 't' */
  118.     if ((s = rindex(argv[0],'/')) == Nullch)
  119.     s = argv[0];
  120.     else
  121.     s++;
  122.     if (*s == 't')
  123.     use_threads = TRUE;
  124. #endif
  125.     foundany = initialize(argc,argv);
  126.  
  127.     if (maxngtodo)
  128.     starthere = 0;
  129.     else if (!foundany) {        /* nothing to do? */
  130. #ifdef VERBOSE
  131.     if (verbose)
  132.         fputs("\
  133. No unread news in subscribed-to newsgroups.  To subscribe to a new\n\
  134. newsgroup use the g<newsgroup> command.\n\
  135. ",stdout) ; FLUSH;
  136. #endif
  137.     starthere = nextrcline;
  138.     }
  139.  
  140.     /* loop through all unread news */
  141.  
  142.     {
  143.     bool special = FALSE;        /* temporarily allow newsgroup */
  144.                     /*   with no unread news? */
  145.     bool retry;            /* cycle back to top of list? */
  146.     NG_NUM recent_ng = 0;
  147.     
  148.     current_ng = 0;
  149.     do {
  150.         retry = FALSE;
  151.         if (findlast) {
  152.         findlast = FALSE;
  153.         starthere = 0;
  154.         if (*lastngname) {
  155.             if ((ng = find_ng(lastngname)) == nextrcline)
  156.             ng = 0;
  157.             else {
  158.             set_ngname(lastngname);
  159.                 set_toread(ng);
  160.             if (toread[ng] <= TR_NONE)
  161.                 ng = 0;
  162.             }
  163.         }
  164.         }
  165.         else {
  166.         ng = starthere;
  167.         starthere = 0;
  168.         }
  169.         while (ng <= nextrcline) {    /* for each newsgroup */
  170.         mode = 'n';
  171.         if (ng >= nextrcline) {    /* after the last newsgroup? */
  172.             ng = nextrcline;    /* force it to 1 after */
  173. #ifdef ONLY
  174.             if (maxngtodo) {
  175.             if (retry)
  176. #ifdef VERBOSE
  177.                 IF(verbose) {
  178.                 printf("\nRestriction %s%s still in effect.\n",
  179.                     ngtodo[0],
  180.                     maxngtodo > 1 ? ", etc." : nullstr) ; FLUSH;
  181.                 }
  182.                 ELSE
  183. #endif
  184. #ifdef TERSE
  185.             {    fputs("\n(\"Only\" mode.)\n",stdout) ; FLUSH; }
  186. #endif
  187.             else {
  188. #ifdef VERBOSE
  189.                 IF(verbose) {
  190.                 fputs("\nNo articles under restriction.",
  191.                   stdout) ; FLUSH;
  192.                 }
  193.                 ELSE
  194. #endif
  195. #ifdef TERSE
  196.             {    fputs("\nNo \"only\" articles.",stdout) ; FLUSH;}
  197. #endif
  198.                 end_only();    /* release the restriction */
  199.                 retry = TRUE;
  200.             }
  201.             }
  202. #endif
  203.         }
  204.         else {
  205.             bool shoe_fits;    /* newsgroup matches restriction? */
  206.  
  207.             if (toread[ng] >= TR_NONE) {    /* recalc toread? */
  208.             set_ngname(rcline[ng]);
  209.             shoe_fits = inlist(ngname);
  210.             if (shoe_fits)
  211.                 set_toread(ng);
  212.             if (paranoid) {
  213.                 recent_ng = current_ng;
  214.                 current_ng = ng;
  215.                 cleanup_rc();
  216.                     /* this may move newsgroups around */
  217.                 ng = current_ng;
  218.                 set_ngname(rcline[ng]);
  219.             }
  220.             }
  221.             if (toread[ng] < (maxngtodo||special ? TR_NONE : TR_ONE)
  222.              || !shoe_fits) {        /* unwanted newsgroup? */
  223.             ng += direction;    /* then skip it */
  224.             if (ng < 0) {
  225.                ng = 1;
  226.                direction = 1;
  227.             }
  228.             continue;
  229.             }
  230.         }
  231.         special = FALSE;    /* go back to normal mode */
  232.         if (ng != current_ng) {
  233.             recent_ng = current_ng;
  234.                     /* remember previous newsgroup */
  235.             current_ng = ng;    /* remember current newsgroup */
  236.         }
  237.     reask_newsgroup:
  238.         unflush_output();    /* disable any ^O in effect */
  239.         if (ng >= nextrcline) {
  240. #ifdef SERVER
  241.             if (time(Null(time_t*)) - lastactfetch > MINFETCHTIME) {
  242.             fclose(actfp);
  243.             ngdata_init();    /* re-grab the active file */
  244.             }
  245. #endif
  246.             dfltcmd = (retry ? "npq" : "qnp");
  247. #ifdef VERBOSE
  248.             IF(verbose)
  249.             printf("\n******** End of newsgroups--what next? [%s] ",
  250.                 dfltcmd);
  251.             ELSE
  252. #endif
  253. #ifdef TERSE
  254.             printf("\n**** End--next? [%s] ", dfltcmd);
  255. #endif
  256.         } else {
  257. #ifdef USETHREADS
  258.             ThreadedGroup = (use_threads
  259.             && (thread_always || rcchar[ng] == '0'));
  260.             dfltcmd = (use_threads && select_on
  261.             && (ART_NUM)toread[ng] >= select_on ? "+ynq" : "ynq");
  262. #else
  263.             dfltcmd = "ynq";
  264. #endif
  265. #ifdef VERBOSE
  266.             IF(verbose)
  267.             printf("\n******** %3ld unread article%s in %s--read now? [%s] ",
  268.                 (long)toread[ng], (toread[ng]==TR_ONE ? nullstr : "s"),
  269.                 ngname, dfltcmd);
  270.             ELSE
  271. #endif
  272. #ifdef TERSE
  273.             printf("\n**** %3ld in %s--read? [%s] ",
  274.                 (long)toread[ng],
  275.                 ngname,dfltcmd);
  276. #endif
  277.         }
  278.         fflush(stdout);
  279.     reinp_newsgroup:
  280.         eat_typeahead();
  281.         getcmd(buf);
  282.         if (errno || *buf == '\f') {
  283.             putchar('\n') ; FLUSH; /* if return from stop signal */
  284.             goto reask_newsgroup;    /* give them a prompt again */
  285.         }
  286.         setdef(buf,dfltcmd);
  287. #ifdef VERIFY
  288.         printcmd();
  289. #endif
  290.     do_command:
  291.         direction = 1;        /* default to forward motion */
  292.         addnewbydefault = 0;
  293.         switch (*buf) {
  294.         case 'P':        /* goto previous newsgroup */
  295.             special = TRUE;    /* don't skip it if toread==0 */
  296.             /* FALL THROUGH */
  297.         case 'p':        /* find previous unread newsgroup */
  298.             if (ng > 0)
  299.             ng--;
  300.             direction = -1;    /* go backward in the newsrc */
  301.             break;
  302.         case '-':
  303.             ng = recent_ng;    /* recall previous newsgroup */
  304.             if (ng < nextrcline)
  305.             if (!get_ng(rcline[ng],FALSE))
  306.                 ng = current_ng;
  307.             special = TRUE;    /* don't skip it if toread==0 */
  308.             break;
  309.         case 'q': case 'Q': case 'x':    /* quit? */
  310.             oh_for_the_good_old_days = (*buf == 'x');
  311.             putchar('\n') ; FLUSH;
  312.             ng = nextrcline+1;    /* satisfy */
  313.             retry = FALSE;    /*   loop conditions */
  314.             break;
  315.         case '^':
  316.             putchar('\n') ; FLUSH;
  317.             ng = 0;
  318.             break;
  319.         case 'n':        /* find next unread newsgroup */
  320.             if (ng == nextrcline) {
  321.             putchar('\n') ; FLUSH;
  322.             retry = TRUE;
  323.             }
  324.             else if (toread[ng] > TR_NONE)
  325.             retry = TRUE;
  326.             ng++;
  327.             break;
  328.         case 'N':        /* goto next newsgroup */
  329.             special = TRUE;    /* and don't skip it if toread==0 */
  330.             ng++;
  331.             break;
  332.         case '1':        /* goto 1st newsgroup */
  333.             ng = 0;
  334.             special = TRUE;    /* and don't skip it if toread==0 */
  335.             break;
  336.         case '$':
  337.             ng = nextrcline;    /* goto last newsgroup */
  338.             retry = TRUE;
  339.             break;
  340.         case 'L':
  341.             list_newsgroups();
  342.             goto reask_newsgroup;
  343.         case '/': case '?':    /* scan for newsgroup pattern */
  344. #ifdef NGSEARCH
  345.             switch (ng_search(buf,TRUE)) {
  346.             case NGS_ERROR:
  347.             goto reask_newsgroup;
  348.             case NGS_ABORT:
  349.             goto reinp_newsgroup;
  350.             case NGS_INTR:
  351. #ifdef VERBOSE
  352.             IF(verbose) {
  353.                 fputs("\n(Interrupted)\n",stdout) ; FLUSH;
  354.             }
  355.             ELSE
  356. #endif
  357. #ifdef TERSE
  358.             {    fputs("\n(Intr)\n",stdout) ; FLUSH;}
  359. #endif
  360.             ng = current_ng;
  361.             goto reask_newsgroup;
  362.             case NGS_FOUND:
  363.             special = TRUE;    /* don't skip it if toread==0 */
  364.             break;
  365.             case NGS_NOTFOUND:
  366. #ifdef VERBOSE
  367.             IF(verbose) {
  368.                 fputs("\n\nNot found--use a or g to add newsgroups\n",
  369.                 stdout) ; FLUSH;
  370.             }
  371.             ELSE
  372. #endif
  373. #ifdef TERSE
  374.                 fputs("\n\nNot found\n",stdout) ; FLUSH;
  375. #endif
  376.             goto reask_newsgroup;
  377.             }
  378. #else
  379.             notincl("/");
  380. #endif
  381.             break;
  382.         case 'm':
  383. #ifndef RELOCATE
  384.             notincl("m");
  385.             break;
  386. #endif            
  387.         case 'g':    /* goto named newsgroup */
  388.             if (!finish_command(FALSE))
  389.                     /* if they didn't finish command */
  390.             goto reinp_newsgroup;    /* go try something else */
  391.  
  392.             for (s = buf+1; *s == ' '; s++);
  393.                     /* skip leading spaces */
  394. #ifdef RELOCATE
  395.             if (!*s && *buf == 'm' && ngname && ng < nextrcline)
  396.             strcpy(s,ngname);
  397. #endif
  398.             if (isalnum(*s)) {
  399.                 char *_s;
  400.             for (_s=s; isdigit(*_s); _s++)
  401.                 ;
  402.                 if (*_s && !isspace(*_s))
  403.                 /* found non-digit before hitting end */
  404.                 set_ngname(s);
  405.             else {
  406.                 int rcnum;
  407.                 rcnum = atoi(s);
  408.                 if (rcnum < nextrcline)
  409.                 set_ngname(rcline[rcnum]);
  410.                 else {
  411.                 printf("\nOnly %d groups. Try again.\n",
  412.                     nextrcline) ; FLUSH;
  413.                 goto reask_newsgroup;
  414.                 }
  415.             }
  416.             }
  417.             else {
  418.             printf("\nPlease specify a newsgroup.\n"); FLUSH;
  419.             goto reask_newsgroup;
  420.             }
  421. #ifdef RELOCATE
  422.             if (!get_ng(ngname,*buf=='m'))
  423.                         /* try to find newsgroup */
  424. #else
  425.             if (!get_ng(ngname,FALSE))    /* try to find newsgroup */
  426. #endif
  427.             ng = current_ng;/* if not found, go nowhere */
  428.             special = TRUE;    /* don't skip it if toread==0 */
  429.             break;
  430. #ifdef DEBUGGING
  431.         case 'D':
  432.             printf("\nTries: %d Hits: %d\n",
  433.             softtries,softtries-softmisses) ; FLUSH;
  434.             goto reask_newsgroup;
  435. #endif
  436.         case '!':        /* shell escape */
  437.             if (escapade())     /* do command */
  438.             goto reinp_newsgroup;
  439.                     /* if rubbed out, re input */
  440.             goto reask_newsgroup;
  441.         case Ctl('k'):        /* edit global KILL file */
  442.             edit_kfile();
  443.             goto reask_newsgroup;
  444.         case 'c':        /* catch up */
  445. #ifdef CATCHUP
  446.             if (ng < nextrcline)
  447.             ask_catchup();
  448.             ng++;
  449. #else
  450.             notincl("c");
  451. #endif
  452.             break;
  453. #ifdef USETHREADS
  454.         case 't':
  455.             if (!use_threads)
  456.             printf("\n\nNot running in thread mode.\n");
  457.             else if (ng < nextrcline && toread[ng] >= TR_NONE) {
  458.             bool force_threaded = (rcchar[ng] == ':');
  459.             rcchar[ng] = (force_threaded ? '0' : ':');
  460.             printf("\n\n%s will %s.\n", rcline[ng],
  461.                 force_threaded ? "always be read threaded"
  462.                 : "be read unthreaded if no thread file exists"
  463.                 ) ; FLUSH;
  464.             set_toread(ng);
  465.             }
  466.             special = TRUE;    /* don't skip it if toread==0 */
  467.             break;
  468. #endif
  469.         case 'u':        /* unsubscribe */
  470.             if (ng < nextrcline && toread[ng] >= TR_NONE) {
  471.                     /* unsubscribable? */
  472.             printf(unsubto,rcline[ng]) ; FLUSH;
  473.             rcchar[ng] = NEGCHAR;
  474.                     /* unsubscribe to (from?) it */
  475.             toread[ng] = TR_UNSUB;
  476.                     /* and make line invisible */
  477.             ng++;        /* do an automatic 'n' */
  478.             }
  479.             break;
  480.         case 'h': {        /* help */
  481.             int cmd;
  482.  
  483.             if ((cmd = help_ng()) > 0)
  484.             pushchar(cmd);
  485.             goto reask_newsgroup;
  486.         }
  487.         case 'A':
  488.             if (ng >= nextrcline)
  489.             break;
  490. reask_abandon:
  491. #ifdef VERBOSE
  492.             IF(verbose)
  493.             in_char("\nAbandon changes to current newsgroup? [yn] ", 'B');
  494.             ELSE
  495. #endif
  496. #ifdef TERSE
  497.             in_char("\nAbandon? [ynh] ", 'B');
  498. #endif
  499.             setdef(buf,"y");
  500. #ifdef VERIFY
  501.             printcmd();
  502. #endif
  503.             putchar('\n') ; FLUSH;
  504.             if (*buf == 'h') {
  505. #ifdef VERBOSE
  506.             printf("Type y or SP to abandon the changes to this group since you started trn.\n");
  507.             printf("Type n to leave the group as it is.\n");
  508. #else
  509.             printf("y or SP to abandon changes to this group.\n");
  510.             printf("n to forget it.\n");
  511. #endif
  512.             goto reask_abandon;
  513.             }
  514.             else if (*buf != 'y' && *buf != 'n' && *buf != 'q') {
  515.             printf(hforhelp);
  516.             settle_down();
  517.             goto reask_abandon;
  518.             } else if (*buf == 'y')
  519.             abandon_ng(ng);
  520.             special = TRUE;    /* don't skip it if toread==0 */
  521.             break;
  522.         case 'a':
  523. /*** OS2: please fix this later ***/
  524. /*            printf("\nNot implemented, sorry!\n");  ** */
  525. /*            goto reask_newsgroup;                   ** */
  526. /** end **/
  527. #ifndef FINDNEWNG
  528.             notincl("a");
  529.             goto reask_newsgroup;
  530. #else
  531.             /* FALL THROUGH */
  532. #endif
  533.         case 'o':
  534. #ifdef ONLY
  535.         {
  536. #ifdef FINDNEWNG
  537.             bool doscan = (*buf == 'a');
  538. #endif
  539.  
  540.             if (!finish_command(TRUE)) /* get rest of command */
  541.             goto reinp_newsgroup;    /* if rubbed out, try something else */
  542.             end_only();
  543.             if (buf[1]) {
  544.             bool minusd = instr(buf+1,"-d", TRUE) != Nullch;
  545.  
  546.             sw_list(buf+1);
  547.             if (minusd)
  548.                 cwd_check();
  549.             putchar('\n') ; FLUSH;
  550. #ifdef FINDNEWNG
  551.             if (doscan && maxngtodo)
  552.                 scanactive();
  553. #endif
  554.             }
  555.             ng = 0;        /* simulate ^ */
  556.             retry = FALSE;
  557.             break;
  558.         }
  559. #else
  560.             notincl("o");
  561.             goto reask_newsgroup;
  562. #endif
  563.         case '&':
  564.             if (switcheroo()) /* get rest of command */
  565.             goto reinp_newsgroup;    /* if rubbed out, try something else */
  566.             goto reask_newsgroup;
  567.         case 'l': {        /* list other newsgroups */
  568.             if (!finish_command(TRUE)) /* get rest of command */
  569.             goto reinp_newsgroup;    /* if rubbed out, try something else */
  570.             for (s = buf+1; *s == ' '; s++);
  571.                         /* skip leading spaces */
  572. /*** OS2: we look for unsubscribed newsgroups with
  573.           our own function and not via the shellscript ***/
  574. /*            sprintf(cmd_buf,"%s '%s'",filexp(NEWSGROUPS),s);  */
  575. /*            resetty();                                        */
  576. /*            if (doshell(sh,cmd_buf))                          */
  577.             if (unsub_group(s))
  578. #ifdef VERBOSE
  579.             IF(verbose) {
  580.                 fputs("    (Error from newsgroups function)\n",
  581.                 stdout) ; FLUSH;
  582.             }
  583.             ELSE
  584. #endif
  585. #ifdef TERSE
  586.                 fputs("(Error)\n",stdout) ; FLUSH;
  587. #endif
  588. /*            noecho();   */
  589. /*            crmode();   */
  590.             goto reask_newsgroup;
  591.         }
  592. #ifdef USETHREADS
  593.         case 'U': case '+':
  594. #endif
  595.         case '.': case '=':
  596.         case 'y': case 'Y': case '\t': /* do normal thing */
  597.             if (ng >= nextrcline) {
  598.             fputs("\nNot on a newsgroup.",stdout) ; FLUSH;
  599.             goto reask_newsgroup;
  600.             }
  601. #ifdef USETHREADS
  602.             else if (*buf == '+' || *buf == 'U' || *buf == '=') {
  603.             buf[1] = '\0';
  604.             s = savestr(buf);
  605.             }
  606. #else
  607.             if (*buf == '=')
  608.             s = savestr("=");
  609. #endif
  610.             else if (*buf == '.') {    /* start command? */
  611.             if (!finish_command(FALSE)) /* get rest of command */
  612.                 goto reinp_newsgroup;
  613.             s = savestr(buf+1);
  614.                     /* do_newsgroup will free it */
  615.             }
  616.             else
  617.             s = Nullch;
  618.             if (toread[ng])
  619.             retry = TRUE;
  620.             switch (do_newsgroup(s)) {
  621.             case NG_ERROR:
  622.             case NG_NORM:
  623.             ng++;
  624.             break;
  625.             case NG_ASK:
  626.             goto reask_newsgroup;
  627.             case NG_SELPRIOR:
  628.             *buf = 'p';
  629.             goto do_command;
  630.             case NG_SELNEXT:
  631.             *buf = 'n';
  632.             goto do_command;
  633.             case NG_MINUS:
  634.             ng = recent_ng;    /* recall previous newsgroup */
  635.             special = TRUE;    /* don't skip it if toread==0 */
  636.             break;
  637.             }
  638.             break;
  639. #ifdef STRICTCR
  640.         case '\n':
  641.             fputs(badcr,stdout) ; FLUSH;
  642.             goto reask_newsgroup;
  643. #endif
  644.         case 'v':
  645.             printf("\n%s",rnid);
  646.             printf("\n%s",patchlevelos2);
  647.             printf("\n%s",patchlevel);
  648. /*** OS2: Send bugs to me not to Wayne for the OS/2 version ***/
  649.             printf("\nSend bugs to haen@veces.stgt.sub.org\n") ; FLUSH;
  650.             goto reask_newsgroup;
  651.         default:
  652.             printf("\n%s",hforhelp) ; FLUSH;
  653.             settle_down();
  654.             goto reask_newsgroup;
  655.         }
  656.         }
  657.     } while (retry);
  658.     }
  659.  
  660.     /* now write .newsrc back out */
  661.  
  662.     write_rc();
  663.  
  664.     if (oh_for_the_good_old_days)
  665.     get_old_rc();
  666.  
  667.  
  668. /*** OS2: reset and clear screen ***/
  669.     termlib_reset();
  670.     clear();
  671.  
  672.     finalize(0);            /* and exit */
  673. }
  674.  
  675. /* set current newsgroup */
  676.  
  677. void
  678. set_ngname(what)
  679. char *what;
  680. {
  681.     int len = strlen(what)+1;
  682.  
  683.     growstr(&ngname,&ngnlen,len);
  684.     strcpy(ngname,what);
  685.     growstr(&ngdir,&ngdlen,len);
  686.     strcpy(ngdir,getngdir(ngname));
  687. }
  688.  
  689. static char *myngdir;
  690. static int ngdirlen = 0;
  691.  
  692. char *
  693. getngdir(ngnam)
  694. char *ngnam;
  695. {
  696.     register char *s;
  697.  
  698.     growstr(&myngdir,&ngdirlen,strlen(ngnam)+1);
  699.     strcpy(myngdir,ngnam);
  700.     for (s = myngdir; *s; s++)
  701.     if (*s == '.')
  702.         *s = '/';
  703.     return myngdir;
  704. }
  705.