home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-27 | 50.4 KB | 2,275 lines |
- Newsgroups: comp.sources.misc
- From: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
- Subject: v29i022: tin - threaded full screen newsreader v1.1P1, Part04/12
- Message-ID: <1992Mar27.033058.2262@sparky.imd.sterling.com>
- Date: Fri, 27 Mar 1992 03:30:58 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Md4-Signature: ea2bff95bf5b8e6337a9782b12c580df
-
- Submitted-by: iain%anl433.uucp@germany.eu.net (Iain J. Lea)
- Posting-number: Volume 29, Issue 22
- Archive-name: tin/part04
- Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
- Supersedes: tin: Volume 28, Issue 45-55
-
- #!/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 art.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 art.c'
- else
- echo 'x - continuing file art.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'art.c' &&
- X } else {
- X error = 12;
- X goto corrupt_index;
- X }
- X
- X /*
- X * Date:
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 13;
- X goto corrupt_index;
- X }
- X
- X buf[strlen (buf)-1] = '\0';
- X my_strncpy (arts[top].date, buf, 12);
- X
- X /*
- X * Archive-name:
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 14;
- X goto corrupt_index;
- X }
- X
- X if (buf[0] == '\n') {
- X arts[top].archive = (char *) 0;
- X } else if (buf[0] == '%') {
- X n = atoi (&buf[1]);
- X if (n > top || n < 0) {
- X error = 15;
- X goto corrupt_index;
- X }
- X arts[top].archive = arts[n].archive;
- X } else if (buf[0] == ' ') {
- X for (p = &buf[1]; *p && *p != '\n' ; p++)
- X continue;
- X *p = '\0';
- X arts[top].archive = hash_str (&buf[1]);
- X } else {
- X error = 16;
- X goto corrupt_index;
- X }
- X
- X /*
- X * part no.
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 17;
- X goto corrupt_index;
- X }
- X
- X if (buf[0] != ' ') {
- X buf[strlen (buf)-1] = '\0';
- X arts[top].part = str_dup (buf);
- X }
- X
- X /*
- X * patch no.
- X */
- X if (fgets(buf, sizeof buf, fp) == NULL) {
- X error = 18;
- X goto corrupt_index;
- X }
- X
- X if (buf[0] != ' ') {
- X buf[strlen (buf)-1] = '\0';
- X arts[top].patch = str_dup (buf);
- X }
- X
- X debug_print_header (&arts[top]);
- X }
- X
- X fclose(fp);
- X return TRUE;
- X
- corrupt_index:
- X if (! update) {
- X sprintf (msg, txt_corrupt_index, index_file, error, top);
- X error_message (msg, "");
- X }
- X
- X if (debug == 2) {
- X sprintf (msg, "cp %s INDEX.BAD", index_file);
- X system (msg);
- X }
- X
- X unlink (index_file);
- X top = 0;
- X return FALSE;
- }
- X
- X
- /*
- X * Look in the local $HOME/RCDIR/INDEXDIR (or wherever) directory for the
- X * index file for the given group. Hashing the group name gets
- X * a number. See if that #.1 file exists; if so, read first line.
- X * Group we want? If no, try #.2. Repeat until no such file or
- X * we find an existing file that matches our group.
- X */
- X
- void find_index_file (group)
- X char *group;
- {
- X char *p;
- X FILE *fp;
- X int i = 1;
- X static char buf[LEN];
- X char dir[LEN];
- X unsigned long h;
- X
- X h = hash_groupname (group);
- X
- #ifdef NNTP_XINDEX
- /* sprintf (dir, "%s/%s", spooldir, INDEXDIR);
- */
- X sprintf (index_file, "/tmp/idx%d", process_id);
- X return;
- #else
- X if (local_index) {
- X strcpy (dir, indexdir);
- X } else {
- X sprintf (dir, "%s/%s", spooldir, INDEXDIR);
- X }
- #endif
- X
- X while (TRUE) {
- X sprintf (index_file, "%s/%lu.%d", dir, h, i);
- X
- X if ((fp = fopen (index_file, "r")) == NULL) {
- X return;
- X }
- X
- X if (fgets (buf, sizeof (buf), fp) == NULL) {
- X fclose (fp);
- X return;
- X }
- X fclose (fp);
- X
- X for (p = buf; *p && *p != '\n'; p++) {
- X continue;
- X }
- X *p = '\0';
- X
- X if (strcmp (buf, group) == 0) {
- X return;
- X }
- X i++;
- X }
- }
- X
- /*
- X * Run the index file updater only for the groups we've loaded.
- X */
- X
- void do_update ()
- {
- X int i, j;
- X char group_path[LEN];
- X char *p;
- X long beg_epoch, end_epoch;
- X
- X if (verbose) {
- X time (&beg_epoch);
- X }
- X
- X for (i = 0; i < group_top; i++) {
- X strcpy(group_path, active[my_group[i]].name);
- X for (p = group_path; *p; p++) {
- X if (*p == '.') {
- X *p = '/';
- X }
- X }
- X if (verbose) {
- X printf ("%s %s\n", (catchup ? "Catchup" : "Updating"),
- X active[my_group[i]].name);
- X fflush (stdout);
- X }
- X index_group (active[my_group[i]].name, group_path);
- X if (catchup) {
- X for (j = 0; j < top; j++) {
- X arts[j].unread = ART_READ;
- X }
- X update_newsrc (active[my_group[i]].name, my_group[i], FALSE);
- X }
- X }
- X
- X if (verbose) {
- X time (&end_epoch);
- X sprintf (msg, "%s %d groups in %ld seconds\n",
- X (catchup ? "Caughtup" : "Updated"), group_top, end_epoch - beg_epoch);
- X wait_message (msg);
- X }
- }
- X
- /*
- X * reload index after any articles have been killed
- X */
- X
- void reload_index_file (group, killed)
- X char *group;
- X int killed;
- {
- X char group_path[LEN];
- X char *p;
- X
- X if (local_index) { /* writing index in home directory */
- X set_real_uid_gid (); /* so become them */
- X }
- 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 if (killed) {
- X if (! update) {
- X wait_message (txt_killing_arts);
- X }
- X index_file_killed = TRUE;
- X setup_base (group, group_path);
- X dump_index_file (group, killed);
- X load_index_file (group);
- X read_newsrc_line (group);
- X } else {
- X if (! update) {
- X wait_message (txt_unkilling_arts);
- X }
- X find_index_file (group);
- X
- X unlink (index_file); /* delete index file */
- X
- X index_file_killed = FALSE;
- X last_read_article = 0L;
- X
- X if (read_group (group, group_path)) {
- X dump_index_file (group, killed);
- X }
- X }
- X
- X make_threads (TRUE);
- X find_base (show_only_unread);
- X
- X if (local_index) {
- X set_tin_uid_gid ();
- X }
- X
- X return;
- }
- X
- /*
- X * convert date from ctime format to sortable format
- X * "24 Jul 91 12:59:59", "Mon, 24 Jul 91 12:59:59" and
- X * "Mon, 24 Jul 1991 12:59:59" are parsed and produce
- X * output of the form "910724125959"
- X */
- X
- char *parse_date (date, str)
- X char *date;
- X char *str;
- {
- X char buf[4];
- X int i = 0;
- X
- X /* Check for extraneous day-of-week at start of date */
- X while (isalpha(date[i]) || date[i] == ',' || date[i] == ' ') {
- X i++;
- X }
- X
- X if (date[i+1] == ' ') { /* ie. "2 Aug..." instead of "12 Aug... */
- X str[4] = '0'; /* day */
- X str[5] = date[i++];
- X i++;
- X } else {
- X str[4] = date[i++]; /* day */
- X str[5] = date[i++];
- X i++;
- X }
- X
- X buf[0] = date[i++]; /* month in Jan,Feb,.. form */
- X buf[1] = date[i++];
- X buf[2] = date[i++];
- X buf[3] = '\0';
- X
- X i++;
- X
- X str[0] = date[i++]; /* year */
- X str[1] = date[i++];
- X if (isdigit(date[i])) { /* 19xx format */
- X str[0] = date[i++];
- X str[1] = date[i++];
- X }
- X
- X i++;
- X
- X if (strcmp (buf, "Jan") == 0) { /* convert Jan to 01 etc */
- X str[2] = '0';
- X str[3] = '1';
- X } else if (strcmp (buf, "Feb") == 0) {
- X str[2] = '0';
- X str[3] = '2';
- X } else if (strcmp (buf, "Mar") == 0) {
- X str[2] = '0';
- X str[3] = '3';
- X } else if (strcmp (buf, "Apr") == 0) {
- X str[2] = '0';
- X str[3] = '4';
- X } else if (strcmp (buf, "May") == 0) {
- X str[2] = '0';
- X str[3] = '5';
- X } else if (strcmp (buf, "Jun") == 0) {
- X str[2] = '0';
- X str[3] = '6';
- X } else if (strcmp (buf, "Jul") == 0) {
- X str[2] = '0';
- X str[3] = '7';
- X } else if (strcmp (buf, "Aug") == 0) {
- X str[2] = '0';
- X str[3] = '8';
- X } else if (strcmp (buf, "Sep") == 0) {
- X str[2] = '0';
- X str[3] = '9';
- X } else if (strcmp (buf, "Oct") == 0) {
- X str[2] = '1';
- X str[3] = '0';
- X } else if (strcmp (buf, "Nov") == 0) {
- X str[2] = '1';
- X str[3] = '1';
- X } else if (strcmp (buf, "Dec") == 0) {
- X str[2] = '1';
- X str[3] = '2';
- X } else {
- X str[2] = '0';
- X str[3] = '0';
- X }
- X
- X str[6] = date[i++]; /* hour */
- X str[7] = date[i++];
- X
- X i++;
- X
- X str[8] = date[i++]; /* minutes */
- X str[9] = date[i++];
- X
- X i++;
- X
- X str[10] = date[i++]; /* seconds */
- X str[11] = date[i++];
- X
- X str[12] = '\0'; /* terminate string */
- X
- X return (str);
- }
- X
- X
- int artnum_comp (p1, p2)
- X char *p1;
- X char *p2;
- {
- X struct article_t *s1 = (struct article_t *) p1;
- X struct article_t *s2 = (struct article_t *) p2;
- X
- X /* s1->artnum less than s2->artnum */
- X if (s1->artnum < s2->artnum) {
- X return -1;
- X }
- X /* s1->artnum greater than s2->artnum */
- X if (s1->artnum > s2->artnum) {
- X return 1;
- X }
- X return 0;
- }
- X
- X
- int subj_comp (p1, p2)
- X char *p1;
- X char *p2;
- {
- X struct article_t *s1 = (struct article_t *) p1;
- X struct article_t *s2 = (struct article_t *) p2;
- X
- X /* return result of strcmp (reversed for descending) */
- X return (sort_art_type == SORT_BY_SUBJ_ASCEND
- X ? strcmp (s1->subject, s2->subject)
- X : strcmp (s2->subject, s1->subject));
- }
- X
- X
- int from_comp (p1, p2)
- X char *p1;
- X char *p2;
- {
- X struct article_t *s1 = (struct article_t *) p1;
- X struct article_t *s2 = (struct article_t *) p2;
- X
- X /* return result of strcmp (reversed for descending) */
- X return (sort_art_type == SORT_BY_FROM_ASCEND
- X ? strcmp (s1->from, s2->from)
- X : strcmp (s2->from, s1->from));
- }
- X
- X
- int date_comp (p1, p2)
- X char *p1;
- X char *p2;
- {
- X struct article_t *s1 = (struct article_t *) p1;
- X struct article_t *s2 = (struct article_t *) p2;
- X /* return result of strcmp (reversed for descending) */
- X return (sort_art_type == SORT_BY_DATE_ASCEND
- X ? strcmp (s1->date, s2->date)
- X : strcmp (s2->date, s1->date));
- }
- X
- X
- void set_article (art)
- X struct article_t *art;
- {
- X art->subject = (char *) 0;
- X art->from = (char *) 0;
- X art->name = (char *) 0;
- X art->date[0] = '\0';
- X art->archive = (char *) 0;
- X art->part = (char *) 0;
- X art->patch = (char *) 0;
- X art->unread = ART_UNREAD;
- X art->inthread = FALSE;
- X art->killed = FALSE;
- X art->tagged = FALSE;
- }
- SHAR_EOF
- echo 'File art.c is complete' &&
- chmod 0600 art.c ||
- echo 'restore of art.c failed'
- Wc_c="`wc -c < 'art.c'`"
- test 24273 -eq "$Wc_c" ||
- echo 'art.c: original size 24273, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= curses.c ==============
- if test -f 'curses.c' -a X"$1" != X"-c"; then
- echo 'x - skipping curses.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting curses.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'curses.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : curses.c
- X * Author : D.Taylor & I.Lea
- X * Created : ??-??-86
- X * Updated : 22-03-92
- X * Notes : This is a screen management library borrowed with permission
- X * from the Elm mail system (a great mailer--I highly recommend
- X * it!).This library was hacked to provide what tin needs.
- X * Copyright : Copyright (c) 1986-92 Dave Taylor & Iain Lea
- X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
- X */
- X
- #include <stdio.h>
- #include <curses.h>
- X
- #define DEFAULT_LINES_ON_TERMINAL 24
- #define DEFAULT_COLUMNS_ON_TERMINAL 80
- X
- int LINES = 23;
- int COLS = 80;
- int inverse_okay = TRUE;
- static int _inraw = FALSE; /* are we IN rawmode? */
- X
- X
- #ifndef INDEX_DAEMON
- X
- #ifndef MINIX
- # include <sys/ioctl.h>
- #endif
- X
- #define BACKSPACE '\b'
- #define VERY_LONG_STRING 2500
- X
- #ifdef BSD
- # ifndef BSD4_1
- # include <sgtty.h>
- # else
- # include <termio.h>
- # endif
- #else
- # ifndef SYSV
- # ifndef MINIX
- # ifdef sinix
- # include <termios.h>
- # else
- # include <termio.h>
- # endif
- # else
- # include <sgtty.h>
- # endif
- # endif
- #endif
- X
- #include <ctype.h>
- X
- #define TTYIN 0
- X
- #ifdef SHORTNAMES
- # define _clearinverse _clrinv
- # define _cleartoeoln _clrtoeoln
- # define _cleartoeos _clr2eos
- #endif
- X
- #if defined(BSD) || defined(MINIX)
- # define TCGETA TIOCGETP
- # define TCSETAW TIOCSETP
- X
- struct sgttyb _raw_tty,
- X _original_tty;
- #else
- # ifdef sinix
- # ifndef TCGETA
- # define TCGETA STCGETA
- # endif
- # ifndef TCSETA
- # define TCSETAW STCSETAW
- # endif
- struct termios _raw_tty,
- X _original_tty;
- # else
- struct termio _raw_tty,
- X _original_tty;
- # endif
- #endif
- X
- static char *_clearscreen, *_moveto, *_cleartoeoln, *_cleartoeos,
- X *_setinverse, *_clearinverse, *_setunderline, *_clearunderline,
- X *_terminalinit, *_terminalend;
- X
- static int _lines,_columns;
- X
- static char _terminal[1024]; /* Storage for terminal entry */
- static char _capabilities[1024]; /* String for cursor motion */
- X
- static char *ptr = _capabilities; /* for buffering */
- X
- int outchar (); /* char output for tputs */
- extern char *tgetstr (); /* Get termcap capability */
- extern char *tgoto (); /* and the goto stuff */
- X
- #endif /* INDEX_DAEMON */
- X
- #include "tin.h"
- X
- X
- int InitScreen ()
- {
- #ifndef INDEX_DAEMON
- X
- X extern int tgetent(); /* get termcap entry */
- X char termname[40], *p;
- X
- X if ((p = (char *) getenv ("TERM")) == NULL) {
- X fprintf (stderr, "%s: TERM variable must be set to use screen capabilities\n", progname);
- X return (FALSE);
- X }
- X if (strcpy (termname, p) == NULL) {
- X fprintf (stderr,"%s: Can't get TERM variable\n", progname);
- X return (FALSE);
- X }
- X if (tgetent (_terminal, termname) != 1) {
- X fprintf (stderr,"%s: Can't get entry for TERM\n", progname);
- X return (FALSE);
- X }
- X
- X /* load in all those pesky values */
- X _clearscreen = tgetstr ("cl", &ptr);
- X _moveto = tgetstr ("cm", &ptr);
- X _cleartoeoln = tgetstr ("ce", &ptr);
- X _cleartoeos = tgetstr ("cd", &ptr);
- X _lines = tgetnum ("li");
- X _columns = tgetnum ("co");
- X _setinverse = tgetstr ("so", &ptr);
- X _clearinverse = tgetstr ("se", &ptr);
- X _setunderline = tgetstr ("us", &ptr);
- X _clearunderline = tgetstr ("ue", &ptr);
- X _terminalinit = tgetstr ("ti", &ptr);
- X _terminalend = tgetstr ("te", &ptr);
- X
- X InitWin ();
- X
- X if (!_clearscreen) {
- X fprintf (stderr,
- X "%s: Terminal must have clearscreen (cl) capability\n",progname);
- X return (FALSE);
- X }
- X if (!_moveto) {
- X fprintf (stderr,
- X "%s: Terminal must have cursor motion (cm)\n", progname);
- X return (FALSE);
- X }
- X if (!_cleartoeoln) {
- X fprintf (stderr,
- X "%s: Terminal must have clear to end-of-line (ce)\n", progname);
- X return (FALSE);
- X }
- X if (!_cleartoeos) {
- X fprintf (stderr,
- X "%s: Terminal must have clear to end-of-screen (cd)\n", progname);
- X return (FALSE);
- X }
- X if (_lines == -1)
- X _lines = DEFAULT_LINES_ON_TERMINAL;
- X if (_columns == -1)
- X _columns = DEFAULT_COLUMNS_ON_TERMINAL;
- X return (TRUE);
- X
- #else
- X
- X return (FALSE);
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * returns the number of lines and columns on the display.
- X */
- X
- void ScreenSize (num_lines, num_columns)
- X int *num_lines, *num_columns;
- {
- #ifndef INDEX_DAEMON
- X
- X if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
- X if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
- X
- X *num_lines = _lines - 1; /* assume index from zero*/
- X *num_columns = _columns; /* assume index from one */
- X
- #endif /* INDEX_DAEMON */
- }
- X
- void InitWin ()
- {
- #ifndef INDEX_DAEMON
- X
- X if (_terminalinit) {
- X tputs (_terminalinit, 1, outchar);
- X fflush (stdout);
- X }
- X
- #endif /* INDEX_DAEMON */
- }
- X
- void EndWin ()
- {
- #ifndef INDEX_DAEMON
- X
- X if (_terminalend) {
- X tputs (_terminalend, 1, outchar);
- X fflush (stdout);
- X }
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * clear the screen: returns -1 if not capable
- X */
- X
- void ClearScreen ()
- {
- #ifndef INDEX_DAEMON
- X
- X tputs (_clearscreen, 1, outchar);
- X fflush (stdout); /* clear the output buffer */
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * move cursor to the specified row column on the screen.
- X * 0,0 is the top left!
- X */
- X
- void MoveCursor (row, col)
- X int row, col;
- {
- #ifndef INDEX_DAEMON
- X
- X char *stuff, *tgoto();
- X
- X stuff = tgoto (_moveto, col, row);
- X tputs (stuff, 1, outchar);
- X fflush (stdout);
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * clear to end of line
- X */
- X
- void CleartoEOLN ()
- {
- #ifndef INDEX_DAEMON
- X
- X tputs (_cleartoeoln, 1, outchar);
- X fflush (stdout); /* clear the output buffer */
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * clear to end of screen
- X */
- X
- void CleartoEOS ()
- {
- #ifndef INDEX_DAEMON
- X
- X int i;
- X
- X if (_cleartoeos) {
- X tputs (_cleartoeos, 1, outchar);
- X } else {
- X for (i=_lines ; i < _lines ; i++) {
- X MoveCursor (i, 0);
- X CleartoEOLN ();
- X }
- X }
- X fflush (stdout); /* clear the output buffer */
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * set inverse video mode
- X */
- X
- void StartInverse ()
- {
- #ifndef INDEX_DAEMON
- X
- X if (_setinverse && inverse_okay)
- X tputs (_setinverse, 1, outchar);
- X fflush (stdout);
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * compliment of startinverse
- X */
- X
- void EndInverse ()
- {
- #ifndef INDEX_DAEMON
- X
- X if (_clearinverse && inverse_okay)
- X tputs (_clearinverse, 1, outchar);
- X fflush (stdout);
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * returns either 1 or 0, for ON or OFF
- X */
- X
- int RawState()
- {
- X return (_inraw);
- }
- X
- /*
- X * state is either TRUE or FALSE, as indicated by call
- X */
- X
- void Raw(state)
- X int state;
- {
- #ifndef INDEX_DAEMON
- X
- X if (state == FALSE && _inraw) {
- X (void) ioctl(TTYIN, TCSETAW, &_original_tty);
- X _inraw = 0;
- X }
- X else if (state == TRUE && ! _inraw) {
- X
- X (void) ioctl(TTYIN, TCGETA, &_original_tty); /** current setting **/
- X
- X (void) ioctl(TTYIN, TCGETA, &_raw_tty); /** again! **/
- #if defined(BSD) || defined(MINIX)
- X _raw_tty.sg_flags &= ~(ECHO | CRMOD); /* echo off */
- X _raw_tty.sg_flags |= CBREAK; /* raw on */
- #else
- X _raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
- X
- X _raw_tty.c_cc[VMIN] = '\01'; /* minimum # of chars to queue */
- X _raw_tty.c_cc[VTIME] = '\0'; /* minimum time to wait for input */
- #endif
- X
- X (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
- X
- X _inraw = 1;
- X }
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * read a character with Raw mode set!
- X */
- X
- int ReadCh()
- {
- #ifndef INDEX_DAEMON
- X
- X register int result;
- X char ch;
- X
- #ifdef READ_CHAR_HACK
- #undef getc
- X ch = getc (stdin);
- X return ((ch == EOF) ? EOF : ch & 0xFF);
- #else
- X result = read(0, &ch, 1);
- X return((result <= 0 ) ? EOF : ch & 0xFF);
- #endif
- X
- #endif /* INDEX_DAEMON */
- }
- X
- /*
- X * output a character. From tputs... (Note: this CANNOT be a macro!)
- X */
- X
- int outchar(c)
- X char c;
- {
- X putc(c, stdout);
- }
- SHAR_EOF
- chmod 0600 curses.c ||
- echo 'restore of curses.c failed'
- Wc_c="`wc -c < 'curses.c'`"
- test 7612 -eq "$Wc_c" ||
- echo 'curses.c: original size 7612, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= debug.c ==============
- if test -f 'debug.c' -a X"$1" != X"-c"; then
- echo 'x - skipping debug.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting debug.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'debug.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : debug.c
- X * Author : I.Lea
- X * Created : 01-04-91
- X * Updated : 07-03-92
- X * Notes : debug routines
- 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
- int debug;
- X
- /*
- X * nntp specific debug routines
- X */
- X
- void debug_nntp (func, line)
- X char *func;
- X char *line;
- {
- #ifdef DEBUG
- X FILE *fp;
- X
- X if (debug != 1)
- X return;
- X
- X if ((fp = fopen ("/tmp/NNTP","a+")) != NULL) {
- X fprintf (fp,"%s: %s\n", func, line);
- X fclose (fp);
- X chmod ("/tmp/NNTP", 0666);
- X }
- #endif
- }
- X
- X
- void debug_nntp_respcode (respcode)
- X int respcode;
- {
- #ifdef DEBUG
- X debug_nntp ("get_respcode", nntp_respcode (respcode));
- #endif
- }
- X
- /*
- X * tin specific debug routines
- X */
- X
- void debug_print_arts ()
- {
- #ifdef DEBUG
- X int i;
- X
- X if (debug != 2)
- X return;
- X
- X for (i = 0; i < top; i++) { /* for each group */
- X debug_print_header (&arts[i]);
- X }
- #endif
- }
- X
- X
- void debug_print_header (s)
- X struct article_t *s;
- {
- #ifdef DEBUG
- X FILE *fp;
- X
- X if (debug != 2)
- X return;
- X
- X if ((fp = fopen ("/tmp/ARTS","a+")) != NULL) {
- X fprintf (fp,"art=[%5ld] killed=[%s]\n", s->artnum,
- X (s->tagged ? "TRUE" : "FALSE"));
- X fprintf (fp,"subj=[%-38s]\n", s->subject);
- X fprintf (fp,"from=[%s] name=[%s]\n", s->from, s->name);
- X if (s->archive) {
- X fprintf (fp, "arch=[%-38s] ", s->archive);
- X } else {
- X fprintf (fp, "arch=[] ");
- X }
- X if (s->part) {
- X fprintf (fp, "part=[%s] ", s->part);
- X } else {
- X fprintf (fp, "part=[] ");
- X }
- X if (s->patch) {
- X fprintf (fp, "patch=[%s]\n", s->patch);
- X } else {
- X fprintf (fp, "patch=[]\n");
- X }
- X fprintf (fp,"thread=[%d] inthread=[%d] unread=[%d]\n",
- X s->thread, s->inthread, s->unread);
- /* fprintf (fp,"thread=[%s] inthread=[%s] unread=[%s]\n",
- X (s->thread == ART_NORMAL ? "ART_NORMAL" : "ART_EXPIRED"),
- X (s->inthread ? "TRUE" : "FALSE"),
- X (s->unread ? "TRUE" : "FALSE"));
- */
- X fflush (fp);
- X fclose (fp);
- X chmod ("/tmp/DUMP", 0666);
- X }
- #endif
- }
- X
- X
- void debug_print_comment (comment)
- X char *comment;
- {
- #ifdef DEBUG
- X FILE *fp;
- X
- X if (debug != 2)
- X return;
- X
- X if ((fp = fopen ("/tmp/BASE","a+")) != NULL) {
- X fprintf (fp,"\n%s\n\n", comment);
- X fflush (fp);
- X fclose (fp);
- X chmod ("/tmp/BASE", 0666);
- X }
- #endif
- }
- X
- X
- void debug_print_base ()
- {
- #ifdef DEBUG
- X FILE *fp;
- X int i;
- X
- X if (debug != 2)
- X return;
- X
- X if ((fp = fopen ("/tmp/BASE","a+")) != NULL) {
- X for (i = 0; i < top_base; i++) {
- X fprintf (fp, "base[%3d]=[%5ld]\n",i,base[i]);
- X }
- X fflush (fp);
- X fclose (fp);
- X chmod ("/tmp/BASE", 0666);
- X }
- #endif
- }
- X
- X
- void debug_print_active ()
- {
- #ifdef DEBUG
- X FILE *fp;
- X int i;
- X
- X if (debug > 0)
- X return;
- X
- X if ((fp = fopen ("/tmp/ACTIVE","w")) != NULL) {
- X for (i = 0; i < num_active; i++) { /* for each group */
- X fprintf (fp, "[%4d]=[%-28s] max=[%4ld] min=[%4ld] mod=[%c] nxt=[%4d] flag=[%d] read=[%d] thread=[%d]\n",
- X i, active[i].name, active[i].max, active[i].min,
- X active[i].moderated, active[i].next, active[i].flag,
- X active[i].read, active[i].thread);
- X }
- X fflush (fp);
- X fclose (fp);
- X chmod ("/tmp/ACTIVE", 0666);
- X }
- #endif
- }
- SHAR_EOF
- chmod 0600 debug.c ||
- echo 'restore of debug.c failed'
- Wc_c="`wc -c < 'debug.c'`"
- test 3371 -eq "$Wc_c" ||
- echo 'debug.c: original size 3371, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= feed.c ==============
- if test -f 'feed.c' -a X"$1" != X"-c"; then
- echo 'x - skipping feed.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting feed.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'feed.c' &&
- /*
- X * Project : tin - a threaded Netnews reader
- X * Module : feed.c
- X * Author : I.Lea
- X * Created : 31-08-91
- X * Updated : 18-03-92
- X * Notes : provides same interface to mail,pipe,print and save commands
- 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"
- X
- extern char *glob_group; /* Group name */
- extern char note_h_date[LEN]; /* Date: */
- extern char note_h_newsgroups[LEN]; /* Newsgroups: */
- extern char note_h_subj[LEN]; /* Subject: */
- extern FILE *note_fp; /* the body of the current article */
- extern int note_end; /* end of article ? */
- extern int note_page; /* what page we're on */
- extern long note_mark[MAX_PAGES]; /* ftells on beginnings of pages */
- X
- char default_mail_address[LEN];
- char default_pipe_command[LEN];
- char default_save_file[LEN];
- char default_regex_pattern[LEN];
- char proc_ch_default; /* set in change_rcfile () */
- X
- X
- void feed_articles (function, level, prompt, respnum, group_path)
- X int function;
- X int level;
- X char *prompt;
- X int respnum;
- X char *group_path;
- {
- #ifndef INDEX_DAEMON
- X
- X char address[LEN];
- X char command[LEN];
- X char file[LEN], *p;
- X char mailbox[LEN];
- X char pattern[LEN];
- X char ch = 'a', ch_default = 'a';
- X char proc_ch = proc_ch_default;
- X FILE *fp;
- X int b, i, j, count = 1;
- X int confirm;
- X int is_mailbox = FALSE;
- X int orig_note_end;
- X int orig_note_page;
- X int patlen;
- X int ret1 = FALSE;
- X int ret2 = FALSE;
- X int redraw_screen = FALSE;
- X
- X if (level == PAGE_LEVEL) {
- X orig_note_end = note_end;
- X orig_note_page = note_page;
- X }
- X
- X b = which_thread (respnum);
- X
- X if (num_of_tagged_files) {
- X ch_default = 'T';
- X }
- X if (! num_of_tagged_files && num_of_responses (b)) {
- X ch_default = 't';
- X }
- X
- X if ((save_archive_name == FALSE || arts[respnum].archive == (char *) 0) ||
- X (save_archive_name == TRUE && function != FEED_SAVE) ||
- X ch_default == 'T') {
- X do {
- X sprintf (msg, "%s%s%c", prompt, txt_art_thread_regex_tag, ch_default);
- X wait_message (msg);
- X MoveCursor (LINES, (int) strlen (msg)-1);
- X if ((ch = (char) ReadCh ()) == CR)
- X ch = ch_default;
- X } while (ch != ESC && ch != 'a' && ch != 't' && ch != 'T' && ch != 'r' && ch != 'e');
- X } else {
- X file[0] = '\0';
- X ch = ch_default;
- X if (str_str (glob_group, "sources", 7)) {
- X proc_ch = 's'; /* *source* group */
- X } else if (str_str (glob_group, "binaries", 8)) {
- X proc_ch = 'u'; /* *binaries* group */
- X } else {
- X proc_ch = 's';
- X }
- X }
- X
- X if (ch == 'e' || ch == ESC) { /* exit */
- X clear_message ();
- X return;
- X }
- X
- X if (ch == 'r') {
- X sprintf (msg, txt_feed_pattern, default_regex_pattern);
- X if (! prompt_string (msg, pattern)) {
- X clear_message ();
- X return;
- X }
- X if (strlen (pattern)) {
- X my_strncpy (default_regex_pattern, pattern, LEN);
- X } else {
- X if (default_regex_pattern[0]) {
- X my_strncpy (pattern, default_regex_pattern, LEN);
- X } else {
- X info_message (txt_no_match);
- X return;
- X }
- X }
- X }
- X
- X switch (function) {
- X case FEED_MAIL:
- X sprintf (msg, txt_mail_art_to, default_mail_address);
- X if (! prompt_string (msg, address)) {
- X clear_message ();
- X return;
- X }
- X if (strlen (address)) {
- X strcpy (default_mail_address, address);
- X } else {
- X if (default_mail_address[0]) {
- X strcpy (address, default_mail_address);
- X } else {
- X info_message (txt_no_mail_address);
- X return;
- X }
- X }
- X break;
- X case FEED_PIPE:
- X sprintf (msg, txt_pipe_to_command, default_pipe_command);
- X if (! prompt_string (msg, command)) {
- X clear_message ();
- X return;
- X }
- X if (strlen (command)) {
- X strcpy (default_pipe_command, command);
- X } else {
- X if (default_pipe_command[0]) {
- X strcpy (command, default_pipe_command);
- X } else {
- X info_message (txt_no_command);
- X return;
- X }
- X }
- X
- X if ((fp = popen (command, "w")) == NULL) {
- X error_message (txt_command_failed_s, command);
- X return;
- X }
- X wait_message (txt_piping);
- X Raw (FALSE);
- X break;
- X case FEED_PRINT:
- X if (default_printer) {
- #ifdef sinix
- X sprintf (command, "%s -dru=%s %s",
- X printer, get_val ("PRINTER","ps"), redirect_output);
- #else
- X sprintf (command, "%s -P%s %s",
- X printer, get_val ("PRINTER","ps"), redirect_output);
- #endif
- X } else {
- X if (cmd_line_printer[0]) {
- X sprintf (command, "%s %s",
- X cmd_line_printer, redirect_output);
- X } else {
- X sprintf (command, "%s %s",
- X printer, redirect_output);
- X }
- X }
- X if ((fp = popen (command, "w")) == NULL) {
- X error_message (txt_command_failed_s, command);
- X return;
- X }
- X break;
- X case FEED_SAVE: /* ask user for filename */
- X free_save_array ();
- X if ((save_archive_name == FALSE || arts[respnum].archive == (char *) 0)) {
- X sprintf (msg, txt_save_filename, default_save_file);
- X if (! prompt_string (msg, file)) {
- X clear_message ();
- X return;
- X }
- X if (strlen (file)) {
- X strcpy (default_save_file, file);
- 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 note_page = art_open (arts[respnum].artnum, group_path);
- X }
- X switch (function) {
- X case FEED_MAIL:
- X redraw_screen = mail_to_someone (address, TRUE);
- 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 print_file (fp, respnum, 1);
- 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 confirm = TRUE;
- 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 note_page = art_open (arts[i].artnum, group_path);
- X switch (function) {
- X case FEED_MAIL:
- X mail_to_someone (address, confirm);
- X confirm = FALSE;
- 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 print_file (fp, respnum, count);
- X count++;
- 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 confirm = TRUE;
- 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 note_page = art_open (arts[j].artnum, group_path);
- X switch (function) {
- X case FEED_MAIL:
- X mail_to_someone (address, confirm);
- X confirm = FALSE;
- 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 print_file (fp, respnum, count);
- X count++;
- 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 confirm = TRUE;
- 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 note_page = art_open (arts[i].artnum, group_path);
- X switch (function) {
- X case FEED_MAIL:
- X mail_to_someone (address, confirm);
- X confirm = FALSE;
- 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 print_file (fp, respnum, count);
- X count++;
- 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 note_page = 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 }
- X
- #endif /* INDEX_DAEMON */
- }
- X
- X
- void print_file (fp, respnum, count)
- X FILE *fp;
- X int respnum;
- X int count;
- {
- X sprintf (msg, "%s%d", txt_printing, count);
- X wait_message (msg);
- X
- X if (print_header) {
- X fseek(note_fp, 0L, 0);
- X } else {
- X fprintf (fp, "Newsgroups: %s\n", note_h_newsgroups);
- 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);
- }
- SHAR_EOF
- chmod 0600 feed.c ||
- echo 'restore of feed.c failed'
- Wc_c="`wc -c < 'feed.c'`"
- test 12199 -eq "$Wc_c" ||
- echo 'feed.c: original size 12199, 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 : 13-03-92
- 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 if (prompt == (char *) 0) {
- X prompt = "";
- 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 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)
- #else
- static void gl_addchar (c)
- X int c;
- #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 11438 -eq "$Wc_c" ||
- echo 'getline.c: original size 11438, 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 : I.Lea & R.Skrenta
- X * Created : 01-04-91
- X * Updated : 22-03-92
- X * Notes :
- X * Copyright : (c) Copyright 1991-92 by Iain Lea & 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
- 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;
- {
- #ifndef INDEX_DAEMON
- X
- X char group_path[LEN];
- X char buf[32];
- 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 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 */
- #if 0 /* JBR */
- 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 ();
- #endif
- 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 continue;
- X }
- X 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);
- SHAR_EOF
- true || echo 'restore of group.c failed'
- fi
- echo 'End of tin1.1 part 4'
- echo 'File group.c is continued in part 5'
- echo 5 > _shar_seq_.tmp
- exit 0
-
- --
- NAME Iain Lea
- EMAIL iain%anl433.uucp@germany.eu.net
- SNAIL Siemens AG, ANL A433SZ, Gruendlacher Str. 248, 8510 Fuerth, Germany.
- PHONE +49-911-3089-407 (work) +49-911-331963 (home) +49-911-3089-290 (FAX)
- --
- 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...
-