home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-22 | 50.4 KB | 2,200 lines |
- Newsgroups: comp.sources.misc
- From: iain%estevax.uucp@unido.Informatik.Uni-Dortmund.DE (Iain Lea)
- Subject: v28i048: tin - threaded full screen newsreader v1.1, Part04/11
- Message-ID: <1992Feb18.043700.13011@sparky.imd.sterling.com>
- X-Md4-Signature: e4e1bb749ad26711a058e20a6a7b26a6
- Date: Tue, 18 Feb 1992 04:37:00 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: iain%estevax.uucp@unido.Informatik.Uni-Dortmund.DE (Iain Lea)
- Posting-number: Volume 28, Issue 48
- Archive-name: tin/part04
- Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
- Supersedes: tin: Volume 23, Issue 15-23
-
- #!/bin/sh
- # this is tin.shar.04 (part 4 of tin1.1)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file feed.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 4; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping feed.c'
- else
- echo 'x - continuing file feed.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'feed.c' &&
- X } else {
- X if (default_save_file[0]) {
- X strcpy (file, default_save_file);
- X } else {
- X info_message (txt_no_filename);
- X return;
- X }
- X }
- X for (p = file; *p && (*p == ' ' || *p == '\t'); p++) {
- X continue;
- X }
- X if (! *p) {
- X info_message (txt_no_filename);
- X return;
- X }
- X if ((file[0] == '~' || file[0] == '+') && strlen (file) == 1) {
- X info_message (txt_no_filename);
- X return;
- X }
- X is_mailbox = create_path (file);
- X if (is_mailbox) {
- X if ((int) strlen (file) > 1) {
- X my_strncpy (mailbox, file+1, LEN);
- X } else {
- X my_strncpy (mailbox, glob_group, LEN);
- X /*
- X * convert 1st letter to uppercase
- X */
- X if (mailbox[0] >= 'a' && mailbox[0] <= 'z') {
- X mailbox[0] = mailbox[0] - 32;
- X }
- X }
- X my_strncpy (file, mailbox, LEN);
- X } else { /* ask for post processing type */
- X do {
- X sprintf (msg, "%s%c", txt_post_process_type, proc_ch_default);
- X wait_message (msg);
- X MoveCursor (LINES, (int) strlen (msg)-1);
- X if ((proc_ch = (char) ReadCh ()) == CR)
- X proc_ch = proc_ch_default;
- X } while (proc_ch != 'n' && proc_ch != 's' &&
- X proc_ch != 'u' && proc_ch != 'U');
- X }
- X }
- X clear_message ();
- X break;
- X }
- X
- X switch (ch) {
- X case 'a': /* article */
- X if (level == GROUP_LEVEL) {
- X art_open (arts[respnum].artnum, group_path);
- X }
- X switch (function) {
- X case FEED_MAIL:
- X redraw_screen = mail_to_someone (address);
- X break;
- X case FEED_PIPE:
- X fseek (note_fp, 0L, 0);
- X copy_fp (note_fp, fp, (char *) 0);
- X break;
- X case FEED_PRINT:
- X wait_message (txt_printing);
- X if (print_header) {
- X fseek (note_fp, 0L, 0);
- X } else {
- X fprintf (fp, "From: %s (%s)\n",
- X arts[respnum].from,arts[respnum].name);
- X fprintf (fp, "Subject: %s\n", note_h_subj);
- X fprintf (fp, "Date: %s\n\n", note_h_date);
- X fseek (note_fp, note_mark[0], 0);
- X }
- X copy_fp (note_fp, fp, (char *) 0);
- X pclose (fp);
- X break;
- X case FEED_SAVE:
- X wait_message (txt_saving);
- X add_to_save_list (0, &arts[respnum], is_mailbox, file);
- X (void) save_art_to_file (respnum, 0, FALSE, (char *) 0);
- X break;
- X }
- X if (mark_saved_read) {
- X arts[respnum].unread = ART_READ;
- X }
- X if (level == GROUP_LEVEL) {
- X art_close ();
- X }
- X break;
- X
- X case 't': /* thread */
- X for (i = (int) base[b]; i >= 0; i = arts[i].thread) {
- X if (function == FEED_PRINT) {
- X if ((fp = popen (command, "w")) == NULL) {
- X error_message (txt_command_failed_s, command);
- X return;
- X }
- X }
- X if (level == PAGE_LEVEL) {
- X art_close ();
- X }
- X art_open (arts[i].artnum, group_path);
- X switch (function) {
- X case FEED_MAIL:
- X mail_to_someone (address);
- X break;
- X case FEED_PIPE:
- X fseek (note_fp, 0L, 0);
- X copy_fp (note_fp, fp, (char *) 0);
- X break;
- X case FEED_PRINT:
- X sprintf (msg, "%s%d", txt_printing, count++);
- X wait_message (msg);
- X if (print_header) {
- X fseek(note_fp, 0L, 0);
- X } else {
- X fprintf (fp, "From: %s (%s)\n",
- X arts[respnum].from,arts[respnum].name);
- X fprintf (fp, "Subject: %s\n", note_h_subj);
- X fprintf (fp, "Date: %s\n\n", note_h_date);
- X fseek (note_fp, note_mark[0], 0);
- X }
- X copy_fp (note_fp, fp, (char *) 0);
- X pclose (fp);
- X break;
- X case FEED_SAVE:
- X add_to_save_list (i, &arts[i], is_mailbox, file);
- X break;
- X }
- X if (mark_saved_read) {
- X arts[i].unread = ART_READ;
- X }
- X art_close ();
- X }
- X if (function == FEED_SAVE) {
- X sort_save_list ();
- X (void) save_thread_to_file (is_mailbox, group_path);
- X }
- X break;
- X
- X case 'T': /* tagged articles */
- X for (i=1 ; i <= num_of_tagged_files ; i++) {
- X for (j=0 ; j < top ; j++) {
- X if (arts[j].tagged && arts[j].tagged == i) {
- X if (function == FEED_PRINT) {
- X if ((fp = popen (command, "w")) == NULL) {
- X error_message (txt_command_failed_s, command);
- X return;
- X }
- X }
- X if (level == PAGE_LEVEL) {
- X art_close ();
- X }
- X art_open (arts[j].artnum, group_path);
- X switch (function) {
- X case FEED_MAIL:
- X mail_to_someone (address);
- X break;
- X case FEED_PIPE:
- X fseek (note_fp, 0L, 0);
- X copy_fp (note_fp, fp, (char *) 0);
- X break;
- X case FEED_PRINT:
- X sprintf (msg, "%s%d", txt_printing, count++);
- X wait_message (msg);
- X if (print_header) {
- X fseek(note_fp, 0L, 0);
- X } else {
- X fprintf (fp, "From: %s (%s)\n",
- X arts[respnum].from,arts[respnum].name);
- X fprintf (fp, "Subject: %s\n", note_h_subj);
- X fprintf (fp, "Date: %s\n\n", note_h_date);
- X fseek (note_fp, note_mark[0], 0);
- X }
- X copy_fp (note_fp, fp, (char *) 0);
- X pclose (fp);
- X break;
- X case FEED_SAVE:
- X add_to_save_list (j, &arts[j], is_mailbox, file);
- X break;
- X }
- X if (mark_saved_read) {
- X arts[j].unread = ART_READ;
- X }
- X art_close ();
- X }
- X }
- X }
- X if (function == FEED_SAVE) {
- X (void) save_regex_arts (is_mailbox, group_path);
- X }
- X break;
- X
- X case 'r': /* regex pattern matched articles */
- X patlen = strlen (pattern);
- X for (i=0 ; i < top ; i++) {
- #ifdef NO_REGEX
- X if (str_str (arts[i].subject, pattern, patlen) != 0) {
- #else
- X if (wildmat (arts[i].subject, pattern)) {
- #endif
- X if (function == FEED_PRINT) {
- X if ((fp = popen (command, "w")) == NULL) {
- X error_message (txt_command_failed_s, command);
- X return;
- X }
- X }
- X if (level == PAGE_LEVEL) {
- X art_close ();
- X }
- X art_open (arts[i].artnum, group_path);
- X switch (function) {
- X case FEED_MAIL:
- X mail_to_someone (address);
- X break;
- X case FEED_PIPE:
- X fseek (note_fp, 0L, 0);
- X copy_fp (note_fp, fp, (char *) 0);
- X break;
- X case FEED_PRINT:
- X sprintf (msg, "%s%d", txt_printing, count++);
- X wait_message (msg);
- X if (print_header) {
- X fseek(note_fp, 0L, 0);
- X } else {
- X fprintf (fp, "From: %s (%s)\n",
- X arts[respnum].from,arts[respnum].name);
- X fprintf (fp, "Subject: %s\n", note_h_subj);
- X fprintf (fp, "Date: %s\n\n", note_h_date);
- X fseek (note_fp, note_mark[0], 0);
- X }
- X copy_fp (note_fp, fp, (char *) 0);
- X pclose (fp);
- X break;
- X case FEED_SAVE:
- X add_to_save_list (i, &arts[i], is_mailbox, file);
- X break;
- X }
- X if (mark_saved_read) {
- X arts[i].unread = ART_READ;
- X }
- X art_close ();
- X }
- X }
- X if (function == FEED_SAVE) {
- X sort_save_list ();
- X (void) save_regex_arts (is_mailbox, group_path);
- X }
- X break;
- X }
- X
- X redraw_screen = mail_check (); /* in case of sending to oneself */
- X
- X switch (function) {
- X case FEED_PIPE:
- X pclose (fp);
- X Raw (TRUE);
- X continue_prompt ();
- X redraw_screen = TRUE;
- X break;
- X case FEED_SAVE:
- X if (proc_ch != 'n' && is_mailbox == FALSE) {
- X ret2 = post_process_files (proc_ch);
- X }
- X free_save_array ();
- X break;
- X }
- X
- X untag_all_articles ();
- X
- X if (level == GROUP_LEVEL) {
- X ret1 = (mark_saved_read ? TRUE : FALSE);
- X }
- X if ((ret1 || ret2) && is_mailbox == FALSE) {
- X redraw_screen = TRUE;
- X }
- X
- X if (level == PAGE_LEVEL) {
- X if (ch != 'a') {
- X art_open (arts[respnum].artnum, group_path);
- X }
- X note_end = orig_note_end;
- X note_page = orig_note_page;
- X fseek (note_fp, note_mark[note_page], 0);
- X if (redraw_screen) {
- X if (note_page == 0) {
- X show_note_page (respnum, glob_group);
- X } else {
- X redraw_page (respnum, glob_group);
- X }
- X } else {
- X if (function == FEED_PIPE) {
- X clear_message ();
- X }
- X }
- X } else {
- X if (redraw_screen) {
- X show_group_page (glob_group);
- X }
- X }
- X if (function == FEED_PRINT) {
- X info_message (txt_printed);
- X }
- }
- SHAR_EOF
- echo 'File feed.c is complete' &&
- chmod 0600 feed.c ||
- echo 'restore of feed.c failed'
- Wc_c="`wc -c < 'feed.c'`"
- test 12822 -eq "$Wc_c" ||
- echo 'feed.c: original size 12822, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= getline.c ==============
- if test -f 'getline.c' -a X"$1" != X"-c"; then
- echo 'x - skipping getline.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting getline.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'getline.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : getline.c
- X * Author : Chris Thewalt / Iain Lea
- X * Created : 09-11-91
- X * Updated : 29-11-91
- X * Notes : emacs style line editing input package.
- X * Copyright : (c) Copyright 1991-92 by Chris Thewalt & Iain Lea
- X * Permission to use, copy, modify, and distribute this
- X * software for any purpose and without fee is hereby
- X * granted, provided that the above copyright notices
- X * appear in all copies and that both the copyright
- X * notice and this permission notice appear in supporting
- X * documentation. This software is provided "as is" without\
- X * express or implied warranty.
- X */
- X
- #include "tin.h"
- X
- extern int isatty ();
- X
- #define BUF_SIZE 1024
- #define SCROLL 30
- #define TABSIZE 4
- #ifndef HIST_SIZE
- #define HIST_SIZE 100
- #endif
- X
- #define CTRL_A '\001'
- #define CTRL_B '\002'
- #define CTRL_D '\004'
- #define CTRL_E '\005'
- #define CTRL_F '\006'
- #define CTRL_H '\010'
- #define CTRL_K '\013'
- #define CTRL_L '\014'
- #define CTRL_R '\022'
- #define CTRL_N '\016'
- #define CTRL_P '\020'
- #define TAB '\t'
- #define DEL '\177'
- X
- char *hist_buf[HIST_SIZE];
- int hist_pos, hist_last;
- static char gl_buf[BUF_SIZE]; /* input buffer */
- static char *gl_prompt; /* to save the prompt string */
- static int gl_init_done = 0; /* -1 is terminal, 1 is batch */
- static int gl_width = 0; /* net size available for input */
- static int gl_pos, gl_cnt = 0; /* position and size of input */
- X
- #if __STDC__
- X
- static int gl_tab (char *, int, int *);
- static void gl_redraw (void);
- static void gl_addchar (int);
- static void gl_newline (void);
- static void gl_fixup (int, int);
- static void gl_del (int);
- static void gl_kill (void);
- static void hist_add (void);
- static void hist_init (void);
- static void hist_next (void);
- static void hist_prev (void);
- X
- int (*gl_in_hook)(char *) = 0;
- int (*gl_out_hook)(char *) = 0;
- int (*gl_tab_hook)(char *, int, int *) = gl_tab;
- X
- #else
- X
- static int gl_tab ();
- static void gl_redraw ();
- static void gl_addchar ();
- static void gl_newline ();
- static void gl_fixup ();
- static void gl_del ();
- static void gl_kill ();
- static void hist_add ();
- static void hist_init ();
- static void hist_next ();
- static void hist_prev ();
- X
- int (*gl_in_hook)() = 0;
- int (*gl_out_hook)() = 0;
- int (*gl_tab_hook)() = gl_tab;
- X
- #endif
- X
- X
- #if __STDC__
- char *getline (char *prompt, int number_only, char *str)
- #else
- char *getline (prompt, number_only, str)
- X char *prompt;
- X int number_only;
- X char *str;
- #endif
- {
- X int c, i, loc, tmp;
- X
- X if (! gl_init_done) {
- X gl_init_done = 1;
- X hist_init ();
- X }
- X
- X gl_buf[0] = 0; /* used as end of input indicator */
- X gl_fixup (-1, 0); /* this resets gl_fixup */
- X gl_width = COLS - strlen (prompt);
- X if (prompt == (char *) 0) {
- X prompt = "";
- X }
- X gl_prompt = prompt;
- X gl_pos = gl_cnt = 0;
- X
- X fputs (prompt, stdout);
- X fflush (stdout);
- X
- X if (gl_in_hook) {
- X loc = gl_in_hook (gl_buf);
- X if (loc >= 0)
- X gl_fixup (0, BUF_SIZE);
- X }
- X if (str != (char *) 0) {
- X for (i=0 ; str[i] ; i++)
- X gl_addchar (str[i]);
- X }
- X while ((c = ReadCh ()) != EOF) {
- X if (isprint (c)) {
- X if (number_only) {
- X if (isdigit (c) && gl_cnt < 6) { /* num < 100000 */
- X gl_addchar (c);
- X } else {
- X ring_bell ();
- X }
- X } else {
- X gl_addchar (c);
- X }
- X } else {
- X switch (c) {
- X case ESC: /* abort */
- X return (char *) 0;
- X break;
- X case '\n': /* newline */
- X case '\r':
- X gl_newline ();
- X return gl_buf;
- X break;
- X case CTRL_A:
- X gl_fixup (-1, 0);
- X break;
- X case CTRL_B:
- X gl_fixup (-1, gl_pos-1);
- X break;
- X case CTRL_D:
- X if (gl_cnt == 0) {
- X gl_buf[0] = 0;
- X fputc ('\n', stdout);
- X return gl_buf;
- X } else {
- X gl_del (0);
- X }
- X break;
- X case CTRL_E:
- X gl_fixup (-1, gl_cnt);
- X break;
- X case CTRL_F:
- X gl_fixup (-1, gl_pos+1);
- X break;
- X case CTRL_H:
- X case DEL:
- X gl_del (-1);
- X break;
- X case TAB:
- X if (gl_tab_hook) {
- X tmp = gl_pos;
- X loc = gl_tab_hook (gl_buf, strlen (gl_prompt), &tmp);
- X if (loc >= 0 || tmp != gl_pos)
- X gl_fixup (loc, tmp);
- X }
- X break;
- X case CTRL_K:
- X gl_kill ();
- X break;
- X case CTRL_L:
- X case CTRL_R:
- X gl_redraw ();
- X break;
- X case CTRL_N:
- X hist_next ();
- X break;
- X case CTRL_P:
- X hist_prev ();
- X break;
- X default:
- X ring_bell ();
- X break;
- X }
- X }
- X }
- X return gl_buf;
- }
- X
- /*
- X * adds the character c to the input buffer at current location if
- X * the character is in the allowed template of characters
- X */
- X
- #if __STDC__
- static void gl_addchar (int c, char *template, int len)
- #else
- static void gl_addchar (c, template, len)
- X int c;
- X char *template;
- X int len;
- #endif
- {
- X int i;
- X
- X if (gl_cnt >= BUF_SIZE - 1) {
- X error_message ("getline: input buffer overflow");
- X exit (1);
- X }
- X
- X for (i=gl_cnt; i >= gl_pos; i--) {
- X gl_buf[i+1] = gl_buf[i];
- X }
- X gl_buf[gl_pos] = c;
- X gl_fixup (gl_pos, gl_pos+1);
- }
- X
- /*
- X * Cleans up entire line before returning to caller. A \n is appended.
- X * If line longer than screen, we redraw starting at beginning
- X */
- X
- static void gl_newline ()
- {
- X int change = gl_cnt;
- X int len = gl_cnt;
- X int loc = gl_width - 5; /* shifts line back to start position */
- X
- X if (gl_cnt >= BUF_SIZE - 1) {
- X error_message ("getline: input buffer overflow");
- X exit (1);
- X }
- X hist_add (); /* only adds if nonblank */
- X if (gl_out_hook) {
- X change = gl_out_hook (gl_buf);
- X len = strlen (gl_buf);
- X }
- X if (loc > len)
- X loc = len;
- X gl_fixup (change, loc); /* must do this before appending \n */
- X gl_buf[len] = '\0';
- }
- X
- /*
- X * Delete a character. The loc variable can be:
- X * -1 : delete character to left of cursor
- X * 0 : delete character under cursor
- X */
- X
- #if __STDC__
- static void gl_del (int loc)
- #else
- static void gl_del (loc)
- X int loc;
- #endif
- {
- X int i;
- X
- X if (loc == -1 && gl_pos > 0 || loc == 0 && gl_pos < gl_cnt) {
- X for (i=gl_pos+loc; i < gl_cnt; i++)
- X gl_buf[i] = gl_buf[i+1];
- X gl_fixup (gl_pos+loc, gl_pos+loc);
- X } else {
- X ring_bell ();
- X }
- }
- X
- /*
- X * delete from current position to the end of line
- X */
- X
- static void gl_kill ()
- {
- X if (gl_pos < gl_cnt) {
- X gl_buf[gl_pos] = '\0';
- X gl_fixup (gl_pos, gl_pos);
- X } else {
- X ring_bell ();
- X }
- }
- X
- /*
- X * emit a newline, reset and redraw prompt and current input line
- X */
- X
- static void gl_redraw ()
- {
- X if (gl_init_done == -1) {
- X fputc ('\n', stdout);
- X fputs (gl_prompt, stdout);
- X gl_pos = 0;
- X gl_fixup (0, BUF_SIZE);
- X }
- }
- X
- /*
- X * This function is used both for redrawing when input changes or for
- X * moving within the input line. The parameters are:
- X * change : the index of the start of changes in the input buffer,
- X * with -1 indicating no changes.
- X * cursor : the desired location of the cursor after the call.
- X * A value of BUF_SIZE can be used to indicate the cursor
- X * should move just past the end of the input line.
- X */
- X
- #if __STDC__
- static void gl_fixup (int change, int cursor)
- #else
- static void gl_fixup (change, cursor)
- X int change;
- X int cursor;
- #endif
- {
- X static int gl_shift; /* index of first on screen character */
- X static int off_right; /* true if more text right of screen */
- X static int off_left; /* true if more text left of screen */
- X int left = 0, right = -1; /* bounds for redraw */
- X int pad; /* how much to erase at end of line */
- X int backup; /* how far to backup before fixing */
- X int new_shift; /* value of shift based on cursor */
- X int extra; /* adjusts when shift (scroll) happens */
- X int i;
- X
- X if (change == -1 && cursor == 0 && gl_buf[0] == 0) { /* reset */
- X gl_shift = off_right = off_left = 0;
- X return;
- X }
- X pad = (off_right) ? gl_width - 1 : gl_cnt - gl_shift; /* old length */
- X backup = gl_pos - gl_shift;
- X if (change >= 0) {
- X gl_cnt = strlen (gl_buf);
- X if (change > gl_cnt)
- X change = gl_cnt;
- X }
- X if (cursor > gl_cnt) {
- X if (cursor != BUF_SIZE) /* BUF_SIZE means end of line */
- X ring_bell ();
- X cursor = gl_cnt;
- X }
- X if (cursor < 0) {
- X ring_bell ();
- X cursor = 0;
- X }
- X if (off_right || off_left && cursor < gl_shift + gl_width - SCROLL / 2)
- X extra = 2; /* shift the scrolling boundary */
- X else
- X extra = 0;
- X new_shift = cursor + extra + SCROLL - gl_width;
- X if (new_shift > 0) {
- X new_shift /= SCROLL;
- X new_shift *= SCROLL;
- X } else
- X new_shift = 0;
- X if (new_shift != gl_shift) { /* scroll occurs */
- X gl_shift = new_shift;
- X off_left = (gl_shift) ? 1 : 0;
- X off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
- X left = gl_shift;
- X right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt;
- X } else if (change >= 0) { /* no scroll, but text changed */
- X if (change < gl_shift + off_left) {
- X left = gl_shift;
- X } else {
- X left = change;
- X backup = gl_pos - change;
- X }
- X off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
- X right = (off_right) ? gl_shift + gl_width - 2 : gl_cnt;
- X }
- X pad -= (off_right) ? gl_width - 1 : gl_cnt - gl_shift;
- X pad = (pad < 0)? 0 : pad;
- X if (left <= right) { /* clean up screen */
- X for (i=0; i < backup; i++)
- X fputc ('\b', stdout);
- X if (left == gl_shift && off_left) {
- X fputc ('$', stdout);
- X left++;
- X }
- X for (i=left; i < right; i++)
- X fputc (gl_buf[i], stdout);
- X if (off_right) {
- X fputc ('$', stdout);
- X gl_pos = right + 1;
- X } else {
- X for (i=0; i < pad; i++) /* erase remains of prev line */
- X fputc (' ', stdout);
- X gl_pos = right + pad;
- X }
- X }
- X i = gl_pos - cursor; /* move to final cursor location */
- X if (i > 0) {
- X while (i--)
- X fputc ('\b', stdout);
- X } else {
- X for (i=gl_pos; i < cursor; i++)
- X fputc (gl_buf[i], stdout);
- X }
- X fflush (stdout);
- X gl_pos = cursor;
- }
- X
- /*
- X * default tab handler, acts like tabstops every TABSIZE cols
- X */
- X
- #if __STDC__
- static int gl_tab (char *buf, int offset, int *loc)
- #else
- static int gl_tab (buf, offset, loc)
- X char *buf;
- X int offset;
- X int *loc;
- #endif
- {
- X int i, count, len;
- X
- X len = strlen (buf);
- X count = TABSIZE - (offset + *loc) % TABSIZE;
- X for (i=len; i >= *loc; i--)
- X buf[i+count] = buf[i];
- X for (i=0; i < count; i++)
- X buf[*loc+i] = ' ';
- X i = *loc;
- X *loc = i + count;
- X return i;
- }
- X
- /*
- X * History functions
- X */
- X
- static void hist_init ()
- {
- X int i;
- X
- X for (i=0; i < HIST_SIZE; i++)
- X hist_buf[i] = (char *) 0;
- }
- X
- X
- static void hist_add ()
- {
- X char *p = gl_buf;
- X
- X while (*p == ' ' || *p == '\t') /* only save nonblank line */
- X p++;
- X if (*p) {
- X hist_buf[hist_last] = str_dup (gl_buf);
- X hist_last = (hist_last + 1) % HIST_SIZE;
- X if (hist_buf[hist_last]) { /* erase next location */
- X free(hist_buf[hist_last]);
- X hist_buf[hist_last] = (char *) 0;
- X }
- X }
- X hist_pos = hist_last;
- }
- X
- /*
- X * loads previous hist entry into input buffer, sticks on first
- X */
- X
- static void hist_prev ()
- {
- X int next;
- X
- X next = (hist_pos - 1 + HIST_SIZE) % HIST_SIZE;
- X if (next != hist_last) {
- X if (hist_buf[next]) {
- X hist_pos = next;
- X strcpy (gl_buf, hist_buf[hist_pos]);
- X } else {
- X ring_bell ();
- X }
- X } else {
- X ring_bell ();
- X }
- X if (gl_in_hook)
- X gl_in_hook (gl_buf);
- X gl_fixup (0, BUF_SIZE);
- }
- X
- /*
- X * loads next hist entry into input buffer, clears on last
- X */
- X
- static void hist_next ()
- {
- X if (hist_pos != hist_last) {
- X hist_pos = (hist_pos + 1) % HIST_SIZE;
- X if (hist_buf[hist_pos]) {
- X strcpy (gl_buf, hist_buf[hist_pos]);
- X } else {
- X gl_buf[0] = 0;
- X }
- X } else {
- X ring_bell ();
- X }
- X if (gl_in_hook)
- X gl_in_hook (gl_buf);
- X gl_fixup (0, BUF_SIZE);
- }
- SHAR_EOF
- chmod 0600 getline.c ||
- echo 'restore of getline.c failed'
- Wc_c="`wc -c < 'getline.c'`"
- test 11498 -eq "$Wc_c" ||
- echo 'getline.c: original size 11498, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= group.c ==============
- if test -f 'group.c' -a X"$1" != X"-c"; then
- echo 'x - skipping group.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting group.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'group.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : group.c
- X * Author : R.Skrenta / I.Lea
- X * Created : 01-04-91
- X * Updated : 23-01-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Rich Skrenta & Iain Lea
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- #include "tin.h"
- X
- extern char cvers[LEN];
- extern int cur_groupnum;
- extern int last_resp; /* page.c */
- extern int this_resp; /* page.c */
- X
- char *glob_group;
- int index_point;
- int first_subj_on_screen;
- int last_subj_on_screen;
- X
- X
- void group_page (group)
- X char *group;
- {
- X char group_path[LEN];
- X char ch;
- X char *p;
- X int flag, i, n;
- X int kill_state;
- X int old_top;
- X int posted;
- X int sav_groupnum;
- X int scroll_lines;
- X int thread_marked_unread = FALSE;
- X long old_artnum;
- X
- X active[my_group[cur_groupnum]].read = TRUE;
- X
- X glob_group = group;
- X sav_groupnum = cur_groupnum;
- X
- X strcpy (group_path, group); /* turn comp.unix.amiga into */
- X for (p = group_path; *p; p++) /* comp/unix/amiga */
- X if (*p == '.')
- X *p = '/';
- X
- X last_resp = -1;
- X this_resp = -1;
- X index_group (group, group_path); /* update index file */
- X read_newsrc_line (group); /* get sequencer information */
- X
- X if (show_only_unread) {
- X make_threads (FALSE);
- X find_base (show_only_unread);
- X }
- X
- X debug_print_base ();
- X
- X if (space_mode) {
- X for (i = 0; i < top_base; i++) {
- X if (new_responses (i)) {
- X break;
- X }
- X }
- X if (i < top_base) {
- X index_point = i;
- X } else {
- X index_point = top_base - 1;
- X }
- X } else {
- X index_point = top_base - 1;
- X }
- X if (index_point < 0) {
- X index_point = 0;
- X }
- X
- X clear_note_area ();
- X
- X show_group_page (group);
- X
- X while (TRUE) {
- X ch = (char) ReadCh ();
- X
- X if (ch > '0' && ch <= '9') { /* 0 goes to basenote */
- X prompt_subject_num (ch, group);
- X } else switch (ch) {
- X case ESC: /* common arrow keys */
- X switch (get_arrow_key ()) {
- X case KEYMAP_UP:
- X goto group_up;
- X
- X case KEYMAP_DOWN:
- X goto group_down;
- X
- X case KEYMAP_PAGE_UP:
- X goto group_page_up;
- X
- X case KEYMAP_PAGE_DOWN:
- X goto group_page_down;
- X
- X case KEYMAP_HOME:
- X if (index_point != 0) {
- X index_point = 0;
- X show_group_page (group);
- X }
- X break;
- X
- X case KEYMAP_END:
- X goto end_of_list;
- X }
- X break;
- X
- #ifndef NO_SHELL_ESCAPE
- X case '!':
- X shell_escape ();
- X show_group_page (group);
- X break;
- #endif
- X
- X case '$': /* show last page of articles */
- end_of_list:
- X if (index_point != top_base - 1) {
- X index_point = top_base - 1;
- X show_group_page (group);
- X }
- X break;
- X
- X case '-': /* go to last viewed article */
- X if (this_resp < 0) {
- X info_message (txt_no_last_message);
- X break;
- X }
- X index_point = show_page (this_resp, group, group_path);
- X if (index_point < 0) {
- X space_mode = FALSE;
- X goto group_done;
- X }
- X clear_note_area ();
- X show_group_page (group);
- X break;
- X
- X case '|': /* pipe article/thread/tagged arts to command */
- X if (index_point >= 0) {
- X set_real_uid_gid ();
- X feed_articles (FEED_PIPE, GROUP_LEVEL, "Pipe",
- X (int) base[index_point], group_path);
- X set_tin_uid_gid ();
- X }
- X break;
- X
- X case '/': /* forward/backward search */
- X case '?':
- X i = (ch == '/');
- X search_subject (i, group);
- X break;
- X
- X case '\r':
- X case '\n': /* read current basenote */
- X if (index_point < 0) {
- X info_message(txt_no_arts);
- X break;
- X }
- X i = (int) base[index_point];
- X index_point = show_page (i, group, group_path);
- X if (index_point < 0) {
- X space_mode = FALSE;
- X goto group_done;
- X }
- X clear_note_area ();
- X show_group_page (group);
- X break;
- X
- X case '\t':
- X space_mode = TRUE;
- X
- X if (index_point < 0
- X || (n=next_unread((int) base[index_point]))<0) {
- X for (i = cur_groupnum+1 ; i < group_top ; i++)
- X if (unread[i] > 0)
- X break;
- X if (i >= group_top)
- X goto group_done;
- X
- X cur_groupnum = i;
- X index_point = -3;
- X goto group_done;
- X }
- X index_point = show_page(n, group, group_path);
- X if (index_point < 0)
- X goto group_done;
- X clear_note_area ();
- X show_group_page(group);
- X break;
- X
- X case ' ': /* page down */
- X case ctrl('D'): /* vi style */
- X case ctrl('V'): /* emacs style */
- group_page_down:
- X if (! top_base || index_point == top_base - 1)
- X break;
- X
- X erase_subject_arrow ();
- X scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
- X index_point = ((index_point + scroll_lines) / scroll_lines) * scroll_lines;
- X if (index_point >= top_base) {
- X index_point = (top_base / scroll_lines) * scroll_lines;
- X if (index_point < top_base - 1) {
- X index_point = top_base - 1;
- X }
- X }
- X if (index_point < first_subj_on_screen
- X || index_point >= last_subj_on_screen)
- X show_group_page (group);
- X else
- X draw_subject_arrow ();
- X break;
- X
- X case ctrl('K'): /* kill article */
- X if (index_point < 0) {
- X info_message (txt_no_arts);
- X break;
- X }
- X if (kill_articles) {
- X old_top = top;
- X n = (int) base[index_point];
- X old_artnum = arts[n].artnum;
- X if (kill_art_menu (group, (int) base[index_point])) {
- X kill_any_articles (group);
- X reload_index_file (group, TRUE);
- X index_point = find_new_pos (old_top, old_artnum, index_point);
- X }
- X show_group_page (group);
- X } else {
- X info_message (txt_switch_on_kill_art_menu);
- X }
- X break;
- X
- X case ctrl('L'): /* redraw screen */
- X case ctrl('R'):
- X case ctrl('W'):
- #ifndef USE_CLEARSCREEN
- X ClearScreen ();
- #endif
- X show_group_page (group);
- X break;
- X
- X case ctrl('N'):
- X case 'j': /* line down */
- group_down:
- X if (! top_base || index_point + 1 >= top_base)
- X break;
- X
- X if (index_point + 1 >= last_subj_on_screen) {
- #ifndef USE_CLEARSCREEN
- X erase_subject_arrow();
- #endif
- X index_point++;
- X show_group_page(group);
- X } else {
- X erase_subject_arrow();
- X index_point++;
- X draw_subject_arrow();
- X }
- X break;
- X
- X case ctrl('P'):
- X case 'k': /* line up */
- group_up:
- X if (!top_base || !index_point)
- X break;
- X
- X if (index_point <= first_subj_on_screen) {
- X index_point--;
- X show_group_page(group);
- X } else {
- X erase_subject_arrow();
- X index_point--;
- X draw_subject_arrow();
- X }
- X break;
- X
- X case ctrl('U'): /* page up */
- X case 'b':
- group_page_up:
- X if (! top_base)
- X break;
- X
- #ifndef USE_CLEARSCREEN
- X clear_message ();
- #endif
- X erase_subject_arrow ();
- X scroll_lines = (full_page_scroll ? NOTESLINES : NOTESLINES / 2);
- X if ((n = index_point % scroll_lines) > 0) {
- X index_point = index_point - n;
- X } else {
- X index_point = ((index_point - scroll_lines) / scroll_lines) * scroll_lines;
- X }
- X if (index_point < 0) {
- X index_point = 0;
- X }
- X if (index_point < first_subj_on_screen
- X || index_point >= last_subj_on_screen)
- X show_group_page (group);
- X else
- X draw_subject_arrow ();
- X break;
- X
- X case 'a': /* author search forward */
- X case 'A': /* author search backward */
- X if (index_point < 0) {
- X info_message (txt_no_arts);
- X break;
- X }
- X
- X i = (ch == 'a');
- X
- X n = search_author(top, (int) base[index_point], i);
- X if (n < 0)
- X break;
- X
- X index_point = show_page(n, group, group_path);
- X if (index_point < 0) {
- X space_mode = FALSE;
- X goto group_done;
- X }
- X clear_note_area ();
- X show_group_page (group);
- X break;
- X
- X case 'B': /* bug/gripe/comment mailed to author */
- X mail_bug_report ();
- #ifndef USE_CLEARSCREEN
- X ClearScreen ();
- #endif
- X show_group_page (group);
- X break;
- X
- X case 'c': /* catchup--mark all articles as read */
- X if (prompt_yn (LINES, txt_mark_all_read, 'y')) {
- X for (n = 0; n < top; n++) {
- X arts[n].unread = ART_READ;
- X }
- X if (cur_groupnum + 1 < group_top) {
- X cur_groupnum++;
- X }
- X goto group_done;
- X }
- X break;
- X
- X case 'd': /* toggle display of subject & subj/author */
- X if (show_author + 1 > SHOW_FROM_BOTH) {
- X show_author = SHOW_FROM_NONE;
- X } else {
- X show_author++;
- X }
- X if (show_author == SHOW_FROM_BOTH) {
- X max_subj = (COLS / 2) - 2;
- X } else {
- X max_subj = (COLS / 2) + 5;
- X }
- X max_from = (COLS - max_subj) - 17;
- X show_group_page (group);
- X break;
- X
- X case 'g': /* choose a new group by name */
- X n = choose_new_group ();
- X if (n >= 0 && n != cur_groupnum) {
- X cur_groupnum = n;
- X index_point = -3;
- X goto group_done;
- X }
- X break;
- X
- X case 'h': /* help */
- X show_info_page (HELP_INFO, help_group, txt_index_page_com);
- X show_group_page (group);
- X break;
- X
- X case 'I': /* toggle inverse video */
- X toggle_inverse_video ();
- X show_group_page (group);
- X break;
- X
- X case 'K': /* mark rest of thread as read */
- X if (index_point < 0) {
- X info_message (txt_no_next_unread_art);
- X break;
- X }
- X if (new_responses (index_point)) {
- X for (i = (int) base[index_point]; i >= 0; i = arts[i].thread) {
- X arts[i].unread = ART_READ;
- X if (arts[i].tagged) {
- X sprintf (msg, "%3d", arts[i].tagged);
- X } else {
- X sprintf (msg, "%3s", (arts[i].unread ? " +" : " "));
- X }
- X mark_screen (SCREEN_READ_UNREAD, msg);
- X }
- X flag = FALSE;
- X } else
- X flag = TRUE;
- X
- X n = next_unread (next_response ((int) base[index_point]));
- X if (n < 0) {
- X if (flag)
- X info_message (txt_no_next_unread_art);
- X else
- X MoveCursor (LINES, 0);
- X break;
- X }
- X
- X if ((n = which_thread (n)) < 0) {
- X info_message("Internal error: K which_thread < 0");
- X break;
- X }
- X
- X if (n >= last_subj_on_screen) {
- X index_point = n;
- X show_group_page (group);
- X } else {
- X erase_subject_arrow ();
- X index_point = n;
- X draw_subject_arrow ();
- X }
- X break;
- X
- X case 'l': /* list articles within current thread */
- X space_mode = TRUE;
- X if (show_thread ((int) base[index_point], group, group_path)) {
- X show_group_page (group);
- X }
- X break;
- X
- X case 'm': /* mail article to somebody */
- X if (index_point >= 0) {
- X set_real_uid_gid ();
- X feed_articles (FEED_MAIL, GROUP_LEVEL, "Mail",
- X (int) base[index_point], group_path);
- X set_tin_uid_gid ();
- X }
- X break;
- X
- X case 'M': /* options menu */
- X if (top_base > 0) {
- X old_top = top;
- X n = (int) base[index_point];
- X old_artnum = arts[n].artnum;
- X }
- X n = sort_art_type;
- X kill_state = change_rcfile (group, TRUE);
- X if (kill_state == NO_KILLING && n != sort_art_type) {
- X make_threads (TRUE);
- X find_base (show_only_unread);
- X }
- X index_point = find_new_pos (old_top, old_artnum, index_point);
- X show_group_page (group);
- X break;
- X
- X case 'n': /* next group */
- X clear_message();
- X if (cur_groupnum + 1 >= group_top)
- X info_message(txt_no_more_groups);
- X else {
- X cur_groupnum++;
- X index_point = -3;
- X space_mode = pos_first_unread;
- X goto group_done;
- X }
- X break;
- X
- X case 'N': /* go to next unread article */
- X if (index_point < 0) {
- X info_message(txt_no_next_unread_art);
- X break;
- X }
- X
- X n = next_unread ((int) base[index_point]);
- X if (n == -1)
- X info_message (txt_no_next_unread_art);
- X else {
- X index_point = show_page (n, group, group_path);
- X if (index_point < 0) {
- X space_mode = pos_first_unread;
- X goto group_done;
- X }
- X clear_note_area ();
- X show_group_page (group);
- X }
- X break;
- X
- X case 'o': /* output art/thread/tagged arts to printer */
- X if (index_point >= 0) {
- X set_real_uid_gid ();
- X feed_articles (FEED_PRINT, GROUP_LEVEL, "Print",
- X (int) base[index_point], group_path);
- X set_tin_uid_gid ();
- X }
- X break;
- X
- X case 'p': /* previous group */
- X clear_message();
- X if (cur_groupnum <= 0)
- X info_message(txt_no_prev_group);
- X else {
- X cur_groupnum--;
- X index_point = -3;
- X space_mode = pos_first_unread;
- X goto group_done;
- X }
- X break;
- X
- X case 'P': /* go to previous unread article */
- X if (index_point < 0) {
- X info_message(txt_no_prev_unread_art);
- X break;
- X }
- X n = prev_response( (int) base[index_point]);
- X n = prev_unread(n);
- X if (n == -1)
- X info_message(txt_no_prev_unread_art);
- X else {
- X index_point = show_page (n, group, group_path);
- X if (index_point < 0) {
- X space_mode = pos_first_unread;
- X goto group_done;
- X }
- X clear_note_area ();
- X show_group_page (group);
- X }
- X break;
- X
- X case 'q': /* quit */
- X index_point = -2;
- X space_mode = FALSE;
- X goto group_done;
- X
- X case 's': /* save regex pattern to file/s */
- X if (index_point >= 0) {
- X set_real_uid_gid ();
- X feed_articles (FEED_SAVE, GROUP_LEVEL, "Save",
- X (int) base[index_point], group_path);
- X set_tin_uid_gid ();
- X }
- X break;
- X
- X case 't':
- X case 'i': /* return to group selection page */
- X goto group_done;
- X
- X case 'T': /* tag/untag art for mailing/piping/printing/saving */
- X if (index_point >= 0) {
- X n = (int) base[index_point];
- X if (arts[n].tagged) {
- X arts[n].tagged = 0;
- X sprintf (msg, "%3s", (arts[n].unread ? " +" : " "));
- X info_message (txt_untagged_art);
- X } else {
- X arts[n].tagged = ++num_of_tagged_files;
- X sprintf (msg, "%3d", arts[n].tagged);
- X info_message (txt_tagged_art);
- X }
- X mark_screen (SCREEN_READ_UNREAD, msg);
- X goto group_down; /* advance an article */
- X }
- X break;
- X
- X case 'u': /* unthread/thread articles */
- X if (index_point >= 0) {
- X thread_arts = !thread_arts;
- X make_threads (TRUE);
- X find_base (show_only_unread);
- X show_group_page (group);
- X }
- X break;
- X
- X case 'U': /* untag all articles */
- X if (index_point >= 0) {
- X untag_all_articles ();
- X show_group_page (group);
- X }
- X break;
- X
- X case 'v':
- X info_message (cvers);
- X break;
- X
- X case 'w': /* post a basenote */
- X if (! can_post) {
- X info_message (txt_cannot_post);
- X break;
- X }
- X if (post_base (group, &posted)) {
- X if (posted) {
- X update_newsrc (group, my_group[cur_groupnum], FALSE);
- X index_group (group, group_path);
- X read_newsrc_line (group);
- X index_point = top_base - 1;
- X }
- X show_group_page (group);
- X }
- X break;
- X
- X case 'W': /* display messages posted by user */
- X if (user_posted_messages ()) {
- X show_group_page(group);
- X }
- X break;
- X
- X case 'z': /* mark article as unread */
- X if (index_point < 0) {
- X info_message (txt_no_arts);
- X break;
- X }
- X i = (int) base[index_point];
- X arts[i].unread = ART_UNREAD;
- X mark_screen (SCREEN_READ_UNREAD, " +");
- X info_message (txt_art_marked_as_unread);
- X break;
- X
- X case 'Z': /* mark thread as unread */
- X if (index_point < 0) {
- X info_message (txt_no_arts);
- X break;
- X }
- X for (i = (int) base[index_point] ; i != -1 ; i = arts[i].thread) {
- X arts[i].unread = ART_UNREAD;
- X thread_marked_unread = TRUE;
- X }
- X if (thread_marked_unread) {
- X mark_screen (SCREEN_READ_UNREAD, " +");
- X info_message (txt_thread_marked_as_unread);
- X thread_marked_unread = FALSE;
- X }
- X break;
- X
- X default:
- X info_message (txt_bad_command);
- X }
- X }
- X
- group_done:
- X fix_new_highest (sav_groupnum);
- X update_newsrc (group, my_group[sav_groupnum], FALSE);
- X
- X if (index_point == -2) {
- X tin_done (0);
- X }
- X clear_note_area ();
- }
- X
- X
- /*
- X * Correct highest[] for the group selection page display since
- X * new articles may have been read or marked unread
- X */
- X
- void fix_new_highest (groupnum)
- X int groupnum;
- {
- X register int i;
- X int sum = 0;
- X
- X for (i = 0; i < top; i++) {
- X if (arts[i].unread) {
- X sum++;
- X }
- X }
- X
- X unread[groupnum] = sum;
- }
- X
- X
- void show_group_page (group)
- X char *group;
- {
- X char buf[LEN];
- X char new_resps[8];
- X char resps[8];
- X char from[LEN];
- X char subject[LEN];
- X int col, i, j, n;
- X int len_from;
- X int len_subj;
- X int respnum;
- X int unread_top = 0;
- X
- X set_signals_group ();
- X
- #ifdef USE_CLEARSCREEN
- X ClearScreen ();
- #else
- X MoveCursor (0, 0);
- X CleartoEOLN ();
- #endif
- X
- X if (show_only_unread) {
- X for (i = 0 ; i < top_base ; i++) {
- X unread_top += 1 + num_of_responses (i);
- X }
- X } else {
- X unread_top = top;
- X }
- X
- X if (active[my_group[cur_groupnum]].thread && thread_arts) {
- X sprintf (buf, "%s (%d %d)", group, top_base, unread_top);
- X } else {
- X sprintf (buf, "%s (U %d)", group, unread_top);
- X }
- X show_title (buf);
- X
- #ifndef USE_CLEARSCREEN
- X MoveCursor (1, 0);
- X CleartoEOLN ();
- #endif
- X
- X MoveCursor (INDEX_TOP, 0);
- X
- X if (index_point >= top_base) {
- X index_point = top_base - 1;
- X }
- X
- X if (NOTESLINES <= 0) {
- X first_subj_on_screen = 0;
- X } else {
- X first_subj_on_screen = (index_point / NOTESLINES) * NOTESLINES;
- X if (first_subj_on_screen < 0) {
- X first_subj_on_screen = 0;
- X }
- X }
- X
- X last_subj_on_screen = first_subj_on_screen + NOTESLINES;
- X
- X if (last_subj_on_screen >= top_base) {
- X last_subj_on_screen = top_base;
- X first_subj_on_screen = (top_base / NOTESLINES) * NOTESLINES;
- X
- X if (first_subj_on_screen == last_subj_on_screen ||
- X first_subj_on_screen < 0) {
- X if (first_subj_on_screen < 0) {
- X first_subj_on_screen = 0;
- X } else {
- X first_subj_on_screen = last_subj_on_screen - NOTESLINES;
- X }
- X }
- X }
- X
- X if (top_base == 0) {
- X first_subj_on_screen = 0;
- X last_subj_on_screen = 0;
- X }
- X
- X if (show_author != SHOW_FROM_NONE) {
- X len_from = max_from-BLANK_GROUP_COLS;
- X } else {
- X len_subj = (max_subj+max_from+3)-BLANK_GROUP_COLS;
- X }
- X
- X if (draw_arrow_mark) {
- X CleartoEOS ();
- X }
- X
- X for (j=0, i = first_subj_on_screen; i < last_subj_on_screen; i++, j++) {
- X respnum = (int) base[i];
- X
- X if (arts[respnum].tagged) {
- X sprintf (new_resps, "%3d", arts[respnum].tagged);
- X } else if (new_responses(i)) {
- X sprintf (new_resps, " %c", UNREAD_ART_MARK);
- X } else {
- X strcpy (new_resps, " ");
- X }
- X
- X n = num_of_responses (i);
- X if (n) {
- X sprintf (resps, "%-3d", n);
- X } else {
- X strcpy (resps, " ");
- X }
- X
- X get_author (FALSE, respnum, from);
- X
- X if (draw_arrow_mark) {
- X if (show_author != SHOW_FROM_NONE) {
- X my_strncpy (subject, arts[respnum].subject, max_subj);
- X printf (" %4d%3s %s%-*s %-s\r\n",
- X i+1, new_resps, resps, max_subj, subject, from);
- X } else {
- X my_strncpy (subject, arts[respnum].subject, max_subj+max_from+3);
- X printf (" %4d%3s %s%-s\r\n",
- X i+1, new_resps, resps, subject);
- X }
- X } else {
- X if (show_author != SHOW_FROM_NONE) {
- X my_strncpy (subject, arts[respnum].subject, max_subj);
- X sprintf (screen[j].col, " %4d%3s %s%-*s %-*s\r\n",
- X i+1, new_resps, resps, max_subj, subject, len_from, from);
- X } else {
- X my_strncpy (subject, arts[respnum].subject, max_subj+max_from+3);
- X sprintf (screen[j].col, " %4d%3s %s%-*s\r\n",
- X i+1, new_resps, resps, len_subj, subject);
- X }
- X printf ("%s", screen[j].col);
- X }
- X }
- X
- #ifndef USE_CLEARSCREEN
- X CleartoEOS ();
- #endif
- X
- X if (top_base <= 0) {
- X info_message(txt_no_arts);
- X return;
- X } else if (last_subj_on_screen == top_base) {
- X info_message(txt_end_of_arts);
- X }
- X
- X draw_subject_arrow();
- }
- X
- void draw_subject_arrow()
- {
- X draw_arrow (INDEX_TOP + (index_point-first_subj_on_screen));
- }
- X
- void erase_subject_arrow()
- {
- X erase_arrow (INDEX_TOP + (index_point-first_subj_on_screen));
- }
- X
- X
- int prompt_subject_num (ch, group)
- X char ch;
- X char *group;
- {
- X int num;
- X
- X clear_message ();
- X
- X if ((num = prompt_num (ch, txt_read_art)) == -1) {
- X clear_message ();
- X return FALSE;
- X }
- X num--; /* index from 0 (internal) vs. 1 (user) */
- X
- X if (num < 0) {
- X num = 0;
- X }
- X if (num >= top_base) {
- X num = top_base - 1;
- X }
- X
- X if (num >= first_subj_on_screen
- X && num < last_subj_on_screen) {
- X erase_subject_arrow();
- X index_point = num;
- X draw_subject_arrow();
- X } else {
- #ifndef USE_CLEARSCREEN
- X erase_subject_arrow();
- #endif
- X index_point = num;
- X show_group_page(group);
- X }
- X return TRUE;
- }
- X
- X
- void clear_note_area ()
- {
- #ifndef USE_CLEARSCREEN
- X MoveCursor (INDEX_TOP, 0);
- X CleartoEOS ();
- #endif
- }
- X
- X
- int find_new_pos (old_top, old_artnum, cur_pos)
- X int old_top;
- X long old_artnum;
- X int cur_pos;
- {
- X int pos;
- X
- X if (top != old_top) {
- X if ((pos = valid_artnum (old_artnum)) >= 0) {
- X if ((pos = which_thread (pos)) >= 0) {
- X return pos;
- X } else {
- X return top_base - 1;
- X }
- X } else {
- X return top_base - 1;
- X }
- X }
- X
- X return cur_pos;
- }
- X
- X
- void mark_screen (col, value)
- X int col;
- X char *value;
- {
- X int i, len;
- X
- X len = strlen (value);
- X
- X if (draw_arrow_mark) {
- X MoveCursor(INDEX_TOP + (index_point - first_subj_on_screen), col);
- X printf ("%s", value);
- X MoveCursor (LINES, 0);
- X fflush(stdout);
- X } else {
- X for (i=0 ; i < len ; i++) {
- X screen[index_point-first_subj_on_screen].col[col+i] = value[i];
- X }
- X draw_subject_arrow();
- X }
- }
- SHAR_EOF
- chmod 0600 group.c ||
- echo 'restore of group.c failed'
- Wc_c="`wc -c < 'group.c'`"
- test 20637 -eq "$Wc_c" ||
- echo 'group.c: original size 20637, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= hashstr.c ==============
- if test -f 'hashstr.c' -a X"$1" != X"-c"; then
- echo 'x - skipping hashstr.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting hashstr.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'hashstr.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : hashstr.c
- X * Author : R.Skrenta
- X * Created : 01-04-91
- X * Updated : 21-01-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Rich Skrenta
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- #include "tin.h"
- X
- /*
- X * Maintain a table of all strings we have seen.
- X * If a new string comes in, add it to the table and return a pointer
- X * to it. If we've seen it before, just return the pointer to it.
- X *
- X * Usage: hash_str("some string") returns char *
- X *
- X * Spillovers are chained on the end
- X */
- X
- /*
- X * Arbitrary table size, but make sure it's prime!
- X */
- X
- #define HASHNODE_TABLE_SIZE 2411
- X
- struct hashnode *table[HASHNODE_TABLE_SIZE];
- X
- X
- char *hash_str (s)
- X char *s;
- {
- X long h; /* result of hash: index into hash table */
- X struct hashnode *p; /* used to descend the spillover structs */
- X
- X if (s == (char *) 0) {
- X return ((char *) 0);
- X }
- X
- X {
- X unsigned char *t = (unsigned char *) s;
- X
- X h = *t++;
- X while (*t)
- X h = ((h << 1) ^ *t++) % (long) HASHNODE_TABLE_SIZE;
- X }
- X
- X p = table[h];
- X
- X if (p == (struct hashnode *) 0) {
- X table[h] = add_string (s);
- X return table[h]->s;
- X }
- X
- X while (1) {
- X if (strcmp (s, p->s) == 0) {
- X return (p->s);
- X }
- X
- X if (p->next == (struct hashnode *) 0) {
- X p->next = add_string (s);
- X return p->next->s;
- X } else {
- X p = p->next;
- X }
- X }
- X /* NOTREACHED */
- }
- X
- X
- struct hashnode *add_string (s)
- X char *s;
- {
- X int *iptr;
- X struct hashnode *p;
- X
- X p = (struct hashnode *) my_malloc ((unsigned) sizeof (*p));
- X
- X p->next = (struct hashnode *) 0;
- X iptr = (int *) my_malloc ((unsigned) strlen (s) + sizeof (int) + 1);
- X *iptr++ = -1;
- X p->s = (char *) iptr;
- X strcpy (p->s, s);
- X return (p);
- }
- X
- X
- void hash_init ()
- {
- X int i;
- X
- X for (i = 0; i < HASHNODE_TABLE_SIZE; i++) {
- X table[i] = (struct hashnode *) 0;
- X }
- }
- X
- X
- void hash_reclaim ()
- {
- X int i;
- X int *iptr;
- X struct hashnode *p, *next;
- X
- X for (i = 0; i < HASHNODE_TABLE_SIZE; i++)
- X if (table[i] != (struct hashnode *) 0) {
- X p = table[i];
- X while (p != (struct hashnode *) 0) {
- X next = p->next;
- X if (p->s != (char *) 0) {
- X iptr = (int *) p->s;
- X free ((char *) --iptr);
- X }
- X free ((char *) p);
- X p = next;
- X }
- X table[i] = (struct hashnode *) 0;
- X }
- }
- SHAR_EOF
- chmod 0600 hashstr.c ||
- echo 'restore of hashstr.c failed'
- Wc_c="`wc -c < 'hashstr.c'`"
- test 2466 -eq "$Wc_c" ||
- echo 'hashstr.c: original size 2466, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= help.c ==============
- if test -f 'help.c' -a X"$1" != X"-c"; then
- echo 'x - skipping help.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting help.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'help.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : help.c
- X * Author : I.Lea
- X * Created : 01-04-91
- X * Updated : 05-02-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Iain Lea
- X * You may freely copy or redistribute this software,
- X * so long as there is no profit made from its use, sale
- X * trade or reproduction. You may not change this copy-
- X * right notice, and it must be included in any copy made
- X */
- X
- #include "tin.h"
- #include "nntp.h"
- X
- char *help_select[] = {
- X txt_help_g_4,
- X txt_help_ctrl_d,
- X txt_help_ctrl_l,
- X txt_help_g_ctrl_k,
- X txt_help_g_ctrl_r,
- X txt_help_g_cr,
- X txt_help_g_tab,
- X txt_help_b,
- X txt_help_bug_report,
- X txt_help_sel_c,
- X txt_help_g,
- X txt_help_j,
- X txt_help_h,
- X txt_help_I,
- X txt_help_m,
- X txt_help_M,
- X txt_help_n,
- X txt_help_q,
- X txt_help_s,
- X txt_help_S,
- X txt_help_v,
- X txt_help_w,
- X txt_help_W,
- X txt_help_g_y,
- X txt_help_g_dollar,
- X txt_help_g_z,
- X txt_help_g_search,
- #ifndef NO_SHELL_ESCAPE
- X txt_help_shell,
- #endif
- X (char *) 0
- };
- X
- char *help_group[] = {
- X txt_help_i_4,
- X txt_help_ctrl_d,
- X txt_help_ctrl_k,
- X txt_help_ctrl_l,
- X txt_help_i_cr,
- X txt_help_i_tab,
- X txt_help_a,
- X txt_help_b,
- X txt_help_bug_report,
- X txt_help_c,
- X txt_help_d,
- X txt_help_g,
- X txt_help_h,
- X txt_help_I,
- X txt_help_j,
- X txt_help_K,
- X txt_help_l,
- X txt_help_p_m,
- X txt_help_M,
- X txt_help_o,
- X txt_help_i_n,
- X txt_help_i_p,
- X txt_help_q,
- X txt_help_p_s,
- X txt_help_t,
- X txt_help_T,
- X
- X txt_help_U,
- X txt_help_v,
- X txt_help_w,
- X txt_help_W,
- X txt_help_p_z,
- X txt_help_i_search,
- #ifndef NO_SHELL_ESCAPE
- X txt_help_shell,
- #endif
- X txt_help_dash,
- X txt_help_pipe,
- X (char *) 0
- };
- X
- char *help_thread[] = {
- X txt_help_t_0,
- X txt_help_t_4,
- X txt_help_ctrl_d,
- X txt_help_ctrl_l,
- X txt_help_t_cr,
- X txt_help_p_tab,
- X txt_help_b,
- X txt_help_h,
- X txt_help_I,
- X txt_help_j,
- X txt_help_p_k,
- X txt_help_q,
- X txt_help_v,
- X txt_help_p_z,
- X (char *) 0
- };
- X
- char *help_page[] = {
- X txt_help_p_0,
- X txt_help_p_4,
- X txt_help_ctrl_h,
- X txt_help_ctrl_k,
- X txt_help_ctrl_l,
- X txt_help_p_ctrl_r,
- X txt_help_p_cr,
- X txt_help_p_tab,
- X txt_help_b,
- X txt_help_a,
- X txt_help_bug_report,
- X txt_help_c,
- X txt_help_C,
- X txt_help_p_d,
- X txt_help_p_f,
- X txt_help_p_g,
- X txt_help_h,
- X txt_help_p_i,
- X txt_help_I,
- X txt_help_p_k,
- X txt_help_p_m,
- X txt_help_M,
- X txt_help_p_n,
- X txt_help_o,
- X txt_help_p_p,
- X txt_help_q,
- X txt_help_p_r,
- X txt_help_p_s,
- X txt_help_t,
- X txt_help_T,
- X txt_help_v,
- X txt_help_w,
- X txt_help_W,
- X txt_help_p_z,
- X txt_help_p_search,
- #ifndef NO_SHELL_ESCAPE
- X txt_help_shell,
- #endif
- X txt_help_dash,
- X txt_help_pipe,
- X txt_help_thread,
- X (char *) 0
- };
- X
- X
- void show_info_page (type, help, title)
- X int type;
- X char *help[];
- X char *title;
- {
- X char buf[LEN];
- X char ch;
- X int i, len;
- X int group_len = 0;
- X int old_page = 0;
- X int cur_page = 1;
- X int max_page = 1;
- X int pos_help = 0;
- X
- X if (NOTESLINES <= 0) {
- X return;
- X }
- X
- X /*
- X * find how many elements in array
- X */
- X if (type == HELP_INFO) {
- X for (i=0 ; help[i] ; i++) {
- X continue;
- X }
- X } else {
- X for (i=0 ; posted[i].date[0] ; i++) {
- X len = strlen (posted[i].group);
- X if (len > group_len) {
- X group_len = len;
- X }
- X }
- X }
- X
- X max_page = i / NOTESLINES;
- X if (i % NOTESLINES) {
- X max_page++;
- X }
- X
- X while (1) {
- X if (cur_page != old_page) {
- X ClearScreen ();
- X sprintf (buf, title, cur_page, max_page);
- X center_line (0, TRUE, buf);
- X MoveCursor (INDEX_TOP, 0);
- X
- X if (type == HELP_INFO) {
- X for (i=pos_help ; i < (pos_help + NOTESLINES) && help[i] ; i++) {
- X printf ("%s", help[i]);
- X }
- X } else {
- X for (i=pos_help ; i < (pos_help + NOTESLINES) && posted[i].date[0] ; i++) {
- X sprintf (msg, "%8s %-*s %s", posted[i].date,
- X group_len, posted[i].group, posted[i].subj);
- X msg[COLS-2] = '\0';
- X printf ("%s\r\n", msg);
- SHAR_EOF
- true || echo 'restore of help.c failed'
- fi
- echo 'End of tin1.1 part 4'
- echo 'File help.c is continued in part 5'
- echo 5 > _shar_seq_.tmp
- exit 0
-
- --
- NAME Iain Lea
- EMAIL iain%estevax.uucp@unido.Informatik.Uni-Dortmund.DE
- SNAIL Bruecken Strasse 12, 8500 Nuernberg 90, Germany
- PHONE +49-911-331963 (home) +49-911-3089-407 (work)
- --
- Dr. med. dipl.-math Dieter Becker Tel.: (0 / +49) 6841 - 16 3046
- Medizinische Universitaets- und Poliklinik Fax.: (0 / +49) 6841 - 16 3369
- Innere Medizin III
- D - 6650 Homburg / Saar Email: becker@med-in.uni-sb.de
- exit 0 # Just in case...
-