#module NEWSPOST "V5.6"

/*
**++
**  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
**
**  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
**
**--
**/

#include "newsinclude.h"
#include "newsdefine.h"
#include "newsextern.h"

/*
 *  parse_newsgroups
 *
 *  Parse the newsgroup specification, building a comma separated list.
 */

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)) {
        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';
        auth_list(newsgroups);
        strcpy(newslist,newsgroups);
        }
    else {
        *newslist = '\0';
        do {
            newsgroups[newsgroups_len] = '\0';
            if (auth_list(newsgroups)) {
                strcat(newslist,newsgroups);
                strcat(newslist,",");
                }
            } while (cli$get_value(c$dsc("NEWSGROUPS"),&newsgroups_dsc,&newsgroups_len) & 1);
        newslist[strlen(newslist) - 1] = '\0';
        }
}

/*
 *  call_edit
 *
 *  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,"TPU");
    strcat(tpucallstr," ");
    strcat(tpucallstr,infile);
    if (screen_active) {
        display_brdcst(2);
        no_broad_trap();
        smg$end_pasteboard_update(&pid);
        smg$save_physical_screen(&pid,&save_vd);
        edit_m_on();
        }
    status = 0;
    if (!strncmp(Editor,"edt",3)) edt$edit(c$dsc(infile),0,0,0,0,0,0,0);
    else if ((*Editor) && strncmp(Editor,"tpu",3)) 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) status = 2;
        else if (status == TPU_EXIT) status = 1;
        else status = 0;
        }
    if (screen_active) {
        edit_m_off();
        smg$restore_physical_screen(&pid,&save_vd);
        smg$begin_pasteboard_update(&pid);
        broad_trap();
        }
    return(status);
}

/*
 *  do_posting
 *
 *  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,
         *c1, *c2,
         *cn1, *cn2,
         mail_cmd[256];
    int fd,
        use_default = 1,
        header = 0,
        cur_time,
        edit_switch = 0,
        control_switch = 0,
        line_count = 0,
        mail_self,
        extract_orig,
        subj_param = 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';

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

    if (postfile) {
        if (cli$present(c$dsc("CONTROL")) & 1) {
            if (no_priv()) return(err_line("\tError: Post - No privs for Control message generation\n"),0);
            control_switch = 1;
            }
        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,((curr_g) ? ga[curr_g]->grp_name : ""),0);
        if (!*ngroup) {
            err_line("\tError: Post - No Authorized Newsgroups specified\n");
            return(0);
            }
        *distribution = '\0';
        *ref_line = '\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);
            }
        if (*infile) {
            if (fpr = fopen(infile,"r")) {
                while (fgets(xfrbuf,512,fpr)) fputs(xfrbuf,fpw);
                fclose(fpr);
                }
            else {
                sprintf(err_oline,"\tError: Post - Cannot open post file %s\n",infile);
                err_line(err_oline);
                return(0);
                }
            }
        strcpy(infile,Post_file);
        if ((fpr = fopen("SIGNATURE","r"))
            || (fpr = fopen("MAIL_SIGNATURE","r"))
            || (fpr = fopen("SYS$LOGIN:MAIL.SIGNATURE","r"))) {

            fputs("-- \n",fpw);
            while (fgets(xfrbuf,512,fpr)) fputs(xfrbuf,fpw);
            fclose(fpr);
            }
        fclose(fpw);
        }
    else {
        if ((!curr_g) || (curr_i <= 0)) {
            err_line("\tError: Reply - No item specified\n");
            return(0);
            }

        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("\tError: Post - no file to post\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);
            }

        *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",fp_open)) {
            while (fgets(xfrbuf,512,fpr)) {
                if (header) {
                    if (extract_orig) {
                        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';
                    s_to_lower(follow_groups);
                    }
                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);
                        if (*fp_open > 1) while (!delete(fp_open));
                        *fp_open = '\0';
                        fclose(fpw);
                        while (!delete(Post_file));
                        write_err_line("\tFollowup-To: poster    - Followup will 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') {
                    if (extract_orig) {
                        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);
            if (*fp_open > 1) while (!delete(fp_open));
            *fp_open = '\0';
            }
        if ((*infile) && (fpr = fopen(infile,"r"))) {
            while (fgets(xfrbuf,512,fpr)) fputs(xfrbuf,fpw);
            fclose(fpr);
            }
        *infile = '\0';
        if ((fpr = fopen("SIGNATURE","r"))
            || (fpr = fopen("MAIL_SIGNATURE","r"))
            || (fpr = fopen("SYS$LOGIN:MAIL.SIGNATURE","r"))) {

            fputs("-- \n",fpw);
            while (fgets(xfrbuf,512,fpr)) fputs(xfrbuf,fpw);
            fclose(fpr);
            }
        fclose(fpw);

        parse_newsgroups(ngroup,follow_groups,1);
        if (!*ngroup) {
            while (!delete(Post_file));
            err_line("\tError: Post - No Authorized Newsgroups specified\n");
            return(0);
            }

        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 (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());
    mail_add_expiry = 0;

    if (!subj_param) {
        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),0);
        if (status == RMS$_EOF) {
            err_line("\tPost - Canceled\n");
            if (!strcmp(infile,Post_file)) while (!(delete(Post_file)));
            return(0);
            }
        s[s_len] = '\0';
        }
    if (!*s) strcpy(s,"<None>");
    sprintf(subj_line,"Subject: %s\n",s);

    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);
    if (control_switch) fprintf(fpw,"Control: %s\n",s);
    fprintf(fpw,"%s",subj_line);
    fprintf(fpw,"Message-ID: %s\n",loc_id);
    fprintf(fpw,"Date: %d %.3s %d %02d:%02d:%02d %s\n",
        stm->tm_mday,p,stm->tm_year,stm->tm_hour,stm->tm_min,stm->tm_sec,
        news_timezone);
    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) {
            fclose(fpw);
            fclose(fpr);
            err_line("\tPost - Canceled\n");
            while (!(delete(Post_file)));
            return(0);
            }
        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) {
            fclose(fpw);
            fclose(fpr);
            err_line("\tPost - Canceled\n");
            while (!(delete(Post_file)));
            return(0);
            }
        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),0);
        else status = get_input(&command,c$dsc("Distribution: "),&response_length);
        if (status == RMS$_EOF) {
            fclose(fpw);
            fclose(fpr);
            err_line("\tPost - Canceled\n");
            while (!(delete(Post_file)));
            return(0);
            }
        if ((status & 1) && (response_length)) {
            response[response_length] = '\0';
            s_to_lower(response);
            strcpy(post_dist,response);
            fprintf(fpw,"Distribution: %s\n",response);
            }

        sprintf(err_oline,"\tFollowup newsgroups (or \"poster\") [%s]\n",ngroup);
        err_line(err_oline);
        status = get_input(&command,c$dsc("Followup-To: "),&response_length);
        if (status == RMS$_EOF) {
            fclose(fpw);
            fclose(fpr);
            err_line("\tPost - Canceled\n");
            while (!(delete(Post_file)));
            return(0);
            }
        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) {
            fclose(fpw);
            fclose(fpr);
            err_line("\tPost - Canceled\n");
            while (!(delete(Post_file)));
            return(0);
            }
        if ((status & 1) && (response_length)) {
            response[response_length] = '\0';
            fprintf(fpw,"Keywords: %s\n",response);
            }

        err_line("\tExpiry Date [use local defaults] (VMS Date format)\n");
        status = get_input(&command,c$dsc("Expires: "),&response_length);
        if (status == RMS$_EOF) {
            fclose(fpw);
            fclose(fpr);
            err_line("\tPost - Canceled\n");
            while (!(delete(Post_file)));
            return(0);
            }
        if ((status & 1) && (response_length)) {
            int etime;
            response[response_length] = '\0';
            if ((etime = cvt_date_val(response)) && (etime > cur_time)) {
                p = ctime(&etime);
                p += 4;
                stm = localtime(&etime);
                fprintf(fpw,"Expires: %d %.3s %d %02d:%02d:%02d %s\n",
                    stm->tm_mday,p,stm->tm_year,stm->tm_hour,stm->tm_min,
                    stm->tm_sec, news_timezone);
                mail_add_expiry = ((etime - cur_time) / 84600) + 1;
                if (mail_add_expiry < 3) mail_add_expiry = 3;
                if (mail_add_expiry > 366) mail_add_expiry = 366;
                }
            }
        }
    fprintf(fpw,"Organization: %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);

    sprintf(err_oline,"Post to %s [y]:",ngroup);
    if ((status = get_input(&command,c$dsc(err_oline),&response_length)) == RMS$_EOF)  {
        err_line("\tPost - Canceled\n");
        while (!(delete(Post_file)));
        return(0);
        }
    if (!((status & 1) && ((!response_length) || ((response_length) && (toupper(*response) == 'Y'))))) {
        err_line("\tPost - Canceled\n");
        while (!(delete(Post_file)));
        return(0);
        }

    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,0,line_count)) {
                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,loc_id,0);

    if (mail_self) {
        sprintf(mail_cmd,"MAIL/NOEDIT %s/SUBJECT=\"%s (NEWS Posting: Author Copy)\" %s",
            Post_file,s,usr_username);
        err_line("Mail copy to self - Spawning MAIL task .. please wait");
        if (screen_active) {
            display_brdcst(2);
            no_broad_trap();
            smg$end_pasteboard_update(&pid);
            }
        _c$cks(lib$spawn(c$dsc(mail_cmd),0,0,0,0,0,0,0,0,0,0,0));
        if (screen_active) {
            smg$begin_pasteboard_update(&pid);
            broad_trap();
            }
        }

    /* now look up news_manager:newspost.cc and then news_post_cc for more
       addresses to mail to */

    sysprv();
    if (fpr = fopen("news_manager:news_post.cc","r")) {
        while (fgets(xfrbuf,510,fpr)) {
            if (*xfrbuf == '#') continue;
            if (c1 = strchr(xfrbuf,' ')) {
                while (*c1 == ' ') *c1++ = '\0';
                if (c2 = strchr(c1,'\n')) *c2 = '\0';

                cn1 = ngroup;
                do {
                    if (cn2 = strchr(cn1,',')) *cn2 = '\0';
                    if (wild_match(cn1,xfrbuf)) {
                        sprintf(mail_cmd,"MAIL/NOEDIT %s/SUBJECT=\"%s\" %s",
                            Post_file,s,add_transform(c1));
                        err_line("Mail copies - Spawning MAIL task .. please wait");
                        if (screen_active) {
                            display_brdcst(2);
                            no_broad_trap();
                            smg$end_pasteboard_update(&pid);
                            }
                        _c$cks(lib$spawn(c$dsc(mail_cmd),0,0,0,0,0,0,0,0,0,0,0));
                        if (screen_active) {
                            smg$begin_pasteboard_update(&pid);
                            broad_trap();
                            }
                        }
                    if (cn2) *cn2++ = ',';
                    } while (cn1 = cn2);

                }
            }
        fclose(fpr);
        }
    nosysprv();
    if ((fpr = fopen("news_post_cc","r")) || (fpr = fopen("sys$login:news_post.cc","r"))) {
        while (fgets(xfrbuf,510,fpr)) {
            if (*xfrbuf == '#') continue;
            if (c1 = strchr(xfrbuf,' ')) {
                while (*c1 == ' ') *c1++ = '\0';
                if (c2 = strchr(c1,'\n')) *c2 = '\0';
                cn1 = ngroup;
                do {
                    if (cn2 = strchr(cn1,',')) *cn2 = '\0';
                    if (wild_match(cn1,xfrbuf)) {
                        sprintf(mail_cmd,"MAIL/NOEDIT %s/SUBJECT=\"%s\" %s",
                            Post_file,s,add_transform(c1));
                        err_line("Mail copies - Spawning MAIL task .. please wait");
                        if (screen_active) {
                            display_brdcst(2);
                            no_broad_trap();
                            smg$end_pasteboard_update(&pid);
                            }
                        _c$cks(lib$spawn(c$dsc(mail_cmd),0,0,0,0,0,0,0,0,0,0,0));
                        if (screen_active) {
                            smg$begin_pasteboard_update(&pid);
                            broad_trap();
                            }
                        }
                    if (cn2) *cn2++ = ',';
                    } while (cn1 = cn2);
                }
            }
        fclose(fpr);
        }
    while (!(delete(Post_file)));
    return(0);
}

/*
 *  do_post
 *
 *  Post a new item into NEWS
 */

do_post()
{
    return(do_posting(1));
}

/*
 *  do_followup
 *
 *  Post a followup item to NEWS
 */

do_followup()
{
    return(do_posting(0));
}

/*
 *  do_edit
 *
 *  Edit an arbitrary file
 */

do_edit()
{
    char filename[256];
    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);
}
