#module NEWSPOST "V4.0"
/*----------------------------------------------------------------------
        N E W S P O S T . C

 Author:
     Geoff Huston
       Computer Services Centre
       Australian National University

 Functionality:
        Post a newsitem into NEWS the NEWS database, and also
        post thie item into the net distribution area.

 Version:
    V1.0    17-Jul-1986     GIH     this version of code checkpointed
    V1.1     1-Aug-1986     GIH     screen handling code added
    V1.2     5-Nov-1986     GIH     Fix bug in LIB$SPAWN args
    V3.0    30-Apr-1987     GIH     NEWS Version 3 Release
    V4.0    30-Oct-1987     GIH     NEWS Version 4.0 Release

----------------------------------------------------------------------*/

#include "newsinclude.h"
#include "newsdefine.h"
#include "newsextern.h"

/*----------------------------------------------------------------------
 *  p a r s e _ n e w s g r o u p s
 *
 *  parse the newsgroup specification, building a comma separated list
 *  of newsgroups.
 *----------------------------------------------------------------------
 */

parse_newsgroups(newslist,dflt,ask)
    char *newslist,
         *dflt;
    int ask;
{
    char newsgroups[256];
    short newsgroups_len;

    $DESCRIPTOR(newsgroups_dsc,newsgroups);

    if ((ask) || (cli$get_value(c$dsc("NEWSGROUPS"),&newsgroups_dsc,&newsgroups_len) == CLI$_ABSENT))
    {
        char *cp1 = newsgroups,
             *cp2 = newslist,
             *cp3;

        status = get_input_dflt(&newsgroups_dsc,c$dsc("Newsgroups: "),&newsgroups_len,c$dsc(dflt));
        if (status == RMS$_EOF) longjmp(env,2);
        newsgroups[newsgroups_len] = '\0';
        while (cp3 = strchr(cp1,','))
        {
            *cp3++ = '\0';
            util_cvrt(cp2,cp1);
            cp2 += strlen(cp2);
            *cp2++ = ',';
            cp1 = cp3;
        }
        util_cvrt(cp2,cp1);
        cp2 += strlen(cp2);
        *cp2++ = '\0';
    }
    else
    {
        *newslist = '\0';
        do
        {
            newsgroups[newsgroups_len] = '\0';
            util_cvrt(newsgroups,newsgroups);
            strcat(newslist,newsgroups);
            strcat(newslist,",");
        } while (cli$get_value(c$dsc("NEWSGROUPS"),&newsgroups_dsc,&newsgroups_len) & 1);
        newslist[strlen(newslist) - 1] = '\0';
    }
}

/*----------------------------------------------------------------------
 *  c a l l _ e d i t
 *
 *  Invoke an editor - return 2 if quit, 1 if exit, 0 unknown
 *----------------------------------------------------------------------
 */

#define TPU_QUIT 0X13F2AF59
#define TPU_EXIT 0X13F2AF01

call_edit(infile)
    char *infile;
{
    char tpucallstr[100];
    int save_vd;

    if (*Editor) strcpy(tpucallstr,Editor);
    else strcpy(tpucallstr,TPUedit);
    strcat(tpucallstr," ");
    strcat(tpucallstr,infile);
    if (screen_active)
    {
        smg$end_pasteboard_update(&pid);
        smg$save_physical_screen(&pid,&save_vd);
        reset_mode();
    }
    status = 0;
    if (*Editor) lib$spawn(c$dsc(tpucallstr),0,0,0,0,0,0,0,0,0,0,0);
    else
    {
        if ((status = tpu$tpu(c$dsc(tpucallstr)))  == TPU_QUIT) /* QUIT from TPU */
            status = 2;
        else if (status == TPU_EXIT) status = 1;  /* EXIT from TPU */
        else status = 0;
    }
    if (screen_active)
    {
        chg_mode();
        smg$restore_physical_screen(&pid,&save_vd);
        smg$begin_pasteboard_update(&pid);
    }
    return(status);
}

/*----------------------------------------------------------------------
 *  d o _ p o s t i n g
 *
 *  post a new news item
 *----------------------------------------------------------------------
 */

do_posting(postfile)
    int postfile;
{
    char ngroup[512],
         post_dist[132],
         post_path[132],
         s[132],
         infile[256],
         loc_id[IDLEN],
         xfrbuf[512],
         *cp1,
         *cp2,
         distribution[256],
         id[256],
         from[256],
         follow_groups[256],
         ref_line[256],
         old_ref_line[256],
         subj_line[256],
         *cp,
         *p;
    int fd,
        use_default = 1,
        header = 0,
        cur_time,
        edit_switch = 0,
        line_count = 0;
    struct stat sbuffer;
    struct tm *stm;
    unsigned short group_no,
                   s_len,
                   infile_len,
                   cre_grp[20];
    FILE *fpr,
         *fpw;
    $DESCRIPTOR(s_dsc,s);
    $DESCRIPTOR(infile_dsc,infile);

    itm_approved = 0;
    *post_dist = '\0';
    clear_err_line();

    if (cli$present(c$dsc("HEADERS")) & 1) use_default = 0;

    if (postfile)
    {
        if (cli$present(c$dsc("EDIT")) & 1) edit_switch = 1;
        if (cli$get_value(c$dsc("INFILE"),&infile_dsc,&infile_len) == CLI$_ABSENT) *infile = '\0';
        if (cli$get_value(c$dsc("SUBJECT"),&s_dsc,&s_len) == CLI$_ABSENT) *s = '\0';
        infile[infile_len] = '\0';
        parse_newsgroups(ngroup,((curr_g) ? ga[curr_g]->grp_name : ""),0);
        if ((!curr_g) && (!*ngroup))
        {
            err_line("\tError: Post - No Newsgroups specified\n");
            return(0);
        }
        if (!*ngroup) util_cpy(ngroup,ga[curr_g]->grp_name);
        *distribution = '\0';
        *ref_line = '\0';
    }
    else
    {
        if ((!curr_g) || (curr_i <= 0))
        {
            err_line("\tError: Post - No item specified\n");
            return(0);
        }
        fd = creat(Post_file,0,"rat=cr","rfm=var");
        if ((fd == -1) || (!(fpw = fdopen(fd,"w"))))
        {
            sprintf(err_oline,"\tError: Post - Cannot open edit file %s\n",Post_file);
            err_line(err_oline);
            return(0);
        }

        *infile = '\0';
        *s = '\0';
        *ref_line = '\0';
        *subj_line = '\0';
        *old_ref_line = '\0';
        *id = '\0';
        *from = '\0';
        *follow_groups = '\0';
        *distribution = '\0';
        if (fpr = do_open_item(curr_g,curr_i,"r"))
        {
            while (fgets(xfrbuf,512,fpr))
            {
                if (header)
                {
                    fputs(">",fpw);
                    if (*xfrbuf != '>') fputs(" ",fpw);
                    fputs(xfrbuf,fpw);
                }
                else if (!strncmp(xfrbuf,"From:",5))
                {
                    strcpy(from,&xfrbuf[6]);
                    if (cp = strchr(from,'\n')) *cp = '\0';
                }
                else if (!strncmp(xfrbuf,"Message-ID:",11))
                {
                    strcpy(id,&xfrbuf[12]);
                    if (cp = strchr(id,'\n')) *cp = '\0';
                }
                else if (!strncmp(xfrbuf,"References:",11))
                {
                    strcpy(old_ref_line,&xfrbuf[12]);
                    if (cp = strchr(old_ref_line,'\n')) *cp = '\0';
                }
                else if (!strncmp(xfrbuf,"Subject:",8))
                {
                    strcpy(subj_line,"Subject: ");
                    if ((strncmp(&xfrbuf[9],"Re: ",4)) && (strncmp(&xfrbuf[9],"re: ",4))) strcat(subj_line,"Re: ");
                    strcat(subj_line,&xfrbuf[9]);
                    strcpy(s,&subj_line[9]);
                    if (cp = strchr(s,'\n')) *cp = '\0';
                }
                else if ((!strncmp(xfrbuf,"Newsgroups:",11)) && (!*follow_groups))
                {
                    strcpy(follow_groups,&xfrbuf[12]);
                    if (cp = strchr(follow_groups,'\n')) *cp = '\0';
                }
                else if (!strncmp(xfrbuf,"Followup-To:",12))
                {
                    strcpy(follow_groups,&xfrbuf[13]);
                    if (cp = strchr(follow_groups,'\n')) *cp = '\0';
                    s_to_lower(follow_groups);
                    if (!strcmp(follow_groups,"poster"))
                    {
                        fclose(fpr);
                        fclose(fpw);
                        while (!delete(Post_file));
                        err_line("\tFollowup postings to be mailed to sender\n");
                        return(do_mail(0,0),0);
                    }
                }
                else if (!strncmp(xfrbuf,"Distribution:",13))
                {
                    strcpy(distribution,&xfrbuf[14]);
                    if (cp = strchr(distribution,'\n')) *cp = '\0';
                }
                else if (*xfrbuf == '\n')
                {
                    fputs("In article ",fpw);
                    if (!*id) sprintf(id,"<%s %s:%d>", usr_nodename, ga[curr_g]->grp_name,ga[curr_g]->grp_ia[curr_i].itm_num);
                    fputs(id,fpw);
                    fprintf(fpw,", %s writes:\n",from);
                    header = 1;
                }
            }
            fclose(fpr);
        }
        fclose(fpw);


        strcpy(ref_line,"References: ");
        if (*old_ref_line)
        {
            strcat(ref_line,old_ref_line);
            strcat(ref_line," ");
        }
        strcat(ref_line,id);
        strcat(ref_line,"\n");

    }

    status = 0;
    if (!*infile) strcpy(infile,Post_file);
    if ((!postfile) || ((edit_switch) || (!*infile)))
    {
        edit_switch = 1;
        if ((status = call_edit(infile)) == 2) return(0);
    }

    if (stat(infile,&sbuffer))
    {
        err_line("\tError: Post - Item text file not found\n");
        return(0);
    }
    if (!sbuffer.st_size)
    {
        err_line("\tError: Post - Item text file is empty\n");
        if (!strcmp(infile,Post_file)) while (!(delete(Post_file)));
        return(0);
    }

    line_count = 0;
    if (fpr = fopen(infile,"r"))
    {
        while (fgets(xfrbuf,510,fpr)) ++line_count;
        fclose(fpr);
    }
    if (!line_count)
    {
        err_line("\tError: Post - Item text file is empty\n");
        if (!strcmp(infile,Post_file)) while (!(delete(Post_file)));
        return(0);
    }
    time(&cur_time);
    p = ctime(&cur_time);
    p += 4;
    stm = localtime(&cur_time);
    strcpy(loc_id,gen_id());

    if (edit_switch)
    {
        if (!status) status = get_input(&command,c$dsc("Enter item in NEWS? [y]:"),&response_length);
        else response_length = 0;
        if (status == RMS$_EOF) longjmp(env,2);
        if (!((status & 1) && ((!response_length) || ((response_length)
            && (toupper(*response) == 'Y')))))
        {
            if (!strcmp(infile,Post_file)) while (!(delete(Post_file)));
            return(0);
        }
    }

    if (!*s) status = get_input(&s_dsc,c$dsc("Subject: "),&s_len);
    else status = get_input_dflt(&s_dsc,c$dsc("Subject: "),&s_len,c$dsc(s));
    if (status == RMS$_EOF) longjmp(env,2);
    s[s_len] = '\0';
    if (!*s) strcpy(s,"<None>");
    sprintf(subj_line,"Subject: %s\n",s);

    if (!postfile) parse_newsgroups(ngroup,follow_groups,1);

    if (!(fpr = fopen(infile,"r")))
    {
        if (!strcmp(infile,Post_file)) while (!(delete(Post_file)));
        return(0);
    }
    if (!(fpw = fopen(Post_file,"w")))
    {
        fclose(fpr);
        if (!strcmp(infile,Post_file)) while (!(delete(Post_file)));
        return(0);
    }

    fprintf(fpw,"Path: %s!%s\n",usr_nodename,usr_username);
    sprintf(post_path," %s!%s",usr_nodename,usr_username);
    fprintf(fpw,"From: %s@%s",usr_username,Node_address);
    if (*usr_persname) fprintf(fpw," (%s)",usr_persname);
    fprintf(fpw,"\n");
    fprintf(fpw,"Newsgroups: %s\n",ngroup);
    fprintf(fpw,"%s",subj_line);
    fprintf(fpw,"Message-ID: %s\n",loc_id);
    fprintf(fpw,"Date: %d %.3s %d %02d:%02d:%02d GMT\n",stm->tm_mday,p,stm->tm_year,stm->tm_hour,stm->tm_min,stm->tm_sec);
    if (*ref_line) fputs(ref_line,fpw);

    if (!use_default)
    {
        err_line("\tSummary of posting [no Summary]\n");
        status = get_input(&command,c$dsc("Summary: "),&response_length);
        if (status == RMS$_EOF) longjmp(env,2);
        if ((status & 1) && (response_length))
        {
            response[response_length] = '\0';
            fprintf(fpw,"Summary: %s\n",response);
        }

        err_line("\tMail address for replies [reply to self]\n");
        status = get_input(&command,c$dsc("Reply-To: "),&response_length);
        if (status == RMS$_EOF) longjmp(env,2);
        if ((status & 1) && (response_length))
        {
            response[response_length] = '\0';
            fprintf(fpw,"Reply-To: %s\n",response);
        }

        err_line("\tDistribution of item [newsgroup based]\n");
        if (*distribution) status = get_input_dflt(&command,c$dsc("Distribution: "),&response_length,c$dsc(distribution));
        else status = get_input(&command,c$dsc("Distribution: "),&response_length);
        if (status == RMS$_EOF) longjmp(env,2);
        if ((status & 1) && (response_length))
        {
            response[response_length] = '\0';
            s_to_lower(response);
            strcpy(post_dist,response);
            fprintf(fpw,"Distribution: %s\n",response);
        }

        err_line("\tNewsgroups for Followup postings  [same as this item]\n");
        status = get_input(&command,c$dsc("Followup-To: "),&response_length);
        if (status == RMS$_EOF) longjmp(env,2);
        if ((status & 1) && (response_length))
        {
            response[response_length] = '\0';
            fprintf(fpw,"Followup-To: %s\n",response);
        }

        err_line("\tKeyword list [no keywords]\n");
        status = get_input(&command,c$dsc("Keywords: "),&response_length);
        if (status == RMS$_EOF) longjmp(env,2);
        if ((status & 1) && (response_length))
        {
            response[response_length] = '\0';
            fprintf(fpw,"Keywords: %s\n",response);
        }
    }
    fprintf(fpw,"Organisation: %s\n",Organisation_name);
    fprintf(fpw,"Lines: %d\n",line_count);
    fprintf(fpw,"\n");
    while (fgets(xfrbuf,510,fpr)) fputs(xfrbuf,fpw);
    fclose(fpr);
    fclose(fpw);

    forward_posting = 1;
    net_news = 0;
    auto_cre_grp = 1;
    if (!sys_local_accept(ngroup,post_dist))
    {
        err_line("\tPost - item NOT posted to local news (news.sys rejection) - forwarded\n");
    }
    else
    {
        do_new_group(ngroup,1,cre_grp);
        if (!*cre_grp)
        {
            err_line("\tPost - item NOT posted to local news (news.sys rejection) - forwarded\n");
        }
        else
        {
            if (status = do_new_item(cre_grp,loc_id,s,Post_file,1))
            {
                if (forward_posting)
                {
                    sprintf(err_oline,"\tError: Post - (%s) %s (%X)\n",ngroup,no_new_item,status);
                    err_line(err_oline);
                }
                else err_line("\tPost - item has been mailed to Moderator\n");
            }
        }
    }

    /* check to see what else should be done with this posting */
    if (forward_posting) sys_remote_send(post_path,ngroup,post_dist,Post_file,0);
    while (!(delete(Post_file)));
    return(0);
}

/*--------------COMMAND FUNCTION-----------------------------------------
 *  d o _ p o s t
 *
 * define verb POST
 *    routine     do_post
 *    parameter   P1,         label=INFILE,value(type=$infile)
 *    qualifier   EDIT,       negatable
 *    qualifier   HEADERS,    negatable
 *    qualifier   NEWSGROUPS, nonnegatable, value(required,list)
 *    qualifier   SUBJECT,    nonnegatable, value(required)
 *
 *  Post a new item into NEWS
 *----------------------------------------------------------------------
 */

do_post()
{
    return(do_posting(1));
}

/*--------------COMMAND FUNCTION-----------------------------------------
 *  d o _ f o l l o w u p
 *
 *  define verb FOLLOWUP
 *    routine     do_followup
 *    qualifier   HEADERS,    negatable
 *
 *  Post a followup item to NEWS
 *----------------------------------------------------------------------
 */

do_followup()
{
    return(do_posting(0));
}
