home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / tin / part02 / spooldir.c next >
Encoding:
C/C++ Source or Header  |  1992-05-20  |  13.9 KB  |  649 lines

  1. /*
  2.  *  Project   : tin - a threaded Netnews reader
  3.  *  Module    : spooldir.c
  4.  *  Author    : I.Lea & Tom Theel
  5.  *  Created   : 08-05-92
  6.  *  Updated   : 13-05-92
  7.  *  Notes     : Changes spooldir to read news from (ie. news, nntp, cdrom)
  8.  *  Copyright : (c) Copyright 1991-92 by Iain Lea & Tom Theel
  9.  *              You may  freely  copy or  redistribute  this software,
  10.  *              so  long as there is no profit made from its use, sale
  11.  *              trade or  reproduction.  You may not change this copy-
  12.  *              right notice, and it must be included in any copy made
  13.  */
  14.  
  15. #include    "tin.h"
  16. #include    "nntplib.h"
  17.  
  18. #define NUM_SPOOLDIRS    50
  19.  
  20. int cur_spoolnum = 0;
  21. int first_spooldir_on_screen;
  22. int last_spooldir_on_screen;
  23. int num_spooldirs = 0;
  24. int spool_top = 0;
  25.  
  26. /*
  27.  * needs to be dynamic but no time 
  28.  */
  29. struct spooldir_t spooldirs[NUM_SPOOLDIRS];
  30.  
  31.  
  32. /*
  33.  * Change spooldir via menu of available choices
  34.  */
  35.  
  36. int spooldir_index ()
  37. {
  38. #ifndef INDEX_DAEMON
  39.  
  40.     char ch;
  41.     int n;
  42.     int scroll_lines;
  43.     
  44.     spool_top = num_spooldirs;
  45.  
  46.     if (! xspooldir_supported) {
  47.         info_message ("Multiple spooldirs are not supported");
  48.         return FALSE;
  49.     }
  50.  
  51.     if (! spool_top) {
  52.         info_message ("No spooldirs");
  53.         return FALSE;
  54.     }
  55.  
  56.     
  57.     mail_setup ();        /* record mailbox size for "you have mail" */
  58.  
  59. #ifndef USE_CLEARSCREEN
  60.     ClearScreen();
  61. #endif
  62.  
  63.     show_spooldir_page ();        /* display spooldir selection page */
  64.     
  65.     while (TRUE) {
  66.         ch = (char) ReadCh ();
  67.  
  68.         if (ch > '0' && ch <= '9') {
  69.             prompt_spooldir_num (ch);
  70.             continue;
  71.         }
  72.         switch (ch) {
  73.             case ESC:    /* (ESC) common arrow keys */
  74.                 switch (get_arrow_key ()) {
  75.                     case KEYMAP_UP:
  76.                         goto spooldir_up;
  77.  
  78.                     case KEYMAP_DOWN:
  79.                         goto spooldir_down;
  80.  
  81.                     case KEYMAP_PAGE_UP:
  82.                         goto spooldir_page_up;
  83.  
  84.                     case KEYMAP_PAGE_DOWN:
  85.                         goto spooldir_page_down;
  86.  
  87.                     case KEYMAP_HOME:
  88.                         if (cur_spoolnum != 0) {
  89.                             if (0 < first_spooldir_on_screen) {
  90. #ifndef USE_CLEARSCREEN
  91.                                 erase_spooldir_arrow ();
  92. #endif                    
  93.                                 cur_spoolnum = 0;
  94.                                 show_spooldir_page ();
  95.                             } else {
  96.                                 erase_spooldir_arrow ();
  97.                                 cur_spoolnum = 0;
  98.                                 draw_spooldir_arrow ();
  99.                             }
  100.                         }
  101.                         break;
  102.                     
  103.                     case KEYMAP_END:
  104.                         goto end_of_list;
  105.                 }
  106.                 break;
  107.  
  108.             case '$':    /* show last page of spooldirs */
  109. end_of_list:
  110.                 if (cur_spoolnum != spool_top - 1) {
  111.                     if (spool_top - 1 > last_spooldir_on_screen) {
  112. #ifndef USE_CLEARSCREEN
  113.                         erase_spooldir_arrow ();
  114. #endif                    
  115.                         cur_spoolnum = spool_top - 1;
  116.                         show_spooldir_page ();
  117.                     } else {
  118.                         erase_group_arrow ();
  119.                         cur_spoolnum = spool_top - 1;
  120.                         draw_spooldir_arrow ();
  121.                     }
  122.                 }
  123.                 break;
  124.  
  125.             case '\r':    /* select spooldir */
  126.             case '\n':
  127.                 if (set_spooldir (spooldirs[cur_spoolnum].name)) {
  128.                     wait_message (txt_reading_active_file);
  129.                     free_active_arrays ();
  130.                     max_active = DEFAULT_ACTIVE_NUM;
  131.                     expand_active ();
  132.                     read_active_file ();
  133.                     read_newsrc (TRUE);
  134.                     return TRUE;
  135.                 }    
  136.                 break;
  137.  
  138.             case ' ':        /* page down */
  139.             case ctrl('D'):        /* vi style */
  140.             case ctrl('V'):        /* emacs style */
  141. spooldir_page_down:
  142.                 if (cur_spoolnum == spool_top - 1) {
  143. #ifdef NO_LOOP_AROUND
  144.                     break;
  145. #else
  146.                     if (0 < first_spooldir_on_screen) {
  147. #    ifndef USE_CLEARSCREEN
  148.                         erase_spooldir_arrow ();
  149. #    endif                    
  150.                         cur_spoolnum = 0;
  151.                         show_spooldir_page ();
  152.                     } else {
  153.                         erase_spooldir_arrow ();
  154.                         cur_spoolnum = 0;
  155.                         draw_spooldir_arrow ();
  156.                     }
  157.                     break;
  158. #endif                    
  159.                 }
  160.                 erase_spooldir_arrow ();
  161.                 scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
  162.                 cur_spoolnum = ((cur_spoolnum + scroll_lines) / scroll_lines) * scroll_lines;
  163.                 if (cur_spoolnum >= spool_top) {
  164.                     cur_spoolnum = (spool_top / scroll_lines) * scroll_lines;
  165.                     if (cur_spoolnum < spool_top - 1) {
  166.                         cur_spoolnum = spool_top - 1;
  167.                     }
  168.                 }
  169.  
  170.                 if (cur_spoolnum <= first_spooldir_on_screen
  171.                 ||  cur_spoolnum >= last_spooldir_on_screen)
  172.                     show_spooldir_page ();
  173.                 else
  174.                     draw_spooldir_arrow ();
  175.                 break;
  176.  
  177.             case ctrl('L'):        /* redraw */
  178. #ifndef USE_CLEARSCREEN
  179.                 ClearScreen ();
  180. #endif
  181.                 show_spooldir_page ();
  182.                 break;
  183.  
  184.             case ctrl('N'):        /* line down */
  185.             case 'j':
  186. spooldir_down:
  187.                 if (cur_spoolnum + 1 >= spool_top) {
  188. #ifdef NO_LOOP_AROUND
  189.                     break;
  190. #else
  191.                     if (0 < first_spooldir_on_screen) {
  192. #    ifndef USE_CLEARSCREEN
  193.                         erase_spooldir_arrow ();
  194. #    endif                    
  195.                         cur_spoolnum = 0;
  196.                         show_spooldir_page ();
  197.                     } else {
  198.                         erase_spooldir_arrow ();
  199.                         cur_spoolnum = 0;
  200.                         draw_spooldir_arrow ();
  201.                     }
  202.                     break;
  203. #endif                    
  204.                 }
  205.                 if (cur_spoolnum + 1 >= last_spooldir_on_screen) {
  206. #ifndef USE_CLEARSCREEN
  207.                     erase_spooldir_arrow ();
  208. #endif                    
  209.                     cur_spoolnum++;
  210.                     show_spooldir_page ();
  211.                 } else {
  212.                     erase_spooldir_arrow ();
  213.                     cur_spoolnum++;
  214.                     draw_spooldir_arrow ();
  215.                 }
  216.                 break;
  217.  
  218.             case ctrl('P'):        /* line up */
  219.             case 'k':
  220. spooldir_up:
  221.                 if (cur_spoolnum == 0) {
  222. #ifdef NO_LOOP_AROUND
  223.                     break;
  224. #else
  225.                     if (spool_top > last_spooldir_on_screen) {
  226.                         cur_spoolnum = spool_top - 1;
  227.                         show_spooldir_page ();
  228.                     } else {
  229.                         erase_spooldir_arrow ();
  230.                         cur_spoolnum = spool_top - 1;
  231.                         draw_spooldir_arrow ();
  232.                     }
  233.                     break;
  234. #endif                    
  235.                 }
  236.                 if (cur_spoolnum <= first_spooldir_on_screen) {
  237.                     cur_spoolnum--;
  238.                     show_spooldir_page ();
  239.                 } else {
  240.                     erase_spooldir_arrow ();
  241.                     cur_spoolnum--;
  242.                     draw_spooldir_arrow ();
  243.                 }
  244.                 break;
  245.  
  246.             case ctrl('U'):        /* page up */
  247.             case 'b':
  248. spooldir_page_up:
  249.                 if (cur_spoolnum == 0) {
  250. #ifdef NO_LOOP_AROUND
  251.                     break;
  252. #else
  253.                     if (spool_top > last_spooldir_on_screen) {
  254.                         cur_spoolnum = spool_top - 1;
  255.                         show_spooldir_page ();
  256.                     } else {
  257.                         erase_spooldir_arrow ();
  258.                         cur_spoolnum = spool_top - 1;
  259.                         draw_spooldir_arrow ();
  260.                     }
  261.                     break;
  262. #endif                    
  263.                 }
  264.                 erase_spooldir_arrow ();
  265.                 scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
  266.                 if ((n = cur_spoolnum % scroll_lines) > 0) {
  267.                     cur_spoolnum = cur_spoolnum - n;
  268.                 } else {
  269.                     cur_spoolnum = ((cur_spoolnum - scroll_lines) / scroll_lines) * scroll_lines;
  270.                 }
  271.                 if (cur_spoolnum < 0) {
  272.                     cur_spoolnum = 0;
  273.                 }
  274.                 if (cur_spoolnum < first_spooldir_on_screen
  275.                 ||  cur_spoolnum >= last_spooldir_on_screen)
  276.                     show_spooldir_page ();
  277.                 else
  278.                     draw_spooldir_arrow ();
  279.                 break;
  280.  
  281.             case 'B':    /* bug/gripe/comment mailed to author */
  282.                 mail_bug_report ();
  283. #ifndef USE_CLEARSCREEN
  284.                 ClearScreen ();
  285. #endif
  286.                 show_spooldir_page ();
  287.                 break;
  288.                 
  289.             case 'h':    /* help */
  290.                 show_info_page (HELP_INFO, help_spooldir, txt_spooldir_com);
  291.                 show_spooldir_page ();
  292.                 break;
  293.  
  294.             case 'I':    /* toggle inverse video */
  295.                 erase_spooldir_arrow ();
  296.                 toggle_inverse_video ();
  297.                 show_spooldir_page ();
  298.                 break;
  299.  
  300.             case 'q':    /* quit */
  301.                 return TRUE;
  302.                 break;
  303.                 
  304.             case 'Q':    /* quit */
  305.                 write_rcfile ();
  306.                 tin_done (0);
  307.                 break;
  308.  
  309.             case 'v':    /* show tin version */
  310.                 info_message (cvers);
  311.                 break;
  312.  
  313.             default:
  314.                 info_message(txt_bad_command);
  315.         }
  316.     }
  317.  
  318. #endif    /* INDEX_DAEMON */
  319. }
  320.  
  321.  
  322. void show_spooldir_page ()
  323. {
  324. #ifndef INDEX_DAEMON
  325.  
  326.     char buf[PATH_LEN];
  327.     int i, j;
  328.     int spoolname_len;
  329.  
  330.     set_signals_spooldir ();
  331.  
  332. #ifdef USE_CLEARSCREEN
  333.     ClearScreen ();
  334. #else
  335.     MoveCursor (0, 0);        /* top left corner */
  336.     CleartoEOLN ();
  337. #endif
  338.  
  339.     sprintf (buf, txt_spooldir_selection, num_spooldirs);
  340.     show_title (buf);
  341.  
  342. #ifndef USE_CLEARSCREEN
  343.     MoveCursor (1, 0);
  344.     CleartoEOLN ();
  345. #endif
  346.  
  347.     MoveCursor (INDEX_TOP, 0);
  348.  
  349.     if (cur_spoolnum >= spool_top) {
  350.         cur_spoolnum = spool_top - 1;
  351.     }
  352.     if (cur_spoolnum < 0) {
  353.         cur_spoolnum = 0;
  354.     }
  355.  
  356.     if (NOTESLINES <= 0) {
  357.         first_spooldir_on_screen = 0;
  358.     } else {
  359.         first_spooldir_on_screen = (cur_spoolnum / NOTESLINES) * NOTESLINES;
  360.         if (first_spooldir_on_screen < 0) {
  361.             first_spooldir_on_screen = 0;
  362.         }
  363.     }
  364.  
  365.     last_spooldir_on_screen = first_spooldir_on_screen + NOTESLINES;
  366.  
  367.     if (last_spooldir_on_screen >= spool_top) {
  368.         last_spooldir_on_screen = spool_top;
  369.         first_spooldir_on_screen = (cur_spoolnum / NOTESLINES) * NOTESLINES;
  370.  
  371.         if (first_spooldir_on_screen == last_spooldir_on_screen ||
  372.             first_spooldir_on_screen < 0) {
  373.             if (first_spooldir_on_screen < 0) {
  374.                 first_spooldir_on_screen = 0;
  375.             } else {
  376.                 first_spooldir_on_screen = last_spooldir_on_screen - NOTESLINES;
  377.             }
  378.         }    
  379.     }
  380.  
  381.     if (spool_top == 0) {
  382.         first_spooldir_on_screen = 0;
  383.         last_spooldir_on_screen = 0;
  384.     }
  385.  
  386.     spoolname_len = COLS - 11;
  387.     
  388.     for (j=0, i = first_spooldir_on_screen; i < last_spooldir_on_screen; i++,j++) {
  389.         sprintf (buf, "%-16.16s  %s", spooldirs[i].name, spooldirs[i].comment);
  390.         sprintf (screen[j].col, "   %4.d  %-*.*s\r\n",
  391.             i+1, spoolname_len, spoolname_len, buf);
  392.         fputs (screen[j].col, stdout);
  393.     }
  394. #ifndef USE_CLEARSCREEN
  395.     CleartoEOS ();
  396. #endif
  397.  
  398.     draw_spooldir_arrow ();
  399.  
  400. #endif    /* INDEX_DAEMON */
  401. }
  402.  
  403.  
  404. int prompt_spooldir_num (ch)
  405.     char ch;
  406. {
  407.     int num;
  408.  
  409.     clear_message ();
  410.  
  411.     if ((num = prompt_num (ch, txt_select_spooldir)) == -1) {
  412.         clear_message ();
  413.         return FALSE;
  414.     }
  415.     num--;        /* index from 0 (internal) vs. 1 (user) */
  416.  
  417.     if (num < 0) {
  418.         num = 0;
  419.     }
  420.     if (num >= spool_top) {
  421.         num = spool_top - 1;
  422.     }
  423.  
  424.     if (num >= first_spooldir_on_screen
  425.     &&  num < last_spooldir_on_screen) {
  426.         erase_spooldir_arrow ();
  427.         cur_spoolnum = num;
  428.         draw_spooldir_arrow ();
  429.     } else {
  430. #ifndef USE_CLEARSCREEN
  431.         erase_spooldir_arrow ();
  432. #endif        
  433.         cur_spoolnum = num;
  434.         show_spooldir_page ();
  435.     }
  436.  
  437.     return TRUE;
  438. }
  439.  
  440.  
  441. void erase_spooldir_arrow ()
  442. {
  443.     erase_arrow (INDEX_TOP + (cur_spoolnum-first_spooldir_on_screen));
  444. }
  445.  
  446.  
  447. void draw_spooldir_arrow()
  448. {
  449.     draw_arrow (INDEX_TOP + (cur_spoolnum-first_spooldir_on_screen));
  450. }
  451.  
  452. /*
  453.  * Load all spooldirs into spooldir[] array
  454.  */
  455.  
  456. int load_spooldirs ()
  457. {
  458.     char comment[PATH_LEN];
  459.     char line[NNTP_STRLEN];
  460.     char name[PATH_LEN];
  461.     char *ptr;
  462.     int i, state;
  463.  
  464. #if 0
  465.     spooldirs = (struct spooldir_t *) 0;
  466. #else
  467.     for (i = 0 ; i < NUM_SPOOLDIRS ; i++) {
  468.         spooldirs[i].state = 0;
  469.         spooldirs[i].name = (char *) 0;
  470.     }
  471. #endif
  472.  
  473.     xspooldir_supported = FALSE;
  474.     
  475.     if (! read_news_via_nntp) {
  476.         return (xspooldir_supported);
  477.     }
  478.  
  479.     put_server ("spooldir list");
  480.     (void) get_server (line, NNTP_STRLEN);
  481.     if (*line != CHAR_OK) {
  482.         xspooldir_supported = FALSE;
  483.         if (debug > 0) {
  484.             fprintf (stderr, "%s", line);
  485.             fprintf (stderr, "Server does not appear to support the spooldir command\n");
  486.             fprintf (stderr, "Reconfigure the news reader or the server & try again.\n");
  487.         }
  488.         return (xspooldir_supported);
  489.     }
  490.     if (debug == 1) {
  491.         wait_message (line);
  492.     }
  493.     
  494.     xspooldir_supported = TRUE;
  495.     
  496.     do {
  497.         get_server (line, NNTP_STRLEN);
  498.         if (line[0] != '.') {
  499.             if (debug == 1) {
  500.                 printf ("%s\n", line);
  501.             }    
  502.             state = atoi (line);
  503.  
  504.             if ((ptr = strchr (line, ' ')) != (char *) 0) {
  505.                 strncpy (name, ++ptr, sizeof (name));
  506.                 ptr = strchr (name, ' ');
  507.                 *ptr = '\0';                
  508.             }
  509.  
  510.             if ((ptr = strchr (line, '[')) != (char *) 0) {
  511.                 strncpy (comment, ++ptr, sizeof (comment));
  512.                 ptr = strchr (comment, ']');
  513.                 *ptr = '\0';                
  514.             }
  515.  
  516. /*                
  517.             spooldirs = (struct spooldir_t *) my_realloc ((char *) spooldirs,
  518.                 (unsigned) sizeof (struct spooldir_t) * num_spooldirs + 1);
  519.             if (spooldirs != (struct spooldir_t *) 0) {
  520.                 spooldirs[num_spooldirs].state = state;
  521.                 spooldirs[num_spooldirs].name = str_dup (name);
  522.                 spooldirs[num_spooldirs].comment = str_dup (comment);
  523.                 num_spooldirs++;
  524.             }    
  525. */                
  526.  
  527.             spooldirs[num_spooldirs].state = state;
  528.             spooldirs[num_spooldirs].name = str_dup (name);
  529.             spooldirs[num_spooldirs].comment = str_dup (comment);
  530.  
  531.             if (debug == 1) {
  532.                 printf ("ALIAS=[%s] COMMENT=[%s]\n", 
  533.                     spooldirs[num_spooldirs].name,
  534.                     spooldirs[num_spooldirs].comment);
  535.             }
  536.             num_spooldirs++;
  537.         }
  538.     } while (!((line[0] == '.') && ((line[1] == '\0') || (line[1] == '\r'))));
  539.  
  540.     return (xspooldir_supported);
  541. }
  542.  
  543. /*
  544.  * Need to select a spooldir directory for reading news from and store all
  545.  * spooldir's in an array for later use when changing spooldir's
  546.  */
  547.  
  548. void get_spooldir ()
  549. {
  550. #ifdef NNTP_ABLE
  551.     char line[NNTP_STRLEN];
  552.     char alias[32];
  553.     char default_alias[32];
  554.     int i, set_alias = FALSE;
  555.     
  556.     default_alias[0] = '\0';
  557.  
  558.     if (! load_spooldirs ()) {
  559.         return;
  560.     }    
  561.  
  562.      /*
  563.       * default to current spooldir from last session or 1st in spooldirs[]
  564.       */
  565.     if (spooldir_alias[0]) {
  566.         my_strncpy (default_alias, spooldir_alias, sizeof (default_alias));
  567.     } else {
  568.         my_strncpy (default_alias, spooldirs[0].name, sizeof (default_alias));
  569.     }
  570.  
  571.     /*
  572.      * Try to use default spooldir. If that fails go through spooldir list
  573.      * looking for first available spooldir.
  574.      */
  575.     if (! set_spooldir (spooldir_alias)) {
  576.         for (i = 0 ; spooldirs[i].name != (char *) 0 ; i++) {
  577.             if (set_spooldir (spooldirs[i].name)) {
  578.                 set_alias = TRUE;
  579.                 break;
  580.             }
  581.         }
  582.         if (! set_alias) {
  583.             error_message ("%s: Cannot change to valid spooldir. Exiting...", progname);
  584.             exit (1);            
  585.         }
  586.     }
  587.  
  588. #if 0     
  589.     do {
  590.         printf ("Which spooldir [%s] ? ", default_alias);
  591.         gets (alias);
  592.         if (alias[0] == '\0') {
  593.             strcpy (alias, default_alias); 
  594.         } else if ((alias[0] == 'q') && (alias[1] == '\0')) {
  595.             exit(0); /* allow user to quit */
  596.         }    
  597.         sprintf (line, "spooldir %s", alias);
  598.         put_server (line);
  599.         (void) get_server (line, NNTP_STRLEN);
  600.         printf ("\r\n%s\r\n", line);
  601.     } while (line[0] != CHAR_OK);
  602. #endif
  603.  
  604.     /*
  605.      * And now set tin to act as though it is reading via NNTP
  606.      */
  607.     read_news_via_nntp = TRUE;
  608.  
  609. #endif /* NNTP_ABLE */
  610. }
  611.  
  612. /*
  613.  * Change to specified spooldir if everythings OK.
  614.  */
  615.  
  616. int set_spooldir (name)
  617.     char *name;
  618. {
  619.     char line[NNTP_STRLEN];
  620.     int respcode;
  621.  
  622.     if (cmd_line) {
  623.         sprintf (line, "Changing spooldir to %s...\n", name);
  624.     } else {
  625.         sprintf (line, "Changing spooldir to %s...", name);
  626.     }    
  627.     wait_message (line);
  628.  
  629.     sprintf (line, "spooldir %s", name);
  630.     debug_nntp ("set_spooldir", line);
  631.     put_server (line);
  632.     debug_nntp ("set_spooldir", line);
  633.  
  634.     respcode = get_respcode ();
  635.     switch (respcode) {
  636.         case OK_SPSWITCH:    /* Switching to a different spooldir */
  637.             my_strncpy (spooldir_alias, name, sizeof (spooldir_alias));
  638.             set_tindir ();
  639.             return TRUE;
  640.             break;
  641.         case OK_SPNOCHANGE:    /* Still using same spooldir */
  642.             break;
  643.         default:
  644.             error_message ("%s", nntp_respcode (respcode));
  645.             return FALSE;
  646.             break;        
  647.     }
  648. }
  649.