home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / UUPC11XT.ZIP / RN / RESPOND.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-21  |  14.6 KB  |  613 lines

  1. /* $Header: E:\SRC\UUPC\RN\RCS/RESPOND.C 1.1 1992/11/21 06:14:58 ahd Exp $
  2.  *
  3.  * $Log: RESPOND.C $
  4.  * Revision 1.1  1992/11/21  06:14:58  ahd
  5.  * Initial
  6.  *
  7.  *
  8.  *    Rev 1.0   18 Nov 1990  0:22:06
  9.  * Initial revision.
  10.  * Revision 4.3.2.3  90/03/22  23:05:19  sob
  11.  * Fixes provided by Wayne Davison <drivax!davison>
  12.  *
  13.  * Revision 4.3.2.2  89/11/26  18:25:10  sob
  14.  * Enlarged the size of the header buffer to accomodate long references lines.
  15.  * Fix provided by Joe Buck.
  16.  *
  17.  * Revision 4.3.2.1  89/11/06  01:00:26  sob
  18.  * Added RRN support from NNTP 1.5
  19.  *
  20.  * Revision 4.3.1.5  85/09/10  11:05:00  lwall
  21.  * Improved %m in in_char().
  22.  *
  23.  * Revision 4.3.1.4  85/05/23  17:24:49  lwall
  24.  * Now allows 'r' and 'f' on null articles.
  25.  *
  26.  * Revision 4.3.1.3  85/05/15  14:42:32  lwall
  27.  * Removed duplicate include of intrp.h.
  28.  *
  29.  * Revision 4.3.1.2  85/05/14  08:55:15  lwall
  30.  * Default for normal/mailbox question was applied to wrong buffer.
  31.  *
  32.  * Revision 4.3.1.1  85/05/10  11:37:33  lwall
  33.  * Branch for patches.
  34.  *
  35.  * Revision 4.3  85/05/01  11:47:04  lwall
  36.  * Baseline for release with 4.3bsd.
  37.  *
  38.  */
  39.  
  40.  
  41. #include <process.h>
  42. #include <stdio.h>
  43. #include "lib.h"
  44.  
  45. currentfile();
  46.  
  47. #include "EXTERN.h"
  48. #include "common.h"
  49. #include "intrp.h"
  50. #include "head.h"
  51. #include "term.h"
  52. #include "ng.h"
  53. #include "util.h"
  54. #include "rn.h"
  55. #include "artio.h"
  56. #include "final.h"
  57. #include "INTERN.h"
  58. #include "respond.h"
  59.  
  60. static char nullart[] = "\nNull article\n";
  61.  
  62. int doshell(char *shl, char *s);
  63.  
  64. void
  65.   respond_init()
  66. {
  67.    ;
  68. }
  69.  
  70. static int
  71.   is_relative_path(s)
  72.    char *s;
  73. {
  74.  
  75. #ifdef msdos
  76.    if (*s == '/')
  77.       return TRUE;
  78.    if (*s == '\\')
  79.       return TRUE;
  80.    if ((strlen(s) >= 3) && (*(s + 1) == ':'))
  81.    {
  82.       if ((*(s + 2) == '/') || (*(s + 2) == '\\'))
  83.          return TRUE;
  84.    }
  85.    return FALSE;
  86. #else
  87.    return (*s == '/');
  88. #endif
  89. }
  90.  
  91. int
  92.   save_article()
  93. {
  94.    bool use_pref;
  95.    register char *s, *c;
  96.    char altbuf[CBUFLEN];
  97.    int iter;
  98.    char *z1, *z2;
  99.    bool interactive = (buf[1] == FINISHCMD);
  100.  
  101.    if (!finish_command(interactive))    /* get rest of command */
  102.       return SAVE_ABORT;
  103.    use_pref = isupper(*buf);
  104.  
  105. #ifdef ASYNC_PARSE
  106.    parse_maybe(art);
  107. #endif
  108.  
  109.    savefrom = (*buf == 'w' || *buf == 'W' ? htype[PAST_HEADER].ht_minpos : 0);
  110.    if (artopen(art) == Nullfp)
  111.    {
  112.  
  113. #ifdef VERBOSE
  114.       IF(verbose)
  115.          fputs("\n\
  116. Saving null articles is not very productive!  :-)\n\
  117. ", stdout) FLUSH;
  118.       ELSE
  119. #endif
  120.  
  121. #ifdef TERSE
  122.          fputs(nullart, stdout) FLUSH;
  123. #endif
  124.  
  125.       return SAVE_DONE;
  126.    }
  127.    if (chdir(cwd))
  128.    {
  129.       printerr(cwd);
  130.       printf(nocd, cwd) FLUSH;
  131.       sig_catcher(0);
  132.    }
  133.    if (savedest)
  134.       free(savedest);
  135.    if ((s = index(buf, '|')) != Nullch)
  136.    {
  137.       /* is it a pipe command? */
  138.       s++;                   /* skip the | */
  139.       while (*s == ' ')
  140.          s++;
  141.       safecpy(altbuf, filexp(s), sizeof altbuf);
  142.       savedest = altbuf;
  143.       interp(cmd_buf, (sizeof cmd_buf), getval("PIPESAVER", PIPESAVER));
  144.       /* then set up for command */
  145.       resetty();             /* restore tty state */
  146.       if (use_pref)          /* use preferred shell? */
  147.          doshell(Nullch, cmd_buf);
  148.       /* do command with it */
  149.       else
  150.          doshell(sh, cmd_buf);  /* do command with sh */
  151.       noecho();              /* and stop echoing */
  152.       crmode();              /* and start cbreaking */
  153.       savedest = savestr(savedest);
  154.    }
  155.    else
  156.    {                         /* normal save */
  157.       bool there, mailbox;
  158.       char *savename = getval("SAVENAME", SAVENAME);
  159.  
  160.       s = buf + 1;           /* skip s or S */
  161.       if (*s == '-')
  162.       {                      /* if they are confused,
  163.                               * skip - also */
  164.  
  165. #ifdef VERBOSE
  166.          IF(verbose)
  167.             fputs("Warning: '-' ignored.  This isn't readnews.\n", stdout)
  168.             FLUSH;
  169.          ELSE
  170. #endif
  171.  
  172. #ifdef TERSE
  173.             fputs("'-' ignored.\n", stdout) FLUSH;
  174. #endif
  175.  
  176.          s++;
  177.       }
  178.       for (; *s == ' '; s++);/* skip spaces */
  179.       safecpy(altbuf, filexp(s), sizeof altbuf);
  180.       s = altbuf;
  181.       if (!index(s, '/'))
  182.       {
  183.          interp(buf, (sizeof buf), getval("SAVEDIR", SAVEDIR));
  184.          if (makedir(buf, MD_DIR))      /* ensure directory
  185.                                          * exists */
  186.             strcpy(buf, cwd);
  187.          if (*s)
  188.          {
  189.             for (c = buf; *c; c++);
  190.             *c++ = '/';
  191.             strcpy(c, s);    /* add filename */
  192.          }
  193.          s = buf;
  194.       }
  195.       for (iter = 0;
  196.             (there = stat(s, &filestat) >= 0) &&
  197.             (filestat.st_mode & S_IFDIR);
  198.             iter++)
  199.       {                      /* is it a directory? */
  200.  
  201.          c = (s + strlen(s));
  202.          *c++ = '/';         /* put a slash before
  203.                               * filename */
  204.          interp(c, s == buf ? (sizeof buf) : (sizeof altbuf),
  205.                 iter ? "News" : savename);
  206.          /* generate a default name somehow or other */
  207.          if (index(c, '/'))
  208.          {                   /* yikes, a '/' in the
  209.                               * filename */
  210.             makedir(s, MD_FILE);
  211.          }
  212.       }
  213.  
  214.       /* was test for (*s != '/')          */
  215.       if (!is_relative_path(s))
  216.       {                      /* mll */
  217.          c = (s == buf ? altbuf : buf);
  218.          sprintf(c, "%s/%s", cwd, s);
  219.          s = c;              /* absolutize it */
  220.       }
  221.       s = savedest = savestr(s);        /* doesn't move any more */
  222.       /* make it handy for %b */
  223.       if (!there)
  224.       {
  225.          if (mbox_always)
  226.             mailbox = TRUE;
  227.          else if (norm_always)
  228.             mailbox = FALSE;
  229.          else
  230.          {
  231.             char *dflt = (instr(savename, "%a") ? "nyq" : "ynq");
  232.  
  233.             sprintf(cmd_buf,
  234.                     "\nFile %s doesn't exist--\n        use mailbox format? [%s] ",
  235.                     s, dflt);
  236.       reask_save:
  237.             in_char(cmd_buf, 'M');
  238.             putchar('\n') FLUSH;
  239.             setdef(buf, dflt);
  240.  
  241. #ifdef VERIFY
  242.             printcmd();
  243. #endif
  244.  
  245.             if (*buf == 'h')
  246.             {
  247.  
  248. #ifdef VERBOSE
  249.                IF(verbose)
  250.                   printf("\n\
  251. Type y to create %s as a mailbox.\n\
  252. Type n to create it as a normal file.\n\
  253. Type q to abort the save.\n\
  254. ", s) FLUSH;
  255.                ELSE
  256. #endif
  257.  
  258. #ifdef TERSE
  259.                   fputs("\n\
  260. y to create mailbox.\n\
  261. n to create normal file.\n\
  262. q to abort.\n\
  263. ", stdout) FLUSH;
  264. #endif
  265.  
  266.                goto reask_save;
  267.             }
  268.             else if (*buf == 'n')
  269.             {
  270.                mailbox = FALSE;
  271.             }
  272.             else if (*buf == 'y')
  273.             {
  274.                mailbox = TRUE;
  275.             }
  276.             else if (*buf == 'q')
  277.             {
  278.                goto s_bomb;
  279.             }
  280.             else
  281.             {
  282.                fputs(hforhelp, stdout) FLUSH;
  283.                settle_down();
  284.                goto reask_save;
  285.             }
  286.          }
  287.       }
  288.       else if (filestat.st_mode & S_IFCHR)
  289.          mailbox = FALSE;
  290.       else
  291.       {
  292.          int tmpfd;
  293.  
  294.          tmpfd = open(s, 0);
  295.          if (tmpfd == -1)
  296.             mailbox = FALSE;
  297.          else
  298.          {
  299.             read(tmpfd, buf, LBUFLEN);
  300.             c = buf;
  301.             if (!isspace(MBOXCHAR))
  302.                while (isspace(*c))
  303.                   c++;
  304.             mailbox = (*c == MBOXCHAR);
  305.             close(tmpfd);
  306.          }
  307.       }
  308.  
  309.       safecpy(cmd_buf, filexp(mailbox ?
  310.                               getval("MBOXSAVER", MBOXSAVER) :
  311.                               getval("NORMSAVER", NORMSAVER)), sizeof cmd_buf);
  312.       /* format the command */
  313.       resetty();             /* make terminal behave */
  314.  
  315. #ifdef msdos
  316.       /* The command name must be "properly" slashed */
  317.       iter = 0;
  318.       while (cmd_buf[iter] != ' ')
  319.       {
  320.          if (cmd_buf[iter] == '/')
  321.             cmd_buf[iter] = '\\';
  322.          iter++;
  323.       }
  324. #endif
  325.  
  326.       if (doshell(use_pref ? Nullch : SH, cmd_buf))
  327.          fputs("Not saved", stdout);
  328.       else
  329.          printf("%s to %s %s",
  330.                 there ? "Appended" : "Saved",
  331.                 mailbox ? "mailbox" : "file",
  332.                 s);
  333.       if (interactive)
  334.          putchar('\n') FLUSH;
  335.       noecho();              /* make terminal do what
  336.                               * we want */
  337.       crmode();
  338.    }
  339. s_bomb:
  340.    /* I think not -- #if defined(SERVER) || defined(msdos) */
  341.  
  342. #if defined(SERVER)
  343.    if (chdir(spool))
  344. #else                        /* not SERVER */
  345.    if (chdir(spool) || chdir(ngdir))
  346. #endif                       /* SERVER */
  347.  
  348.    {
  349.       printerr(ngdir);
  350.       printf(nocd, ngdir) FLUSH;
  351.       sig_catcher(0);
  352.    }
  353.    return SAVE_DONE;
  354. }
  355.  
  356. int
  357.   cancel_article()
  358. {
  359.    char *artid_buf;
  360.    char *ngs_buf;
  361.    char *from_buf;
  362.    char *reply_buf;
  363.  
  364. #ifndef msdos
  365.    int myuid = getuid();
  366.  
  367. #else
  368.    int myuid = 99;
  369.  
  370. #endif
  371.    int r = -1;
  372.  
  373.    if (artopen(art) == Nullfp)
  374.    {
  375.  
  376. #ifdef VERBOSE
  377.       IF(verbose)
  378.          fputs("\n\
  379. Cancelling null articles is your idea of fun?  :-)\n\
  380. ", stdout) FLUSH;
  381.       ELSE
  382. #endif
  383.  
  384. #ifdef TERSE
  385.          fputs(nullart, stdout) FLUSH;
  386. #endif
  387.  
  388.       return r;
  389.    }
  390.    reply_buf = fetchlines(art, REPLY_LINE);
  391.    from_buf = fetchlines(art, FROM_LINE);
  392.    artid_buf = fetchlines(art, ARTID_LINE);
  393.    ngs_buf = fetchlines(art, NGS_LINE);
  394.    if (!instr(from_buf, sitename) ||
  395.          (!instr(from_buf, logname) &&
  396.           !instr(reply_buf, logname) &&
  397.  
  398. #ifdef NEWSADMIN
  399.           myuid != newsuid &&
  400. #endif
  401.  
  402.           myuid != ROOTID))
  403.  
  404. #ifdef VERBOSE
  405.       IF(verbose)
  406.          fputs("\nYou can't cancel someone else's article\n", stdout)
  407.          FLUSH;
  408.    ELSE
  409. #endif
  410.  
  411. #ifdef TERSE
  412.       fputs("\nNot your article\n", stdout) FLUSH;
  413. #endif
  414.  
  415.    else
  416.    {
  417.       tmpfp = fopen(headname, "w");     /* open header file */
  418.       if (tmpfp == Nullfp)
  419.       {
  420.          printf(cantcreate, headname) FLUSH;
  421.          goto no_cancel;
  422.       }
  423.       interp(buf, (sizeof buf), getval("CANCELHEADER", CANCELHEADER));
  424.       fputs(buf, tmpfp);
  425.       fclose(tmpfp);
  426.       fputs("\nCanceling...\n", stdout) FLUSH;
  427.       r = doshell(sh, filexp(getval("CANCEL", CANCEL)));
  428.    }
  429. no_cancel:
  430.    free(artid_buf);
  431.    free(ngs_buf);
  432.    free(from_buf);
  433.    free(reply_buf);
  434.    return r;
  435. }
  436.  
  437. void
  438.   reply()
  439. {
  440.    bool incl_body = (*buf == 'R');
  441.    char *maildoer = savestr(filexp(getval("MAILPOSTER", MAILPOSTER)));
  442.  
  443.    artopen(art);
  444.    tmpfp = fopen(headname, "w");        /* open header file */
  445.    if (tmpfp == Nullfp)
  446.    {
  447.       printf(cantcreate, headname) FLUSH;
  448.       goto no_reply;
  449.    }
  450.    interp(buf, (sizeof buf), getval("MAILHEADER", MAILHEADER));
  451.    fputs(buf, tmpfp);
  452.    if (!instr(maildoer, "%h"))
  453.  
  454. #ifdef VERBOSE
  455.       IF(verbose)
  456.          printf("\n%s\n(Above lines saved in file %s)\n", buf, headname)
  457.          FLUSH;
  458.    ELSE
  459. #endif
  460.  
  461. #ifdef TERSE
  462.       printf("\n%s\n(Header in %s)\n", buf, headname) FLUSH;
  463. #endif
  464.  
  465.    if (incl_body && artfp != Nullfp)
  466.    {
  467.       interp(buf, (sizeof buf), getval("YOUSAID", YOUSAID));
  468.       fprintf(tmpfp, "%s\n", buf);
  469.  
  470. #ifdef ASYNC_PARSE
  471.       parse_maybe(art);
  472. #endif
  473.  
  474.       fseek(artfp, (long) htype[PAST_HEADER].ht_minpos, 0);
  475.       while (fgets(buf, LBUFLEN, artfp) != Nullch)
  476.       {
  477.          stripcr(buf);
  478.          fprintf(tmpfp, "%s%s", indstr, buf);
  479.       }
  480.       fprintf(tmpfp, "\n");
  481.    }
  482.    fclose(tmpfp);
  483.    interp(cmd_buf, (sizeof cmd_buf), maildoer);
  484.    invoke(cmd_buf, origdir);
  485.    UNLINK(headname);         /* kill the header file */
  486. no_reply:
  487.    free(maildoer);
  488. }
  489.  
  490. void
  491.   followup()
  492. {
  493.    bool incl_body = (*buf == 'F');
  494.  
  495. #ifdef msdos
  496. /*      char hbuf[LBUFLEN];             /* DOS requires a smaller buffer to prevent stack overflow */
  497. #define hbuf buf
  498. #else
  499.    char hbuf[4 * LBUFLEN];   /* four times the old
  500.                               * size */
  501.  
  502. #endif
  503.  
  504.    artopen(art);
  505.    tmpfp = fopen(headname, "w");
  506.    if (tmpfp == Nullfp)
  507.    {
  508.       printf(cantcreate, headname) FLUSH;
  509.       return;
  510.    }
  511.    interp(hbuf, (sizeof hbuf), getval("NEWSHEADER", NEWSHEADER));
  512.    fprintf(tmpfp, "%s", hbuf);
  513.  
  514. #ifdef msdos
  515.    interp(hbuf, (sizeof hbuf), getval("NEWSHEADER2", NEWSHEADER2));
  516.    fprintf(tmpfp, "%s", hbuf);
  517.    interp(hbuf, (sizeof hbuf), getval("NEWSHEADER3", NEWSHEADER3));
  518.    fprintf(tmpfp, "%s", hbuf);
  519.    interp(hbuf, (sizeof hbuf), getval("NEWSHEADER4", NEWSHEADER4));
  520.    fprintf(tmpfp, "%s", hbuf);
  521.    interp(hbuf, (sizeof hbuf), getval("NEWSHEADER5", NEWSHEADER5));
  522.    fprintf(tmpfp, "%s", hbuf);
  523. #endif
  524.  
  525.    if (incl_body && artfp != Nullfp)
  526.    {
  527.  
  528. #ifdef VERBOSE
  529.       if (verbose)
  530.          fputs("\n\
  531. (Be sure to double-check the attribution against the signature, and\n\
  532. trim the quoted article down as much as possible.)\n\
  533. ", stdout) FLUSH;
  534. #endif
  535.  
  536.       interp(buf, (sizeof buf), getval("ATTRIBUTION", ATTRIBUTION));
  537.       fprintf(tmpfp, "%s\n", buf);
  538.  
  539. #ifdef ASYNC_PARSE
  540.       parse_maybe(art);
  541. #endif
  542.  
  543.       fseek(artfp, (long) htype[PAST_HEADER].ht_minpos, 0);
  544.       while (fgets(buf, LBUFLEN, artfp) != Nullch)
  545.       {
  546.          stripcr(buf);
  547.          fprintf(tmpfp, "%s%s", indstr, buf);
  548.       }
  549.       fprintf(tmpfp, "\n");
  550.    }
  551.    fclose(tmpfp);
  552.    safecpy(cmd_buf, filexp(getval("NEWSPOSTER", NEWSPOSTER)), sizeof cmd_buf);
  553.    invoke(cmd_buf, origdir);
  554.    UNLINK(headname);
  555.  
  556. #ifdef msdos
  557. #undef hbuf
  558. #endif
  559. }
  560.  
  561. void
  562.   invoke(cmd, dir)
  563.    char *cmd, *dir;
  564. {
  565.    if (chdir(dir))
  566.    {
  567.       printerr(dir);
  568.       printf(nocd, dir) FLUSH;
  569.       return;
  570.    }
  571.  
  572. #ifdef VERBOSE
  573.    IF(verbose)
  574.       printf("\n(leaving cbreak mode; cwd=%s)\nInvoking command: %s\n\n",
  575.              dir, cmd) FLUSH;
  576.    ELSE
  577. #endif
  578.  
  579. #ifdef TERSE
  580.       printf("\n(-cbreak; cwd=%s)\nInvoking: %s\n\n", dir, cmd) FLUSH;
  581. #endif
  582.  
  583.    resetty();                /* make terminal
  584.                               * well-behaved */
  585.    doshell(sh, cmd);         /* do the command */
  586.    noecho();                 /* set no echo */
  587.    crmode();                 /* and cbreak mode */
  588.  
  589. #ifdef VERBOSE
  590.    IF(verbose)
  591.       fputs("\n(re-entering cbreak mode)\n", stdout) FLUSH;
  592.    ELSE
  593. #endif
  594.  
  595. #ifdef TERSE
  596.       fputs("\n(+cbreak)\n", stdout) FLUSH;
  597. #endif
  598.  
  599.    /* I think not -- #if defined(SERVER) || defined(msdos) */
  600.  
  601. #if defined(SERVER)
  602.    if (chdir(spool))
  603. #else                        /* not SERVER */
  604.    if (chdir(spool) || chdir(ngdir))
  605. #endif                       /* SERVER */
  606.  
  607.    {
  608.       printerr(ngdir);
  609.       printf(nocd, ngdir) FLUSH;
  610.       sig_catcher(0);
  611.    }
  612. }
  613.