home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / trn / part11 / ngstuff.c < prev    next >
C/C++ Source or Header  |  1991-08-22  |  11KB  |  531 lines

  1. /* $Header: ngstuff.c,v 4.3.3.3 91/01/16 03:18:25 davison Trn $
  2.  *
  3.  * $Log:    ngstuff.c,v $
  4.  * Revision 4.3.3.3  91/01/16  03:18:25  davison
  5.  * Changed some expressions to registers to bypass a compiler problem.
  6.  * 
  7.  * Revision 4.3.3.2  90/08/20  18:29:08  davison
  8.  * Expanded path arrays for consistancy.
  9.  * 
  10.  * Revision 4.3.3.1  90/07/21  20:29:12  davison
  11.  * Initial Trn Release
  12.  * 
  13.  * Revision 4.3.2.2  90/04/14  19:40:02  sob
  14.  * Fixed small syntax problem that generates errors with particular C
  15.  * preprocessors.
  16.  *
  17.  * Revision 4.3.1.2  85/05/10  14:31:52  lwall
  18.  * Prevented "Junked" or "Marked unread" when no state change.
  19.  * 
  20.  * Revision 4.3.1.1  85/05/10  11:36:45  lwall
  21.  * Branch for patches.
  22.  * 
  23.  * Revision 4.3  85/05/01  11:45:03  lwall
  24.  * Baseline for release with 4.3bsd.
  25.  * 
  26.  */
  27.  
  28. #include "EXTERN.h"
  29. #include "common.h"
  30. #include "term.h"
  31. #include "util.h"
  32. #include "ng.h"
  33. #include "bits.h"
  34. #include "intrp.h"
  35. #include "cheat.h"
  36. #include "head.h"
  37. #include "final.h"
  38. #include "sw.h"
  39. #ifdef USETHREADS
  40. #include "rthreads.h"
  41. #include "rn.h"
  42. #include "rcstuff.h"
  43. #endif
  44. #include "uudecode.h"
  45. #include "INTERN.h"
  46. #include "ngstuff.h"
  47.  
  48. void
  49. ngstuff_init()
  50. {
  51.     ;
  52. }
  53.  
  54. /* do a shell escape */
  55.  
  56. int
  57. escapade()
  58. {
  59.     register char *s;
  60.     bool interactive = (buf[1] == FINISHCMD);
  61.     bool docd;
  62.     char whereiam[512];
  63.  
  64.     if (!finish_command(interactive))    /* get remainder of command */
  65.     return -1;
  66.     s = buf+1;
  67.     docd = *s != '!';
  68.     if (!docd) {
  69.     s++;
  70.     }
  71.     else {
  72.     getwd(whereiam);
  73.     if (chdir(cwd)) {
  74.         printf(nocd,cwd) FLUSH;
  75.         sig_catcher(0);
  76.     }
  77.     }
  78.     while (*s == ' ') s++;
  79.                     /* skip leading spaces */
  80.     interp(cmd_buf, (sizeof cmd_buf), s);/* interpret any % escapes */
  81.     resetty();                /* make sure tty is friendly */
  82.     doshell(Nullch,cmd_buf);    /* invoke the shell */
  83.     noecho();                /* and make terminal */
  84.     crmode();                /*   unfriendly again */
  85.     if (docd) {
  86.     if (chdir(whereiam)) {
  87.         printf(nocd,whereiam) FLUSH;
  88.         sig_catcher(0);
  89.     }
  90.     }
  91. #ifdef MAILCALL
  92.     mailcount = 0;            /* force recheck */
  93. #endif
  94.     return 0;
  95. }
  96.  
  97. /* process & command */
  98.  
  99. int
  100. switcheroo()
  101. {
  102.     if (!finish_command(TRUE)) /* get rest of command */
  103.     return -1;    /* if rubbed out, try something else */
  104.     if (!buf[1])
  105.     pr_switches();
  106. #ifdef PUSHBACK
  107.     else if (buf[1] == '&') {
  108.     if (!buf[2]) {
  109.         page_init();
  110.         show_macros();
  111.     }
  112.     else {
  113.         char tmpbuf[LBUFLEN];
  114.         register char *s;
  115.  
  116.         for (s=buf+2; isspace(*s); s++);
  117.         mac_line(s,tmpbuf,(sizeof tmpbuf));
  118.     }
  119.     }
  120. #endif
  121.     else {
  122.     bool docd = (instr(buf,"-d") != Nullch);
  123.      char whereami[512];
  124.  
  125.     if (docd)
  126.         getwd(whereami);
  127.     sw_list(buf+1);
  128.     if (docd) {
  129.         cwd_check();
  130.         if (chdir(whereami)) {        /* -d does chdirs */
  131.         printf(nocd,whereami) FLUSH;
  132.         sig_catcher(0);
  133.         }
  134.     }
  135.     }
  136.     return 0;
  137. }
  138.  
  139. /* process range commands */
  140.  
  141. int
  142. numnum()
  143. {
  144.     ART_NUM min, max;
  145.     char *cmdlst = Nullch;
  146.     register char *s, *c;
  147.     ART_NUM oldart = art;
  148.     char tmpbuf[LBUFLEN];
  149.     bool justone = TRUE;        /* assume only one article */
  150.  
  151.     perform_cnt = 0;
  152.     if (!finish_command(TRUE))    /* get rest of command */
  153.     return NN_INP;
  154.     if (lastart < 1) {
  155.         fputs("\nNo articles\n",stdout) FLUSH;
  156.         return NN_ASK;
  157.     }
  158. #ifdef ARTSRCH
  159.     if (srchahead)
  160.     srchahead = -1;
  161. #endif
  162.     for (s=buf; *s && (isdigit(*s) || index(" ,-.$",*s)); s++)
  163.     if (!isdigit(*s))
  164.         justone = FALSE;
  165.     if (*s) {
  166.     cmdlst = savestr(s);
  167.     justone = FALSE;
  168.     }
  169.     else if (!justone)
  170.     cmdlst = savestr("m");
  171.     *s++ = ',';
  172.     *s = '\0';
  173.     safecpy(tmpbuf,buf,LBUFLEN);
  174.     for (s = tmpbuf; c = index(s,','); s = ++c) {
  175.     *c = '\0';
  176.     if (*s == '.')
  177.         min = oldart;
  178.     else
  179.         min = atol(s);
  180. #ifdef USETHREADS
  181.     if (min<absfirst && justone) {
  182.         int r;
  183.  
  184.         /* Check if this is a root number */
  185.         for (r = 0; r < total.root; r++) {
  186.         if (p_roots[r].root_num == min) {
  187.             p_art = p_articles + p_roots[r].articles;
  188.             art = p_art->num;
  189.             if (p_art->subject == -1) {
  190.             follow_thread('N');
  191.             }
  192.             return NN_REREAD;
  193.         }
  194.         }
  195.     }
  196. #endif
  197.     if (min<absfirst) {        /* make sure it is reasonable */
  198.         min = absfirst;
  199.         printf("(First article is %ld)\n",(long)absfirst) FLUSH;
  200.         pad(just_a_sec/3);
  201.     }
  202.     if ((s=index(s,'-')) != Nullch) {
  203.         s++;
  204.         if (*s == '$')
  205.         max = lastart;
  206.         else if (*s == '.')
  207.         max = oldart;
  208.         else
  209.         max = atol(s);
  210.     }
  211.     else
  212.         max = min;
  213.     if (max>lastart) {
  214.         max = lastart;
  215.         if (min > max)
  216.         min = max;
  217.         printf("(Last article is %ld)\n",(long)lastart) FLUSH;
  218.         pad(just_a_sec/3);
  219.     }
  220.     if (max < min) {
  221.         fputs("\nBad range\n",stdout) FLUSH;
  222.         if (cmdlst)
  223.         free(cmdlst);
  224.         return NN_ASK;
  225.     }
  226.     if (justone) {
  227.         art = min;
  228.         return NN_REREAD;
  229.     }
  230.     check_first(min);
  231.     for (art=min; art<=max; art++) {
  232.         if (perform(cmdlst,TRUE)) {
  233. #ifdef VERBOSE
  234.         IF(verbose)
  235.             printf("\n(Interrupted at article %ld)\n",(long)art)
  236.               FLUSH;
  237.         ELSE
  238. #endif
  239. #ifdef TERSE
  240.             printf("\n(Intr at %ld)\n",(long)art) FLUSH;
  241. #endif
  242.         if (cmdlst)
  243.             free(cmdlst);
  244.         return NN_ASK;
  245.         }
  246.     }
  247.     }
  248.     art = oldart;
  249.     if (cmdlst)
  250.     free(cmdlst);
  251.     return NN_NORM;
  252. }
  253.  
  254. #ifdef USETHREADS
  255. int
  256. use_selected()
  257. {
  258.     PACKED_ARTICLE *root_limit;
  259.     register char *s, ch;
  260.     register int r;
  261.     char *cmdstr;
  262.     int ret = 1, orig_root_cnt = selected_root_cnt;
  263.  
  264.     if (!finish_command(TRUE))    /* get rest of command */
  265.     return 0;
  266.     if (!(ch = buf[1]))
  267.     return -1;
  268.     cmdstr = savestr(buf+1);
  269.  
  270.     perform_cnt = 0;
  271.     page_line = 1;
  272.  
  273.     /* Multiple commands and commands that operate on individual articles
  274.     ** use the article loop.
  275.     */
  276.     if (strlen(cmdstr) > 1 || index("ejmMsSwW|=", ch)) {
  277.     bool want_unread = (unread_selector || ch == 'm');
  278.  
  279.     for (r = 0; r < total.root; r++) {
  280.         if (scan_all_roots
  281.          || (!orig_root_cnt&&root_article_cnts[r]&&!(selected_roots[r]&4))
  282.          || (selected_roots[r] & (unread_selector+1))) {
  283.         p_art = p_articles + p_roots[r].articles;
  284.         root_limit = upper_limit( p_art, 0 );
  285.         for (; p_art < root_limit; p_art++) {
  286.             art = p_art->num;
  287.             if (p_art->subject != -1
  288.              && (!was_read(art) ^ want_unread)) {
  289.             if (perform(cmdstr, TRUE)) {
  290.                 fputs("\nInterrupted\n", stdout) FLUSH;
  291.                 goto break_out;
  292.             }
  293.             }
  294.             if (p_art == Nullart)
  295.             break;
  296.         }/* for all articles */
  297.         }/* if selected */
  298.     }/* for all threads */
  299.     }                /* other commands get the root loop */
  300.     else if (ch == '+' || ch == '-' || ch == 'J' || ch == 'T' || ch == 't') {
  301.     for (r = 0; r < total.root; r++) {
  302.         if (scan_all_roots
  303.          || (!orig_root_cnt&&root_article_cnts[r]&&!(selected_roots[r]&4))
  304.          || (selected_roots[r] & (unread_selector+1))) {
  305.         if (mode != 't' && ch != 't') {
  306.             printf("T%-5ld ", (long)p_roots[r].root_num);
  307.         }
  308.         p_art = p_articles + p_roots[r].articles;
  309.         art = p_art->num;
  310.         if (perform(cmdstr, FALSE)) {
  311.             fputs("\nInterrupted\n", stdout) FLUSH;
  312.             goto break_out;
  313.         }
  314. #ifdef VERBOSE
  315.         IF(verbose)
  316.             if (mode != 't' && ch != 't' && ch != 'T')
  317.             putchar('\n') FLUSH;
  318. #endif
  319.         }
  320.     }
  321.     }
  322.     else if (ch == 'E') {    /* one command needs no looping at all */
  323.     if (uu_out != Nullfp) {
  324.         uud_end();
  325.     } else {
  326.         ret = 2;
  327.     }
  328.     }
  329.     else {
  330.     printf("???%s\n",cmdstr);
  331.     ret = -1;
  332.     }
  333.   break_out:
  334.     free(cmdstr);
  335.     return ret;
  336. }
  337. #endif
  338.  
  339. int
  340. perform(cmdlst,toplevel)
  341. register char *cmdlst;
  342. int toplevel;
  343. {
  344.     register int ch;
  345.     
  346.     if (toplevel) {
  347.     printf("%-6ld ",art);
  348.     fflush(stdout);
  349.     }
  350.     perform_cnt++;
  351.     for (; ch = *cmdlst; cmdlst++) {
  352.     if (isspace(ch) || ch == ':')
  353.         continue;
  354.     if (ch == 'j') {
  355.         if (!was_read(art)) {
  356.         mark_as_read();
  357. #ifdef VERBOSE
  358.         IF(verbose)
  359.             fputs("\tJunked",stdout);
  360. #endif
  361.         }
  362.     }
  363. #ifdef USETHREADS
  364.     else if (ch == '+') {
  365.       register char mask = unread_selector+1;
  366.         find_article(art);
  367.         if (p_art && !(selected_roots[p_art->root] & mask)) {
  368.           register int r = p_art->root;
  369.         selected_roots[r] |= mask;
  370.         selected_root_cnt++;
  371.         if (mode == 't') {
  372.             selected_count += root_article_cnts[r];
  373.         } else {
  374.             selected_count += count_one_root(r);
  375. #ifdef VERBOSE
  376.             IF(verbose)
  377.             fputs("\tSelected",stdout);
  378. #endif
  379.         }
  380.         }
  381.     }
  382.     else if (ch == '-') {
  383.       register char mask = unread_selector+1;
  384.         find_article(art);
  385.         if (p_art && selected_root_cnt
  386.          && (selected_roots[p_art->root] & mask)) {
  387.           register int r = p_art->root;
  388.         selected_roots[r] &= ~mask;
  389.         selected_root_cnt--;
  390.         if (mode == 't') {
  391.             selected_count -= root_article_cnts[r];
  392.         } else {
  393.             selected_count -= count_one_root(r);
  394. #ifdef VERBOSE
  395.             IF(verbose)
  396.             fputs("\tDeselected",stdout);
  397. #endif
  398.         }
  399.         }
  400.     }
  401.     else if (ch == 't') {
  402.         find_article(art);
  403.         entire_tree();
  404.     }
  405.     else if (ch == 'J' || ch == 'T') {
  406.         char tmpbuf[128];
  407.         ART_NUM oldart = art;
  408.  
  409.         find_article(art);
  410.         if (p_art) {
  411.         if (ch == 'T') {
  412.             sprintf(tmpbuf,"T%ld\t# %s",
  413.             (long)p_roots[p_art->root].root_num,
  414.             subject_ptrs[p_art->subject]);
  415.             fputs(tmpbuf,stdout);
  416.             kf_append(tmpbuf);
  417.         }
  418.         follow_thread('J');
  419.         art = oldart;
  420.         }
  421.     }
  422. #endif
  423.     else if (ch == 'm') {
  424.         if (was_read(art)) {
  425.         unmark_as_read();
  426. #ifdef VERBOSE
  427.         IF(verbose)
  428.             fputs("\tMarked unread",stdout);
  429. #endif
  430.         }
  431.     }
  432.     else if (ch == 'M') {
  433. #ifdef DELAYMARK
  434.         delay_unmark(art);
  435. #ifdef VERBOSE
  436.         IF(verbose)
  437.         fputs("\tWill return",stdout);
  438. #endif
  439. #else
  440.         notincl("M");
  441.         return -1;
  442. #endif
  443.     }
  444.     else if (ch == '=') {
  445.         printf("\t%s",fetchsubj(art,FALSE,FALSE));
  446. #ifdef VERBOSE
  447.         IF(verbose)
  448.         ;
  449.         ELSE
  450. #endif
  451.         putchar('\n') FLUSH;        /* ghad! */
  452.     }
  453.     else if (ch == 'C') {
  454. #ifdef ASYNC_PARSE
  455.         printf("\t%sancelled",(cancel_article() ? "Not c" : "C"));
  456. #else
  457.         notincl("C");
  458.         return -1;
  459. #endif
  460.     }
  461.     else if (ch == '%') {
  462. #ifdef ASYNC_PARSE
  463.         char tmpbuf[512];
  464.  
  465.         if (one_command)
  466.         interp(tmpbuf, (sizeof tmpbuf), cmdlst);
  467.         else
  468.         cmdlst = dointerp(tmpbuf, (sizeof tmpbuf), cmdlst, ":") - 1;
  469.         perform_cnt--;
  470.         if (perform(tmpbuf,FALSE))
  471.         return -1;
  472. #else
  473.         notincl("%");
  474.         return -1;
  475. #endif
  476.     }
  477.     else if (index("!&sSwWe|",ch)) {
  478.         if (one_command)
  479.         strcpy(buf,cmdlst);
  480.         else
  481.         cmdlst = cpytill(buf,cmdlst,':') - 1;
  482.         /* we now have the command in buf */
  483.         if (ch == '!') {
  484.         escapade();
  485. #ifdef VERBOSE
  486.         IF(verbose)
  487.             fputs("\tShell escaped",stdout);
  488. #endif
  489.         }
  490.         else if (ch == '&') {
  491.         switcheroo();
  492. #ifdef VERBOSE
  493.         IF(verbose)
  494.             if (buf[1] && buf[1] != '&')
  495.             fputs("\tSwitched",stdout);
  496. #endif
  497.         }
  498.         else {
  499.         putchar('\t');
  500.         save_article();
  501. #ifdef VERBOSE
  502.         IF(verbose)
  503.             ;
  504.         ELSE
  505. #endif
  506.             putchar('\n') FLUSH;
  507.         }
  508.     }
  509.     else {
  510.         printf("\t???%s\n",cmdlst);
  511.         return -1;
  512.     }
  513. #ifdef VERBOSE
  514.     fflush(stdout);
  515. #endif
  516.     if (one_command)
  517.         break;
  518.     }
  519.     if (toplevel) {
  520. #ifdef VERBOSE
  521.     IF(verbose)
  522.         putchar('\n') FLUSH;
  523. #endif
  524.     }
  525.     if( int_count ) {
  526.     int_count = 0;
  527.     return -1;
  528.     }
  529.     return 0;
  530. }
  531.