home *** CD-ROM | disk | FTP | other *** search
- From: skrenta@blekko.commodore.com (Rich Skrenta)
- Newsgroups: alt.sources
- Subject: Tass 3.2 newsreader part 3/3
- Message-ID: <161@blekko.commodore.com>
- Date: 17 Apr 91 17:02:04 GMT
-
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # This archive contains:
- # page.c screen.c select.c spool_open.c
- #
-
- echo x - page.c
- cat >page.c <<'@EOF'
-
- #include <stdio.h>
- #include <signal.h>
- #include <sys/types.h>
- #include "tass.h"
-
-
- #define MAX_PAGES 1000
- #define NOTE_UNAVAIL -1
-
- char note_h_path[LEN]; /* Path: */
- char note_h_date[LEN]; /* Date: */
- char note_h_subj[LEN]; /* Subject: */
- char note_h_from[LEN]; /* From: */
- char note_h_org[LEN]; /* Organization: */
- char note_h_newsgroups[LEN]; /* Newsgroups: */
- char note_h_messageid[LEN]; /* Message-ID: */
- char note_h_distrib[LEN]; /* Distribution: */
- char note_h_followup[LEN]; /* Followup-To: */
-
- int note_line;
- int note_page; /* what page we're on */
- long note_mark[MAX_PAGES]; /* ftells on beginnings of pages */
- FILE *note_fp; /* the body of the current article */
- int note_end; /* we're done showing this article */
- int rotate; /* 0=normal, 13=rot13 decode */
-
- long note_size; /* stat size in bytes of article */
-
- char note_full_name[100];
- char note_from_addr[100];
-
-
- int last_resp; /* current & previous article for - command */
- int this_resp;
-
- int glob_respnum;
- char *glob_page_group;
- extern int cur_groupnum;
-
-
- #ifdef SIGTSTP
- void
- page_susp(i)
- int i;
- {
-
- Raw(FALSE);
- putchar('\n');
- signal(SIGTSTP, SIG_DFL);
- #ifdef BSD
- sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
- #endif
- kill(0, SIGTSTP);
-
- signal(SIGTSTP, page_susp);
- mail_setup();
- Raw(TRUE);
- redraw_page(glob_respnum, glob_page_group);
- }
- #endif
-
-
- show_page(respnum, group, group_path)
- int respnum;
- char *group;
- char *group_path;
- {
- char ch;
- int n;
- int i;
- long art;
-
- restart:
-
- glob_respnum = respnum;
- glob_page_group = group;
-
- #ifdef SIGTSTP
- signal(SIGTSTP, page_susp);
- #endif
-
- if (respnum != this_resp) { /* remember current & previous */
- last_resp = this_resp; /* articles for - command */
- this_resp = respnum;
- }
-
- rotate = 0; /* normal mode, not rot13 */
- art = arts[respnum].artnum;
- arts[respnum].unread = 0; /* mark article as read */
- open_note(art, group_path);
-
- if (note_page == NOTE_UNAVAIL) {
- ClearScreen();
- printf("[Article %ld unvailable]\r\r", art);
- fflush(stdout);
- } else
- show_note_page(respnum, group);
-
- while (1) {
- ch = ReadCh();
-
- if (ch >= '0' && ch <= '9') {
-
- n = prompt_response(ch, respnum);
- if (n != -1) {
- respnum = n;
- goto restart;
- }
-
- } else switch (ch) {
- case 'a': /* author search forward */
- case 'A': /* author search backward */
- i = (ch == 'a');
- n = search_author(respnum, i, group);
- if (n < 0)
- break;
-
- respnum = n;
- goto restart;
- break;
-
- case '|': /* pipe article into command */
- pipe_article();
- redraw_page(respnum, group);
- break;
-
- case 'I': /* toggle inverse video */
- inverse_okay = !inverse_okay;
- if (inverse_okay)
- info_message("Inverse video enabled");
- else
- info_message("Inverse video disabled");
- goto pager_ctrlr;
- break;
-
- case 's':
- save_art_to_file();
- break;
-
- case 'S':
- save_thread_to_file(respnum, group_path);
- break;
-
- case ctrl('X'):
- case '%': /* toggle rot-13 mode */
- if (rotate)
- rotate = 0;
- else
- rotate = 13;
- redraw_page(respnum, group);
- /* goto pager_ctrlr; */
- break;
-
- case 'P': /* previous unread article */
- n = prev_unread(prev_response(respnum));
- if (n == -1)
- info_message("No previous unread article");
- else {
- note_cleanup();
- respnum = n;
- goto restart;
- }
- break;
-
- case 'F': /* post a followup to this article */
- if (post_response(group, TRUE)) {
- update_newsrc(group,
- my_group[cur_groupnum]);
- n = which_base(respnum);
- note_cleanup();
- index_group(group, group_path);
- read_newsrc_line(group);
- respnum = choose_resp(n, nresp(n));
- goto restart;
- } else
- redraw_page(respnum, group);
- break;
-
- case 'f': /* post a followup to this article */
- if (post_response(group, FALSE)) {
- update_newsrc(group,
- my_group[cur_groupnum]);
- n = which_base(respnum);
- note_cleanup();
- index_group(group, group_path);
- read_newsrc_line(group);
- respnum = choose_resp(n, nresp(n));
- goto restart;
- } else
- redraw_page(respnum, group);
- break;
-
- case 'z': /* mark article as unread (to return) */
- arts[respnum].unread = 2;
- info_message("Article marked as unread");
- break;
-
- case 'K': /* mark rest of thread as read */
- for (n = respnum; n >= 0; n = arts[n].thread)
- arts[n].unread = 0;
- n = next_unread(next_response(respnum));
- if (n == -1)
- goto return_to_index;
- else {
- note_cleanup();
- respnum = n;
- goto restart;
- }
- break;
-
- case 'i': /* return to index page */
- return_to_index:
- note_cleanup();
- return( which_base(respnum) );
-
- case 't': /* return to group selection page */
- note_cleanup();
- return -1;
-
- case ctrl('R'): /* redraw beginning of article */
- pager_ctrlr:
- if (note_page == NOTE_UNAVAIL) {
- ClearScreen();
- printf("[Article %ld unvailable]\r\n",
- arts[respnum].artnum);
- fflush(stdout);
- } else {
- note_page = 0;
- note_end = FALSE;
- fseek(note_fp, note_mark[0], 0);
- show_note_page(respnum, group);
- }
- break;
-
- case '!':
- shell_escape();
- redraw_page(respnum, group);
- break;
-
- case '\b':
- case 'b': /* back a page */
- if (note_page == NOTE_UNAVAIL
- || note_page <= 1) {
- note_cleanup();
- n = prev_response(respnum);
- if (n == -1)
- return( which_resp(respnum) );
-
- respnum = n;
- goto restart;
-
- } else {
- note_page -= 2;
- note_end = FALSE;
- fseek(note_fp, note_mark[note_page], 0);
- show_note_page(respnum, group);
- }
- break;
-
- case 'm': /* mail article to somebody */
- mail_to_someone();
- redraw_page(respnum, group);
- break;
-
- case 'r': /* reply to author through mail */
- mail_to_author(FALSE);
- redraw_page(respnum, group);
- break;
-
- case 'R': /* reply to author, copy text */
- mail_to_author(TRUE);
- redraw_page(respnum, group);
- break;
-
- case '-': /* show last viewed article */
- if (last_resp < 0) {
- info_message("No last message");
- break;
- }
- note_cleanup();
- respnum = last_resp;
- goto restart;
-
-
- case 'p': /* previous article */
- note_cleanup();
- n = prev_response(respnum);
- if (n == -1)
- return( which_resp(respnum) );
-
- respnum = n;
- goto restart;
-
- case 'n': /* skip to next article */
- note_cleanup();
- n = next_response(respnum);
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
-
- case 'k':
- if (note_page == NOTE_UNAVAIL) {
- n = next_unread(next_response(respnum));
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
-
- } else {
- note_cleanup();
- n = next_unread(next_response(respnum));
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
- }
- break;
-
- case ' ': /* next page or response */
- if (note_page == NOTE_UNAVAIL) {
- n = next_response(respnum);
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
-
- } else if (note_end) {
- note_cleanup();
- n = next_response(respnum);
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
- } else
- show_note_page(respnum, group);
- break;
-
- case '\t': /* next page or unread response */
- if (note_page == NOTE_UNAVAIL) {
- n = next_unread(next_response(respnum));
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
-
- } else if (note_end) {
- note_cleanup();
- n = next_unread(next_response(respnum));
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
- } else
- show_note_page(respnum, group);
- break;
-
- case 'N': /* next unread article */
- n = next_unread(next_response(respnum));
- if (n == -1)
- info_message("No next unread article");
- else {
- note_cleanup();
- respnum = n;
- goto restart;
- }
- break;
-
- case '\r':
- case '\n': /* go to start of next thread */
- note_cleanup();
- n = next_basenote(respnum);
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
-
- case 'q': /* quit */
- return -2;
-
- case 'H': /* show article headers */
- if (note_page == NOTE_UNAVAIL) {
- n = next_response(respnum);
- if (n == -1)
- return( which_base(respnum) );
-
- respnum = n;
- goto restart;
- } else {
- note_page = 0;
- note_end = FALSE;
- fseek(note_fp, 0L, 0);
- show_note_page(respnum, group);
- }
- break;
-
-
- case 'h':
- tass_page_help();
- redraw_page(respnum, group);
- break;
-
- default:
- info_message("Bad command. Type 'h' for help.");
- }
- }
- }
-
-
- note_cleanup() {
-
- if (note_page != NOTE_UNAVAIL)
- fclose(note_fp);
- }
-
-
- redraw_page(respnum, group)
- int respnum;
- char *group;
- {
-
- if (note_page == NOTE_UNAVAIL) {
- ClearScreen();
- printf("[Article %ld unvailable]\r\r", arts[respnum].artnum);
- fflush(stdout);
- } else if (note_page > 0) {
- note_page--;
- fseek(note_fp, note_mark[note_page], 0);
- show_note_page(respnum, group);
- }
- }
-
-
- show_note_page(respnum, group)
- int respnum;
- char *group;
- {
- char buf[LEN];
- char buf2[LEN+50];
- int percent;
- char *p, *q;
- int i, j;
- int ctrl_L; /* form feed character detected */
-
- ClearScreen();
-
- note_line = 1;
-
- if (note_page == 0)
- show_first_header(respnum, group);
- else
- show_cont_header(respnum);
-
- ctrl_L = FALSE;
- while (note_line < LINES) {
- if (fgets(buf, LEN, note_fp) == NULL) {
- note_end = TRUE;
- break;
- }
-
- buf[LEN-1] = '\0';
- if (rotate)
- for (p = buf, q = buf2;
- *p && *p != '\n' && q<&buf2[LEN]; p++) {
- if (*p == '\b' && q > buf2) {
- q--;
- } else if (*p == 12) { /* ^L */
- *q++ = '^';
- *q++ = 'L';
- ctrl_L = TRUE;
- } else if (*p == '\t') {
- i = q - buf2;
- j = (i|7) + 1;
-
- while (i++ < j)
- *q++ = ' ';
- } else if (((*p)&0x7F) < 32) {
- *q++ = '^';
- *q++ = ((*p)&0x7F) + '@';
- } else if (*p >= 'A' && *p <= 'Z')
- *q++ = 'A' + (*p - 'A' + rotate) % 26;
- else if (*p >= 'a' && *p <= 'z')
- *q++ = 'a' + (*p - 'a' + rotate) % 26;
- else
- *q++ = *p;
- }
- else
- for (p = buf, q = buf2;
- *p && *p != '\n' && q<&buf2[LEN]; p++) {
- if (*p == '\b' && q > buf2) {
- q--;
- } else if (*p == 12) { /* ^L */
- *q++ = '^';
- *q++ = 'L';
- ctrl_L = TRUE;
- } else if (*p == '\t') {
- i = q - buf2;
- j = (i|7) + 1;
-
- while (i++ < j)
- *q++ = ' ';
- } else if (((*p)&0x7F) < 32) {
- *q++ = '^';
- *q++ = ((*p)&0x7F) + '@';
- } else
- *q++ = *p;
- }
-
- *q = '\0';
-
- printf("%s\r\n", buf2);
-
- #if 1
- note_line += (strlen(buf2) / COLS) + 1;
- #else
- if (*buf2)
- note_line += (strlen(buf2) + COLS) / (COLS+1);
- else
- note_line++;
- #endif
- if (ctrl_L)
- break;
- }
-
- note_mark[++note_page] = ftell(note_fp);
-
- MoveCursor(LINES, MORE_POS);
- /* StartInverse(); */
- if (note_end) {
- if (arts[respnum].thread != -1)
- printf("-- next response --");
- else
- printf("-- last response --");
- } else {
- if (note_size > 0) {
- percent = note_mark[note_page] * 100 / note_size;
- printf("--More--(%d%%)", percent);
- } else
- printf("--More--");
- }
- /* EndInverse(); */
-
- fflush(stdout);
- }
-
-
- show_first_header(respnum, group)
- int respnum;
- char *group;
- {
- int whichresp;
- int x_resp;
- char buf[200];
- char tmp[200];
- int pos, i;
- int n;
-
- whichresp = which_resp( respnum );
- x_resp = nresp( which_base(respnum) );
-
- ClearScreen();
-
- strcpy(buf, note_h_date);
- pos = (COLS - strlen(group)) / 2;
- for (i = strlen(buf); i < pos; i++)
- buf[i] = ' ';
- buf[i] = '\0';
-
- strcat(buf, group);
-
- for (i = strlen(buf); i < RIGHT_POS; i++)
- buf[i] = ' ';
- buf[i] = '\0';
-
- printf("%sNote %3d of %3d\r\n", buf, which_base(respnum) + 1, top_base);
-
- sprintf(buf, "Article %ld ", arts[respnum].artnum);
- n = strlen(buf);
- fputs(buf, stdout);
-
- pos = (COLS - strlen( note_h_subj )) / 2 - 2;
-
- if (pos > n)
- MoveCursor(1, pos);
- else
- MoveCursor(1, n);
-
- StartInverse();
- strcpy(buf, note_h_subj);
- buf[RIGHT_POS - 2 - n] = '\0';
- fputs(buf, stdout);
- EndInverse();
-
- MoveCursor(1, RIGHT_POS);
- if (whichresp)
- printf("Resp %3d of %3d\r\n", whichresp, x_resp);
- else {
- if (x_resp == 0)
- printf("No responses\r\n");
- else if (x_resp == 1)
- printf("1 Response\r\n");
- else
- printf("%d Responses\r\n", x_resp);
- }
-
- if (*note_h_org)
- sprintf(tmp, "%s at %s", note_full_name, note_h_org);
- else
- strcpy(tmp, note_full_name);
-
- tmp[79] = '\0';
-
- sprintf(buf, "%s ", note_from_addr);
-
- pos = COLS - 1 - strlen(tmp);
- if (strlen(buf) + strlen(tmp) >= COLS - 1) {
- strncat(buf, tmp, COLS - 1 - strlen(buf));
- buf[COLS - 1] = '\0';
- } else {
- for (i = strlen(buf); i < pos; i++)
- buf[i] = ' ';
- buf[i] = '\0';
- strcat(buf, tmp);
- }
- printf("%s\r\n\r\n", buf);
-
- note_line += 4;
- }
-
-
- show_cont_header(respnum)
- int respnum;
- {
- int whichresp;
- int whichbase;
- char buf[200];
-
- whichresp = which_resp(respnum);
- whichbase = which_base(respnum);
-
- assert (whichbase < top_base);
-
- if (whichresp)
- sprintf(buf, "Note %d of %d, Resp %d (page %d): %s",
- whichbase + 1,
- top_base,
- whichresp,
- note_page + 1,
- note_h_subj);
- else
- sprintf(buf, "Note %d of %d (page %d): %s",
- whichbase + 1,
- top_base,
- note_page + 1,
- note_h_subj);
-
- buf[COLS] = '\0';
- printf("%s\r\n\r\n", buf);
-
- note_line += 2;
- }
-
-
- open_note(art, group_path)
- long art;
- char *group_path;
- {
- char buf[1025];
- char *p;
- extern FILE *open_art_fp();
-
- note_page = 0;
-
- note_fp = open_art_fp(group_path, art);
- if (note_fp == NULL) {
- note_page = NOTE_UNAVAIL;
- return;
- }
-
- note_h_from[0] = '\0';
- note_h_path[0] = '\0';
- note_h_subj[0] = '\0';
- note_h_org[0] = '\0';
- note_h_date[0] = '\0';
- note_h_newsgroups[0] = '\0';
- note_h_messageid[0] = '\0';
- note_h_distrib[0] = '\0';
- note_h_followup[0] = '\0';
-
- while (fgets(buf, 1024, note_fp) != NULL) {
- buf[1024] = '\0';
-
- for (p = buf; *p && *p != '\n'; p++)
- if (((*p)&0x7F) < 32)
- *p = ' ';
- *p = '\0';
-
- if (*buf == '\0')
- break;
-
- if (strncmp(buf, "From: ", 6) == 0) {
- strncpy(note_h_from, &buf[6], LEN);
- note_h_from[LEN-1] = '\0';
- } else if (strncmp(buf, "Path: ", 6) == 0) {
- strncpy(note_h_path, &buf[6], LEN);
- note_h_path[LEN-1] = '\0';
- } else if (strncmp(buf, "Subject: ", 9) == 0) {
- strncpy(note_h_subj, &buf[9], LEN);
- note_h_subj[LEN-1] = '\0';
- } else if (strncmp(buf, "Organization: ", 14) == 0) {
- strncpy(note_h_org, &buf[14], LEN);
- note_h_org[LEN-1] = '\0';
- } else if (strncmp(buf, "Date: ", 6) == 0) {
- strncpy(note_h_date, &buf[6], LEN);
- note_h_date[LEN-1] = '\0';
- } else if (strncmp(buf, "Newsgroups: ", 12) == 0) {
- strncpy(note_h_newsgroups, &buf[12], LEN);
- note_h_newsgroups[LEN-1] = '\0';
- } else if (strncmp(buf, "Message-ID: ", 12) == 0) {
- strncpy(note_h_messageid, &buf[12], LEN);
- note_h_messageid[LEN-1] = '\0';
- } else if (strncmp(buf, "Distribution: ", 14) == 0) {
- strncpy(note_h_distrib, &buf[14], LEN);
- note_h_distrib[LEN-1] = '\0';
- } else if (strncmp(buf, "Followup-To: ", 13) == 0) {
- strncpy(note_h_followup, &buf[13], LEN);
- note_h_followup[LEN-1] = '\0';
- }
- }
-
- note_page = 0;
- note_mark[0] = ftell(note_fp);
-
- parse_from(note_h_from, note_from_addr, note_full_name);
- note_end = FALSE;
-
- return;
- }
-
-
- prompt_response(ch, respnum)
- int respnum;
- {
- int num;
-
- clear_message();
-
- if ((num = parse_num(ch, "Read response> ")) == -1) {
- clear_message();
- return(-1);
- }
-
- return choose_resp( which_base(respnum), num );
- }
-
-
- /*
- * return response number n from thread i
- */
-
- choose_resp(i, n)
- int i;
- int n;
- {
- int j;
-
- j = base[i];
-
- while (n-- && arts[j].thread >= 0)
- j = arts[j].thread;
-
- return j;
- }
-
-
- /*
- * Parse various From: lines into the component mail addresses and
- * real names
- */
-
- parse_from(str, addr, name)
- char *str;
- char *addr;
- char *name;
- {
- char *p;
-
- for (p = str; *p; p++)
- if (((*p) & 0x7F) < 32)
- *p = ' ';
-
- while (*str && *str != ' ')
- *addr++ = *str++;
- *addr = '\0';
- if (*str++ == ' ') {
- if (*str++ == '(') {
- if (*str == '"')
- str++; /* Kill "quotes around names" */
- /* But don't touch quotes inside the */
- /* Name (that's what that nonsense */
- /* below is for */
- while (*str && *str != ')' && !(*str=='"'&&str[1]==')'))
- *name++ = *str++;
- }
- }
- *name = '\0';
- }
-
-
- tass_page_help() {
- char title[100];
-
- sprintf(title, "%s, Article Pager Commands", TASS_HEADER);
-
- ClearScreen();
- center_line(0, title);
-
- MoveCursor(2, 0);
-
- printf("\t4\tRead response 4 in this thread (0 is basenote)\r\n");
- printf("\t<CR>\tSkip to next base article\r\n");
- printf("\t<TAB>\tAdvance to next page or unread article\r\n");
- printf("\taA\tAuthor search forward (A=backward)\r\n");
- printf("\tb\tBack a page\r\n");
- printf("\tfF\tPost a followup (F=include text)\r\n");
- printf("\tH\tShow article headers\r\n");
- printf("\ti\tReturn to index page\r\n");
- printf("\tkK\tMark article (K=thread) as read & advance to next unread\r\n");
- printf("\tm\tMail this article to someone\r\n");
- printf("\tnN\tSkip to the next (N=unread) article)\r\n");
- printf("\tpP\tGo to the previous (P=unread) article\r\n");
- printf("\tq\tQuit\r\n");
- printf("\trR\tReply through mail (R=include text) to author\r\n");
- printf("\tsS\tSave article (S=thread) to file\r\n");
- printf("\tt\tReturn to group selection page\r\n");
- printf("\tz\tMark article as unread\r\n");
- printf("\t^R\tRedisplay first page of article\r\n");
- printf("\t%%, ^X\tToggle rot-13 decoding for this article\r\n");
- printf("\t-\tShow last article\r\n");
- printf("\t|\tPipe article into command\r\n");
-
- center_line(LINES, "-- hit any key --");
- ReadCh();
- }
-
-
- yank_to_addr(orig, addr)
- char *orig;
- char *addr;
- {
- char *p;
-
- for (p = orig; *p; p++)
- if (((*p) & 0x7F) < 32)
- *p = ' ';
-
- while (*addr)
- addr++;
-
- while (*orig) {
- while (*orig && (*orig == ' ' || *orig == '"' || *orig == ','))
- orig++;
- *addr++ = ' ';
- while (*orig && (*orig != ' ' && *orig != ',' && *orig != '"'))
- *addr++ = *orig++;
- while (*orig && (*orig == ' ' || *orig == '"' || *orig == ','))
- orig++;
- if (*orig == '(') {
- while (*orig && *orig != ')')
- orig++;
- if (*orig == ')')
- orig++;
- }
- }
- *addr = '\0';
- }
-
-
- /*
- * Read a file grabbing the address given for To: and
- * sticking it in mail_to
- */
-
- find_new_to(nam, mail_to)
- char *nam;
- char *mail_to;
- {
- FILE *fp;
- char buf[LEN];
- char buf2[LEN];
- char dummy[LEN];
- char new_mail_to[LEN];
- char *p;
-
- *new_mail_to = '\0';
-
- fp = fopen(nam, "r");
- if (fp == NULL) {
- fprintf(stderr, "reopen of %s failed\n", nam);
- return;
- }
-
- while (fgets(buf, 1024, fp) != NULL) {
- for (p = buf; *p && *p != '\n'; p++) ;
- *p = '\0';
-
- if (*buf == '\0')
- break;
-
- if (strncmp(buf, "To: ", 4) == 0) {
- strncpy(buf2, &buf[4], LEN);
- buf2[LEN-1] = '\0';
- yank_to_addr(buf2, new_mail_to);
- } else if (strncmp(buf, "Cc: ", 4) == 0) {
- strncpy(buf2, &buf[4], LEN);
- buf2[LEN-1] = '\0';
- yank_to_addr(buf2, new_mail_to);
- }
- }
-
- fclose(fp);
- if (new_mail_to[0] == ' ')
- strcpy(mail_to, &new_mail_to[1]);
- else
- strcpy(mail_to, new_mail_to);
- }
-
-
- mail_to_someone() {
- char nam[100];
- FILE *fp;
- char ch;
- char buf[200];
- char mail_to[LEN+1];
- char subj[LEN+1];
-
- if (!parse_string("Mail article to: ", mail_to))
- return;
- if (mail_to[0] == '\0')
- return;
-
- setuid(real_uid);
- setgid(real_gid);
-
- sprintf(nam, "%s/.letter", homedir);
- if ((fp = fopen(nam, "w")) == NULL) {
- fprintf(stderr, "can't open %s: ", nam);
- perror("");
- setuid(tass_uid);
- setgid(tass_gid);
- return(FALSE);
- }
- chmod(nam, 0600);
-
- fprintf(fp, "To: %s\n", mail_to);
- fprintf(fp, "Subject: %s\n", note_h_subj);
- if (*note_h_followup)
- fprintf(fp, "Newsgroups: %s\n\n", note_h_followup);
- else
- fprintf(fp, "Newsgroups: %s\n", note_h_newsgroups);
- if (*my_org)
- fprintf(fp, "Organization: %s\n", my_org);
- fputs("\n", fp);
-
- fseek(note_fp, 0L, 0);
- copy_fp(note_fp, fp, "");
-
- add_signature(fp, TRUE);
- fclose(fp);
-
- while (1) {
- do {
- MoveCursor(LINES, 0);
- fputs("abort, edit, send: ", stdout);
- fflush(stdout);
- ch = ReadCh();
- } while (ch != 'a' && ch != 'e' && ch != 's');
-
- switch (ch) {
- case 'e':
- invoke_editor(nam);
- break;
-
- case 'a':
- setuid(tass_uid);
- setgid(tass_gid);
- return FALSE;
-
- case 's':
- /*
- * Open letter an get the To: line in case they changed it with
- * the editor
- */
-
- find_new_to(nam, mail_to);
- printf("\r\nMailing to %s...", mail_to);
- fflush(stdout);
- sprintf(buf, "%s %s < %s", MAILER,
- mail_to, nam);
- if (invoke_cmd(buf)) {
- printf("Message sent\r\n");
- fflush(stdout);
- goto mail_to_someone_done;
- } else {
- printf("Command failed: %s\r\n", buf);
- fflush(stdout);
- break;
- }
- }
- }
-
- mail_to_someone_done:
- setuid(tass_uid);
- setgid(tass_gid);
-
- continue_prompt();
-
- return TRUE;
- }
-
-
- mail_to_author(copy_text)
- int copy_text;
- {
- char nam[100];
- FILE *fp;
- char ch;
- char buf[200];
- char mail_to[LEN+1];
-
- setuid(real_uid);
- setgid(real_gid);
-
- printf("\r\nMailing to %s...\r\n\r\n", note_h_from);
-
- sprintf(nam, "%s/.letter", homedir);
- if ((fp = fopen(nam, "w")) == NULL) {
- fprintf(stderr, "can't open %s: ", nam);
- perror("");
- setuid(tass_uid);
- setgid(tass_gid);
- return(FALSE);
- }
- chmod(nam, 0600);
-
- fprintf(fp, "To: %s\n", note_h_from);
- fprintf(fp, "Subject: Re: %s\n", eat_re(note_h_subj) );
- fprintf(fp, "Newsgroups: %s\n", note_h_newsgroups);
- if (*my_org)
- fprintf(fp, "Organization: %s\n", my_org);
- fputs("\n", fp);
-
- if (copy_text) { /* if "copy_text" */
- fprintf(fp, "In article %s you write:\n", note_h_messageid);
-
- fseek(note_fp, note_mark[0], 0);
- copy_fp(note_fp, fp, "> ");
- }
-
- add_signature(fp, TRUE);
- fclose(fp);
-
- ch = 'e';
- while (1) {
- switch (ch) {
- case 'e':
- invoke_editor(nam);
- break;
-
- case 'a':
- setuid(tass_uid);
- setgid(tass_gid);
- return FALSE;
-
- case 's':
- strcpy(mail_to, note_from_addr);
- find_new_to(nam, mail_to);
- printf("\r\nMailing to %s... ", mail_to);
- fflush(stdout);
- sprintf(buf, "%s %s < %s", MAILER, mail_to, nam);
- if (invoke_cmd(buf)) {
- printf("Message sent\r\n");
- fflush(stdout);
- goto mail_to_author_done;
- } else {
- printf("Command failed: %s\r\n", buf);
- fflush(stdout);
- break;
- }
- }
-
- do {
- MoveCursor(LINES, 0);
- fputs("abort, edit, send: ", stdout);
- fflush(stdout);
- ch = ReadCh();
- } while (ch != 'a' && ch != 'e' && ch != 's');
- }
-
- mail_to_author_done:
- setuid(tass_uid);
- setgid(tass_gid);
-
- continue_prompt();
-
- return TRUE;
- }
-
-
- post_response(group, respnum)
- int respnum;
- {
- FILE *fp;
- char nam[100];
- char ch;
- char buf[200];
- int post_anyway = FALSE;
-
- if (*note_h_followup && strcmp(note_h_followup, "poster") == 0) {
- clear_message();
- MoveCursor(LINES,0);
- printf("Note: Responses have been directed to the poster");
- if (!prompt_yn("Post anyway? (y/n): "))
- return FALSE;
- *note_h_followup = '\0';
- } else if (*note_h_followup && strcmp(note_h_followup, group) != 0) {
- clear_message();
- MoveCursor(LINES,0);
- printf("Note: Responses have been directed to %s\r\n\r\n",
- note_h_followup);
- if (!prompt_yn("Continue? (y/n): "))
- return FALSE;
- }
-
- setuid(real_uid);
- setgid(real_gid);
-
- sprintf(nam, "%s/.article", homedir);
- if ((fp = fopen(nam, "w")) == NULL) {
- fprintf(stderr, "can't open %s: ", nam);
- perror("");
- setuid(tass_uid);
- setgid(tass_gid);
- return FALSE;
- }
- chmod(nam, 0600);
-
- fprintf(fp, "Subject: Re: %s\n", eat_re(note_h_subj));
-
- if (*note_h_followup && strcmp(note_h_followup, "poster") != 0)
- fprintf(fp, "Newsgroups: %s\n", note_h_followup);
- else
- fprintf(fp, "Newsgroups: %s\n", note_h_newsgroups);
-
- if (*my_org)
- fprintf(fp, "Organization: %s\n", my_org);
-
- if (note_h_distrib != '\0')
- fprintf(fp, "Distribution: %s\n", note_h_distrib);
-
- fprintf(fp, "References: %s\n", note_h_messageid);
- fprintf(fp, "\n");
-
- if (respnum) { /* if "copy_text" */
- fprintf(fp, "%s writes:\n", note_h_from);
-
- fseek(note_fp, note_mark[0], 0);
- copy_fp(note_fp, fp, "> ");
- }
-
- add_signature(fp, FALSE);
- fclose(fp);
-
- ch = 'e';
- while (1) {
- switch (ch) {
- case 'e':
- invoke_editor(nam);
- break;
-
- case 'a':
- setuid(tass_uid);
- setgid(tass_gid);
- return FALSE;
-
- case 'p':
- printf("Posting... ");
- fflush(stdout);
- sprintf(buf, "%s/inews -h < %s", LIBDIR, nam);
- if (invoke_cmd(buf)) {
- printf("article posted\r\n");
- fflush(stdout);
- goto post_response_done;
- } else {
- printf("article rejected\r\n");
- fflush(stdout);
- break;
- }
- }
-
- do {
- MoveCursor(LINES, 0);
- fputs("abort, edit, post: ", stdout);
- fflush(stdout);
- ch = ReadCh();
- } while (ch != 'a' && ch != 'e' && ch != 'p');
- }
-
- post_response_done:
- setuid(tass_uid);
- setgid(tass_gid);
-
- continue_prompt();
-
- return TRUE;
- }
-
-
- save_art_to_file()
- {
- char nam[LEN];
- FILE *fp;
- char *p;
-
- if (!parse_string("Save article to file: ", nam))
- return;
- if (nam[0] == '\0')
- return;
-
- for (p = nam; *p && (*p == ' ' || *p == '\t'); p++) ;
- if (!*p)
- return;
-
- setuid(real_uid);
- setgid(real_gid);
-
- if ((fp = fopen(p, "a+")) == NULL) {
- fprintf(stderr, "can't open %s: ", nam);
- perror("");
- info_message("-- article not saved --");
- setuid(real_uid);
- setgid(real_gid);
- return;
- }
-
- MoveCursor(LINES, 0);
- fputs("Saving...", stdout);
- fflush(stdout);
-
- fprintf(fp, "From %s %s\n", note_h_path, note_h_date);
-
- fseek(note_fp, 0L, 0);
- copy_fp(note_fp, fp, "");
- fputs("\n", fp);
-
- fclose(fp);
-
- setuid(real_uid);
- setgid(real_gid);
- info_message("-- article saved --");
- }
-
-
- save_thread_to_file(respnum, group_path)
- long respnum;
- char *group_path;
- {
- char nam[LEN];
- FILE *fp;
- FILE *art;
- int i;
- char buf[8192];
- int b;
- int count = 0;
- char *p;
-
- b = which_base(respnum);
-
- if (!parse_string("Save thread to file: ", nam))
- return;
- if (nam[0] == '\0')
- return;
-
- for (p = nam; *p && (*p == ' ' || *p == '\t'); p++) ;
- if (!*p)
- return;
-
- setuid(real_uid);
- setgid(real_gid);
-
- if ((fp = fopen(nam, "a+")) == NULL) {
- fprintf(stderr, "can't open %s: ", nam);
- perror("");
- info_message("-- thread not saved --");
- setuid(real_uid);
- setgid(real_gid);
- return;
- }
-
- MoveCursor(LINES, 0);
- fputs("Saving... ", stdout);
- fflush(stdout);
-
- note_cleanup();
-
- for (i = base[b]; i >= 0; i = arts[i].thread) {
- open_note(arts[i].artnum, group_path);
-
- fprintf(fp, "From %s %s\n", note_h_path, note_h_date);
- fseek(note_fp, 0L, 0);
- copy_fp(note_fp, fp, "");
- fputs("\n", fp);
-
- note_cleanup();
- printf("\b\b\b\b%4d", ++count);
- fflush(stdout);
- }
-
- fclose(fp);
- setuid(real_uid);
- setgid(real_gid);
-
- info_message("-- thread saved --");
- open_note(arts[respnum].artnum, group_path);
- }
-
-
- pipe_article() {
- char command[LEN];
- FILE *fp;
-
- if (!parse_string("Pipe to command: ", command))
- return;
- if (command[0] == '\0')
- return;
-
- fp = popen(command, "w");
- if (fp == NULL) {
- fprintf(stderr, "command failed: ");
- perror("");
- goto pipe_article_done;
- }
-
- fseek(note_fp, 0L, 0);
- copy_fp(note_fp, fp, "");
- pclose(fp);
-
- pipe_article_done:
-
- continue_prompt();
- }
-
- @EOF
-
- chmod 644 page.c
-
- echo x - screen.c
- cat >screen.c <<'@EOF'
-
- #include <stdio.h>
- #include "tass.h"
-
-
-
- info_message(msg)
- char *msg;
- {
- clear_message(); /* Clear any old messages hanging around */
- center_line(LINES, msg); /* center the message at screen bottom */
- MoveCursor(LINES, 0);
- }
-
-
- clear_message()
- {
- MoveCursor(LINES, 0);
- CleartoEOLN();
- }
-
-
- center_line(line, str)
- int line;
- char *str;
- {
- int pos;
-
- pos = (COLS - strlen(str)) / 2;
- MoveCursor(line, pos);
- printf("%s", str);
- fflush(stdout);
- }
-
-
- draw_arrow(line)
- int line;
- {
- MoveCursor(line, 0);
- printf("->");
- fflush(stdout);
- MoveCursor(LINES, 0);
- }
-
- erase_arrow(line)
- int line;
- {
- MoveCursor(line, 0);
- printf(" ");
- fflush(stdout);
- }
-
- @EOF
-
- chmod 644 screen.c
-
- echo x - select.c
- cat >select.c <<'@EOF'
-
- #include <stdio.h>
- #include <signal.h>
- #include "tass.h"
-
-
- int first_group_on_screen;
- int last_group_on_screen;
- int cur_groupnum = 0;
- extern int index_point;
- int space_mode;
- extern char *cvers;
-
- char group_search_string[LEN+1];
-
-
-
- #ifdef SIGTSTP
- void
- select_susp(i)
- int i;
- {
-
- Raw(FALSE);
- putchar('\n');
- signal(SIGTSTP, SIG_DFL);
- #ifdef BSD
- sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
- #endif
- kill(0, SIGTSTP);
-
- signal(SIGTSTP, select_susp);
- Raw(TRUE);
- mail_setup();
- group_selection_page();
- }
- #endif
-
-
- selection_index()
- {
- char ch;
- int n;
- int i;
- char buf[200];
-
- group_selection_page(); /* display group selection page */
-
- while (1) {
- ch = ReadCh();
-
- if (ch > '0' && ch <= '9') {
- prompt_group_num(ch);
- } else switch (ch) {
- case 'c': /* catchup--mark all articles as read */
- if (prompt_yn("Mark group as read? (y/n): ")) {
- unread[cur_groupnum] = 0;
- mark_group_read(
- active[my_group[cur_groupnum]].name,
- my_group[cur_groupnum]);
- MoveCursor(INDEX_TOP + (cur_groupnum -
- first_group_on_screen), 47);
- printf(" ");
- MoveCursor(LINES, 0);
- fflush(stdout);
- /* group_selection_page(); */
- }
- break;
-
- case ctrl('K'):
- if (local_top <= 0) {
- info_message("No groups to delete");
- break;
- }
-
- delete_group(
- active[my_group[cur_groupnum]].name);
- active[my_group[cur_groupnum]].flag = NOTGOT;
-
- local_top--;
- for (i = cur_groupnum; i < local_top; i++) {
- my_group[i] = my_group[i+1];
- unread[i] = unread[i+1];
- }
- if (cur_groupnum >= local_top)
- cur_groupnum = local_top - 1;
-
- group_selection_page();
- break;
-
- case ctrl('Y'):
- undel_group();
- group_selection_page();
- break;
-
- case 'I': /* toggle inverse video */
- inverse_okay = !inverse_okay;
- if (inverse_okay)
- info_message("Inverse video enabled");
- else
- info_message("Inverse video disabled");
- break;
-
- case ctrl('R'): /* reset .newsrc */
- if (prompt_yn("Reset newsrc? (y/n): ")) {
- reset_newsrc();
- cur_groupnum = 0;
- group_selection_page();
- }
- break;
-
- case '$': /* reread .newsrc, no unsub groups */
- cur_groupnum = 0;
- local_top = 0;
- for (i = 0; i < num_active; i++)
- active[i].flag = NOTGOT;
- read_newsrc(TRUE);
- group_selection_page();
- break;
-
- case 's': /* subscribe to current group */
- MoveCursor(INDEX_TOP +
- (cur_groupnum-first_group_on_screen), 3);
- putchar(' ');
- fflush(stdout);
- MoveCursor(LINES, 0);
-
- subscribe(active[my_group[cur_groupnum]].name,
- ':', my_group[cur_groupnum], FALSE);
- sprintf(buf, "subscribed to %s",
- active[my_group[cur_groupnum]].name);
- info_message(buf);
- break;
-
- case 'u': /* unsubscribe to current group */
- MoveCursor(INDEX_TOP +
- (cur_groupnum-first_group_on_screen), 3);
- putchar('u');
- fflush(stdout);
- MoveCursor(LINES, 0);
-
- subscribe(active[my_group[cur_groupnum]].name,
- '!', my_group[cur_groupnum], FALSE);
- sprintf(buf, "unsubscribed to %s",
- active[my_group[cur_groupnum]].name);
- info_message(buf);
- break;
-
- case '\t':
- for (i = cur_groupnum; i < local_top; i++)
- if (unread[i] != 0)
- break;
- if (i >= local_top) {
- info_message("No more groups to read");
- break;
- }
-
- erase_group_arrow();
- cur_groupnum = i;
- if (cur_groupnum >= last_group_on_screen)
- group_selection_page();
- else
- draw_group_arrow();
- space_mode = TRUE;
- goto go_into_group;
-
- case 'g': /* prompt for a new group name */
- n = choose_new_group();
- if (n >= 0) {
- erase_group_arrow();
- cur_groupnum = n;
- if (cur_groupnum < first_group_on_screen
- || cur_groupnum >= last_group_on_screen)
- group_selection_page();
- else
- draw_group_arrow();
- }
- break;
-
- case 27: /* (ESC) common arrow keys */
- ch = ReadCh();
- if (ch == '[' || ch == 'O')
- ch = ReadCh();
- switch (ch) {
- case 'A':
- case 'D':
- case 'i':
- goto select_up;
-
- case 'B':
- case 'I':
- case 'C':
- goto select_down;
- }
- break;
-
- case 'y': /* pull in rest of groups from active */
- n = local_top;
- for (i = 0; i < num_active; i++)
- active[i].flag = NOTGOT;
- read_newsrc(FALSE);
- for (i = 0; i < num_active; i++)
- if (active[i].flag & NOTGOT) {
- active[i].flag &= ~NOTGOT;
- my_group[local_top] = i;
- unread[local_top] = -1;
- local_top++;
- }
- if (n < local_top) {
- sprintf(buf, "Added %d group%s",
- local_top - n,
- local_top - n == 1 ? "" : "s");
- group_selection_page();
- info_message(buf);
- } else
- info_message("No more groups to yank in");
- break;
-
- case ctrl('U'): /* page up */
- erase_group_arrow();
- cur_groupnum -= NOTESLINES / 2;
- if (cur_groupnum < 0)
- cur_groupnum = 0;
- if (cur_groupnum < first_group_on_screen
- || cur_groupnum >= last_group_on_screen)
- group_selection_page();
- else
- draw_group_arrow();
- break;
-
- case ctrl('D'): /* page down */
- erase_group_arrow();
- cur_groupnum += NOTESLINES / 2;
- if (cur_groupnum >= local_top)
- cur_groupnum = local_top - 1;
-
- if (cur_groupnum <= first_group_on_screen
- || cur_groupnum >= last_group_on_screen)
- group_selection_page();
- else
- draw_group_arrow();
- break;
-
- case '!':
- shell_escape();
- group_selection_page();
- break;
-
- case 'v':
- info_message(cvers);
- break;
-
- case ctrl('N'): /* line down */
- case 'j':
- select_down:
- if (cur_groupnum + 1 >= local_top)
- break;
-
- if (cur_groupnum + 1 >= last_group_on_screen) {
- cur_groupnum++;
- group_selection_page();
- } else {
- erase_group_arrow();
- cur_groupnum++;
- draw_group_arrow();
- }
- break;
-
- case ctrl('P'): /* line up */
- case 'k':
- select_up:
- if (!cur_groupnum)
- break;
-
- if (cur_groupnum <= first_group_on_screen) {
- cur_groupnum--;
- group_selection_page();
- } else {
- erase_group_arrow();
- cur_groupnum--;
- draw_group_arrow();
- }
- break;
-
- case 't': /* redraw */
- case ctrl('W'):
- case ctrl('L'):
- group_selection_page();
- break;
-
- case ' ':
- case '\r': /* go into group */
- case '\n':
- space_mode = FALSE;
- go_into_group:
- clear_message();
- index_point = -1;
- do {
- group_page(
- active[my_group[cur_groupnum]].name);
- } while (index_point == -3);
- group_selection_page();
- break;
-
- case '/': /* search forward */
- search_group(TRUE);
- break;
-
- case '?': /* search backward */
- search_group(FALSE);
- break;
-
- case 'q': /* quit */
- tass_done(0);
-
- case 'h':
- tass_select_help();
- group_selection_page();
- break;
-
- default:
- info_message("Bad command. Type 'h' for help.");
- }
- }
- }
-
-
- group_selection_page() {
- int i;
- int n;
- char new[10];
- char subs;
-
- #ifdef SIGTSTP
- signal(SIGTSTP, select_susp);
- #endif
-
- ClearScreen();
- printf("%s\r\n", nice_time()); /* print time in upper left */
-
- if (mail_check()) { /* you have mail message */
- MoveCursor(0, 66); /* in upper right */
- printf("you have mail\n");
- }
-
- center_line(1, "Group Selection");
- MoveCursor(INDEX_TOP, 0);
-
- first_group_on_screen = (cur_groupnum / NOTESLINES) * NOTESLINES;
-
- last_group_on_screen = first_group_on_screen + NOTESLINES;
- if (last_group_on_screen >= local_top)
- last_group_on_screen = local_top;
-
- for (i = first_group_on_screen; i < last_group_on_screen; i++) {
- switch (unread[i]) {
- case -2:
- strcpy(new, "? ");
- break;
-
- case -1:
- strcpy(new, "- ");
- break;
-
- case 0:
- strcpy(new, " ");
- break;
-
- default:
- sprintf(new, "%-4d", unread[i]);
- }
-
- n = my_group[i];
- if (active[n].flag & SUBS) /* subscribed? */
- subs = ' ';
- else
- subs = 'u'; /* u next to unsubscribed groups */
-
- printf(" %c %4d %-35s %s\r\n", subs, i+1,
- active[n].name, new);
- }
-
- draw_group_arrow();
- }
-
-
- prompt_group_num(ch)
- char ch;
- {
- int num;
-
- clear_message();
-
- if ((num = parse_num(ch, "Select group> ")) == -1) {
- clear_message();
- return FALSE;
- }
- num--; /* index from 0 (internal) vs. 1 (user) */
-
- if (num >= local_top)
- num = local_top - 1;
-
- if (num >= first_group_on_screen
- && num < last_group_on_screen) {
- erase_group_arrow();
- cur_groupnum = num;
- draw_group_arrow();
- } else {
- cur_groupnum = num;
- group_selection_page();
- }
-
- return TRUE;
- }
-
- erase_group_arrow() {
- erase_arrow(INDEX_TOP + (cur_groupnum-first_group_on_screen) );
- }
-
- draw_group_arrow() {
- draw_arrow(INDEX_TOP + (cur_groupnum-first_group_on_screen) );
- }
-
- search_group(forward)
- int forward;
- {
- char buf[LEN+1];
- char buf2[LEN+1];
- int i;
- int len;
- char *prompt;
-
- clear_message();
-
- if (forward)
- prompt = "/";
- else
- prompt = "?";
-
- if (!parse_string(prompt, buf))
- return;
-
- if (strlen(buf))
- strcpy(group_search_string, buf);
- else if (!strlen(group_search_string)) {
- info_message("No search string");
- return;
- }
-
- i = cur_groupnum;
-
- make_lower(group_search_string, buf);
- len = strlen(buf);
-
- do {
- if (forward)
- i++;
- else
- i--;
-
- if (i >= local_top)
- i = 0;
- if (i < 0)
- i = local_top - 1;
-
- make_lower(active[my_group[i]].name, buf2);
- if (match(buf, buf2, len)) {
- if (i >= first_group_on_screen
- && i < last_group_on_screen) {
- erase_group_arrow();
- cur_groupnum = i;
- draw_group_arrow();
- } else {
- cur_groupnum = i;
- group_selection_page();
- }
- return;
- }
- } while (i != cur_groupnum);
-
- info_message("No match");
- }
-
-
- tass_select_help() {
- char title[100];
-
- sprintf(title, "%s, Group Selection Commands", TASS_HEADER);
-
- ClearScreen();
- center_line(0, title);
-
- MoveCursor(2, 0);
-
- printf("\t4\tSelect group 4\r\n");
- printf("\t^D\tPage down\r\n");
- printf("\t^R\tReset .newsrc\r\n");
- printf("\t^U\tPage up\r\n");
- printf("\t^K\tDelete group\r\n");
- printf("\t^Y\tUndelete group\r\n");
- printf("\t<CR>\tRead current group\r\n");
- printf("\t<TAB>\tView next unread group\r\n");
- printf("\tc\tMark group as all read\r\n");
- printf("\tg\tChoose a new group by name\r\n");
- printf("\tj\tDown a line\r\n");
- printf("\tk\tUp a line\r\n");
- printf("\tq\tQuit\r\n");
- printf("\ts\tSubscribe to current group\r\n");
- printf("\tu\tUnsubscribe to current group\r\n");
- printf("\ty\tYank in groups that are not in the .newsrc\r\n");
- printf("\t$\tReread group list from .newsrc\r\n");
- printf("\t/?\tGroup search forward (?=backward)\r\n");
-
- center_line(LINES, "-- hit any key --");
- ReadCh();
- }
-
-
- choose_new_group() {
- char buf[LEN+1];
- char *p;
- int ret;
-
- if (!parse_string("Newsgroup> ", buf))
- return -1;
-
- for (p = buf; *p && (*p == ' ' || *p == '\t'); p++) ;
- if (*p == '\0')
- return -1;
-
- ret = add_group(p, TRUE);
- if (ret < 0)
- info_message("Group not found in active file");
-
- return ret;
- }
-
-
- /*
- * Add a group to the selection list (my_group[])
- * Return the index of my_group[] if group is added or was already
- * there. Return -1 if named group is not in active[].
- */
-
- add_group(s, get_unread)
- char *s;
- int get_unread; /* look in .newsrc for sequencer unread info? */
- {
- long h;
- int i, j;
- extern long hash_groupname();
-
- h = hash_groupname(s);
-
- for (i = group_hash[h]; i >= 0; i = active[i].next)
- if (strcmp(s, active[i].name) == 0) {
- for (j = 0; j < local_top; j++)
- if (my_group[j] == i)
- return j;
-
- active[i].flag &= ~NOTGOT; /* mark that we got it */
- my_group[local_top] = i;
-
- if (get_unread)
- unread[local_top] = get_line_unread(s, i);
- else
- unread[local_top] = -2;
-
- local_top++;
- return local_top - 1;
- }
-
- return -1;
- }
-
-
- @EOF
-
- chmod 644 select.c
-
- echo x - spool_open.c
- cat >spool_open.c <<'@EOF'
-
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "tass.h"
-
-
- /* Hopefully one of these is right for you. */
-
- #ifdef BSD
- # include <sys/types.h>
- # include <sys/dir.h>
- # define DIR_BUF struct direct
- # define D_LENGTH d_namlen
- #endif
- #ifdef M_XENIX
- # include <sys/ndir.h>
- # define DIR_BUF struct direct
- # define D_LENGTH d_namlen
- #endif
- #ifndef DIR_BUF
- # include <sys/types.h>
- # include <dirent.h>
- # define DIR_BUF struct dirent
- # define D_LENGTH d_reclen
- #endif
-
-
-
- char *
- is_remote() {
-
- return "";
- }
-
- nntp_startup() {
- }
-
- nntp_finish() {
- }
-
-
- FILE *open_active_fp() {
- FILE *fp;
-
- fp = fopen(active_file, "r");
- if (fp == NULL) {
- fprintf(stderr, "can't open %s: ", active_file);
- perror("");
- exit(1);
- }
-
- return fp;
- }
-
-
-
- FILE *
- open_art_fp(group_path, art)
- char *group_path;
- long art;
- {
- char buf[LEN];
- struct stat sb;
- extern long note_size;
-
- sprintf(buf, "%s/%s/%ld", SPOOLDIR, group_path, art);
-
- if (stat(buf, &sb) < 0)
- note_size = 0;
- else
- note_size = sb.st_size;
-
- return fopen(buf, "r");
- }
-
-
- open_header_fd(group_path, art)
- char *group_path;
- long art;
- {
- char buf[LEN];
-
- sprintf(buf, "%s/%s/%ld", SPOOLDIR, group_path, art);
- return open(buf, 0);
- }
-
-
-
- /*
- * Longword comparison routine for the qsort()
- */
-
- base_comp(a, b)
- long *a;
- long *b;
- {
-
- if (*a < *b)
- return -1;
- if (*a > *b)
- return 1;
- return 0;
- }
-
-
- /*
- * Read the article numbers existing in a group's spool directory
- * into base[] and sort them. base_top is one past top.
- */
-
- setup_base(group, group_path)
- char *group;
- char *group_path;
- {
- DIR *d;
- DIR_BUF *e;
- long art;
- char buf[200];
-
- top_base = 0;
-
- sprintf(buf, "%s/%s", SPOOLDIR, group_path);
-
- if (access(buf, 4) != 0)
- return;
-
- d = opendir(buf);
- if (d != NULL) {
- while ((e = readdir(d)) != NULL) {
- art = my_atol(e->d_name, e->D_LENGTH);
- if (art >= 0) {
- if (top_base >= max_art)
- expand_art();
- base[top_base++] = art;
- }
- }
- closedir(d);
- qsort(base, top_base, sizeof(long), base_comp);
- }
- }
-
- @EOF
-
- chmod 644 spool_open.c
-
- exit 0
-