home *** CD-ROM | disk | FTP | other *** search
- /*
- * (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;
- }
-
-