home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
tass.lzh
/
page.c
< prev
next >
Wrap
Text File
|
1993-01-24
|
50KB
|
1,586 lines
#include <stdio.h>
#include <signal.h>
#ifndef OSK
#include <sys/types.h>
#include <sys/stat.h>
#else /* OSK */
#include <types.h>
#include <stat.h>
extern FILE *popen ();
#endif /* OSK */
#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_reply[LEN]; /* Reply-To: */
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 */
struct stat note_stat; /* so we can tell how big it is */
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);
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;
long art;
int sav_unread;
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;
sav_unread = arts[respnum].unread;
arts[respnum].unread = 0; /* mark article as read */
open_note(art, group_path);
if (note_page == NOTE_UNAVAIL) {
ClearScreen();
printf("[Article %ld unvailable]\r\012", art);
fflush(stdout);
} else
show_note_page(respnum, group);
while (1) {
if ((n = ReadCh()) == EOF)
longjmp (jmp_buffer, 1);
ch = (char) n;
if ((ch >= '0' && ch <= '9') || (ch == '=')) {
if (ch != '=')
n = prompt_response(ch, respnum);
else {
n = choose_resp (which_base (respnum), 0);
info_message ("Base note selected");
}
if (n != -1) {
arts[respnum].unread = sav_unread;
respnum = n;
goto restart;
}
} else switch (ch) {
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;
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 */
case 'W': /* ... compatible to notes */
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 */
case 'w': /* ... compatible to notes */
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 */
case 'J': /* ... compatible to notes */
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 */
case ctrl('B'): /* possibly cursor doen */
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\012",
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 */
case ctrl('P'): /* possibly cursor doen */
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':
case 'j': /* ... compatible to notes */
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 */
case ctrl('N'): /* possibly cursor doen */
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 'C': /* Cancel */
case 'd': /* delete */
case 'Z': /* zap (director option in notes) */
note_cleanup();
cancel_article ();
note_page = NOTE_UNAVAIL;
/* Fall through ... */
#ifndef OSK
case '\r':
#else /* OSK */
case '\l':
#endif /* OSK */
case '\n': /* go to start of next thread */
case ctrl('F'): /* possibly cursor down */
note_cleanup();
n = next_basenote(respnum);
if (n == -1)
return( which_base(respnum) );
respnum = n;
goto restart;
#ifndef OSK
case 'q': /* quit */
return -2;
#endif /* OSK */
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\012", 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';
#ifdef MNEWS
conv_charset (buf, strlen (buf));
#endif /* MNEWS */
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\012", 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_stat.st_size > 0) {
percent = note_mark[note_page] * 100 / note_stat.st_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\012", 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\012", whichresp, x_resp);
else {
if (x_resp == 0)
printf("No responses\r\012");
else if (x_resp == 1)
printf("1 Response\r\012");
else
printf("%d Responses\r\012", 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\012\r\012", buf);
note_line += 4;
}
show_cont_header(respnum)
int respnum;
{
int whichresp;
int whichbase;
char buf[LEN+60];
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\012\r\012", buf);
note_line += 2;
}
void
open_note(art, group_path)
long art;
char *group_path;
{
char buf[1025];
note_page = 0;
#ifndef OSK
sprintf(buf, "/usr/spool/news/%s/%ld", group_path, art);
#else /* OSK */
sprintf(buf, "%s/%s/%ld", spooldir, group_path, art);
#endif /* OSK */
if (stat(buf, ¬e_stat) < 0)
note_stat.st_size = 0;
note_fp = fopen(buf, "r");
#ifdef MNEWS
if (note_fp)
if (fgets (buf, 256, note_fp)) {
rewind (note_fp);
if (!strncmp (buf, "%(#)$ ", 6)) {
char sav[200];
buf[strlen (buf) - 1] = '\0';
strcpy (sav, buf + 6);
sprintf (buf, "%s/%s", spooldir, sav);
fclose (note_fp);
if (stat (buf, ¬e_stat) < 0)
note_stat.st_size = 0;
note_fp = fopen (buf, "r");
}
}
#endif /* MNEWS */
if (note_fp == NULL) {
fprintf(stderr, "can't open %s: ", buf);
perror("");
note_page = NOTE_UNAVAIL;
return;
}
note_h_from[0] = '\0';
note_h_reply[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';
buf[strlen(buf)-1] = '\0';
#ifdef MNEWS
conv_charset (buf, strlen (buf));
#endif /* MNEWS */
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, "Reply-To: ", 10) == 0) {
strncpy(note_h_reply, &buf[10], LEN);
note_h_reply[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;
{
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';
}
/*
* Find the previous response. Go to the last response in the previous
* thread if we go past the beginning of this thread.
*/
prev_response(n)
int n;
{
int resp;
int i;
resp = which_resp(n);
if (resp > 0)
return choose_resp( which_base(n), resp-1 );
i = which_base(n) - 1;
if (i < 0)
return -1;
return choose_resp( i, nresp(i) );
}
/*
* Find the next response. Go to the next basenote if there
* are no more responses in this thread
*/
next_response(n)
int n;
{
int i;
if (arts[n].thread >= 0)
return arts[n].thread;
i = which_base(n) + 1;
if (i >= top_base)
return -1;
return base[i];
}
/*
* Given a respnum (index into arts[]), find the respnum of the
* next basenote
*/
next_basenote(n)
int n;
{
int i;
i = which_base(n) + 1;
if (i >= top_base)
return -1;
return base[i];
}
void
tass_page_help() {
char ch;
page_help_start:
ClearScreen();
center_line(0, TASS_HEADER);
center_line(1, "Article Pager Commands (page 1 of 2)");
MoveCursor(3, 0);
printf("0, = Read the base article in this thread\r\012");
printf("4 Read response 4 in this thread\r\012");
printf("<CR> Skip to next base article\r\012");
printf("<TAB> Advance to next page or unread article\r\012");
printf("b Back a page\r\012");
printf("f, w Post a followup\r\012");
printf("F, W Post a followup, copy text)\r\012");
printf("H Show article headers\r\012");
printf("i Return to index page\r\012");
printf("k, j Mark article as read & advance to next unread\r\012");
printf("K, J Mark rest of thread as read && advance to next unread\r\012");
printf("m Mail this article to someone\r\012");
printf("n Skip to the next article)\r\012");
printf("N Skip to the next unread article\r\012");
printf("p Go to the previous article\r\012");
printf("P Go to the previous unread article\r\012");
center_line(LINES, "-- hit space for more commands --");
ch = ReadCh();
if (ch != ' ')
return;
ClearScreen();
center_line(0, TASS_HEADER);
center_line(1, "Article Pager Commands (page 2 of 2)");
MoveCursor(3, 0);
printf("q Quit\r\012");
printf("r Reply through mail to author\r\012");
printf("R Reply through mail to author, copy text\r\012");
printf("s Save article to file\r\012");
printf("S Save thread to file\r\012");
printf("t Return to group selection index\r\012");
printf("z Mark article as unread\r\012");
printf("d, C, Z delete article (if it's yours)\r\012");
printf("^R Redisplay first page of article\r\012");
printf("%%, ^X Toggle rot-13 decoding for this article\r\012");
printf("- Show last message\r\012");
printf("| Pipe article into command\r\012");
center_line(LINES, "-- hit any key --");
ch = ReadCh();
if (ch == 'b')
goto page_help_start;
}
/*
* Read a file grabbing the address given for To: and
* sticking it in mail_to
*/
void
find_new_to(nam, mail_to)
char *nam;
char *mail_to;
{
FILE *fp;
char buf[LEN];
char buf2[LEN];
char dummy[LEN];
char *ptr;
fp = fopen(nam, "r");
if (fp != NULL) {
while (fgets(buf, 1024, fp) != NULL) {
if (*buf == '\n')
break;
if (strncmp(buf, "To: ", 4) == 0) {
buf[strlen(buf)-1] = '\0';
strncpy(buf2, &buf[4], LEN);
buf2[LEN-1] = '\0';
parse_from(buf2, mail_to, dummy);
break;
}
}
fclose(fp);
}
for (ptr = mail_to; *ptr; ++ptr)
if (*ptr == ',')
*ptr++ = ' ';
else if (*ptr == '(') {
int nest = 0;
while (*ptr) {
if (*ptr == '(')
++nest;
else if (*ptr == ')')
--nest;
*ptr++ = ' ';
if (nest <= 0)
break;
}
} else
++ptr;
}
void
cancel_article () {
char buf[LEN+40];
FILE *pp;
int err;
if (!note_h_messageid[0]) {
printf ("\rLost message-id!");
CleartoEOLN ();
return;
}
printf("\rCancel %s... ", note_h_messageid);
CleartoEOLN ();
#ifndef MNEWS
Insert your cancel-cmd here!
#else /* MNEWS */
sprintf(buf, "inews '-c=cancel:%s'", note_h_messageid);
#endif /* MNEWS */
if (pp = popen (buf, "w")) {
fprintf (pp, "\nArticle canceled from tass\n");
err = pclose (pp);
} else
err = 1;
if (! err)
printf("article canceled ");
else
printf("article not canceled ");
continue_prompt();
}
mail_to_someone() {
char nam[100];
FILE *fp;
char ch;
char buf[200];
char mail_to[LEN+1];
char subj[LEN+1];
int line;
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
if (!parse_string("Mail article to: ", mail_to))
return(FALSE);
if (mail_to[0] == '\0')
return(FALSE);
sprintf(nam, "%s/.letter", homedir);
umask (omask);
if ((fp = fopen(nam, "w")) == NULL) {
umask (0);
fprintf(stderr, "can't open %s: ", nam);
perror("");
return(FALSE);
}
#ifndef OSK
chmod(nam, 0600);
#else /* OSK */
chmod(nam, 013);
#endif /* OSK */
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);
line = 3;
if (*my_org) {
fprintf(fp, "Organization: %s\n", my_org);
++line;
}
fputs("\n", fp);
++line;
fseek(note_fp, 0L, 0);
copy_fp(note_fp, fp, "");
fclose(fp);
umask (0);
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, line);
break;
case 'a':
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("\rMailing to %s...", mail_to);
CleartoEOLN ();
#ifndef OSK
sprintf(buf, "%s \"%s\" < %s", MAILER,
#else /* OSK */
sprintf(buf, "%s \"%s\" <%s", MAILER,
#endif /* OSK */
mail_to, nam);
if (invoke_cmd(buf)) {
printf("Message sent ");
fflush(stdout);
goto mail_to_someone_done;
} else {
printf("Command failed: %s ", buf);
fflush(stdout);
break;
}
}
}
mail_to_someone_done:
#ifdef USE_UID
setuid(tass_uid);
setgid(tass_gid);
#endif /* USE_UID */
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];
int line;
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
printf("\r\012Mailing to %s...\r\012\r\012", note_h_from);
sprintf(nam, "%s/.letter", homedir);
umask (omask);
if ((fp = fopen(nam, "w")) == NULL) {
umask (0);
fprintf(stderr, "can't open %s: ", nam);
perror("");
return(FALSE);
}
#ifndef OSK
chmod(nam, 0600);
#else /* OSK */
chmod(nam, 013);
#endif /* OSK */
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);
line = 3;
if (*my_org) {
fprintf(fp, "Organization: %s\n", my_org);
++line;
}
fputs("\n", fp);
++line;
if (copy_text) { /* if "copy_text" */
fprintf(fp, "In article %s you write:\n", note_h_messageid);
fseek(note_fp, note_mark[0], 0);
#ifndef INCSTR
copy_fp(note_fp, fp, "> ");
#else /* INCSTR */
copy_fp(note_fp, fp, incstr);
#endif /* INCSTR */
}
#ifdef APPEND_SIG
add_signature (fp);
#endif /* APPEND_SIG */
fclose(fp);
umask (0);
ch = 'e';
while (1) {
switch (ch) {
case 'e':
invoke_editor(nam, line);
break;
case 'a':
return FALSE;
case 's':
strcpy(mail_to, note_h_reply[0] ? note_h_reply : note_from_addr);
find_new_to(nam, mail_to);
printf("\rMailing to %s... ", mail_to);
CleartoEOLN ();
#ifndef OSK
sprintf(buf, "/usr/bin/rmail \"%s\" < %s",
#else /* OSK */
sprintf(buf, "%s \"%s\" <%s", MAILER,
#endif /* OSK */
mail_to, nam);
if (invoke_cmd(buf)) {
printf("Message sent ");
fflush(stdout);
goto mail_to_author_done;
} else {
printf("Command failed: %s ", 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:
#ifdef USE_UID
setuid(tass_uid);
setgid(tass_gid);
#endif /* USE_UID */
continue_prompt();
return TRUE;
}
post_response(group, respnum)
int respnum;
{
FILE *fp;
char nam[100];
char ch;
char buf[200];
int post_anyway = FALSE;
int line;
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\012\r\012",
note_h_followup);
if (!prompt_yn("Continue? (y/n): "))
return FALSE;
}
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
sprintf(nam, "%s/.article", homedir);
umask (omask);
if ((fp = fopen(nam, "w")) == NULL) {
umask (0);
fprintf(stderr, "can't open %s: ", nam);
perror("");
return FALSE;
}
#ifndef OSK
chmod(nam, 0600);
#else /* OSK */
chmod(nam, 013);
#endif /* OSK */
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);
line = 2;
if (*my_org) {
fprintf(fp, "Organization: %s\n", my_org);
++line;
}
if (note_h_distrib != '\0') {
fprintf(fp, "Distribution: %s\n", note_h_distrib);
++line;
}
fprintf(fp, "References: %s\n", note_h_messageid);
fprintf(fp, "\n");
line += 2;
if (respnum) { /* if "copy_text" */
fprintf(fp, "%s writes:\n", note_h_from);
++line;
fseek(note_fp, note_mark[0], 0);
#ifndef INCSTR
copy_fp(note_fp, fp, "> ");
#else /* INCSTR */
copy_fp(note_fp, fp, incstr);
#endif /* INCSTR */
}
#ifdef APPEND_SIG
add_signature (fp);
#endif /* APPEND_SIG */
fclose(fp);
umask (0);
ch = 'e';
while (1) {
switch (ch) {
case 'e':
invoke_editor(nam, line);
break;
case 'a':
return FALSE;
case 'p':
printf("\rPosting... ");
CleartoEOLN ();
#ifndef OSK
sprintf(buf, "%s/inews -h < %s", LIBDIR, nam);
#else /* OSK */
sprintf(buf, "inews -h <%s", nam);
#endif /* OSK */
if (invoke_cmd(buf)) {
printf("article posted ");
fflush(stdout);
goto post_response_done;
} else {
printf("article rejected ");
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:
#ifdef USE_UID
setuid(tass_uid);
setgid(tass_gid);
#endif /* USE_UID */
continue_prompt();
return TRUE;
}
void
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;
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
umask (omask);
if ((fp = fopen(p, "a+")) == NULL) {
umask (0);
fprintf(stderr, "can't open %s: ", nam);
perror("");
info_message("-- article not saved --");
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
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);
umask (0);
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
info_message("-- article saved --");
}
void
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;
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
umask (omask);
if ((fp = fopen(nam, "a+")) == NULL) {
umask (0);
fprintf(stderr, "can't open %s: ", nam);
perror("");
info_message("-- thread not saved --");
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
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);
umask (0);
#ifdef USE_UID
setuid(real_uid);
setgid(real_gid);
#endif /* USE_UID */
info_message("-- thread saved --");
open_note(arts[respnum].artnum, group_path);
}
void
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();
}