home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume22
/
nn6.4
/
part14
/
answer.c
next >
Wrap
C/C++ Source or Header
|
1990-06-07
|
19KB
|
854 lines
/*
* (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
*
* Response handling.
*/
#include "config.h"
#include "news.h"
#include "term.h"
#include "keymap.h"
#include "options.h"
extern char *temp_file;
export char *default_distribution = NULL;
export char *extra_mail_headers = NULL;
export char *extra_news_headers = NULL;
export char *mail_record = NULL;
export char *news_record = NULL;
export char *mail_script = NULL;
export char *news_script = NULL;
export char *mailer_program = REC_MAIL;
export int mailer_pipe_input = 1;
export char *editor_program = NULL;
export char *spell_checker = NULL;
export char *bug_address = BUG_REPORT_ADDRESS;
export int include_art_id = 0;
export int include_full_header = 0;
export int orig_to_include_mask = 0x3;
export int empty_answer_check = 1; /* reject replies that are not edited */
export int response_check_pause = 0; /* time to wait for background cmds */
export char *response_dflt_answer = "send";
#ifdef APPEND_SIGNATURE
export int append_sig_mail = 1; /* mail does not append it */
#else
export int append_sig_mail = 0;
#endif
export int append_sig_post = 0; /* inews should always do this */
export int query_signature = 1; /* query user */
#define INCL_MARK_SIZE 10
export char included_mark[INCL_MARK_SIZE + 1] = ">";
import char delayed_msg[];
static int ed_line;
#ifdef NNTP
#ifdef NNTP_MINI_INEWS_HEADER
#include <time.h>
static mini_inews_header(t)
FILE *t;
{
time_t now;
extern struct tm *gmtime();
extern char *asctime();
char *date, host[64];
now = cur_time();
date = asctime(gmtime(&now));
date[3] = date[7] = date[10] = date[19] = date[24] = NUL;
gethostname(host, 64);
fprintf(t, "Path: %s!%s\n", host, user_name());
fprintf(t, "Date: %s %s %s %s GMT\n", date+8, date+4, date+22, date+11);
fprintf(t, "Message-ID: <%s.%ld@%s>\n", user_name, (long)now, host);
ed_line += 3;
}
#endif
#endif
static subj_line(t, re, subj, prefix)
FILE *t;
int re;
char *subj, *prefix;
{
if (subj == NULL) return 0;
fputs("Subject: ", t);
if (re >= 0)
fputs("Re: ", t);
if (prefix) {
fputs(prefix, t);
fputc(' ', t);
}
fputs(subj, t);
fputc(NL, t);
ed_line++;
return 1;
}
static ng_line(t, use_follow)
FILE *t;
int use_follow;
{
fprintf(t, "Newsgroups: %s\n",
use_follow && news.ng_follow ? news.ng_follow : news.ng_groups);
ed_line++;
}
static ref_line(t)
FILE *t;
{
if (news.ng_ref == NULL && news.ng_ident == NULL) return;
fputs("References:", t);
if (news.ng_ref) fprintf(t, " %s", news.ng_ref);
if (news.ng_ident) fprintf(t, " %s", news.ng_ident);
putc(NL, t);
ed_line++;
}
static to_line(t, to)
FILE *t;
char *to;
{
if (to == NULL) return 0;
fprintf(t, "To: %s\n", to);
ed_line++;
return 1;
}
static alt_to_line(t, to, mask)
FILE *t;
char *to;
int mask;
{
if (to == NULL) return;
if (mask && (orig_to_include_mask & mask) == 0) return;
fprintf(t, "Orig-To: %s\n", to);
ed_line++;
}
static end_header(t, extra_headers)
FILE *t;
register char *extra_headers;
{
if (extra_headers != NULL && *extra_headers != NUL) {
while (*extra_headers != NUL) {
if (*extra_headers == ';') {
if (*++extra_headers == NUL) break;
fputc(NL, t);
ed_line++;
} else
fputc(*extra_headers++, t);
}
fputc(NL, t);
ed_line++;
}
fputc(NL, t);
ed_line++;
}
static reply_to(t, address)
FILE *t;
char *address;
{
char route[512];
if (address == NULL) return 0;
if (reroute(route, address)) {
to_line(t, route);
return 1;
}
return 0;
}
/*
* invoke aux shell script with suitable arguments
*
* WARNING: record may be NULL, so it must be the last argument!!
*/
static aux_param_bool(f, name, on)
FILE *f;
char *name;
int on;
{
fprintf(f, "%s=%s\n", name, on ? "true" : "false");
}
static aux_param_str(f, name, str)
FILE *f;
char *name, *str;
{
fprintf(f, "%s='%s'\n", name, str != NULL ? str : "");
}
static aux_param_int(f, name, i)
FILE *f;
char *name;
int i;
{
fprintf(f, "%s=%d\n", name, i);
}
static aux_sh(ah, script, prog, action, record, sent_fmt, append_sig)
article_header *ah;
char *script, *prog, *action, *record, *sent_fmt;
int append_sig;
{
FILE *param;
char *args[10], *fn;
register char **ap = args;
import int novice;
import char *pager;
#ifdef NNTP
extern char *nntp_get_filename();
#endif
param = open_file(relative(nn_directory, ".param"), OPEN_CREATE);
if (param == NULL) {
strcpy(delayed_msg, "cannot create .param file for aux script");
return 0;
}
if (strcmp(prog, "cancel") == 0) {
aux_param_str(param, "ART_ID", action); /* article id for cancel */
aux_param_str(param, "GROUP", record); /* group name for cancel */
} else {
aux_param_str(param, "FIRST_ACTION", action);
aux_param_str(param, "RECORD", record);
aux_param_str(param, "WORK", temp_file);
aux_param_int(param, "ED_LINE", ed_line);
aux_param_bool(param, "NOVICE", novice);
aux_param_bool(param, "EMPTY_CHECK", empty_answer_check);
aux_param_bool(param, "APPEND_SIG", append_sig);
aux_param_bool(param, "QUERY_SIG", append_sig && query_signature);
if (editor_program != NULL)
aux_param_str(param, "EDITOR", editor_program);
aux_param_str(param, "SPELL_CHECKER", spell_checker);
aux_param_str(param, "PAGER", pager);
aux_param_str(param, "MAILER", mailer_program);
aux_param_bool(param, "MAILER_PIPE", mailer_pipe_input);
aux_param_int(param, "WAIT_PERIOD", response_check_pause);
aux_param_str(param, "DFLT_ANSW", response_dflt_answer);
if (current_group != NULL) {
aux_param_str(param, "G", current_group->group_name);
if (ah == NULL)
fn = NULL;
else
#ifdef NNTP
if (use_nntp)
fn = nntp_get_filename(ah->a_number, current_group);
else
#endif
fn = group_path_name;
aux_param_str(param, "A", fn != NULL ? fn : "");
}
/*
aux_param_str(param, "", );
aux_param_bool(param, "", );
aux_param_int(param, "", );
*/
}
fclose(param);
stop_usage();
/* OBS: relative() returns ptr to static data below */
*ap++ = "nnaux";
*ap++ = script != NULL ? script : relative(lib_directory, "aux");
*ap++ = prog;
*ap++ = NULL;
if (execute(SHELL, args, 1)) {
sprintf(delayed_msg, sent_fmt, " not");
return 1;
}
sprintf(delayed_msg, sent_fmt, "");
return 0;
}
static append_file(name, f)
char *name;
register FILE *f;
{
register FILE *s;
register int c;
s = open_file(name, OPEN_READ);
if (s == NULL) return;
while ((c = getc(s)) != EOF) putc(c, f);
fclose(s);
}
answer(ah, command, incl)
article_header *ah;
int command;
int incl; /* <0: ask, 0: don't include, >0: include article */
{
register FILE *t, *art;
char *pgm, *first_action, *record_file;
int edit_message, append_sig;
char *str, *script;
news_header_buffer nhbuf, dhbuf;
first_action = "edit";
edit_message = 1;
append_sig = 0;
if (incl < 0) {
prompt("Include original article? ");
if ((incl = yes(0)) < 0) return 0;
}
art = NULL;
if (ah && ah->a_group) init_group(ah->a_group);
if (incl || (command != K_MAIL_OR_FORWARD && command != K_BUG_REPORT)) {
int open_modes;
open_modes = FILL_NEWS_HEADER | GET_ALL_FIELDS | SKIP_HEADER;
if (ah->flag & A_DIGEST) open_modes |= FILL_DIGEST_HEADER;
art = open_news_article(ah, open_modes, nhbuf, dhbuf);
if (art == NULL) {
msg("Can't find original article");
return 0;
}
if (ah->flag & A_DIGEST) {
if (digest.dg_from)
news.ng_path = news.ng_from = digest.dg_from;
if (digest.dg_subj)
news.ng_subj = digest.dg_subj;
}
} else
ah = NULL;
/* build header */
new_temp_file();
if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
msg("Can't create %s", temp_file);
return 0;
}
ed_line = 0;
follow_to_poster:
record_file = mail_record;
script = mail_script;
if (command == K_REPLY) {
pgm = "reply";
append_sig = append_sig_mail;
ah->flag |= A_ST_REPLY;
if (reply_to(t, news.ng_reply) ||
reply_to(t, news.ng_from) ||
reply_to(t, news.ng_path)) goto alt0;
if (to_line(t, news.ng_reply)) goto alt1;
if (to_line(t, news.ng_from)) goto alt2;
if (to_line(t, news.ng_path)) goto alt3;
goto err;
alt0:
alt_to_line(t, news.ng_reply, 0x1);
alt1:
alt_to_line(t, news.ng_from, 0x2);
alt2:
alt_to_line(t, news.ng_path, 0x4);
alt3:
if (news.ng_subj)
subj_line(t, ah->replies, ah->subject, (char *)NULL);
else
subj_line(t, 0, current_group->group_name, "Your Article in");
ng_line(t, 0);
ref_line(t);
end_header(t, extra_mail_headers);
if (incl) {
fprintf(t, "In %s you write:\n", current_group->group_name);
ed_line++;
}
}
if (command == K_FOLLOW_UP) {
if (news.ng_follow && strcmp(news.ng_follow, "poster") == 0) {
command = K_REPLY;
msg("Followup by reply to poster");
goto follow_to_poster;
}
pgm = "follow";
record_file = news_record;
script = news_script;
append_sig = append_sig_post;
ah->flag |= A_ST_FOLLOW;
#ifdef NNTP
#ifdef NNTP_MINI_INEWS_HEADER
mini_inews_header(t);
#endif
#endif
ng_line(t, 1);
if (news.ng_subj)
subj_line(t, ah->replies, ah->subject, (char *)NULL);
else
if (!subj_line(t, 0, news.ng_from, "Babble from"))
if (!subj_line(t, 0, news.ng_ident, "Article")) {
prompt("Subject: ");
str = get_s(NONE, NONE, NONE, NULL_FCT);
if (str == NULL) goto err;
subj_line(t, -1, str, (char *)NULL);
}
if (news.ng_keyw) {
fprintf(t, "Keywords: %s\n", news.ng_keyw);
ed_line++;
}
if (news.ng_dist) {
fprintf(t, "Distribution: %s\n", news.ng_dist);
ed_line++;
}
ref_line(t);
end_header(t, extra_news_headers);
if (incl) {
if (news.ng_from) {
if (include_art_id && news.ng_ident)
fprintf(t, "In%s %s ",
ah->flag & A_DIGEST ? " digest" : "",
news.ng_ident);
fprintf(t, "%s writes:\n", news.ng_from);
ed_line++;
} else
if (news.ng_ident) {
fprintf(t, "In %s %s:\n",
ah->flag & A_DIGEST ? "digest" : "article",
news.ng_ident);
ed_line++;
}
}
}
if (command == K_MAIL_OR_FORWARD || command == K_BUG_REPORT) {
pgm = incl ? "forward" : "mail";
append_sig = append_sig_mail;
m3_again:
prompt("To: ");
str = get_s(user_name(),
command == K_BUG_REPORT ? bug_address : NONE,
NONE, NULL_FCT);
if (str == NULL) goto close_t;
if (*str == NUL) str = user_name();
if (*str == '?') goto m3_again;
if (strcmp(str, user_name()) == 0)
record_file = NULL; /* we will get this anyway,
there is so no need to save it */
/* if (reply_to(t, str)) { alt_to_line(t, str, 0); } else */
to_line(t, str);
do {
prompt("Subject: ");
str = get_s(incl ? ah->subject : NONE,
command == K_BUG_REPORT ? "nn bug report" : NONE,
NONE, NULL_FCT);
if (str == NULL) goto close_t;
if (*str == NUL && incl) str = ah->subject;
} while (*str == NUL);
subj_line(t, -1, str, (char *)NULL);
end_header(t, extra_mail_headers);
if (incl) {
prompt("\1Edit\1 forwarded message? ");
if ((edit_message = yes(0)) < 0) goto close_t;
if (!edit_message) {
first_action = "send";
fseek(art, ah->hpos, 0);
} else
if (include_full_header && command == K_MAIL_OR_FORWARD)
fseek(art, ah->hpos, 0);
}
if (command == K_BUG_REPORT) {
fprintf(t, "\n=== configuration ===\n");
append_file(relative(lib_directory, "conf"), t);
fprintf(t, "=== end ===\n");
}
}
/* empty line terminates header */
fputc(NL, t);
ed_line++;
prompt("\1WAIT\1");
if (incl) {
register c, prevnl = 1;
while ((c = getc(art)) != EOF) {
if (c == NL) {
putc(c, t);
if (ftell(art) >= ah->lpos) break;
prevnl++;
continue;
}
if (prevnl) {
if (command != K_MAIL_OR_FORWARD || ftell(art) < ah->fpos)
fputs(included_mark, t);
prevnl = 0;
}
putc(c, t);
}
} else {
putc(NL, t);
ed_line++;
}
fclose(t);
if (art) fclose(art);
aux_sh(ah, script, pgm, first_action, record_file,
command == K_FOLLOW_UP ? "Article%s posted" : "Mail%s sent",
append_sig);
return edit_message;
err:
msg("Can't build header for %s",
command != K_FOLLOW_UP ? "letter" : "article");
close_t:
fclose(t);
unlink(temp_file);
if (art) fclose(art);
return 0;
}
/*
* inet_name: return "<user_name()>@<host_name()>"
*/
static char *inet_name()
{
static char *inetname = NULL;
char hname[100], *un;
if (inetname == NULL) {
gethostname(hname, 100);
un = user_name();
inetname = newstr(strlen(hname) + strlen(un) + 2);
sprintf(inetname, "%s@%s", un, hname);
}
return inetname;
}
/*
* check_sender: If sender is "root", "news", the full name or the internet
* name of the user, return 1 otherwise 0
*/
static int check_sender(sender)
char *sender;
{
char *full_name();
return strcmp(user_name(), "root") == 0
|| strcmp(user_name(), "news") == 0
|| strmatch(full_name(), sender)
|| strmatch(inet_name(), sender);
}
cancel(ah)
article_header *ah;
{
news_header_buffer nhbuf;
FILE *f;
if (ah->a_group) init_group(ah->a_group);
if (ah->flag & A_DIGEST) {
fputs("\rCancel entire digest ? ", stdout); clrline();
if (yes(1) > 0)
ah->flag &= ~A_DIGEST;
else {
msg("Can only cancel entire digests (yet?)");
return 2;
}
}
f = open_news_article(ah, FILL_NEWS_HEADER|GET_ALL_FIELDS, nhbuf, (char *)NULL);
if (f == NULL) {
msg("Article not found");
return 2;
}
fclose(f);
if (! check_sender(news.ng_from)) {
msg("You can only cancel your own articles!");
return 1;
}
prompt("Confirm cancel: '%s: %.30s'",
ah->sender ? ah->sender : "",
ah->subject ? ah->subject : "");
if (yes(1) <= 0) return 1;
printf("\rCancelling article %s in group %s",
news.ng_ident, current_group->group_name);
clrline();
ed_line = -1;
if (aux_sh(ah, (char *)NULL, "cancel", news.ng_ident, current_group->group_name,
"Article%s cancelled", 0))
return -1;
return 0;
}
static char *post_distribution = NULL;
static char *post_subject = NULL;
static char *post_summary = NULL;
static char *post_keywords = NULL;
static char *post_source_file = NULL;
static int post_no_edit = 0;
static char *post_to_groups = NULL;
Option_Description(post_options) {
'd', String_Option(post_distribution),
'f', String_Option(post_source_file),
'k', String_Option(post_keywords),
's', String_Option(post_subject),
'y', String_Option(post_summary),
'p', Bool_Option(post_no_edit),
'\0',
};
do_nnpost(argc, argv)
int argc;
char *argv[];
{
int ngroups, i;
char newsgroups[FILENAME*2];
init_term();
visit_init_file(0, (char *)NULL);
current_group = NULL;
ngroups =
parse_options(argc, argv, (char *)NULL, post_options,
" newsgroup...");
if (post_no_edit && post_source_file == NULL) {
printf("Must specify a source file with -p\n");
nn_exit(1);
}
if (ngroups > 0) {
strcpy(newsgroups, argv[1]);
for (i = 2; i <= ngroups; i++) {
strcat(newsgroups, ",");
strcat(newsgroups, argv[i]);
}
post_to_groups = newsgroups;
}
raw();
clrdisp();
prompt_line = 0;
post_menu();
putchar(CR); putchar(NL);
unset_raw();
if (*delayed_msg)
printf("%s\n", delayed_msg);
nn_exit(0);
}
post_menu()
{
register FILE *t, *src;
register int c;
char *str, *tail;
char group_name[FILENAME], subject[FILENAME],
distribution[FILENAME], keywords[FILENAME], summary[FILENAME];
extern group_completion();
if (post_source_file) {
src = open_file(post_source_file, OPEN_READ);
if (src == NULL) {
printf("File %s not found\n");
nn_exit(1);
}
}
if (post_to_groups)
strcpy(group_name, post_to_groups);
else {
group_name[0] = NUL;
again_group:
prompt(who_am_i == I_AM_POST ? "Newsgroups: " : "\1POST to group\1 ");
str = get_s(current_group ? current_group->group_name : NONE,
group_name, NONE, group_completion);
if (str == NULL) return 0;
if (*str == NUL) {
if (current_group == NULL || (current_group->group_flag & G_FAKED))
return 0;
str = current_group->group_name;
}
strcpy(group_name, str);
for (str = group_name; str; str = tail) {
tail = strchr(str, ',');
if (tail) *tail = NUL;
if (lookup(str) == NULL) {
msg("unknown group: %s", str);
*str = NUL;
goto again_group;
}
if (tail) *tail++ = ',';
}
if (who_am_i == I_AM_POST) prompt_line++;
}
if ((str = post_subject) == NULL) {
prompt("Subject: ");
str = get_s(NONE, NONE, NONE, NULL_FCT);
if (str == NULL || *str == NUL) return 0;
if (who_am_i == I_AM_POST) prompt_line++;
}
strcpy(subject, str);
if ((str = post_keywords) == NULL) {
prompt("Keywords: ");
str = get_s(NONE, NONE, NONE, NULL_FCT);
if (str == NULL) return 0;
if (who_am_i == I_AM_POST) prompt_line++;
}
strcpy(keywords, str);
if ((str = post_summary) == NULL) {
prompt("Summary: ");
str = get_s(NONE, NONE, NONE, NULL_FCT);
if (str == NULL) return 0;
if (who_am_i == I_AM_POST) prompt_line++;
}
strcpy(summary, str);
if (post_distribution) {
strcpy(distribution, post_distribution);
} else {
if (default_distribution != NULL)
strcpy(distribution, default_distribution);
else {
strcpy(distribution, group_name);
if (str = strchr(distribution, ',')) *str = NUL;
if (str = strchr(distribution, '.')) *str = NUL;
}
prompt("Distribution: (default '%s') ", distribution);
str = get_s(NONE, NONE, NONE, NULL_FCT);
if (str == NULL) return 0;
if (*str) strcpy(distribution, str);
if (who_am_i == I_AM_POST) prompt_line++;
}
new_temp_file();
if ((t = open_file(temp_file, OPEN_CREATE)) == NULL) {
msg("Can't create %s", temp_file);
return 0;
}
if (!post_no_edit)
prompt("\1WAIT\1");
ed_line = 3;
#ifdef NNTP
#ifdef NNTP_MINI_INEWS_HEADER
mini_inews_header(t);
#endif
#endif
fprintf(t, "Newsgroups: %s\n", group_name);
fprintf(t, "Distribution: %s\n", distribution);
fprintf(t, "Subject: %s\n", subject);
if (*summary) {
fprintf(t, "Summary: %s\n", summary);
ed_line++;
}
if (*keywords) {
fprintf(t, "Keywords: %s\n", keywords);
ed_line++;
}
end_header(t, extra_news_headers);
if (post_source_file) {
while ((c = getc(src)) != EOF) putc(c, t);
fclose(src);
} else
fputc(NL, t);
fclose(t);
aux_sh((article_header *)NULL, news_script, "post",
post_no_edit ? "send" : "edit", news_record,
"Article%s posted", append_sig_post);
return 1;
}