home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-09-25 | 49.5 KB | 2,469 lines |
- Newsgroups: comp.sources.misc
- From: iain@estevax.uucp (Iain J. Lea)
- Subject: v23i019: tin - threaded full screen newsreader v1.0 PL2, Part05/09
- Message-ID: <1991Sep25.205221.2056@sparky.imd.sterling.com>
- X-Md4-Signature: 4a1bc3779892384aae5396602b0d9d7a
- Date: Wed, 25 Sep 1991 20:52:21 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: iain@estevax.uucp (Iain J. Lea)
- Posting-number: Volume 23, Issue 19
- Archive-name: tin/part05
- Environment: BSD, SCO, ISC, SUNOS, SYSVR3, SYSVR4, ULTRIX, XENIX
-
- #!/bin/sh
- # this is tin.shar.05 (part 5 of tin1.02)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file misc.c continued
- #
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- if test ! -r shar3_seq_.tmp; then
- echo "Please unpack part 1 first!"
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 5; then
- echo "Please unpack part $Scheck next!"
- exit 1
- else
- exit 0
- fi
- ) < shar3_seq_.tmp || exit 1
- echo "x - Continuing file misc.c"
- sed 's/^X//' << 'SHAR_EOF' >> misc.c &&
- X int line;
- X char *cond;
- X{
- X fprintf(stderr, "%s: assertion failure: %s (%d): %s\n",progname,file,line,cond);
- X fflush (stderr);
- X exit(1);
- X}
- X
- X
- Xvoid copy_fp(a, b, prefix)
- X FILE *a;
- X FILE *b;
- X char *prefix;
- X{
- X char buf[8192];
- X
- X while (fgets (buf, sizeof (buf), a) != NULL)
- X fprintf (b, "%s%s", prefix, buf);
- X}
- X
- X
- Xchar *get_val(env, def)
- X char *env; /* Environment variable we're looking for */
- X char *def; /* Default value if no environ value found */
- X{
- X char *ptr;
- X
- X if ((ptr = (char *) getenv(env)) != NULL)
- X return (ptr);
- X else
- X return (def);
- X}
- X
- X
- Xint invoke_editor (nam)
- X char *nam;
- X{
- X char buf[LEN+1];
- X static char editor[LEN+1];
- X static int first = TRUE;
- X
- X if (first) {
- X strcpy (editor, get_val ("EDITOR", DEFAULT_EDITOR));
- X first = FALSE;
- X }
- X
- X#ifdef DONT_USE_START_LINE
- X sprintf (buf, "%s %s", editor, nam);
- X#else
- X sprintf (buf, "%s +%d %s", editor, start_line_offset, nam);
- X#endif
- X
- X printf ("%s", buf);
- X return invoke_cmd (buf);
- X}
- X
- X
- Xvoid shell_escape ()
- X{
- X char shell[LEN+1];
- X char *p;
- X
- X#ifdef SIGTSTP
- X void (*susp)();
- X#endif
- X
- X if (! parse_string (txt_shell_escape, shell))
- X strcpy (shell, get_val ("SHELL", DEFAULT_SHELL));
- X
- X for (p = shell; *p && (*p == ' ' || *p == '\t'); p++)
- X continue;
- X
- X if (! *p)
- X strcpy (shell, get_val ("SHELL", DEFAULT_SHELL));
- X
- X Raw (FALSE);
- X
- X set_real_uid_gid ();
- X
- X fputs ("\r\n", stdout);
- X
- X#ifdef SIGTSTP
- X if (do_sigtstp)
- X susp = signal (SIGTSTP, SIG_DFL);
- X#endif
- X
- X system (p);
- X
- X#ifdef SIGTSTP
- X if (do_sigtstp)
- X signal (SIGTSTP, susp);
- X#endif
- X
- X set_tin_uid_gid ();
- X
- X Raw (TRUE);
- X
- X mail_setup ();
- X
- X continue_prompt ();
- X
- X if (draw_arrow_mark) {
- X ClearScreen ();
- X }
- X}
- X
- X
- Xvoid tin_done (ret)
- X int ret;
- X{
- X nntp_finish (); /* disconnect from NNTP server */
- X free_all_arrays (); /* deallocate all arrays */
- X ClearScreen();
- X Raw(FALSE);
- X exit(ret);
- X}
- X
- X/*
- X * Load the active file into active[] and create copy of active ~/.tin/active
- X */
- X
- Xint read_active ()
- X{
- X FILE *fp;
- X char *p, *q;
- X char buf[LEN+1];
- X int created, i;
- X long h;
- X
- X num_active = 0;
- X
- X if ((fp = open_active_fp ()) == NULL) {
- X if (compiled_with_nntp) {
- X printf ("Cannot open %s. Try %s -r to read news via NNTP.\n",
- X active_file, progname);
- X } else {
- X printf (txt_cannot_open, active_file);
- X }
- X fflush (stdout);
- X exit (1);
- X }
- X
- X while (fgets (buf, sizeof (buf), fp) != NULL) {
- X for (p = buf; *p && *p != ' '; p++)
- X continue;
- X if (*p != ' ') {
- X error_message (txt_bad_active_file, "");
- X continue;
- X }
- X *p++ = '\0';
- X
- X if (num_active >= max_active)
- X expand_active ();
- X
- X h = hash_groupname (buf);
- X
- X if (group_hash[h] == -1) {
- X group_hash[h] = num_active;
- X } else { /* hash linked list chaining */
- X for (i=group_hash[h]; active[i].next >= 0; i=active[i].next) {
- X if (strcmp(active[i].name, buf) == 0) {
- X goto read_active_continue; /* kill dups */
- X }
- X }
- X if (strcmp(active[i].name, buf) == 0)
- X goto read_active_continue;
- X active[i].next = num_active;
- X }
- X
- X for (q = p; *q && *q != ' '; q++)
- X continue;
- X if (*q != ' ') {
- X error_message (txt_bad_active_file, "");
- X continue;
- X }
- X
- X active[num_active].name = str_dup (buf);
- X active[num_active].max = (long) atol (p);
- X active[num_active].min = (long) atol (q);
- X active[num_active].next = -1; /* hash chaining */
- X active[num_active].flag = NOTGOT; /* not in my_group[] yet */
- X
- X num_active++;
- X
- Xread_active_continue:;
- X
- X }
- X fclose (fp);
- X
- X /*
- X * exit if active file is empty
- X */
- X if (! num_active) {
- X error_message ("%s contains no newsgroups. Exiting.", active_file);
- X exit (1);
- X }
- X
- X /*
- X * create backup of LIBDIR/active for use by -n option to notify new groups
- X */
- X created = backup_active (TRUE);
- X
- X#ifdef SORT_ACTIVE_FILE /* DOES NOT WORK - ERROR */
- X if (num_active) {
- X qsort (active, num_active, sizeof (struct group_ent), active_comp);
- X }
- X#endif
- X
- X debug_print_active ();
- X
- X return (created);
- X}
- X
- X
- X#ifdef SORT_ACTIVE_FILE /* DOES NOT WORK - ERROR */
- Xint active_comp (p1, p2)
- X char *p1;
- X char *p2;
- X {
- X struct group_ent *s1 = (struct group_ent *) p1;
- X struct group_ent *s2 = (struct group_ent *) p2;
- X
- X /* s1->name less than s2->name */
- X if (strcmp (s1->name, s2->name) < 0) {
- X return -1;
- X }
- X /* s1->name greater than s2->name */
- X if (strcmp (s1->name, s2->name) > 0) {
- X return 1;
- X }
- X return 0;
- X}
- X#endif
- X
- X
- X/*
- X * create ~/.tin/active from LIBDIR/active if it does not exist
- X */
- X
- Xint backup_active (create)
- X int create;
- X{
- X char buf[LEN];
- X FILE *fp;
- X int created = FALSE;
- X int i;
- X struct stat sb;
- X
- X set_real_uid_gid ();
- X
- X sprintf (buf, "%s/active", rcdir);
- X
- X if (create) {
- X if (stat (buf, &sb) != -1) {
- X goto backup_active_done;
- X }
- X }
- X
- X if ((fp = fopen (buf, "w")) != NULL) {
- X for (i = 0; i < num_active ; i++) { /* for each group */
- X fprintf (fp, "%s\n", active[i].name);
- X }
- X fclose (fp);
- X chmod (buf, 0644);
- X created = TRUE;
- X }
- X
- Xbackup_active_done:
- X set_tin_uid_gid ();
- X return (created);
- X}
- X
- X
- Xvoid add_signature (fp, flag)
- X FILE *fp;
- X int flag;
- X{
- X FILE *sigf;
- X
- X if ((sigf = fopen(signature, "r")) != NULL) {
- X if (flag) {
- X fprintf(fp, "\n--\n");
- X copy_fp(sigf, fp, "");
- X }
- X fclose(sigf);
- X return;
- X }
- X
- X if ((sigf = fopen(sig, "r")) != NULL) {
- X fprintf(fp, "\n--\n");
- X copy_fp(sigf, fp, "");
- X fclose(sigf);
- X }
- X}
- X
- X
- X#ifdef USE_MKDIR
- Xmkdir (path, mode)
- X char *path;
- X int mode;
- X{
- X char buf[LEN+1];
- X struct stat sb;
- X
- X sprintf(buf, "mkdir %s", path);
- X if (stat (path, &sb) == -1) {
- X system (buf);
- X chmod (path, mode);
- X }
- X}
- X#endif
- X
- X
- Xlong hash_groupname (buf) /* hash group name for fast lookup later */
- X char *buf;
- X{
- X unsigned long h;
- X unsigned char *t = (unsigned char *) buf;
- X
- X h = *t++;
- X while (*t)
- X h = ((h << 1) ^ *t++) % TABLE_SIZE;
- X
- X return h;
- X}
- X
- X
- Xvoid rename_file (old_filename, new_filename)
- X char *old_filename;
- X char *new_filename;
- X{
- X char buf[LEN];
- X
- X unlink (new_filename);
- X if (link (old_filename, new_filename) == 1) {
- X sprintf (buf, txt_rename_error, old_filename, new_filename);
- X error_message (buf, "TWO");
- X return;
- X }
- X if (unlink (old_filename) == -1) {
- X sprintf (buf, txt_rename_error, old_filename, new_filename);
- X error_message (buf, "THREE");
- X return;
- X }
- X}
- X
- X
- Xchar *str_dup (str)
- X char *str;
- X{
- X char *dup = (char *) 0;
- X
- X assert (str != (char *) 0);
- X
- X if (str) {
- X dup = my_malloc (strlen (str)+1);
- X strcpy (dup, str);
- X }
- X return dup;
- X}
- X
- X
- Xint invoke_cmd (nam)
- X char *nam;
- X{
- X int ret;
- X
- X#ifdef SIGTSTP
- X void (*susp)();
- X#endif
- X
- X Raw (FALSE);
- X set_real_uid_gid ();
- X
- X#ifdef SIGTSTP
- X if (do_sigtstp)
- X susp = signal(SIGTSTP, SIG_DFL);
- X#endif
- X
- X ret = system (nam);
- X
- X#ifdef SIGTSTP
- X if (do_sigtstp)
- X signal (SIGTSTP, susp);
- X#endif
- X
- X set_tin_uid_gid ();
- X Raw (TRUE);
- X
- X return ret == 0;
- X}
- X
- X
- Xvoid draw_percent_mark (cur_num, max_num)
- X int cur_num;
- X int max_num;
- X{
- X char buf[32];
- X int percent = 0;
- X
- X if (NOTESLINES <= 0) {
- X return;
- X }
- X
- X if (cur_num <= 0 && max_num <= 0) {
- X return;
- X }
- X
- X percent = cur_num * 100 / max_num;
- X sprintf (buf, "%s(%d%%) [%d/%d]", txt_more, percent, cur_num, max_num);
- X MoveCursor (LINES, (COLS - (int) strlen (buf))-(1+BLANK_PAGE_COLS));
- X StartInverse ();
- X printf ("%s", buf);
- X fflush (stdout);
- X EndInverse ();
- X}
- X
- X
- Xvoid set_real_uid_gid ()
- X{
- X setuid (real_uid);
- X setgid (real_gid);
- X}
- X
- X
- Xvoid set_tin_uid_gid ()
- X{
- X setuid (tin_uid);
- X setgid (tin_gid);
- X}
- X
- X
- Xvoid notify_groups ()
- X{
- X char buf[LEN];
- X FILE *fp;
- X int group_not_found;
- X int i, j, index;
- X int num = 0;
- X int update_old_active = FALSE;
- X struct notify_t {
- X char name[LEN];
- X int len;
- X } *old_active;
- X
- X set_real_uid_gid ();
- X
- X sprintf (buf, "%s/active", rcdir);
- X
- X if ((fp = fopen (buf, "r")) == NULL) {
- X error_message (txt_cannot_open, buf);
- X goto notify_groups_done;
- X }
- X
- X Raw (FALSE);
- X
- X printf ("Checking for new newsgroups...");
- X fflush (stdout);
- X
- X old_active = (struct notify_t *) my_malloc (sizeof (struct notify_t) * num_active);
- X if (old_active == (struct notify_t *) 0) {
- X error_message (txt_out_of_memory, progname);
- X goto notify_groups_done;
- X }
- X
- X while (fgets (old_active[num].name, sizeof (old_active[num].name), fp) != NULL) {
- X old_active[num].len = strlen (old_active[num].name)-1;
- X old_active[num].name[old_active[num].len] = '\0';
- X num++;
- X if (num == num_active) {
- X break;
- X }
- X }
- X
- X for (i = 0 ; i < num_active ; i++) {
- X group_not_found = TRUE;
- X for (j=0; j < num ; j++) {
- X if (strncmp (old_active[j].name, active[i].name, old_active[j].len) == 0) {
- X group_not_found = FALSE; /* found it so read in next group */
- X break;
- X }
- X }
- X
- X if (group_not_found) {
- X/*
- X&& strlen (active[i].name) == old_active[j].len) {
- X*/
- X update_old_active = TRUE;
- X printf ("\r\nSubscribe to %s (y/n): ", active[i].name);
- X fflush (stdout);
- X scanf ("%s", buf);
- X if (buf[0] == 'y') {
- X index = add_group (active[i].name, TRUE);
- X subscribe (active[my_group[index]].name, ':',
- X my_group[index], FALSE);
- X }
- X printf ("Checking...");
- X fflush (stdout);
- X }
- X }
- X fclose (fp);
- X
- X if (old_active != (struct notify_t *) 0) {
- X free (old_active);
- X old_active = (struct notify_t *) 0;
- X }
- X
- X Raw (TRUE);
- X
- X /*
- X * write active[] to ~/.tin/active
- X */
- X if (update_old_active) {
- X backup_active (FALSE);
- X }
- X
- Xnotify_groups_done:
- X set_tin_uid_gid ();
- X}
- X
- X
- Xvoid basename (dirname, basename)
- X char *dirname; /* argv[0] */
- X char *basename; /* progname is returned */
- X{
- X int i;
- X
- X strcpy (basename, dirname);
- X
- X for (i=(int) strlen(dirname)-1 ; i ; i--) {
- X if (dirname[i] == '/') {
- X strcpy (basename, dirname+(i+1));
- X break;
- X }
- X }
- X}
- X
- X
- X/*
- X * Record size of mailbox so we can detect if new mail has arrived
- X */
- X
- Xvoid mail_setup ()
- X{
- X struct stat buf;
- X
- X mailbox_name = get_val ("MAIL", mailbox);
- X
- X if (stat (mailbox_name, &buf) >= 0) {
- X mailbox_size = buf.st_size;
- X } else {
- X mailbox_size = 0;
- X }
- X}
- X
- X/*
- X * Return TRUE if new mail has arrived
- X */
- X
- Xint mail_check ()
- X{
- X struct stat buf;
- X
- X if (mailbox_name != NULL
- X && stat(mailbox_name, &buf) >= 0
- X && mailbox_size < buf.st_size)
- X return TRUE;
- X
- X return FALSE;
- X}
- SHAR_EOF
- echo "File misc.c is complete" &&
- $TOUCH -am 0923200291 misc.c &&
- chmod 0600 misc.c ||
- echo "restore of misc.c failed"
- set `wc -c misc.c`;Wc_c=$1
- if test "$Wc_c" != "19195"; then
- echo original size 19195, current size $Wc_c
- fi
- # ============= newsrc.c ==============
- echo "x - extracting newsrc.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > newsrc.c &&
- X/*
- X * Project : tin - a visual threaded usenet newsreader
- X * Module : newsrc.c
- X * Author : R.Skrenta / I.Lea
- X * Created : 01-04-91
- X * Updated : 23-09-91
- X * Release : 1.0
- X * Notes :
- X * Copyright : (c) Copyright 1991 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
- X#include "tin.h"
- X
- X
- X/*
- X * make a backup of users .newsrc in case of the bogie man
- X */
- X
- Xvoid backup_newsrc ()
- X{
- X char buf[8192];
- X FILE *fp_newsrc, *fp_backup;
- X
- X set_real_uid_gid ();
- X
- X if ((fp_newsrc = fopen (newsrc, "r")) != NULL) {
- X sprintf (buf, "%s/.oldnewsrc", homedir);
- X if ((fp_backup = fopen (buf, "w")) != NULL) {
- X while (fgets (buf, sizeof (buf), fp_newsrc) != NULL) {
- X fputs (buf, fp_backup);
- X }
- X fclose (fp_backup);
- X }
- X fclose (fp_newsrc);
- X }
- X
- X set_tin_uid_gid ();
- X}
- X
- X/*
- X * Read $HOME/.newsrc into my_group[]. my_group[] ints point to
- X * active[] entries. Sub_only determines whether we just read
- X * subscribed groups or all of them.
- X */
- X
- Xvoid read_newsrc (sub_only)
- X int sub_only; /* TRUE=subscribed groups only, FALSE=all groups */
- X{
- X char c, *p, buf[8192];
- X char old_groups[LEN];
- X FILE *fp, *fp_old;
- X int i;
- X int remove_old_groups = FALSE;
- X
- X local_top = 0;
- X
- X set_real_uid_gid ();
- X
- X if ((fp = fopen (newsrc, "r")) == NULL) { /* attempt to make a .newsrc */
- X for (i = 0; i < num_active; i++) {
- X if (local_top >= max_active) {
- X expand_active ();
- X }
- X my_group[local_top] = i;
- X active[i].flag = 0;
- X unread[local_top] = -1;
- X local_top++;
- X }
- X write_newsrc ();
- X return;
- X }
- X
- X sprintf (old_groups, "%s/.newsrc.%d", homedir, getpid ());
- X
- X while (fgets (buf, sizeof buf, fp) != NULL) {
- X p = buf;
- X while (*p && *p != '\n' && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X *p++ = '\0';
- X
- X if (c == '!' && sub_only)
- X continue; /* unsubscribed */
- X
- X#ifdef XXX
- X if (strncmp ("options ", buf, 8) == 0)
- X continue; /* options line */
- X#endif
- X
- X if ((i = add_group (buf, FALSE)) < 0) {
- X if (! remove_old_groups) {
- X if ((fp_old = fopen (old_groups, "w")) == NULL) {
- X error_message (txt_cannot_open, old_groups);
- X continue;
- X }
- X remove_old_groups = TRUE;
- X }
- X fprintf (fp_old, "%s\n", buf);
- X continue;
- X }
- X
- X if (c != '!') /* if we're subscribed to it */
- X active[my_group[i]].flag |= SUBS;
- X
- X unread[i] = parse_unread (p, my_group[i]);
- X }
- X fclose (fp);
- X
- X /*
- X * rewrite newsrc to get rid of any non-existant groups
- X */
- X if (remove_old_groups) {
- X fclose (fp_old);
- X rewrite_newsrc ();
- X }
- X
- X set_tin_uid_gid ();
- X}
- X
- X/*
- X * Write a new newsrc from my_group[] and active[] mygroup if
- X * rewriting to get rid of groups that don't exist any longer. Used
- X * to a create a new .newsrc if there isn't one already, or when
- X * the newsrc is reset.
- X */
- X
- Xvoid write_newsrc ()
- X{
- X FILE *fp;
- X int i;
- X
- X set_real_uid_gid ();
- X
- X if ((fp = fopen (newsrc, "w")) == NULL)
- X goto write_newsrc_done;
- X
- X for (i=0 ; i < num_active ; i++) {
- X fprintf (fp, "%s: \n", active[i].name);
- X }
- X
- X fclose (fp);
- X
- Xwrite_newsrc_done:
- X set_tin_uid_gid ();
- X}
- X
- X/*
- X * Rewrite newsrc to get rid of groups that don't exist any longer.
- X */
- X
- Xvoid rewrite_newsrc ()
- X{
- X char buf[8192], old[LEN+1];
- X char old_groups[LEN];
- X FILE *fp, *fp_old, *fp_new;
- X int found_old_group, len;
- X
- X set_real_uid_gid ();
- X
- X sprintf (old_groups, "%s/.newsrc.%d", homedir, getpid ());
- X
- X if ((fp = fopen (newsrc, "r")) == NULL)
- X goto removed_old_groups_done;
- X
- X if ((fp_old = fopen (old_groups, "r")) == NULL)
- X goto removed_old_groups_done;
- X
- X if ((fp_new = fopen (newnewsrc, "w")) == NULL)
- X goto removed_old_groups_done;
- X
- X while (fgets (buf, sizeof buf, fp) != NULL) { /* read group from newsrc */
- X rewind (fp_old);
- X found_old_group = FALSE;
- X while (fgets (old, sizeof old, fp_old) != NULL) { /* read group from oldgroups */
- X len = strlen (old)-1;
- X if ((buf[len] == ':' || buf[len] == '!') &&
- X strncmp (buf, old, len) == 0) {
- X old[len] = '\0';
- X fprintf (stderr, txt_not_in_active_file, old);
- X fprintf (stderr, ". Deleting.\n");
- X fflush (stderr);
- X found_old_group = TRUE;
- X }
- X }
- X if (! found_old_group) {
- X fprintf (fp_new, "%s", buf);
- X }
- X }
- X
- X fclose (fp);
- X fclose (fp_old);
- X fclose (fp_new);
- X
- X rename_file (newnewsrc, newsrc);
- X
- Xremoved_old_groups_done:
- X unlink (old_groups);
- X set_tin_uid_gid ();
- X}
- X
- X/*
- X * Load the sequencer rang lists and mark arts[] according to the
- X * .newsrc info for a particular group. i.e. rec.arts.comics: 1-94,97
- X */
- X
- Xvoid read_newsrc_line (group)
- X char *group;
- X{
- X FILE *fp;
- X char buf[8192];
- X char *p;
- X
- X if ((fp = fopen (newsrc, "r")) == NULL)
- X return;
- X
- X while (fgets (buf, sizeof buf, fp) != NULL) {
- X p = buf;
- X while (*p && *p != '\n' && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X *p++ = '\0';
- X if (strcmp (buf, group) != 0)
- X continue;
- X parse_seq (p);
- X break;
- X }
- X
- X fclose (fp);
- X}
- X
- X/*
- X * For our current group, update the sequencer information in .newsrc
- X */
- X
- Xvoid update_newsrc (group, groupnum, mark_unread)
- X char *group;
- X int groupnum; /* index into active[] for this group */
- X int mark_unread;
- X{
- X FILE *fp;
- X FILE *newfp;
- X char buf[8192];
- X char *p;
- X char c;
- X
- X set_real_uid_gid ();
- X
- X if ((newfp = fopen (newnewsrc, "w")) == NULL)
- X goto update_done;
- X
- X if ((fp = fopen (newsrc, "r")) != NULL) {
- X while (fgets (buf, sizeof buf, fp) != NULL) {
- X for (p = buf; *p; p++)
- X if (*p == '\n') {
- X *p = '\0';
- X break;
- X }
- X
- X p = buf;
- X while (*p && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X if (strcmp (buf, group) == 0) {
- X if (mark_unread) {
- X fprintf (newfp, "%s%c\n", buf, c);
- X } else {
- X fprintf (newfp, "%s%c ", buf, c);
- X print_seq (newfp, groupnum);
- X fprintf (newfp, "\n");
- X }
- X } else
- X fprintf (newfp, "%s%c%s\n", buf, c, p);
- X }
- X fclose (fp);
- X }
- X
- X fclose (newfp);
- X rename_file (newnewsrc, newsrc);
- X
- Xupdate_done:
- X set_tin_uid_gid ();
- X}
- X
- X/*
- X * Subscribe/unsubscribe to a group in .newsrc. ch should either be
- X * '!' to unsubscribe or ':' to subscribe. num is the group's index
- X * in active[].
- X */
- X
- Xvoid subscribe (group, ch, num, out_seq)
- X char *group;
- X char ch;
- X int num;
- X int out_seq; /* output sequencer info? */
- X{
- X FILE *fp;
- X FILE *newfp;
- X char buf[8192];
- X char *p;
- X char c;
- X int gotit = FALSE;
- X
- X if (ch == '!')
- X active[num].flag &= ~SUBS;
- X else
- X active[num].flag |= SUBS;
- X
- X set_real_uid_gid ();
- X
- X if ((newfp = fopen (newnewsrc, "w")) == NULL)
- X goto subscribe_done;
- X
- X if ((fp = fopen (newsrc, "r")) != NULL) {
- X while (fgets (buf, sizeof buf, fp) != NULL) {
- X if (strncmp ("options ", buf, 8) == 0) {
- X fprintf (newfp, buf);
- X } else {
- X for (p = buf; *p; p++) {
- X if (*p == '\n') {
- X *p = '\0';
- X break;
- X }
- X }
- X
- X p = buf;
- X while (*p && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X if (strcmp (buf, group) == 0) {
- X fprintf (newfp, "%s%c%s\n", buf, ch, p);
- X gotit = TRUE;
- X } else {
- X fprintf (newfp, "%s%c%s\n", buf, c, p);
- X }
- X }
- X }
- X fclose (fp);
- X }
- X
- X if (! gotit) {
- X if (out_seq) {
- X fprintf (newfp, "%s%c ", group, ch);
- X print_seq (newfp, num);
- X fprintf (newfp, "\n");
- X } else
- X fprintf (newfp, "%s%c\n", group, ch);
- X }
- X
- X fclose (newfp);
- X rename_file (newnewsrc, newsrc);
- X
- Xsubscribe_done:
- X set_tin_uid_gid ();
- X}
- X
- X
- Xvoid reset_newsrc ()
- X{
- X FILE *fp;
- X FILE *newfp;
- X char buf[8192];
- X char *p;
- X char c;
- X int i;
- X
- X set_real_uid_gid ();
- X
- X if ((newfp = fopen (newnewsrc, "w")) == NULL)
- X goto update_done;
- X
- X if ((fp = fopen (newsrc, "r")) != NULL) {
- X while (fgets (buf, sizeof (buf), fp) != NULL) {
- X for (p = buf; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X
- X p = buf;
- X while (*p && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X fprintf (newfp, "%s%c\n", buf, c);
- X }
- X fclose (fp);
- X }
- X
- X fclose (newfp);
- X rename_file (newnewsrc, newsrc);
- X
- Xupdate_done:
- X set_tin_uid_gid ();
- X
- X for (i = 0; i < local_top; i++)
- X unread[i] = -1;
- X}
- X
- X
- Xvoid delete_group (group)
- X char *group;
- X{
- X FILE *fp;
- X FILE *newfp;
- X char buf[8192];
- X char *p;
- X char c;
- X int gotit = FALSE;
- X FILE *del;
- X
- X set_real_uid_gid ();
- X
- X if ((newfp = fopen (newnewsrc, "w")) == NULL)
- X goto del_done;
- X
- X if ((del = fopen (delgroups, "a+")) == NULL)
- X goto del_done;
- X
- X if ((fp = fopen (newsrc, "r")) != NULL) {
- X while (fgets (buf, sizeof (buf), fp) != NULL) {
- X for (p = buf; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X
- X p = buf;
- X while (*p && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X if (strcmp (buf, group) == 0) {
- X fprintf (del, "%s%c%s\n", buf, c, p);
- X gotit = TRUE;
- X } else
- X fprintf (newfp, "%s%c%s\n", buf, c, p);
- X }
- X fclose (fp);
- X }
- X
- X fclose (newfp);
- X
- X if (! gotit)
- X fprintf (del, "%s! \n", group);
- X
- X fclose (del);
- X rename_file (newnewsrc, newsrc);
- X
- Xdel_done:
- X set_tin_uid_gid ();
- X}
- X
- X
- Xint undel_group ()
- X{
- X FILE *del;
- X FILE *newfp;
- X FILE *fp;
- X char buf[2][8192];
- X char *p;
- X int which = 0;
- X long h;
- X extern int cur_groupnum;
- X int i, j;
- X char c;
- X
- X set_real_uid_gid ();
- X
- X if ((del = fopen(delgroups, "r")) == NULL) {
- X set_tin_uid_gid ();
- X return FALSE;
- X }
- X
- X unlink(delgroups);
- X
- X if ((newfp = fopen(delgroups, "w")) == NULL) {
- X set_tin_uid_gid ();
- X return FALSE;
- X }
- X
- X buf[0][0] = '\0';
- X buf[1][0] = '\0';
- X
- X while (fgets(buf[which], sizeof (buf[which]), del) != NULL) {
- X which = !which;
- X if (*buf[which])
- X fputs(buf[which], newfp);
- X }
- X
- X fclose(del);
- X fclose(newfp);
- X which = !which;
- X
- X if (!*buf[which]) {
- X set_tin_uid_gid ();
- X return FALSE;
- X }
- X
- X for (p = buf[which]; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X
- X p = buf[which];
- X while (*p && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X h = hash_groupname (buf[which]);
- X
- X for (i = group_hash[h]; i >= 0; i = active[i].next) {
- X if (strcmp(buf[which], active[i].name) == 0) {
- X for (j = 0; j < local_top; j++)
- X if (my_group[j] == i) {
- X set_tin_uid_gid ();
- X return j;
- X }
- X
- X active[i].flag &= ~NOTGOT; /* mark that we got it */
- X if (c != '!')
- X active[i].flag |= SUBS;
- X
- X if (local_top >= max_active)
- X expand_active();
- X local_top++;
- X for (j = local_top; j > cur_groupnum; j--) {
- X my_group[j] = my_group[j-1];
- X unread[j] = unread[j-1];
- X }
- X my_group[cur_groupnum] = i;
- X unread[cur_groupnum] = parse_unread(p, i);
- X
- X if ((fp = fopen(newsrc, "r")) == NULL) {
- X set_tin_uid_gid ();
- X return FALSE;
- X }
- X if ((newfp = fopen(newnewsrc, "w")) == NULL) {
- X fclose(fp);
- X set_tin_uid_gid ();
- X return FALSE;
- X }
- X i = 0;
- X while (fgets(buf[!which], sizeof (buf[!which]), fp) != NULL) {
- X for (p = buf[!which]; *p && *p != '\n'; p++)
- X continue;
- X *p = '\0';
- X
- X p = buf[!which];
- X while (*p && *p!=' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X while (i < cur_groupnum) {
- X if (strcmp(buf[!which],
- X active[my_group[i]].name) == 0) {
- X fprintf(newfp, "%s%c%s\n",
- X buf[!which], c, p);
- X goto foo_cont;
- X }
- X i++;
- X }
- X fprintf(newfp, "%s%c%s\n", buf[which], c, p);
- X fprintf(newfp, "%s%c%s\n", buf[!which], c, p);
- X break;
- Xfoo_cont:;
- X }
- X
- X while (fgets (buf[!which], sizeof (buf[!which]), fp) != NULL)
- X fputs (buf[!which], newfp);
- X
- X fclose (newfp);
- X fclose (fp);
- X rename_file (newnewsrc, newsrc);
- X set_tin_uid_gid ();
- X return TRUE;
- X }
- X }
- X set_tin_uid_gid ();
- X
- X return FALSE;
- X}
- X
- X
- Xvoid mark_group_read (group, groupnum)
- X char *group;
- X int groupnum; /* index into active[] for this group */
- X{
- X FILE *fp;
- X FILE *newfp;
- X char buf[8192];
- X char *p;
- X char c;
- X
- X if (active[groupnum].max < 2)
- X return;
- X
- X set_real_uid_gid ();
- X
- X if ((newfp = fopen (newnewsrc, "w")) == NULL)
- X goto mark_group_read_done;
- X
- X if ((fp = fopen (newsrc, "r")) != NULL) {
- X while (fgets(buf, sizeof (buf), fp) != NULL) {
- X for (p = buf; *p; p++)
- X if (*p == '\n') {
- X *p = '\0';
- X break;
- X }
- X
- X p = buf;
- X while (*p && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X c = *p;
- X if (c != '\0')
- X *p++ = '\0';
- X
- X if (c != '!')
- X c = ':';
- X
- X if (strcmp (buf, group) == 0) {
- X fprintf (newfp, "%s%c 1-%ld\n", buf, c, active[groupnum].max);
- X } else
- X fprintf(newfp, "%s%c%s\n", buf, c, p);
- X }
- X fclose (fp);
- X }
- X
- X fclose (newfp);
- X rename_file (newnewsrc, newsrc);
- X
- Xmark_group_read_done:
- X set_tin_uid_gid ();
- X}
- X
- X
- Xvoid parse_seq(s)
- X char *s;
- X{
- X long low, high;
- X int i;
- X
- X while (*s) {
- X while (*s && (*s < '0' || *s > '9'))
- X s++;
- X
- X if (*s && *s >= '0' && *s <= '9') {
- X low = (long) atol (s);
- X while (*s && *s >= '0' && *s <= '9')
- X s++;
- X if (*s == '-') {
- X s++;
- X high = (long) atol (s);
- X while (*s && *s >= '0' && *s <= '9')
- X s++;
- X } else
- X high = low;
- X
- X for (i = 0; i < top; i++)
- X if (arts[i].artnum >= low && arts[i].artnum <= high)
- X arts[i].unread = ART_READ;
- X }
- X }
- X}
- X
- X
- Xint parse_unread (s, groupnum)
- X char *s;
- X int groupnum; /* index for group in active[] */
- X{
- X long low, high;
- X long last_high;
- X int sum = 0;
- X int gotone = FALSE;
- X int n;
- X
- X/*
- X * Read the first range from the .newsrc sequencer information. If the
- X * top of the first range is higher than what the active file claims is
- X * the bottom, use it as the new bottom instead
- X */
- X
- X high = 0;
- X if (*s) {
- X while (*s && (*s < '0' || *s > '9'))
- X s++;
- X
- X if (*s && *s >= '0' && *s <= '9') {
- X low = (long) atol (s);
- X while (*s && *s >= '0' && *s <= '9')
- X s++;
- X if (*s == '-') {
- X s++;
- X high = (long) atol (s);
- X while (*s && *s >= '0' && *s <= '9')
- X s++;
- X } else
- X high = low;
- X gotone = TRUE;
- X }
- X }
- X
- X if (high < active[groupnum].min)
- X high = active[groupnum].min;
- X
- X while (*s) {
- X last_high = high;
- X
- X while (*s && (*s < '0' || *s > '9'))
- X s++;
- X
- X if (*s && *s >= '0' && *s <= '9') {
- X low = (long) atol (s);
- X while (*s && *s >= '0' && *s <= '9')
- X s++;
- X if (*s == '-') {
- X s++;
- X high = (long) atol (s);
- X while (*s && *s >= '0' && *s <= '9')
- X s++;
- X } else
- X high = low;
- X
- X if (low > last_high) /* otherwise seq out of order */
- X sum += (low - last_high) - 1;
- X }
- X }
- X
- X if (gotone) {
- X if (active[groupnum].max > high)
- X sum += active[groupnum].max - high;
- X return sum;
- X }
- X
- X n = (int) (active[groupnum].max - active[groupnum].min);
- X if (n < 2)
- X return 0;
- X
- X return -1;
- X}
- X
- X
- Xint get_line_unread(group, groupnum)
- X char *group;
- X int groupnum; /* index for group in active[] */
- X{
- X FILE *fp;
- X char buf[8192];
- X char *p;
- X int ret = -1;
- X
- X if ((fp = fopen(newsrc, "r")) == NULL)
- X return -1;
- X
- X while (fgets(buf, sizeof (buf), fp) != NULL) {
- X p = buf;
- X while (*p && *p != '\n' && *p != ' ' && *p != ':' && *p != '!')
- X p++;
- X *p++ = '\0';
- X
- X if (strcmp (buf, group) != 0)
- X continue;
- X
- X ret = parse_unread (p, groupnum);
- X break;
- X }
- X
- X fclose (fp);
- X return ret;
- X}
- X
- X
- Xvoid print_seq (fp, groupnum)
- X FILE *fp;
- X int groupnum; /* index into active[] for this group */
- X{
- X int i;
- X int flag = FALSE;
- X
- X if (top <= 0) {
- X if (active[groupnum].min > 1) {
- X fprintf (fp, "1-%ld", active[groupnum].min);
- X fflush (fp);
- X }
- X return;
- X }
- X
- X /*
- X * sort into the same order as in the spool area for writing
- X * read article numbers to ~/.newsrc
- X */
- X qsort (arts, top, sizeof (struct header), artnum_comp);
- X
- X i = 0;
- X if (arts[0].artnum > 1) {
- X for (; i < top && !arts[i].unread; i++)
- X continue;
- X if (i > 0)
- X fprintf (fp, "1-%ld", arts[i-1].artnum);
- X else
- X fprintf (fp, "1-%ld", arts[0].artnum - 1);
- X flag = TRUE;
- X }
- X
- X for (; i < top; i++) {
- X if (! arts[i].unread) {
- X if (flag)
- X fprintf(fp, ",");
- X else
- X flag = TRUE;
- X fprintf (fp, "%ld", arts[i].artnum);
- X if (i+1 < top && !arts[i+1].unread) {
- X while (i+1 < top && ! arts[i+1].unread)
- X i++;
- X fprintf (fp, "-%ld", arts[i].artnum);
- X }
- X }
- X }
- X
- X if (! flag && active[groupnum].min > 1)
- X fprintf (fp, "1-%ld", active[groupnum].min);
- X fflush (fp);
- X
- X /*
- X * resort into required sort order
- X */
- X switch (sort_art_type) {
- X case SORT_BY_NOTHING: /* already sorted above */
- X break;
- X case SORT_BY_SUBJ_DESCEND:
- X case SORT_BY_SUBJ_ASCEND:
- X qsort (arts, top, sizeof (struct header), subj_comp);
- X break;
- X case SORT_BY_FROM_DESCEND:
- X case SORT_BY_FROM_ASCEND:
- X qsort (arts, top, sizeof (struct header), from_comp);
- X break;
- X case SORT_BY_DATE_DESCEND:
- X case SORT_BY_DATE_ASCEND:
- X qsort (arts, top, sizeof (struct header), date_comp);
- X break;
- X }
- X}
- X
- X/*
- X * rewrite .newsrc and position group at specifed position
- X */
- X
- Xint pos_group_in_newsrc (group, pos)
- X char *group;
- X int pos;
- X{
- X char sub[1024];
- X char unsub[1024];
- X char buf[1024];
- X char newsgroup[1024];
- X extern int cur_groupnum;
- X FILE *fp_in, *fp_out;
- X FILE *fp_sub, *fp_unsub;
- X int repositioned = FALSE;
- X int subscribed_pos = 1;
- X int group_len;
- X int option_line = FALSE;
- X int ret_code = FALSE;
- X
- X set_real_uid_gid ();
- X
- X if ((fp_in = fopen (newsrc, "r")) == NULL) {
- X goto rewrite_group_done;
- X }
- X if ((fp_out = fopen (newnewsrc, "w")) == NULL) {
- X goto rewrite_group_done;
- X }
- X
- X sprintf (sub, "/tmp/.subrc.%d", getpid ());
- X sprintf (unsub, "/tmp/.unsubrc.%d", getpid ());
- X
- X if ((fp_sub = fopen (sub, "w")) == NULL) {
- X goto rewrite_group_done;
- X }
- X if ((fp_unsub = fopen (unsub, "w")) == NULL) {
- X goto rewrite_group_done;
- X }
- X
- X /*
- X * split newsrc into subscribed and unsubscribed to files
- X */
- X group_len = strlen (group);
- X
- X while (fgets (buf, sizeof (buf), fp_in) != NULL) {
- X if (strncmp (group, buf, group_len) == 0 && buf[group_len] == ':') {
- X my_strncpy (newsgroup, buf, LEN);
- X } else if (strchr (buf, ':') != NULL) {
- X fprintf (fp_sub, "%s", buf);
- X } else if (strchr (buf, '!') != NULL) {
- X fprintf (fp_unsub, "%s", buf);
- X } else { /* options line at beginning of .newsrc */
- X fprintf (fp_sub, "%s", buf);
- X option_line = TRUE;
- X }
- X }
- X
- X fclose (fp_in);
- X fclose (fp_sub);
- X fclose (fp_unsub);
- X
- X /*
- X * write subscribed groups & position group to newnewsrc
- X */
- X if ((fp_sub = fopen (sub, "r")) == NULL) {
- X unlink (sub);
- X goto rewrite_group_done;
- X }
- X while (fgets (buf, LEN, fp_sub) != NULL) {
- X if (option_line) {
- X if (strchr (buf, ':') == NULL && strchr (buf, '!') == NULL) {
- X fprintf (fp_out, "%s", buf);
- X continue;
- X } else {
- X option_line = FALSE;
- X }
- X }
- X
- X if (pos == subscribed_pos) {
- X fprintf (fp_out, "%s\n", newsgroup);
- X repositioned = TRUE;
- X }
- X
- X fprintf (fp_out, "%s", buf);
- X
- X subscribed_pos++;
- X }
- X if (! repositioned) {
- X fprintf (fp_out, "%s\n", newsgroup);
- X repositioned = TRUE;
- X }
- X
- X fclose (fp_sub);
- X unlink (sub);
- X
- X /*
- X * write unsubscribed groups to newnewsrc
- X */
- X if ((fp_unsub = fopen (unsub, "r")) == NULL) {
- X unlink (unsub);
- X goto rewrite_group_done;
- X }
- X while (fgets (buf, LEN, fp_unsub) != NULL) {
- X fprintf (fp_out, "%s", buf);
- X }
- X
- X fclose (fp_unsub);
- X unlink (unsub);
- X fclose (fp_out);
- X
- X if (repositioned) {
- X cur_groupnum = pos;
- X rename_file (newnewsrc, newsrc);
- X ret_code = TRUE;
- X }
- X
- Xrewrite_group_done:
- X set_tin_uid_gid ();
- X return ret_code;
- X}
- X
- X/*
- X * mark all orther Xref: articles as read when one article read
- X * Xref: sitename newsgroup:artnum newsgroup:artnum [newsgroup:artnum ...]
- X */
- X
- Xvoid mark_all_xref_read (xref_line)
- X char *xref_line;
- X{
- X char group[LEN];
- X long artnum;
- X
- X if (xref_line == (char *) 0) {
- X return;
- X }
- X
- X /*
- X * check sitename macthes nodename of current machine
- X */
- X
- X /*
- X * tokenize each pair and update that newsgroup if it
- X * is in users my_group[].
- X */
- X
- X}
- SHAR_EOF
- $TOUCH -am 0923175591 newsrc.c &&
- chmod 0600 newsrc.c ||
- echo "restore of newsrc.c failed"
- set `wc -c newsrc.c`;Wc_c=$1
- if test "$Wc_c" != "19674"; then
- echo original size 19674, current size $Wc_c
- fi
- # ============= open.c ==============
- echo "x - extracting open.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > open.c &&
- X/*
- X * Project : tin - a visual threaded usenet newsreader
- X * Module : open.c
- X * Author : R.Skrenta / I.Lea
- X * Created : 01-04-91
- X * Updated : 28-08-91
- X * Release : 1.0
- X * Notes : reads news locally (/usr/spool/news) or via NNTP
- X * Copyright : (c) Copyright 1991 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
- X#include "tin.h"
- X#ifdef USE_NNTP
- X#include "nntp.h"
- X#endif
- X
- X/* Hopefully one of these is right for you. */
- X
- X#ifdef BSD
- X# include <sys/dir.h>
- X# define DIR_BUF struct direct
- X# define D_LENGTH d_namlen
- X#endif
- X#ifdef M_XENIX
- X# include <sys/ndir.h>
- X# define DIR_BUF struct direct
- X# define D_LENGTH d_namlen
- X#endif
- X#ifndef DIR_BUF
- X#ifdef sorix960
- X# include <sys/dirent.h>
- X#else
- X# include <dirent.h>
- X#endif
- X# define DIR_BUF struct dirent
- X# define D_LENGTH d_reclen
- X#endif
- X
- X#ifdef USE_NNTP
- Xint compiled_with_nntp = TRUE; /* used in mail_bug_report() info */
- X#else
- Xint compiled_with_nntp = FALSE;
- X#endif
- X
- Xchar server_name[LEN+1];
- X
- X
- Xchar *is_remote ()
- X{
- X server_name[0] = '\0';
- X
- X#ifdef USE_NNTP
- X if (read_news_via_nntp) {
- X if (nntp_server[0]) {
- X sprintf (server_name, " (%s)", nntp_server);
- X } else {
- X if (getserverbyfile (NNTP_SERVER_FILE)) {
- X sprintf (server_name, " (%s)", getserverbyfile (NNTP_SERVER_FILE));
- X } else {
- X strcpy (server_name, " (NO SERVER)");
- X }
- X }
- X }
- X#endif
- X
- X return (server_name);
- X}
- X
- X
- Xvoid nntp_startup ()
- X{
- X#ifdef USE_NNTP
- X char *server_name;
- X int ret;
- X extern char *getenv();
- X
- X if (read_news_via_nntp) {
- X if (nntp_server[0]) {
- X server_name = nntp_server;
- X } else {
- X server_name = getserverbyfile (NNTP_SERVER_FILE);
- X }
- X if (server_name == NULL) {
- X fprintf(stderr, txt_cannot_get_nntp_server_name);
- X fprintf(stderr, txt_server_name_in_file_env_var, NNTP_SERVER_FILE);
- X exit(1);
- X }
- X
- X ret = server_init (server_name);
- X/*
- X handle_server_response (ret, server_name);
- X*/
- X switch (ret) {
- X case OK_CANPOST:
- X case OK_NOPOST:
- X break;
- X
- X case -1:
- X fprintf (stderr, txt_failed_to_connect_to_server, server_name);
- X exit (1);
- X
- X default:
- X fprintf (stderr, txt_rejected_by_nntpserver, ret);
- X exit (1);
- X }
- X }
- X#endif
- X}
- X
- X
- Xvoid nntp_finish()
- X{
- X#ifdef USE_NNTP
- X if (read_news_via_nntp) {
- X close_server();
- X }
- X#endif
- X}
- X
- X
- XFILE *open_active_fp()
- X{
- X if (read_news_via_nntp) {
- X#ifdef USE_NNTP
- X put_server ("list");
- X if (get_respcode () != OK_GROUPS) {
- X return NULL;
- X }
- X return nntp_to_fp ();
- X#else
- X return NULL;
- X#endif
- X } else {
- X return fopen (active_file, "r");
- X }
- X}
- X
- X
- XFILE *open_art_fp (group_path, art)
- X char *group_path;
- X long art;
- X{
- X char buf[LEN+1];
- X struct stat sb;
- X extern long note_size;
- X
- X if (read_news_via_nntp) {
- X#ifdef USE_NNTP
- X sprintf (buf, "article %ld", art);
- X
- X put_server (buf);
- X if (get_respcode () != OK_ARTICLE) {
- X return NULL;
- X }
- X
- X return nntp_to_fp ();
- X#else
- X return NULL;
- X#endif
- X } else {
- X sprintf (buf, "%s/%s/%ld", SPOOLDIR, group_path, art);
- X
- X if (stat (buf, &sb) < 0) {
- X note_size = 0;
- X } else {
- X note_size = sb.st_size;
- X }
- X return fopen (buf, "r");
- X }
- X}
- X
- X
- Xint open_header_fd (group_path, art)
- X char *group_path;
- X long art;
- X{
- X char buf[LEN+1];
- X
- X if (read_news_via_nntp) {
- X#ifdef USE_NNTP
- X sprintf(buf, "head %ld", art);
- X
- X put_server (buf);
- X if (get_respcode () != OK_HEAD) {
- X return -1;
- X }
- X
- X return nntp_to_fd ();
- X#else
- X return -1;
- X#endif
- X } else {
- X sprintf (buf, "%s/%s/%ld", SPOOLDIR, group_path, art);
- X return open (buf, 0);
- X }
- X}
- X
- X/*
- X * Longword comparison routine for the qsort()
- X */
- X
- Xint base_comp (p1, p2)
- X char *p1;
- X char *p2;
- X{
- X long *a = (long *) p1;
- X long *b = (long *) p2;
- X
- X if (*a < *b)
- X return -1;
- X if (*a > *b)
- X return 1;
- X return 0;
- X}
- X
- X
- X/*
- X * Read the article numbers existing in a group's spool directory
- X * into base[] and sort them. base_top is one past top.
- X */
- X
- Xvoid setup_base (group, group_path)
- X char *group;
- X char *group_path;
- X{
- X char buf[LEN+1];
- X#ifdef USE_NNTP
- X char line[NNTP_STRLEN];
- X#endif
- X DIR *d;
- X DIR_BUF *e;
- X long art, start, last, dummy, count;
- X
- X top_base = 0;
- X
- X if (read_news_via_nntp) {
- X#ifdef USE_NNTP
- X sprintf (buf, "group %s", group);
- X put_server (buf);
- X
- X if (get_server(line, NNTP_STRLEN) == -1) {
- X fprintf(stderr, txt_connection_to_server_broken);
- X tin_done(1);
- X }
- X
- X if (atoi(line) != OK_GROUP) {
- X return;
- X }
- X
- X sscanf (line,"%ld %ld %ld %ld", &dummy, &count, &start, &last);
- X if (last - count > start) {
- X start = last - count;
- X }
- X
- X while (start <= last) {
- X if (top_base >= max_art) {
- X expand_art();
- X }
- X base[top_base++] = start++;
- X }
- X#else
- X return;
- X#endif
- X } else {
- X sprintf (buf, "%s/%s", SPOOLDIR, group_path);
- X
- X if (access (buf, 4) != 0) {
- X return;
- X }
- X
- X d = opendir (buf);
- X if (d != NULL) {
- X while ((e = readdir (d)) != NULL) {
- X art = my_atol (e->d_name, (int) e->D_LENGTH);
- X if (art >= 0) {
- X if (top_base >= max_art)
- X expand_art ();
- X base[top_base++] = art;
- X }
- X }
- X closedir (d);
- X qsort ((char *) base, top_base, sizeof(long), base_comp);
- X }
- X }
- X}
- X
- X/*
- X * get_respcode
- X * get a response code from the server and return it to the caller
- X */
- X
- Xint get_respcode()
- X{
- X#ifdef USE_NNTP
- X char line[NNTP_STRLEN];
- X
- X if (get_server (line, NNTP_STRLEN) == -1) {
- X fprintf (stderr, txt_connection_to_server_broken);
- X tin_done (1);
- X }
- X
- X return atoi (line);
- X#endif
- X}
- X
- X
- Xint stuff_nntp (fnam)
- X char *fnam;
- X{
- X#ifdef USE_NNTP
- X FILE *fp;
- X char line[NNTP_STRLEN];
- X extern char *mktemp();
- X struct stat sb;
- X extern long note_size;
- X
- X strcpy(fnam, "/tmp/tin_nntpXXXXXX");
- X mktemp(fnam);
- X
- X if ((fp = fopen(fnam, "w")) == NULL) {
- X error_message (txt_stuff_nntp_cannot_open, fnam);
- X return FALSE;
- X }
- X
- X while (1) {
- X if (get_server(line, NNTP_STRLEN) == -1) {
- X fprintf(stderr, txt_connection_to_server_broken);
- X tin_done (1);
- X }
- X if (strcmp(line, ".") == 0)
- X break; /* end of text */
- X strcat(line, "\n");
- X if (line[0] == '.') /* reduce leading .'s */
- X fputs(&line[1], fp);
- X else
- X fputs(line, fp);
- X }
- X fclose(fp);
- X
- X if (stat(fnam, &sb) < 0)
- X note_size = 0;
- X else
- X note_size = sb.st_size;
- X
- X return TRUE;
- X#endif
- X}
- X
- X
- XFILE *nntp_to_fp ()
- X{
- X char fnam[LEN+1];
- X FILE *fp;
- X
- X if (! stuff_nntp (fnam))
- X return NULL;
- X
- X if ((fp = fopen (fnam, "r")) == NULL) {
- X error_message (txt_nntp_to_fp_cannot_reopen, fnam);
- X return NULL;
- X }
- X unlink (fnam);
- X return fp;
- X}
- X
- X
- Xint nntp_to_fd ()
- X{
- X#ifdef USE_NNTP
- X char fnam[LEN+1];
- X int fd;
- X
- X if (! stuff_nntp (fnam))
- X return -1;
- X
- X if ((fd = open (fnam, 0)) == -1) {
- X error_message (txt_nntp_to_fd_cannot_reopen, fnam);
- X return -1;
- X }
- X unlink (fnam);
- X return fd;
- X#endif
- X}
- SHAR_EOF
- $TOUCH -am 0923175591 open.c &&
- chmod 0600 open.c ||
- echo "restore of open.c failed"
- set `wc -c open.c`;Wc_c=$1
- if test "$Wc_c" != "6736"; then
- echo original size 6736, current size $Wc_c
- fi
- # ============= page.c ==============
- echo "x - extracting page.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > page.c &&
- X/*
- X * Project : tin - a visual threaded usenet newsreader
- X * Module : page.c
- X * Author : R.Skrenta / I.Lea
- X * Created : 01-04-91
- X * Updated : 16-09-91
- X * Release : 1.0
- X * Notes :
- X * Copyright : (c) Copyright 1991 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
- X#include "tin.h"
- X
- X#define NOTE_UNAVAIL -1
- X
- Xextern int cur_groupnum;
- X
- Xchar note_h_path[LEN+1]; /* Path: */
- Xchar note_h_date[LEN+1]; /* Date: */
- Xchar note_h_subj[LEN+1]; /* Subject: */
- Xchar note_h_from[LEN+1]; /* From: */
- Xchar note_h_org[LEN+1]; /* Organization: */
- Xchar note_h_newsgroups[LEN+1]; /* Newsgroups: */
- Xchar note_h_messageid[LEN+1]; /* Message-ID: */
- Xchar note_h_distrib[LEN+1]; /* Distribution: */
- Xchar note_h_followup[LEN+1]; /* Followup-To: */
- X
- Xchar note_full_name[100];
- Xchar note_from_addr[100];
- Xchar *glob_page_group;
- X
- XFILE *note_fp; /* the body of the current article */
- X
- Xint note_line;
- Xint note_page; /* what page we're on */
- Xint note_end; /* we're done showing this article */
- Xint rotate; /* 0=normal, 13=rot13 decode */
- Xint last_resp; /* current & previous article for - command */
- Xint this_resp;
- Xint glob_respnum;
- X
- Xlong note_mark[MAX_PAGES]; /* ftells on beginnings of pages */
- Xlong note_size; /* stat size in bytes of article */
- X
- X
- Xint show_page (respnum, group, group_path)
- X int respnum;
- X char *group;
- X char *group_path;
- X{
- X char ch;
- X int i, n;
- X int kill_state = NO_KILLING;
- X int old_artnum;
- X int old_sort_art_type = sort_art_type;
- X int old_top;
- X long art;
- X
- Xrestart:
- X
- X glob_respnum = respnum;
- X glob_page_group = group;
- X
- X#ifdef SIGTSTP
- X if (do_sigtstp) {
- X#ifdef POSIX_JOB_CONTROL
- X sigemptyset (&page_act.sa_mask);
- X page_act.sa_flags = SA_RESTART | SA_RESETHAND;
- X page_act.sa_handler = page_suspend;
- X sigaction (SIGTSTP, &page_act, 0L);
- X#else
- X signal (SIGTSTP, page_suspend);
- X#endif
- X }
- X#endif
- X
- X#ifdef SIGWINCH
- X signal (SIGWINCH, page_resize);
- X#endif
- X
- X if (respnum != this_resp) { /* remember current & previous */
- X last_resp = this_resp; /* articles for - command */
- X this_resp = respnum;
- X }
- X
- X rotate = 0; /* normal mode, not rot13 */
- X art = arts[respnum].artnum;
- X arts[respnum].unread = ART_READ; /* mark article as read */
- X open_note (art, group_path);
- X
- X if (note_page == NOTE_UNAVAIL) {
- X ClearScreen ();
- X printf (txt_art_unavailable, art);
- X fflush (stdout);
- X } else {
- X show_note_page (respnum, group);
- X }
- X
- X while (1) {
- X ch = ReadCh();
- X
- X if (ch >= '0' && ch <= '9') {
- X
- X n = prompt_response (ch, respnum);
- X if (n != -1) {
- X respnum = n;
- X goto restart;
- X }
- X
- X } else switch (ch) {
- X case 27:
- X ch = ReadCh ();
- X if (ch == '[' || ch == 'O')
- X ch = ReadCh ();
- X switch (ch) {
- X case 'G': /* ansi PgDn */
- X case 'U': /* at386 PgDn */
- X goto page_down;
- X
- X case 'I': /* ansi PgUp */
- X case 'V': /* at386 PgUp */
- X goto page_up;
- X
- X case 'H': /* at386 Home */
- X goto begin_of_article;
- X
- X case 'F': /* ansi End */
- X case 'Y': /* at386 End */
- X goto end_of_article;
- X }
- X break;
- X
- X case '!':
- X shell_escape ();
- X redraw_page (respnum, group);
- X break;
- X
- X case '$': /* goto end of article */
- X case 'G': /* 'less' compatible */
- Xend_of_article:
- X if (show_last_page ()) {
- X show_note_page(respnum, group);
- X }
- X break;
- X
- X case '-': /* show last viewed article */
- X if (last_resp < 0) {
- X info_message(txt_no_last_message);
- X break;
- X }
- X note_cleanup();
- X respnum = last_resp;
- X goto restart;
- X
- X case '|': /* pipe article/thread/tagged arts to command */
- X feed_articles (FEED_PIPE, PAGE_LEVEL, "Pipe", respnum, group_path);
- X break;
- X
- X case '/': /* search forwards in article */
- X if (search_article (TRUE)) {
- X show_note_page (respnum, group);
- X }
- X break;
- X
- X case '<': /* goto first article in current thread */
- X n = which_base (respnum);
- X if (n != respnum && n >= 0) {
- X respnum = n;
- X note_cleanup ();
- X goto restart;
- X }
- X break;
- X
- X case '>': /* goto last article in current thread */
- X for (i = respnum; i >= 0; i = arts[i].thread) {
- X n = i;
- X }
- X if (n != respnum) {
- X respnum = n;
- X note_cleanup ();
- X goto restart;
- X }
- X break;
- X
- X case ctrl('D'):
- X case ' ': /* next page or response */
- Xpage_down:
- X if (note_page == NOTE_UNAVAIL) {
- X n = next_response (respnum);
- X if (n == -1) {
- X return (which_base (respnum));
- X }
- X respnum = n;
- X goto restart;
- X } else if (note_end) {
- X note_cleanup ();
- X n = next_response (respnum);
- X if (n == -1) {
- X return (which_base (respnum));
- X }
- X respnum = n;
- X goto restart;
- X } else
- X show_note_page (respnum, group);
- X break;
- X
- X case '\r':
- X case '\n': /* go to start of next thread */
- X note_cleanup ();
- X n = next_basenote (respnum);
- X if (n == -1)
- X return (which_base (respnum));
- X
- X respnum = n;
- X goto restart;
- X
- X case '\t': /* next page or unread response */
- X if (note_page == NOTE_UNAVAIL) {
- X n = next_unread (next_response (respnum));
- X if (n == -1)
- X return (which_base (respnum));
- X
- X respnum = n;
- X goto restart;
- X
- X } else if (note_end) {
- X note_cleanup();
- X n = next_unread(next_response(respnum));
- X if (n == -1)
- X return (which_base (respnum));
- X
- X respnum = n;
- X goto restart;
- X } else
- X show_note_page(respnum, group);
- X break;
- X
- X case ctrl('H'): /* show article headers */
- X if (note_page == NOTE_UNAVAIL) {
- X n = next_response (respnum);
- X if (n == -1)
- X return (which_base (respnum));
- X
- X respnum = n;
- X goto restart;
- X } else {
- X note_page = 0;
- X note_end = FALSE;
- X fseek(note_fp, 0L, 0);
- X show_note_page(respnum, group);
- X }
- X break;
- X
- X case ctrl('K'): /* kill article */
- X if (kill_articles) {
- X if (kill_art_menu (group, respnum)) {
- X if (kill_any_articles (group)) {
- X reload_index_file (group, TRUE);
- X }
- X }
- X redraw_page(respnum, group);
- X } else {
- X info_message (txt_switch_on_kill_art_menu);
- X }
- X break;
- X
- X case ctrl('L'): /* redraw current page of article */
- X redraw_page (respnum, group);
- X break;
- X
- X case ctrl('R'): /* redraw beginning of article */
- X case 'g': /* 'less' compatible */
- Xbegin_of_article:
- X if (note_page == NOTE_UNAVAIL) {
- X ClearScreen();
- X printf(txt_art_unavailable,arts[respnum].artnum);
- X fflush(stdout);
- X } else {
- X note_page = 0;
- X note_end = FALSE;
- X fseek(note_fp, note_mark[0], 0);
- X show_note_page(respnum, group);
- X }
- X break;
- X
- X case ctrl('X'):
- X case '%':
- X case 'd': /* toggle rot-13 mode */
- X if (rotate)
- X rotate = 0;
- X else
- X rotate = 13;
- X redraw_page (respnum, group);
- X info_message (txt_toggled_rot13);
- X break;
- X
- X case 'a': /* author search forward */
- X case 'A': /* author search backward */
- X i = (ch == 'a');
- X n = search_author (respnum, i);
- X if (n < 0)
- X break;
- X respnum = n;
- X goto restart;
- X /* NOTREACHED */
- X
- X case ctrl('U'):
- X case 'b': /* back a page */
- Xpage_up:
- X if (note_page == NOTE_UNAVAIL) {
- X note_cleanup();
- X n = prev_response (respnum);
- X if (n == -1)
- X return (which_resp (respnum));
- X
- X respnum = n;
- X goto restart;
- X
- X } else {
- X if (note_page <= 1) {
- X info_message (txt_begin_of_art);
- X } else {
- X note_page -= 2;
- X note_end = FALSE;
- X fseek (note_fp, note_mark[note_page], 0);
- X show_note_page (respnum, group);
- X }
- X }
- X break;
- X
- X case 'B': /* bug/gripe/comment mailed to author */
- X mail_bug_report ();
- X redraw_page (respnum, 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 fix_new_highest(cur_groupnum);
- X if (cur_groupnum + 1 < local_top) {
- X cur_groupnum++;
- X }
- X note_cleanup();
- X return -1;
- X }
- X break;
- X
- X case 'C': /* cancel an article */
- X if (cancel_article ()) {
- X redraw_page (respnum, group);
- X }
- X break;
- X
- X case 'f': /* post a followup to this article */
- X if (post_response (group, FALSE)) {
- X update_newsrc (group, my_group[cur_groupnum], FALSE);
- X n = which_base (respnum);
- X note_cleanup ();
- X index_group (group, group_path);
- X read_newsrc_line (group);
- X respnum = choose_resp (n, nresp(n));
- X goto restart;
- X } else
- X redraw_page (respnum, group);
- X break;
- X
- X case 'F': /* post a followup to this article */
- X if (post_response (group, TRUE)) {
- X update_newsrc (group, my_group[cur_groupnum], FALSE);
- X n = which_base (respnum);
- X note_cleanup ();
- X index_group (group, group_path);
- X read_newsrc_line (group);
- X respnum = choose_resp (n, nresp(n));
- X goto restart;
- X } else
- X redraw_page (respnum, group);
- X break;
- X
- X case 'h': /* help overview */
- X show_info_page (HELP_INFO, help_page, txt_art_pager_com);
- X redraw_page (respnum, group);
- X break;
- X
- X case 'H': /* help in-depth */
- X help_page_info ();
- X redraw_page(respnum, group);
- X break;
- X
- X case 'i': /* return to index page */
- Xreturn_to_index:
- X note_cleanup ();
- X if (kill_state == NO_KILLING &&
- X sort_art_type != old_sort_art_type) {
- X make_threads (TRUE);
- X find_base ();
- X }
- X if (kill_state == KILLING) {
- X old_top = top;
- X old_artnum = arts[respnum].artnum;
- X if (kill_articles) {
- X kill_any_articles (group);
- X reload_index_file (group, TRUE); /* kill arts */
- SHAR_EOF
- echo "End of tin1.02 part 5"
- echo "File page.c is continued in part 6"
- echo "6" > shar3_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-