/*
**++
**  FACILITY:
**      NEWSPOST
**
**  ABSTRACT:
**      Post a newsitem into NEWS the NEWS database, and also post the item
**      into the net distribution area.
**
**  AUTHOR:
**      Geoff Huston
**
**  COPYRIGHT:
**      Copyright © 1988,1989,1990,1991
**
**  MODIFICATION HISTORY:
**      V5.5     7-OCT-1988     GIH
**          Modify SPAWN to accomodate SMG brdcst trap and terminal mbx
**      V5.6    11-Nov-1988     GIH
**          Include NEWS_TIMEZONE as timezone in outgoing postings
**      V5.7    16-Dec-1988     GIH
**          Call get_post_defaults to read default newsgroup followup
**          and distribution keywords
**       -  Correct bug when moderator posts to group
**      V5.8     3-Feb-1988     GIH
**       -  Correct bug in SPAWN to mailer for moderator mail
**      V5.9    10-May-1989     GIH
**        - If NEWS_FROM or PMDF_FROM is defined then use this logical name
**          instead of the username in postings.
**	V6.0-4	19-March-1991	reggers@ria.ccs.uwo.ca
**	  - Add support for UWO/Mail for Vax/VMS 
**	V6.1	 9-Feb-1992	rankin@eql.caltech.edu
**	  - Lint cleanup
**      V6.1    25-FEB-1993     ewilts%GALAXY.GOV.BC.CA
**        - fixed typo in message
**        - fixed problem with FOLLOW/REPLY
**	V6.1b6	23-Mar-1993	bailey@genetics.upenn.edu
**	  - Report error if can't open Followup/File input file
**      V6.1b7  13-Jul-1993	Charles Bailey  bailey@genetics.upenn.edu
**        - changed do_posting() so that when a reply is mailed to original
**          poster, copy_self mail profile setting is honored
**      V6.1b8  14-Oct-1993	Charles Bailey  bailey@genetics.upenn.edu
**        - changed do_posting() so that when post is cancelled, contents
**          of infile are included in dead.letter
**	V6.1b7  26-Apr-1993     winter@vision.rs.ch
**	  - added /NEWSGROUPS=(list_of_newsgroups) to FOLLOWUP to avoid the
**	    newsgroup-prompt
**	    (new patch archive entry reformatted for 6.1b8 on 10-Aug-1993
**	     by Charles Bailey  bailey@genetics.upenn.edu)
**  	V6.1b8  15-May-1994	mark.martinec@ijs.si
**	  - add 'if (smg_active)' before all calls to newsgroup_header()
**	    to avoid SMG calls which would fail (problem manifested
**	    itself as SMG failures during REPOST in 'noscreen' mode)
**	V6.1b9	17-Aug-1994     Mark Martinec   mark.martinec@ijs.si
**	  - code cleanup to make it compile under gcc 2.6.0 with full
**	    warnings reporting turned on - with no or very few harmless warnings
**	V6.1b9	17-Sep-1994     Mark Martinec   mark.martinec@ijs.si
**	  - code cleanup to preserve the read-only nature of string literals
**	    (strategically placed 'const' attribute to string parameters)
**	V6.1b11	21-Feb-1997     Mark Martinec   mark.martinec@ijs.si
**	  - fp_open is now int;  pass it by ref;
**	    don't try to delete_file_versions(fp_open);
**	V6.1b11 14-Apr-1997	Mark Martinec   mark.martinec@ijs.si
**	  - change %s to %.<n>s in sprintf to guard against overwriting buffer
**	  - replace several calls to strcpy/strcat with safer strnncpy/strnncat
**	  - replace pattern strcpy(news_malloc(strlen(x)+1),x) with news_strdup
**	  - add extra parameter (buffer size) to parse_newsgroups()
**	  - fix the year 2000 problem when generating 'Date:' headers
**	  - when generating 'Path:' header as a NNTP client, do not put
**	    our host name into the path - it belongs to the 'Nntp-Posting-Host:'
**	    Puting posting host name in path causes a problem when the posting
**	    host is also running a Usenet server. Articles posted via NNTP
**	    to another server will not propagate to the server which happen
**	    to be running on the posting host.
**--
**/

#ifdef vaxc
#module NEWSPOST "V6.2"
#endif

#define _NEWSPOST_C
#define module_name "NEWSPOST"

#include "newsinclude.h"
#include "newsextern.h"
#include "newsmail.h"

extern
char profile_organization[];


#if UWO
int call_mail(file,subject,address,msg)
  int save_displ;
  const char *file, *subject, *address, *msg;
{
  char mail_cmd[IO_SIZE];
  char my_subject[512], my_address[512];
  int mail_cmd_l;

  err_line(msg);
  strnncpy(my_subject,sizeof(my_subject), quotes(subject),-1, 0);
  strnncpy(my_address,sizeof(my_address), quotes(address),-1, 0);
  sprintf(mail_cmd,"MAIL/NOEDIT%s /FILE=", (mail_self_flag ? " /SELF" : ""));
  strnncat(mail_cmd,sizeof(mail_cmd),-1,         file,-1,          &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "/SUBJECT=\"",-1, &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, my_subject,-1,    &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "\" \"",3,        &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, my_address,-1,    &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "\"",1,           &mail_cmd_l);
  save_displ = leave_screen(0);
  /* saving/restoring screen is probably a waste in this case,
     but to be on the safe side ... */
  lib$spawn(c$dsc(mail_cmd),c$dsc("nl:"),c$dsc("nl:"),0,0,0,0,0,0,0,0,0,0);
  join_screen(save_displ);
  clear_err_line();
  return 0;
}

#else	/* UWO */
#ifdef SPAWN_MAIL
int call_mail(file,subject,address,msg)
  int save_displ;
  const char *file, *subject, *address, *msg;
{
  char mail_cmd[IO_SIZE];
  char my_subject[512], my_address[512];
  int mail_cmd_l;

  err_line(msg);
  strnncpy(my_subject,sizeof(my_subject), quotes(subject),-1, 0);
  strnncpy(my_address,sizeof(my_address), quotes(address),-1, 0);
  sprintf(mail_cmd,"MAIL/NOEDIT%s ", (mail_self_flag ? " /SELF" : ""));
  strnncat(mail_cmd,sizeof(mail_cmd),-1,         file,-1,          &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "/SUBJECT=\"",-1, &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, my_subject,-1,    &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "\" \"",3,        &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, my_address,-1,    &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "\"",1,           &mail_cmd_l);
  save_displ = leave_screen(0);
  /* saving/restoring screen is probably a waste in this case,
     but to be on the safe side ... */
  lib$spawn(c$dsc(mail_cmd),0,0,0,0,0,0,0,0,0,0,0,0);
  join_screen(save_displ);
  clear_err_line();
  return 0;
}
#else
#ifndef VMSV4

#ifdef VMSV5

int call_mail(file,subject,address,msg)
#else

int call_mail_v5(file,subject,address,msg)
#endif

  const char *file, *subject, *address, *msg;
{
  int context = 0,
      sts,
      i = 0;
  unsigned int mail_username_len = 0;
  short cc_type = MAIL$_CC;
  char mail_username[255+1];
  const char *cp1, *cp2;

  struct mai_itmlst
    null_list[] = {{0,0,0,0}},
    att_list[4];

  err_line(msg);
  if (smg_active) {
    display_brdcst(2);
    smg$end_pasteboard_update(&pid);
    smg$begin_pasteboard_update(&pid);
    }

  i = 0;
  if (mail_self_flag) {
    att_list[i].bl = sizeof mail_username - 1;
    att_list[i].ic = MAIL$_SEND_USER;
    att_list[i].ba = mail_username;
    att_list[i].rl = &mail_username_len;
    ++i;
    }
  att_list[i] = null_list[0];
  sysprv();
  if (!((sts = mail$send_begin(&context,null_list,att_list)) & 1)) {
    nosysprv();
    clear_err_line();
    return(sts);
    }
  i = 0;
  att_list[i].bl = strlen(address);
  att_list[i].ic = MAIL$_SEND_TO_LINE;
  att_list[i].ba = (char *) address;
  att_list[i].rl = 0;
  ++i;

  if (subject && *subject) {
    att_list[i].bl = strlen(subject);
    att_list[i].ic = MAIL$_SEND_SUBJECT;
    att_list[i].ba = (char *) subject;
    att_list[i].rl = 0;
    ++i;
    }
  att_list[i] = null_list[0];

  if (!((sts = mail$send_add_attribute(&context,att_list,null_list)) & 1)) {
    mail$send_end(&context,null_list,null_list);
    nosysprv();
    clear_err_line();
    return(sts);
    }
  att_list[0].bl = strlen(file);
  att_list[0].ic = MAIL$_SEND_FILENAME;
  att_list[0].ba = (char *) file;
  att_list[0].rl = 0;
  att_list[1] = null_list[0];

  if (!((sts = mail$send_add_bodypart(&context,att_list,null_list)) & 1)) {
    mail$send_end(&context,null_list,null_list);
    nosysprv();
    clear_err_line();
    return(sts);
    }
  
  cp1 = address;
	/* add support for "@file" for distribution lists */
  if (*cp1 == '@') {
    struct rms_file *df;

    if ((df = rms_open(cp1+1,"sys$login:.dis",0)) != 0) {
      char dis_line[512];

      att_list[0].ic = MAIL$_SEND_USERNAME;
      att_list[0].ba = dis_line;
      att_list[0].rl = 0;
      att_list[1] = null_list[0];

      while (rms_get(dis_line,sizeof(dis_line),df)) {
        att_list[0].bl = strlen(dis_line);
        if (!((sts = mail$send_add_address(&context,att_list,null_list)) & 1)) {
          mail$send_end(&context,null_list,null_list);
          nosysprv();
          clear_err_line();
          return(sts);
          }
        }
      rms_close(df);
      }
    }
  else {
    att_list[0].ic = MAIL$_SEND_USERNAME;
    att_list[0].rl = 0;
    att_list[1] = null_list[0];
    for (; cp1; cp1 = cp2 ? cp2+1 : NULL) {
      cp2 = strchr(cp1,',');
      att_list[0].bl = cp2 ? cp2-cp1 : strlen(cp1);
      att_list[0].ba = (char *) cp1;
      if (!((sts = mail$send_add_address(&context,att_list,null_list)) & 1)) {
        mail$send_end(&context,null_list,null_list);
        nosysprv();
        clear_err_line();
        return(sts);
        }
      }
    }
  if (mail_self_flag) {
    att_list[0].bl = mail_username_len;
    att_list[0].ic = MAIL$_SEND_USERNAME;
    att_list[0].ba = mail_username;
    att_list[0].rl = 0;
    att_list[1].bl = sizeof cc_type;
    att_list[1].ic = MAIL$_SEND_USERNAME_TYPE;
    att_list[1].ba = (char *) &cc_type;
    att_list[1].rl = 0;
    att_list[2] = null_list[0];
    if (!((sts = mail$send_add_address(&context,att_list,null_list)) & 1)) {
      mail$send_end(&context,null_list,null_list);
      nosysprv();
      clear_err_line();
      return(sts);
      }
    }

  if (!((sts = mail$send_message(&context,null_list,null_list)) & 1)) {
    mail$send_end(&context,null_list,null_list);
    nosysprv();
    clear_err_line();
    return(sts);
    }
  mail$send_end(&context,null_list,null_list);
  nosysprv();
  clear_err_line();
  return(1);
}

#endif

#ifndef VMSV5

int call_mail(file,subject,address,msg)
    const char
         *file,
         *subject,
         *address,
         *msg;
{
    char mail_cmd[IO_SIZE];
    int mail_cmd_l;
    int save_displ;

#ifndef VMSV4
  if (vms_major > 4) return(call_mail_v5(file,subject,address,msg));
#endif
  err_line(msg);
  sprintf(mail_cmd,"MAIL/NOEDIT%s ", (mail_self_flag ? " /SELF" : ""));
  strnncat(mail_cmd,sizeof(mail_cmd),-1,         file,-1,          &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "/SUBJECT=\"",-1, &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, quotes(subject),-1, &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, "\" ",2,          &mail_cmd_l);
  strnncat(mail_cmd,sizeof(mail_cmd),mail_cmd_l, address,-1,       &mail_cmd_l);
  save_displ = leave_screen(0);
  /* saving/restoring screen is probably a waste in this case,
     but to be on the safe side ... */
  lib$spawn(c$dsc(mail_cmd),0,0,0,0,0,0,0,0,0,0,0,0);
  join_screen(save_displ);
  clear_err_line();
  return 0;
}

#endif
#endif
#endif /* UWO */

int all_local(gl)
  char *gl;
{
  char s[GRPNAMELEN],
       *locg,
       *cp1,
       *cp2;
  int g;

  locg = news_strdup(gl,-1);
  for (cp1=locg; cp1; cp1=cp2) {
    cp2 = chop_str_plus(cp1,',');
    util_cvrt(s,cp1);
    if (   (g = ga_exact_name(s))
        && (   !(ga[g]->grp_flags & NEWS_M_LOCAL)
            || (ga[g]->grp_flags & NEWS_M_MAILLIST))) {
      news_free(locg);
      return(0);
      }
    }
  news_free(locg);
  return(1);
}

/*
 *  parse_newsgroups
 *
 *  Parse the newsgroup specification, building a comma separated list.
 */

void
parse_newsgroups(newslist,newslist_m,dflt,ask,use_aliases,auth_check)
  char *newslist;
  int newslist_m;  /* sizeof(newslist) */
  const char *dflt;
  int ask, use_aliases, auth_check;
{
  int status;
  int newslist_l;
  char newsgroups[256];
  unsigned short newsgroups_len;
  $DESCRIPTOR(newsgroups_dsc,newsgroups);

  if ((ask) ||
      (cli$get_value(c$dsc("NEWSGROUPS"), &newsgroups_dsc, &newsgroups_len) == CLI$_ABSENT)) {
    unsigned short trm;

    status = get_input_dflt(&newsgroups_dsc,c$dsc("Newsgroups: "),
      &newsgroups_len,c$dsc(dflt),&trm);
    if (status == RMS$_EOF) longjmp(env,2);
    newsgroups[newsgroups_len] = '\0';
    if (use_aliases) strnncpy(newsgroups,sizeof(newsgroups),
                              aliases(newsgroups,newsgroups_len),-1, 0);
    if (auth_check) auth_list(newsgroups);
    strnncpy(newslist,newslist_m, newsgroups,-1, &newslist_l);
    }
  else {
    *newslist = '\0'; newslist_l = 0;
    do {
      newsgroups[newsgroups_len] = '\0';
      if (use_aliases) strnncpy(newsgroups,sizeof(newsgroups),
                                aliases(newsgroups,newsgroups_len),-1, 0);
      if (!auth_check || auth_list(newsgroups)) {
        strnncat(newslist,newslist_m,newslist_l, newsgroups,-1, &newslist_l);
        strnncat(newslist,newslist_m,newslist_l, ",",1,         &newslist_l);
        }
      } while (cli$get_value(c$dsc("NEWSGROUPS"),&newsgroups_dsc,
          &newsgroups_len) & 1);
    if (newslist_l > 0) newslist[--newslist_l] = '\0';
    }
}

/*
 *  call_edit
 *
 *  Invoke an editor - return 2 if quit, 1 if exit, 0 unknown
 */

#define TPU_QUIT 0X13F2AF59
#define TPU_EXIT 0X13F2AF01

int call_edit(infile)
  char *infile;
{
  int status;
  int save_displ;

  if (news_captive) return(0);
  save_displ = leave_screen(0);
  status = invoke_editor(0,Editor,infile,infile);
  join_screen(save_displ);
  if (status == TPU_QUIT) status = 2;
  else if (status == TPU_EXIT) status = 1;
  else status = 0;
#if !MEM_DYNAMIC_QUOTA
  _c$cks(set_mem_ceiling());
#endif
  return(status);
}

/*
 *  do_posting
 *
 *  post a new news item
 */

static void kill_posting(errmsg, fpr, fpw)
  char *errmsg;
  FILE *fpr, *fpw;
{
  char xfrbuf[512];

  if (*errmsg) err_line(errmsg);
  if (fpr && fpw) {
    fputs("\n",fpw);
    while (fgets(xfrbuf,sizeof(xfrbuf),fpr)) fputs(xfrbuf,fpw);
    fclose(fpr);
    fclose(fpw);
    }
  rename(Post_file,"Sys$Scratch:Dead.Letter");
  delete_file_versions(Post_file);
  return;
}

/* set post_path to " path!username" */
static void make_post_path(char *post_path, int post_path_m)
{ int ll;
  strcpy(post_path," "); ll = 1;
  if (nntp_client) {}   /* posting node name will be added by the NNTP server */
  else {
    strnncat(post_path,post_path_m,ll, news_pathname,-1, &ll);
    strnncat(post_path,post_path_m,ll, "!",1,            &ll);
    }
  strnncat(post_path,post_path_m,ll, usr_username,-1, 0);
}

/* set mod_address to "username@nodename" */
static void make_mod_address(char *mod_address, int mod_address_m)
{ int ll;
  strnncpy(mod_address,mod_address_m,    usr_username,-1,  &ll);
  strnncat(mod_address,mod_address_m,ll, "@",1,            &ll);
  strnncat(mod_address,mod_address_m,ll, Node_address,-1,  0);
}

static int do_posting(postfile,crosspost)
  int postfile, crosspost;
{
  int status;
  char ngroup[512], post_path[512], s[512], infile[256], loc_id[IDLEN],
       xfrbuf[512], *cp1, *cp2, reply_address[512],
       distribution[512], id[512], from[512], follow_groups[512],
       xnewsgroups[512], xfollowgroups[512],
       followup_groups[512], ref_line[512], old_ref_line[512], subj_line[512],
       mod_address[512], post_address[512], control_val[512],
       *cp, *p, *c1, *cn1, *cn2, *xx, *yy, *zz, lg[512], *pa, *sa;
  int approval_required = 0,
      postrot = 0,
      add_approved = 1,
      g = 0,
      use_default = 1,
      header = 0,
      file_headers = 0;
  time_t cur_time;
  int edit_switch = 0, control_switch = 0,
      line_count = 0,
      mail_self, reply_switch,
      extract_orig,
      subj_param = 0, linesseen = 0, post_result = 1;
  struct stat sbuffer;
  struct tm *stm;
  unsigned short s_len, infile_len;
  FILE *fpr, *fpw;
  $DESCRIPTOR(s_dsc,s);
  $DESCRIPTOR(infile_dsc,infile);

  itm_approved = 0;
  *follow_groups = *followup_groups = *xnewsgroups = *xfollowgroups = *ngroup = '\0';
  *s = *ref_line = *subj_line = *old_ref_line = *id = *from = *reply_address = '\0';

  if (crosspost) {
    use_default = 1;
    mail_self = 0;
    edit_switch = reply_switch = 0;
    postfile = 0;
    }
  else {
    if (cli$present(c$dsc("ROT13")) & 1) postrot = 1;
    if (cli$present(c$dsc("HEADERS")) & 1) use_default = 0;
    mail_self = (cli$present(c$dsc("SELF")) & 1);
    reply_switch = (cli$present(c$dsc("REPLY")) & 1);
    edit_switch = (cli$present(c$dsc("EDIT")) & 1);
    }

  if (postfile) {
    if (cli$present(c$dsc("CONTROL")) & 1) {
      if (no_priv()) return(err_line("Error: Post - No privs for Control message generation"),0);
      control_switch = 1;
      if (!(cli$get_value(c$dsc("CONTROL"),&infile_dsc,&infile_len) & 1))
        get_input(&infile_dsc,c$dsc("Control: "),&infile_len);
      infile[infile_len] = '\0';
      if (!infile_len)
        return(err_line("Error: Post/Control - No control message entered"),0);
      strnncpy(control_val,sizeof(control_val), infile,infile_len, 0);
      strcpy(err_oline,"Add Approved: header to control posting [y]:");
      status = get_input(&usr_inp_dsc,c$dscl(&err_oline_d),&usr_inp_l);
      if ((status == RMS$_EOF) || (status == SMG$_EOF))
        return(err_line("Post - Cancelled"),0);
      if (!(   (status & 1)
            && (   !usr_inp_l
                || (   usr_inp_l
                    && (toupper(*usr_inp) == 'Y')))))
        add_approved = 0;
      }

    if (cli$get_value(c$dsc("INFILE"),&infile_dsc,&infile_len) == CLI$_ABSENT)
      *infile = '\0';
    else
      infile[infile_len] = '\0';

    if (cli$get_value(c$dsc("SUBJECT"),&s_dsc,&s_len) == CLI$_ABSENT)
      *s = '\0';
    else {
      subj_param = 1;
      s[s_len] = '\0';
      }

    parse_newsgroups(ngroup,sizeof(ngroup),
                     ((curr_g) ? ga[curr_g]->grp_name : ""),0,1,1);
    if (!*ngroup) {
      err_line("Error: Post - No Authorized Newsgroups specified");
      return(0);
      }
    if (!sys_local_accept(ngroup,0)) {
      err_line("Post - item not accepted by local news filter (SYS file rejection)");
      return(0);
      }
    *distribution = '\0';
    *ref_line = '\0';
    if (!(fpw = fopen(Post_file,"w","rat=cr","rfm=var"))) {
      strcpy(err_oline,"Error: Post - Cannot open edit file ");
      err_oline_cat(Post_file);
      err_line(err_oline);
      return(0);
      }
    if (*infile) {
      if ((fpr = fopen(infile,"r","mbc=16")) != 0) {
        while (fgets(xfrbuf,sizeof(xfrbuf),fpr)) fputs(xfrbuf,fpw);
        fclose(fpr);
        }
      else {
        strcpy(err_oline,"Error: Post - Cannot open post file ");
        err_oline_cat(infile);
        err_line(err_oline);
	fclose(fpw);
	delete_file_versions(Post_file);
        return(0);
        }
      }
    strnncpy(infile,sizeof(infile), Post_file,-1, 0);
    if ((fpr = profile_sigfile(ngroup)) != 0) {
      fputs("-- \n",fpw);
      while (fgets(xfrbuf,sizeof(xfrbuf),fpr)) fputs(xfrbuf,fpw);
      fclose(fpr);
      }
    fclose(fpw);
    }
  else {
    int i;
    unsigned short item_len;
    char item[128];
    $DESCRIPTOR(item_dsc,item);

    if (!curr_g) {
      err_line("Error: Followup - No item specified");
      return(0);
      }

    if (!crosspost && (cli$get_value(c$dsc("NEWSITEM"),&item_dsc,&item_len) & 1)) {
      item[item_len] = '\0';
      if (!(i = item_find(item))) return(0);
      cur_set_itm(curr_g,i);
      }

    if (curr_i <= 0) {
      err_line("Error: Followup - No item specified");
      return(0);
      }

    if (crosspost) {
      extract_orig = 1;
      *infile = '\0';
      }
    else {
      extract_orig = (cli$present(c$dsc("EXTRACT")) & 1);
      if (!(cli$get_value(c$dsc("INFILE"),&infile_dsc,&infile_len) & 1))
        *infile = '\0';
      else infile[infile_len] = '\0';
      if ((!*infile) && (!edit_switch)) {
        err_line("Error: Post - no file to post");
        return(0);
        }
      }

    if (!(fpw = fopen(Post_file,"w","rat=cr","rfm=var"))) {
      strcpy(err_oline,"Error: Post - Cannot open edit file ");
      err_oline_cat(Post_file);
      err_line(err_oline);
      return(0);
      }

    *s = *ref_line = *subj_line = *old_ref_line = *id = *from = *reply_address = '\0';
    *distribution = '\0';
    if ((fpr = do_open_item(curr_g,curr_i,"r",&fp_open)) != 0) {
      int mailflag = (ga[curr_g]->grp_flags & NEWS_M_MAILGROUP),
          skipfgets = 0;

      while (skipfgets || fgets(xfrbuf,sizeof(xfrbuf),fpr)) {
        skipfgets = 0;
        if (header) {
          if (extract_orig) {
            if (!crosspost) {
              fputs(">",fpw);
              if (*xfrbuf != '>') fputs(" ",fpw);
              }
            fputs(xfrbuf,fpw);
            }
          }
        else if (!strncmp(xfrbuf,"From:",5)) {
          strnncpy(from,sizeof(from), &xfrbuf[6],-1, 0);
          chop_str(from,'\n');
          if (reply_switch && !(*reply_address)) {
            cp = &xfrbuf[5];
            if ((sa = strchr(cp,'<')) != 0) {
              strnncpy(reply_address,sizeof(reply_address), ++sa,-1, 0);
              chop_str(reply_address,'>');
              chop_str(reply_address,'\n');
              }
            else {
              while (isspace(*cp)) cp++;
              strnncpy(reply_address,sizeof(reply_address), cp,-1, 0);
              cp = reply_address;			/* glass@mgi.com V6.0-1 */
              while (*cp && !isspace(*cp)) cp++;  /*    "			*/
              *cp = '\0';                         /*    "			*/
              chop_str(reply_address,'(');
              }
            }
          }
        else if (!strncmp(xfrbuf,"Reply-To:",9) && reply_switch) {
          cp = &xfrbuf[9];
          if ((sa = strchr(cp,'<')) != 0) {
            strnncpy(reply_address,sizeof(reply_address), ++sa,-1, 0);
            chop_str(reply_address,'>');
            chop_str(reply_address,'\n');
            }
          else {
            while (isspace(*cp)) cp++;
            strnncpy(reply_address,sizeof(reply_address), cp,-1, 0);
            cp = reply_address;			/* glass@mgi.com V6.0-1 */
            while (*cp && !isspace(*cp)) cp++;  /*    "			*/
            *cp = '\0';                         /*    "			*/
            chop_str(reply_address,'(');
            }
          }
        else if (!strncmp(xfrbuf,"Message-ID:",11)) {
          strnncpy(id,sizeof(id), &xfrbuf[12],-1, 0);
          chop_str(id,'\n');
          }
        else if (!strncmp(xfrbuf,"Message-Id:",11)) {
          strnncpy(id,sizeof(id), &xfrbuf[12],-1, 0);
          chop_str(id,'\n');
          }
        else if (!strncmp(xfrbuf,"References:",11)) {
          strnncpy(old_ref_line,sizeof(old_ref_line), &xfrbuf[12],-1, 0);
          chop_str(old_ref_line,'\n');
          }
        else if (!strncmp(xfrbuf,"Subject:",8)) {
          strcpy(subj_line,"Subject: ");
          if (   !crosspost
              && strncmp(&xfrbuf[9],"Re: ",4)
              && strncmp(&xfrbuf[9],"RE: ",4)
              && strncmp(&xfrbuf[9],"re: ",4))
            strnncat(subj_line,sizeof(subj_line),-1, "Re: ",4, 0);
          strnncat(subj_line,sizeof(subj_line),-1, &xfrbuf[9],-1, 0);
          strnncpy(s,sizeof(s), &subj_line[9],-1, 0);
          chop_str(s,'\n');
          }
        else if (!strncmp(xfrbuf,"Subj:",5) && !*subj_line) {
          strcpy(subj_line,"Subject: ");
          if (   !crosspost
              && strncmp(&xfrbuf[6],"Re: ",4)
              && strncmp(&xfrbuf[6],"RE: ",4)
              && strncmp(&xfrbuf[6],"re: ",4))
            strnncat(subj_line,sizeof(subj_line),-1, "Re: ",4, 0);
          strnncat(subj_line,sizeof(subj_line),-1, &xfrbuf[6],-1, 0);
          strnncpy(s,sizeof(s), &subj_line[9],-1, 0);
          chop_str(s,'\n');
          }
        else if (!strncmp(xfrbuf,"Newsgroups:",11)) {
          strnncpy(xnewsgroups,sizeof(xnewsgroups), &xfrbuf[12],-1, 0);
          if (!*follow_groups) {
            strnncpy(follow_groups,sizeof(follow_groups), &xfrbuf[12],-1, 0);
            chop_str(follow_groups,'\n');
            lower_case(follow_groups);
            }
          }
        else if (!strncmp(xfrbuf,"Followup-To:",12)) {
          strnncpy(follow_groups,sizeof(follow_groups), &xfrbuf[13],-1, 0);
          strnncpy(xfollowgroups,sizeof(xfollowgroups), follow_groups,-1, 0);
          chop_str(follow_groups,'\n');
          lower_case(follow_groups);
          strnncpy(followup_groups,sizeof(followup_groups), follow_groups,-1,0);
          if (!crosspost && !strcmp(follow_groups,"poster")) {
            parse_newsgroups(ngroup,sizeof(ngroup), follow_groups,1,1,1);
	    if ( !strcmp(ngroup,"poster") ) {
              fclose(fpr);
           /* if (*fp_open > 1) delete_file_versions(fp_open); */
              fp_open = 0;
              fclose(fpw);
              delete_file_versions("SYS$SCRATCH:lastpost.letter");
              rename(Post_file,"SYS$SCRATCH:lastpost.letter");
              delete_file_versions(Post_file);
              write_err_line("Followup-To: poster    - Followup will be mailed to sender");
              return(do_mail(0,0),0);
              }
            }
          }
        else if (!strncmp(xfrbuf,"Distribution:",13)) {
          if (crosspost) fputs(xfrbuf,fpw);
          strnncpy(distribution,sizeof(distribution), &xfrbuf[14],-1, 0);
          chop_str(distribution,'\n');
          }
        else if (*xfrbuf == '\n') {
          header = 1;
          if (mailflag && fgets(xfrbuf,512,fpr)) {
            skipfgets = 1;
            cp = xfrbuf;
            while (*cp != ':' && isprint(*cp)) cp++;
            if ((*cp == ':') && (isspace(*(cp+1)))) header = 0;
            }
          if (crosspost && header) fputs("\n",fpw);
          if (header && !crosspost && extract_orig) {
            fputs("In article ",fpw);
            if (!*id) sprintf(id,"<%.48s %.200s:%d>",
                              news_node, ga[curr_g]->grp_name,
                              ga[curr_g]->grp_ia[curr_i].itm_num);
            fputs(id,fpw);
            fprintf(fpw,", %s writes:\n",from);
            }
          }
        else if (crosspost && !strncmp(xfrbuf,"Lines:",6)) {
          fputs(xfrbuf,fpw);
          linesseen = 1;
          }
        else if (crosspost && strncmp(xfrbuf,"Path:",5) && strncmp(xfrbuf,"CC:",3)) {
          if (!strchr(xfrbuf,':')) fputs(xfrbuf,fpw);
          else {
            ++file_headers;
            if (strncmp(xfrbuf,"X-",2)) fputs("X-",fpw);
            else fputs("X",fpw);
            fputs(xfrbuf,fpw);
            }
          }
        }
      fclose(fpr);
   /* if (*fp_open > 1) delete_file_versions(fp_open); */
      fp_open = 0;
      }
    if (*infile) {
      if ((fpr = fopen(infile,"r","mbc=16")) != 0) {
        while (fgets(xfrbuf,sizeof(xfrbuf),fpr)) fputs(xfrbuf,fpw);
        fclose(fpr);
        }
      else {
        strcpy(err_oline,"Error: Post - Cannot open post file ");
        err_oline_cat(infile);
        err_line(err_oline);
        delete_file_versions(Post_file);
        return(0);
        }
      }
    *infile = '\0';
    if (crosspost) parse_newsgroups(ngroup,sizeof(ngroup), "",0,1,1);
    else {
      if ( !(*ngroup) )
	parse_newsgroups(ngroup,sizeof(ngroup), follow_groups,0,1,1);
      if ((fpr = profile_sigfile(ngroup)) != 0) {
        fputs("-- \n",fpw);
        while (fgets(xfrbuf,sizeof(xfrbuf),fpr)) fputs(xfrbuf,fpw);
        fclose(fpr);
        }
      }
    fclose(fpw);

    if (!*ngroup) {
      rename(Post_file,"SYS$SCRATCH:dead.letter");
      delete_file_versions(Post_file);
      err_line("Error: Post - No Authorized Newsgroups specified");
      return(0);
      }
    if (!sys_local_accept(ngroup,0)) {
      err_line("Post - item not accepted by local news filter (SYS file rejection)");
      }

    if (*old_ref_line || *id) {
      int ll;
      strnncpy(ref_line,sizeof(ref_line), "References: ",-1, &ll);
      if (*old_ref_line) {
        strnncat(ref_line,sizeof(ref_line),ll, old_ref_line,-1, &ll);
        strnncat(ref_line,sizeof(ref_line),ll, " ",1, &ll);
        }
      strnncat(ref_line,sizeof(ref_line),ll, id,-1,  &ll);
      strnncat(ref_line,sizeof(ref_line),ll, "\n",1, &ll);
      }
    }
  status = 0;
  if (!*infile) strnncpy(infile,sizeof(infile), Post_file,-1, 0);
  if (edit_switch || (!*infile)) {
    edit_switch = 1;
    if ((status = call_edit(infile)) == 2) {
      delete_file_versions(Post_file);
      return(0);
      }
    }

  if (stat(infile,&sbuffer)) {
    err_line("Error: Post - Item text file not found");
    return(0);
    }

  if (!sbuffer.st_size) {
    err_line("Error: Post - Item text file is empty");
    if (!strcmp(infile,Post_file)) delete_file_versions(Post_file);
    return(0);
    }

  line_count = 0;
  if ((fpr = fopen(infile,"r","mbc=16")) != 0) {
    char *a;
    char headlines = crosspost;

    if (postrot) postrot = (fpw = fopen(Post_file,"w","mbc=16")) != 0;
    if (postrot) strnncpy(infile,sizeof(infile), Post_file,-1, 0);
    while (fgets(xfrbuf,sizeof(xfrbuf)-2,fpr)) {
      if (headlines) {
        if (!strcmp(xfrbuf,"\n")) headlines = 0;
        if (postrot) fputs(xfrbuf,fpw);
        }
      else {
        if (postrot) {
          for (a=xfrbuf; *a; a++) {
            if ((*a >= 'A') && (*a <= 'Z')) *a = ((*a - 'A' + 13) % 26) + 'A';
            if ((*a >= 'a') && (*a <= 'z')) *a = ((*a - 'a' + 13) % 26) + 'a';
            }
          fputs(xfrbuf,fpw);
          }
        ++line_count;
        }
      }
    fclose(fpr);
    if (postrot) fclose(fpw);
    }

  if (!line_count && !crosspost) {
    err_line("Error: Post - Item text file is empty");
    delete_file_versions(Post_file);
    return(0);
    }
  time(&cur_time);
  p = ctime(&cur_time);
  p += 4;
  stm = localtime(&cur_time);
  strnncpy(loc_id,sizeof(loc_id), gen_id(),-1, 0);
  mail_add_expiry = 0;

  if (!(fpr = fopen(infile,"r","mbc=16"))) {
    strcpy(err_oline,"Error: Unable to open input file ");
    err_oline_cat(infile);
    kill_posting(err_oline,0,0);
    return(0);
    }
  if (!(fpw = fopen(Post_file,"w","mbc=16"))) {
    strcpy(err_oline,"Error: Unable to open temp file ");
    err_oline_cat(Post_file);
    kill_posting(err_oline,fpr,0);
    return(0);
    }

  if (!subj_param && !crosspost) {
    status = get_input_dflt(&s_dsc,c$dsc("Subject: "),&s_len,*s ? c$dsc(s):0,0);
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    s[s_len] = '\0';
    }
  if (!*s) strcpy(s,"<None>");
  strcpy(subj_line,"Subject: ");
  strnncat(subj_line,sizeof(subj_line),-1, s,-1, 0);

    /* Re-order the newsgroup list 1) local groups, 2) known net
       groups 3) unknown groups */

  c$free_tmp();
  xx = (char *) news_malloc(strlen(ngroup) + 1);
  yy = (char *) news_malloc(strlen(ngroup) + 1);
  zz = (char *) news_malloc(strlen(ngroup) + 1);
  *xx = *yy = *zz = '\0';
  for (cp1=ngroup; cp1 && *cp1; cp1=cp2) {
    cp2 = chop_str(cp1,',');
    util_cvrt(lg,cp1);
    if ((g = ga_exact_name(lg)) != 0) {
      if (ga[g]->grp_flags & NEWS_M_LOCAL) {
        if (*xx) strcat(xx,",");
        strcat(xx,cp1);
        }
      else {
        if (*yy) strcat(yy,",");
        strcat(yy,cp1);
	}
      }
    else {
      if (*zz) strcat(zz,",");
      strcat(zz,cp1);
      }
    if (cp2) *cp2++ = ',';
    }
  { int ll;
    strnncpy(ngroup,sizeof(ngroup), xx,-1, &ll);
    if (*yy) {
      if (*ngroup) strnncat(ngroup,sizeof(ngroup),ll, ",",1, &ll);
      strnncat(ngroup,sizeof(ngroup),ll, yy,-1, &ll);
      }
    if (*zz) {
      if (*ngroup) strnncat(ngroup,sizeof(ngroup),ll, ",",1, &ll);
      strnncat(ngroup,sizeof(ngroup),ll, zz,-1, &ll);
      }
  }
  news_free(xx);
  news_free(yy);
  news_free(zz);

  lower_case(distribution);
  lower_case(followup_groups);
  get_post_defaults(ngroup,distribution,followup_groups);

  make_post_path(post_path, sizeof(post_path));
  fprintf(fpw,"Path:%s\n",post_path);
  fprintf(fpw,"From: %s",mail_sig);
  if (*usr_persname) fprintf(fpw," (%s)",usr_persname);
  fprintf(fpw,"\n");
  fprintf(fpw,"Newsgroups: %s\n",ngroup);
  if (control_switch) {
    fprintf(fpw,"Control: %s\n",control_val);
    if (add_approved) fprintf(fpw,"Approved: %s\n",mail_sig);
    }
  else add_approved = 0;
  fprintf(fpw,"%s\n",subj_line);
  fprintf(fpw,"Message-ID: %s\n",loc_id);
  fprintf(fpw,"Date: %d %.3s %04d %02d:%02d:%02d %s\n",
          stm->tm_mday, p, stm->tm_year + 1900,
          stm->tm_hour, stm->tm_min, stm->tm_sec, news_timezone);
  if (*ref_line && strcmp(ref_line,"References: \n")) fputs(ref_line,fpw);
  if (crosspost) {
    fprintf(fpw,"X-From: %s\n",from);
    if (*xnewsgroups) fprintf(fpw,"X-Newsgroups: %s",xnewsgroups);
    fprintf(fpw,"Followup-To: ");
    if (*followup_groups) fprintf(fpw,"%s",followup_groups);
    else fprintf(fpw,"%s",ngroup);
    if (*xfollowgroups) fprintf(fpw,",%s",xfollowgroups);
    else if (*xnewsgroups) fprintf(fpw,",%s",xnewsgroups);
    else fprintf(fpw,"\n");
    }

  if (!use_default) {
    err_line("Summary of posting [no Summary]");
    status = get_input(&usr_inp_dsc,c$dsc("Summary: "),&usr_inp_l);
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    if ((status & 1) && (usr_inp_l)) {
      usr_inp[usr_inp_l] = '\0';
      fprintf(fpw,"Summary: %s\n",usr_inp);
      }

    err_line("Mail address for replies [reply to self]");
    status = get_input_dflt(&usr_inp_dsc,c$dsc("Reply-To:"),&usr_inp_l,c$dsc(profile_reply_to),0);
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    if ((status & 1) && (usr_inp_l)) {
      usr_inp[usr_inp_l] = '\0';
      fprintf(fpw,"Reply-To: %s\n",usr_inp);
      }

    if (*followup_groups) {
      strcpy(err_oline,"Followup newsgroups (or \"poster\")");
      err_line(err_oline);
      status = get_input_dflt(&usr_inp_dsc,c$dsc("Followup-To: "),&usr_inp_l,c$dsc(followup_groups),0);
      }
    else {
      sprintf(err_oline,"Followup newsgroups (or \"poster\") [%.200s]",ngroup);
      err_line(err_oline);
      status = get_input(&usr_inp_dsc,c$dsc("Followup-To: "),&usr_inp_l);
      }
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    if ((status & 1) && (usr_inp_l)) {
      usr_inp[usr_inp_l] = '\0';
      fprintf(fpw,"Followup-To: %s\n",usr_inp);
      }

    err_line("Keyword list [no keywords]");
    status = get_input(&usr_inp_dsc,c$dsc("Keywords: "),&usr_inp_l);
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    if ((status & 1) && (usr_inp_l)) {
      usr_inp[usr_inp_l] = '\0';
      fprintf(fpw,"Keywords: %s\n",usr_inp);
      }

    err_line("Expiry Date [use local defaults] (VMS Date format)");
    status = get_input(&usr_inp_dsc,c$dsc("Expires: "),&usr_inp_l);
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    if ((status & 1) && (usr_inp_l)) {
      time_t etime;

      usr_inp[usr_inp_l] = '\0';
      if ((etime = cvt_date_val(usr_inp)) && (etime > cur_time)) {
        p = ctime(&etime);
        p += 4;
        stm = localtime(&etime);
        fprintf(fpw,"Expires: %d %.3s %04d %02d:%02d:%02d %s\n",
                stm->tm_mday, p, stm->tm_year + 1900,
                stm->tm_hour, stm->tm_min, stm->tm_sec, news_timezone);
        mail_add_expiry = ((etime - cur_time) / DAY_SECS) + 1;
        if (mail_add_expiry < MIN_DAYS) mail_add_expiry = MIN_DAYS;
        if (mail_add_expiry > MAX_DAYS) mail_add_expiry = MAX_DAYS;
        }
      }

    if (*distribution) {
      err_line("Distribution of item");
      status = get_input_dflt(&usr_inp_dsc,c$dsc("Distribution: "),&usr_inp_l,c$dsc(distribution),0);
      }
    else {
      err_line("Distribution of item");
      status = get_input_dflt(&usr_inp_dsc,c$dsc("Distribution: "),&usr_inp_l,c$dsc("world"),0);
      }
    while ((status & 1) && (usr_inp_l)) {
      usr_inp[usr_inp_l] = '\0';
      strip_compress_lower(usr_inp);
      blank_strip(usr_inp);
      strnncpy(distribution,sizeof(distribution), usr_inp,-1, 0);
      if (!*distribution || check_distribution_string(distribution)) break;
      err_line("Distribution of item - no valid distribution keyword specified");
/*###
      status = get_input_andshowfile(DISTRIBUTION_FILE,&usr_inp_dsc,c$dsc("Distribution: "),&usr_inp_l,c$dsc(distribution),0);
*/
      status = get_input_dflt(&usr_inp_dsc,c$dsc("Distribution: "),&usr_inp_l,c$dsc(distribution),0);
      }
    if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
      kill_posting("Post - Cancelled",fpr,fpw);
      return(0);
      }
    if (*distribution) fprintf(fpw,"Distribution: %s\n",usr_inp);
    }
  else {
    if (*followup_groups) fprintf(fpw,"Followup-To: %s\n",followup_groups);
    if (*profile_reply_to) fprintf(fpw,"Reply-To: %s\n",profile_reply_to);
    if (*distribution) {
      do {
        strip_compress_lower(distribution);
        blank_strip(distribution);
        if (!*distribution || check_distribution_string(distribution)) break;
        err_line("Distribution of item - no valid distribution keyword specified");
        status = get_input_dflt(&usr_inp_dsc,c$dsc("Distribution: "),&usr_inp_l,c$dsc(distribution),0);
        usr_inp[usr_inp_l] = '\0';
        strnncpy(distribution,sizeof(distribution), usr_inp,usr_inp_l, 0);
        } while ((status & 1) && (usr_inp_l));
      if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
        kill_posting("Post - Cancelled",fpr,fpw);
        return(0);
        }
      if (*distribution) fprintf(fpw,"Distribution: %s\n",distribution);
      }
    }

  if (!crosspost) {
    if (*profile_organization)
      fprintf(fpw,"Organization: %s\n",profile_organization);
    else if (*Organisation_name)
      fprintf(fpw,"Organization: %s\n",Organisation_name);
    }

  clear_err_line();
  if (!sys_local_accept(ngroup,distribution)) {
    err_line("Post - Distribution of item not accepted by local news filter");
    }
  sprintf(err_oline,"Post to %.200s [y]:",ngroup);
  status = get_input(&usr_inp_dsc,c$dscl(&err_oline_d),&usr_inp_l);
  if ((status == RMS$_EOF) || (status == SMG$_EOF)) {
    kill_posting("Post - Cancelled",fpr,fpw);
    return(0);
    }
  if (!((status & 1) && ((!usr_inp_l) || ((usr_inp_l) && (toupper(*usr_inp) == 'Y'))))) {
    kill_posting("Post - Cancelled",fpr,fpw);
    return(0);
    }

    /* check if this posting is by the moderator of a newsgroup,
       and if so, whether there is further moderation required,
       or if the posting can happen now */

  make_mod_address(mod_address, sizeof(mod_address));
  *post_address = '\0';
  for (cp1=ngroup; cp1 && *cp1; cp1=cp2) {
    cp2 = chop_str(cp1,',');
    util_cvrt(lg,cp1);
    if (cp2) *cp2++ = ',';
    if ((g = ga_exact_name(lg)) != 0 && (ga[g]->grp_flags & NEWS_M_MAILLIST)) {
      char infile_name[257],
	   *pa;

      if (fgetname(fpr,infile_name)) {
	fclose(fpr);
        if ((pa = moderator_address(ga[g]->grp_name)) != 0) {
          sprintf(err_oline,"Post to %.200s List-Server (%.200s)",
                  ga[g]->grp_name,pa);
          call_mail(infile_name,&subj_line[9],add_transform(pa),err_oline);
	  fpr = fopen(infile_name,"r");
          }
        else if (!nntp_client) {
          strcpy(err_oline,"No maillist server address for group ");
          err_oline_cat(ga[g]->grp_name);
          err_line(err_oline);
          }
	}
      }
    else if (g && (ga[g]->grp_flags & NEWS_M_MAILMODERATE)) {
      if ((pa = moderator_address(ga[g]->grp_name)) != 0) {
        if (strcmp(mod_address,pa)) {
          strnncpy(post_address,sizeof(post_address), pa,-1, 0);
          break;
          }
        else approval_required = 1;
        }
      }
    }
  c$free_tmp();

  if (approval_required && !add_approved) 
    fprintf(fpw,"Approved: %s\n",mod_address);

  if (*post_address)
    fprintf(fpw,"News-Moderator: Approval required for posting to %s\n",
            ga[g]->grp_name);
  if (!linesseen) {
    fprintf(fpw,"Lines: %d\n",line_count);
    }
  if ((!crosspost) || (crosspost && !file_headers)) fprintf(fpw,"\n");
  while (fgets(xfrbuf,sizeof(xfrbuf)-2,fpr)) fputs(xfrbuf,fpw);
  fclose(fpr);
  fclose(fpw);

  c$free_tmp();
  log_to_usage_file(-2,g);
  if (*post_address) {
    sprintf(err_oline,"Post to %.200s Moderator (%.200s)",
            ga[g]->grp_name,post_address);
    call_mail(Post_file,&subj_line[9],add_transform(post_address),err_oline);
    }
  else if (nntp_client) post_result = post_to_server(nntp_node,nntp_proto,Post_file);
#if !NNTP_CLIENT_ONLY
  else {
    forward_posting = 1;
    net_news = 0;
    auto_cre_grp = 1;
    c$free_tmp();
    if (!sys_local_accept(ngroup,distribution))
      err_line("Post - item NOT locally posted (filter rejection) - forwarded");
    else {
      unsigned int cre_grp[20];
      do_new_group(ngroup,1,cre_grp);
      c$free_tmp();
      if (!*cre_grp)
        err_line("Post - Item NOT locally posted (filter rejection) - forwarded");
      else {
        c$free_tmp();
        status = do_new_item(cre_grp,loc_id,s,mail_sig,
                             Post_file,1,0,line_count,0);
        if (status != 0) {
          if (forward_posting) {
            sprintf(err_oline,"Error: Post - (%.200s) %.200s (%X)",ngroup,
		    no_new_item,status);
            err_line(err_oline);
            }
          else err_line("Post - item has been mailed to Moderator");
          }
        }
      }

        /* check to see what else should be done with this posting */
    if (forward_posting) {
      sys_remote_send(post_path,ngroup,distribution,Post_file,loc_id,0);
      flush_downstream(0);
      }
    }

    /* now look up news_manager:newspost.cc and then news_post_cc for more
       addresses to mail to */
  c$free_tmp();
  sysprv();
  if ((fpr = fopen("news_manager:news_post.cc","r")) != 0) {
    while ((xx = fgetl(fpr)) != 0) {
      chop_str(xx,'#');
      chop_str(xx,'\n');
      strip_compress(xx);
      if ((c1 = strchr(xx,' ')) != 0) {
        while (*c1 == ' ') *c1++ = '\0';
        lower_case(xx);
        for (cn1=ngroup; cn1; cn1=cn2) {
          cn2 = chop_str(cn1,',');
          if (wild_match(cn1,xx))
            call_mail(Post_file,s,add_transform(c1),"CC: - Mailing copies");
          if (cn2) *cn2++ = ',';
          }
        }
      }
    fclose(fpr);
    }
  nosysprv();
  c$free_tmp();
#endif

  if ((fpr = fopen("news_post_cc","r")) != 0
   || (fpr = fopen("sys$login:news_post.cc","r")) != 0) {
    while ((xx = fgetl(fpr)) != 0) {
      chop_str(xx,'#');
      chop_str(xx,'\n');
      strip_compress(xx);
      if ((c1 = strchr(xx,' ')) != 0) {
        while (*c1 == ' ') *c1++ = '\0';
        lower_case(xx);
        for (cn1=ngroup; cn1; cn1=cn2) {
          cn2 = chop_str(cn1,',');
          if (wild_match(cn1,xx))
            call_mail(Post_file,s,add_transform(c1),"CC: - Mailing copies");
          if (cn2) *cn2++ = ',';
          }
        }
      }
    fclose(fpr);
    }
  if (post_result) {
    if (reply_switch) {
      char ngroup[512], *comma_pointer, *address_field, xfrbuf[512];
      int xfrbuf_l;
      unsigned short ngroup_len;
      $DESCRIPTOR(ngroup_dsc,ngroup);

      *xfrbuf = '\0'; xfrbuf_l = 0;
      status = get_input_dflt(&ngroup_dsc,c$dsc("To: "),&ngroup_len,c$dsc(reply_address),0);
      if (!((status == RMS$_EOF) || (status == SMG$_EOF))) {
        ngroup[ngroup_len] = '\0';
        for (address_field=ngroup; address_field; address_field=comma_pointer) {
          comma_pointer = chop_str_plus(address_field,',');
          strnncat(xfrbuf,sizeof(xfrbuf),xfrbuf_l,
                   add_transform(address_field),-1,       &xfrbuf_l);
          strnncat(xfrbuf,sizeof(xfrbuf),xfrbuf_l, ",",1, &xfrbuf_l);
          };
        if (xfrbuf_l > 0) {
          /* if user hasn't explicitly requested cc to self, use mail profile
             setting for replies.  */
          if (!mail_self) set_mail_self_flag(0);
          call_mail(Post_file,s,xfrbuf,"Invoking mailer - reply to poster");
          mail_self_flag = 0;  /* reset flag in case we just set it */
          }
        }
      if (mail_self) call_mail(Post_file,s,usr_username,"CC: self - mailing");
      }
    delete_file_versions("SYS$SCRATCH:lastpost.letter");
    rename(Post_file,"SYS$SCRATCH:lastpost.letter");
    delete_file_versions(Post_file);
    }
  else rename(Post_file,"SYS$SCRATCH:dead.letter");
  return(0);
}

/*
 *  do_post
 *
 *  Post a new item into NEWS
 */

static int dpst()
{
  return(do_posting(1,0));
}

int do_post()
{
  if (!news_readonly) return(unwind_display(OUTER_LOOP,dpst));
  return(0);
}

/*
 *  do_followup
 *
 *  Post a followup item to NEWS
 */

static int dflwp()
{
  return(do_posting(0,0));
}

int do_followup()
{
  if (!news_readonly) return(unwind_display(I_DISPLAY_LOOP,dflwp));
  return(0);
}

static int dxpst()
{
  return(do_posting(0,1));
}

int do_xpost()
{
  if (!news_readonly) return(unwind_display(I_DISPLAY_LOOP,dxpst));
  return(0);
}

static int drepost()
{
  int status;
  char inpline[512], mail_from[256], repost_file[256], *p, *cp1, *cp2, *pa,
       summary[512], replyto[512], followupto[512], keywords[512],
       expires[512], distribution[512], ngroup[256], post_dist[256],
       mod_address[256], post_address[256], lg[132], subj_line[256], loc_id[132],
       post_path[132], *xx, *c1, *cn1, *cn2, mail_id[256], id[256], mail_dist[256];
  time_t cur_time;
  int line_count = 0, g = 0;
  struct stat sbuffer;
  struct tm *stm;
  FILE *fpw, *fpr;

                            /* check if - local posting and user is newsmgr or
                               local posting by this user or is the moderator
                               of the newsgroup. Get the From: field for the
                               check */
  if (!(fp = do_open_item(curr_g,curr_i,"r",&fp_open))) {
    err_line("Error: Repost - Cannot access item text");
    return(0);
    }

  *mail_dist = *ngroup = *mail_id = *subj_line = *mail_from = '\0';
  *summary = *replyto = *followupto = *keywords = *expires = *distribution = '\0';
  while (fgets(inpline,256,fp)) {
    if (*inpline == '\n') break;
    if (!strncmp(inpline,"From:",5)) sscanf(inpline,"From: %s",mail_from);
    else if (!strncmp(inpline,"Newsgroups:",11)) sscanf(inpline,"Newsgroups: %s",ngroup);
    else if (!strncmp(inpline,"Subject:",8))
      strnncpy(subj_line,sizeof(subj_line), inpline,-1, 0);
    else if (!strncmp(inpline,"Message-ID:",11))
      strnncpy(mail_id,sizeof(mail_id), inpline,-1, 0);
    else if (!strncmp(inpline,"Distribution:",13))
      strnncpy(mail_dist,sizeof(mail_dist), inpline,-1, 0);
    }
  chop_str(ngroup,'\n');
  chop_str(subj_line,'\n');
  chop_str(mail_id,'\n');
  chop_str(mail_dist,'\n');

  if (!*mail_from) {
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    err_line("Error: Repost - Cannot locate item sender address");
    return(0);
    }

  chop_str(mail_from,'\n');
  lower_case(mail_from);
  sprintf(inpline,"*%.200s@%.200s*",usr_username,Node_address);
  lower_case(inpline);
  if (!wild_match(mail_from,inpline)) {
    sprintf(inpline,"*%.500s*",mail_sig);
    lower_case(inpline);
    if (!wild_match(mail_from,inpline)) {
      fclose(fp);
   /* if (*fp_open > 1) delete_file_versions(fp_open); */
      fp_open = 0;
      strcpy(err_oline,"Error: Cannot Repost this item: sender ");
      err_oline_cat(mail_from);
      err_line(err_oline);
      return(0);
      }
    }

  sprintf(repost_file,"SYS$SCRATCH:NEWS_REPOST_%X.TMP",getpid());
  if (!(fpw = fopen(repost_file,"w"))) {
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    strcpy(err_oline,"Error: Repost  - cannot open temp file ");
    err_oline_cat(repost_file);
    err_line(err_oline);
    return(0);
    }

  while (fgets(inpline,256,fp)) fputs(inpline,fpw);
  fclose(fpw);

  if ((status = call_edit(repost_file)) == 2) {
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    err_line("Repost - Abort from edit session");
    delete_file_versions(repost_file);
    return(0);
    }

  if (stat(repost_file,&sbuffer)) {
    err_line("Error: Post - Item text file not found");
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    return(0);
    }

  if ((fpr = fopen(repost_file,"r")) != 0) {
    while (fgets(inpline,sizeof(inpline),fpr)) ++line_count;
    }

  if (!sbuffer.st_size || !fpr || !line_count) {
    if (fpr) fclose(fpr);
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    err_line("Error: Repost - Item text file is empty");
    delete_file_versions(repost_file);
    return(0);
    }

  fseek(fpr,0,0);
  fseek(fp,0,0);
  if (!(fpw = fopen(repost_file,"w"))) {
    strcpy(err_oline,"Error: Repost  - cannot open temp file ");
    err_oline_cat(repost_file);
    err_line(err_oline);
    fclose(fpr);
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    return(0);
    }

  time(&cur_time);
  p = ctime(&cur_time);
  p += 4;
  stm = localtime(&cur_time);
  strnncpy(loc_id,sizeof(loc_id), gen_id(),-1, 0);
  while (fgets(inpline,sizeof(inpline),fp)) {
    if (*inpline == '\n') break;
    if (!strncmp(inpline,"Message-ID:",11))
      fprintf(fpw,"Message-ID: %s\n",loc_id);
    else if (!strncmp(inpline,"Date:",5))
      fprintf(fpw,"Date: %d %.3s %04d %02d:%02d:%02d %s\n",
              stm->tm_mday, p, stm->tm_year + 1900,
              stm->tm_hour, stm->tm_min, stm->tm_sec, news_timezone);
    else if (!strncmp(inpline,"Lines:",6)) fprintf(fpw,"Lines: %d\n",line_count);
    else if (!strncmp(inpline,"Summary:",8))
      strnncpy(summary,sizeof(summary), &inpline[9],-1, 0);
    else if (!strncmp(inpline,"Reply-To:",9))
      strnncpy(replyto,sizeof(replyto), &inpline[10],-1, 0);
    else if (!strncmp(inpline,"Followup-To:",12))
      strnncpy(followupto,sizeof(followupto), &inpline[13],-1, 0);
    else if (!strncmp(inpline,"Keywords:",9))
      strnncpy(keywords,sizeof(keywords), &inpline[10],-1, 0);
    else if (!strncmp(inpline,"Expires:",8))
      strnncpy(expires,sizeof(expires), &inpline[9],-1, 0);
    else if (!strncmp(inpline,"Distribution:",13))
      strnncpy(distribution,sizeof(distribution), &inpline[14],-1, 0);
    else if (strncmp(inpline,"Xref:",5)) fputs(inpline,fpw);
    }
  fseek(fp,0,0);
  chop_str(summary,'\n');
  chop_str(replyto,'\n');
  chop_str(followupto,'\n');
  chop_str(keywords,'\n');
  chop_str(expires,'\n');
  chop_str(distribution,'\n');

#define closeoff(x)	{		\
			fclose(fpr);	\
			fclose(fpw);	\
			fclose(fp);	\
			/* if (*fp_open>1) delete_file_versions(fp_open); */ \
			fp_open = 0;	\
			delete_file_versions(repost_file);	\
			err_line("Repost cancelled by ^Z");	\
			return(x);	\
			}

  err_line("Summary of posting");
  if ((status = get_input_dflt(&usr_inp_dsc,c$dsc("Summary: "),&usr_inp_l,
			       c$dsc(summary),0)) == RMS$_EOF) closeoff(0);
  if ((status & 1) && (usr_inp_l)) {
    usr_inp[usr_inp_l] = '\0';
    fprintf(fpw,"Summary: %s\n",usr_inp);
    }

  err_line("Mail address for replies");
  if ((status = get_input_dflt(&usr_inp_dsc,c$dsc("Reply-To: "),&usr_inp_l,
			       c$dsc(replyto),0)) == RMS$_EOF) closeoff(0);
  if ((status & 1) && (usr_inp_l)) {
    usr_inp[usr_inp_l] = '\0';
    fprintf(fpw,"Reply-To: %s\n",usr_inp);
    }

  err_line("Followup newsgroups");
  if ((status = get_input_dflt(&usr_inp_dsc,c$dsc("Followup-To: "),&usr_inp_l,
			       c$dsc(followupto),0)) == RMS$_EOF) closeoff(0);
  if ((status & 1) && (usr_inp_l)) {
    usr_inp[usr_inp_l] = '\0';
    fprintf(fpw,"Followup-To: %s\n",usr_inp);
    }

  err_line("Keyword list");
  status = get_input_dflt(&usr_inp_dsc,c$dsc("Keywords: "),
			  &usr_inp_l, c$dsc(keywords),0);
  if (status == RMS$_EOF) closeoff(0);
  if ((status & 1) && (usr_inp_l)) {
    usr_inp[usr_inp_l] = '\0';
    fprintf(fpw,"Keywords: %s\n",usr_inp);
    }

  time (&cur_time);
  err_line("Expiry Date");
  status = get_input_dflt(&usr_inp_dsc,c$dsc("Expires: "),
			  &usr_inp_l,c$dsc(expires),0);
  if (status == RMS$_EOF) closeoff(0);
  if ((status & 1) && (usr_inp_l)) {
    time_t etime;
    usr_inp[usr_inp_l] = '\0';

    if (((etime = cvt_date_val(usr_inp)) || (etime = parse_usenet_date(usr_inp)))
     && (etime > cur_time)) {
      p = ctime(&etime);
      p += 4;
      stm = localtime(&etime);
      fprintf(fpw,"Expires: %d %.3s %04d %02d:%02d:%02d %s\n",
              stm->tm_mday, p, stm->tm_year + 1900,
              stm->tm_hour, stm->tm_min, stm->tm_sec, news_timezone);
      mail_add_expiry = ((etime - cur_time) / DAY_SECS) + 1;
      if (mail_add_expiry < MIN_DAYS) mail_add_expiry = MIN_DAYS;
      if (mail_add_expiry > MAX_DAYS) mail_add_expiry = MAX_DAYS;
      }
    }

  strnncpy(post_dist,sizeof(post_dist), distribution,-1, 0);
  err_line("Distribution of item");
  if ((status = get_input_dflt(&usr_inp_dsc,c$dsc("Distribution: "),&usr_inp_l,
			       c$dsc(distribution),0)) == RMS$_EOF) closeoff(0);
  if ((status & 1) && (usr_inp_l)) {
    usr_inp[usr_inp_l] = '\0';
    lower_case(usr_inp);
    strnncpy(post_dist,sizeof(post_dist), usr_inp,usr_inp_l, 0);
    fprintf(fpw,"Distribution: %s\n",usr_inp);
    }
#undef closeoff

  clear_err_line();
  sprintf(err_oline,"Repost to %.200s [y]:",ngroup);
  status = get_input(&usr_inp_dsc,c$dscl(&err_oline_d),&usr_inp_l);
  if (!((status & 1) && ((!usr_inp_l) || ((usr_inp_l) && (toupper(*usr_inp) == 'Y'))))) {
    err_line("Post - Cancelled");
    fclose(fpr);
    fclose(fpw);
    fclose(fp);
 /* if (*fp_open > 1) delete_file_versions(fp_open); */
    fp_open = 0;
    delete_file_versions(repost_file);
    return(0);
    }

    /* check if this posting is by the moderator of a newsgroup,
       and if so, whether there is further moderation required,
       or if the posting can happen now */

  make_post_path(post_path, sizeof(post_path));
  make_mod_address(mod_address, sizeof(mod_address));
  *post_address = '\0';
  for (cp1=ngroup; cp1 && *cp1; cp1=cp2) {
    cp2 = chop_str(cp1,',');
    util_cvrt(lg,cp1);
    if (cp2) *cp2++ = ',';
    if ((g = ga_exact_name(lg)) != 0 && (ga[g]->grp_flags & NEWS_M_MAILLIST)) {
      char infile_name[257],
	   *pa;

      if (fgetname(fpr,infile_name)) {
	fclose(fpr);
        pa = moderator_address(ga[g]->grp_name);
        sprintf(err_oline,"Post to %.200s List-Server (%.200s)",ga[g]->grp_name,pa);
        call_mail(infile_name,&subj_line[9],add_transform(pa),err_oline);
	fpr = fopen(infile_name,"r");
	}
      }
    else if (g && (ga[g]->grp_flags & NEWS_M_MAILMODERATE)) {
      if (strcmp(mod_address,(pa = moderator_address(ga[g]->grp_name)))) {
        strnncpy(post_address,sizeof(post_address), pa,-1, 0);
        break;
        }
      }
    }
  c$free_tmp();

  fputs("\n",fpw);
  while (fgets(inpline,sizeof(inpline),fpr)) fputs(inpline,fpw);
  fclose(fpw);
  fclose(fpr);

  c$free_tmp();
  log_to_usage_file(-2,g);
  if (*post_address) {
    sprintf(err_oline,"Post to %.200s Moderator (%.200s)",
            ga[g]->grp_name,post_address);
    call_mail(repost_file,&subj_line[9],add_transform(post_address),err_oline);
    }
  else if (nntp_client) post_to_server(nntp_node,nntp_proto,repost_file);
#if !NNTP_CLIENT_ONLY
  else {
    forward_posting = 1;
    net_news = 0;
    auto_cre_grp = 1;
    c$free_tmp();
    if (!sys_local_accept(ngroup,post_dist))
      err_line("Post - item NOT locally posted (filter rejection) - forwarded");
    else {
      unsigned int cre_grp[20];
      do_new_group(ngroup,1,cre_grp);
      c$free_tmp();
      if (!*cre_grp)
        err_line("Post - Item NOT locally posted (filter rejection) - forwarded");
      else {
        c$free_tmp();
        status = do_new_item(cre_grp,loc_id,&subj_line[9],mail_sig,
			     repost_file,1,0,line_count,0);
        if (status != 0) {
          if (forward_posting) {
            sprintf(err_oline,"Error: Post - (%.200s) %.200s (%X)",ngroup,
		    no_new_item,status);
            err_line(err_oline);
            }
          else err_line("Post - item has been mailed to Moderator");
          }
        }
      }

        /* check to see what else should be done with this posting */
    if (forward_posting) {
      sys_remote_send(post_path,ngroup,post_dist,repost_file,loc_id,0);
      flush_downstream(0);
      }
    }
    /* now look up news_manager:newspost.cc and then news_post_cc for more
       addresses to mail to */
  c$free_tmp();
  sysprv();
  if ((fpr = fopen("news_manager:news_post.cc","r")) != 0) {
    while ((xx = fgetl(fpr)) != 0) {
      chop_str(xx,'#');
      chop_str(xx,'\n');
      strip_compress(xx);
      if ((c1 = strchr(xx,' ')) != 0) {
        while (*c1 == ' ') *c1++ = '\0';
        lower_case(xx);
        for (cn1=ngroup; cn1; cn1=cn2) {
          cn2 = chop_str(cn1,',');
          if (wild_match(cn1,xx))
            call_mail(repost_file,&subj_line[9],add_transform(c1),"CC: - Mailing copies");
          if (cn2) *cn2++ = ',';
          }
        }
      }
    fclose(fpr);
    }
  nosysprv();
  c$free_tmp();

#endif
  if ((fpr = fopen("news_post_cc","r")) != 0
   || (fpr = fopen("sys$login:news_post.cc","r")) != 0) {
    while ((xx = fgetl(fpr)) != 0) {
      chop_str(xx,'#');
      chop_str(xx,'\n');
      strip_compress(xx);
      if ((c1 = strchr(xx,' ')) != 0) {
        while (*c1 == ' ') *c1++ = '\0';
        lower_case(xx);
        for (cn1 = ngroup; cn1; cn1=cn2) {
          cn2 = chop_str(cn1,',');
          if (wild_match(cn1,xx))
            call_mail(repost_file,&subj_line[9],add_transform(c1),"CC: - Mailing copies");
          if (cn2) *cn2++ = ',';
          }
        }
      }
    fclose(fpr);
    }
  delete_file_versions(repost_file);

  fclose(fp);
/*if (*fp_open > 1) delete_file_versions(fp_open); */
  fp_open = 0;
  sscanf(mail_id,"Message-ID: %s",id);

  if ((fp = fopen(Post_file,"w")) != 0) {
    char subj_line[132];

    make_post_path(post_path, sizeof(post_path));
    fprintf(fp,"Path:%s\n",post_path);
    fprintf(fp,"From: %s\n",mail_from);
    fprintf(fp,"Newsgroups: %s\n",ngroup);
    fprintf(fp,"Subject: cancel %s\n",id);
    strcpy(subj_line,"cancel ");
    strnncat(subj_line,sizeof(subj_line),-1, id,-1, 0);
    strnncpy(loc_id,sizeof(loc_id), gen_id(),-1, 0);
    fprintf(fp,"Message-ID: %s\n",loc_id);
    time(&cur_time);
    p = ctime(&cur_time);
    p += 4;
    stm = localtime(&cur_time);
    fprintf(fp,"Date: %d %.3s %04d %02d:%02d:%02d %s\n",
            stm->tm_mday, p, stm->tm_year + 1900,
            stm->tm_hour, stm->tm_min, stm->tm_sec, news_timezone);
    fprintf(fp,"Control: cancel %s\n",id);
    *post_dist = '\0';
    if (*mail_dist) {
      if (!sscanf(mail_dist,"Distribution: %s",post_dist))
      *post_dist = '\0';
      fprintf(fp,mail_dist);
      fprintf(fp,"\n");
      }
    fprintf(fp,"Lines: 1\n\ncancel %s\n",id);
    fclose(fp);
    if (nntp_client) post_to_server(nntp_node,nntp_proto,Post_file);
#if !NNTP_CLIENT_ONLY
    else {
      unsigned int cre_grp[2];
      do_new_group("control",0,cre_grp);
      if (cre_grp[0])
        do_new_item(cre_grp,loc_id,subj_line,mail_from,Post_file,1,1,1,0);
      sys_remote_send(post_path,ngroup,post_dist,Post_file,loc_id,0);
      flush_downstream(0);
      }
#endif
    }
  delete_file_versions(Post_file);
  del_id(ga[curr_g]->grp_ia[curr_i].itm_id,(char *)1);
  if (smg_active) newsgroup_header();
  return(0);
}

int do_repost()
{
  if (!curr_g || curr_i <= 0 || news_context == 1 || news_readonly) return(0);
  return(unwind_display(I_DISPLAY_LOOP,drepost));
}
/*
 *  do_edit
 *
 *  Edit an arbitrary file
 */

static int dedit()
{
  char filename[256];
  unsigned short filename_len;
  $DESCRIPTOR(filename_dsc,filename);

  if ((cli$get_value(c$dsc("FILE"),&filename_dsc,&filename_len) & 1)
      && filename_len) {
    filename[filename_len] = '\0';
    call_edit(filename);
    }
  return(0);
}

int do_edit()
{
  return(unwind_display(I_DISPLAY_LOOP,dedit));
}
