home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / dotilde.c < prev    next >
Text File  |  1994-09-25  |  17KB  |  593 lines

  1. /*  dotilde.c   This program handles the ~ commands from mailx and postnews.
  2.     Copyright (C) 1990, 1993  Rick Adams and Bob Billson
  3.  
  4.     This file is part of the OS-9 UUCP package, UUCPbb.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     The author of UUCPbb, Bob Billson, can be contacted at:
  21.     bob@kc2wz.bubble.org  or  uunet!kc2wz!bob  or  by snail mail:
  22.     21 Bates Way, Westfield, NJ 07090
  23. */
  24.  
  25. /* Handle ~ commands from mail and postnews.  Made into a separate program
  26.    for the CoCo to save keep mail and postnews smaller --REB
  27.  
  28.    args passed to us in the order:
  29.         command t2flag myuid quotechar letter homedir message  */
  30.  
  31. #define MAIN
  32.  
  33. #include "uucp.h"
  34. #include <signal.h>
  35. #ifndef _OSK
  36. #include <os9.h>
  37. #endif
  38.  
  39. #define SHOWLINES  6              /* lines to show on screen with ~r and ~m */
  40.  
  41. #ifndef TERMCAP
  42. QQ flag t2flag, winopen = FALSE;
  43. #endif
  44. QQ unsigned myuid;
  45. char dline[256];
  46. long _gs_size();
  47. int interrupt();
  48.  
  49.  
  50. main (argc, argv)
  51. int argc;
  52. char **argv;
  53. {
  54.      char cmd[80], from[256], msgid[100], command[128];
  55.      char *letter, *message, quotechar, *fname, c, *p, *words[3];
  56.      FILE *infile, *outfile;
  57.      register char *doline;
  58.      flag douuencode = TRUE;
  59.      char *errmsg = "ERROR--",
  60.           *reopen = "can't reopen letter file\n",
  61.           *required = "a filename is required...\n",
  62.           *editor;                           /* moved from getparam.c --REB */
  63.  
  64.      pflinit();                              /* longs will be printed */
  65.      intercept (interrupt);
  66.      ++argv;
  67.      strcpy (command, *argv++);
  68. #ifndef TERMCAP
  69.      t2flag = atoi (*argv);
  70. #endif
  71.      ++argv;
  72.      myuid = atoi (*argv++);
  73.      quotechar = **argv;
  74.      letter = *(++argv);
  75.      homedir = *(++argv);
  76.      message = argc == 8 ? *(++argv) : NULL;
  77.      doline = dline;
  78.      editor = NULL;
  79.  
  80.      switch (*(command + 1))
  81.        {
  82.           /* ~v: edit letter with "vi" */
  83.           case 'v':
  84.           case 'V':
  85.                sprintf (cmd, "vi %s", letter);
  86.  
  87.                if (docmd_na (cmd) != 0)
  88.                     sleep (2);
  89.                break;
  90.  
  91.           /* ~e: edit letter with appropriate editor */
  92.           case 'e':
  93.           case 'E':
  94. #ifndef _OSK
  95.                sprintf (doline, "%s/%s/%s", homedir, uudir, _MAILRC);
  96. #else
  97.                sprintf (doline, "%s/%s", homedir, _MAILRC);
  98. #endif
  99.                if ((infile = fopen (doline, "r")) != NULL)
  100.                  {
  101.                     while (mfgets (doline, sizeof (dline), infile) != NULL)
  102.                          if (getargs (words, dline, 3) == 3)
  103.                               if (strucmp ("editor", *words) == 0)
  104.                                 {
  105.                                    editor = strdup (words[2]);
  106.                                    break;
  107.                                 }
  108.                     fclose (infile);
  109.                  }
  110.  
  111.                if (editor == NULL)
  112.                     if ((editor = getenv ("EDITOR")) == NULL)
  113.                       {
  114.                          puts ("EDITOR is undefined");
  115.                          break;
  116.                       }
  117.                sprintf (cmd, "%s %s", editor, letter);
  118.                docmd_na (cmd);
  119.                free (editor);
  120.                break;
  121.  
  122.           /* ~R: append contents of file to letter NO attempt to uuencode */
  123.           case 'R':
  124.                douuencode = FALSE;
  125.  
  126.           /* ~r: append contents of file to letter, uuencode if binary */
  127.           case 'r':
  128.                if (*(command + 2) != '\0')
  129.                     fname = skipspace (command + 3);
  130.                else
  131.                     *fname = '\0';
  132.  
  133.                if (*fname == '\0')
  134.                  {
  135.                     printf ("%s%s", errmsg, required);
  136.                     break;
  137.                  }
  138.  
  139.                if ((p = strchr (command, '\n')) != NULL)
  140.                     *p = '\0';
  141.  
  142.                if (douuencode  &&  (p = strrchr (fname, '.')) != NULL)
  143.                  {
  144.                     ++p;
  145.  
  146.                     if (isbin (fname, letter, p) == TRUE)
  147.                          break;
  148.                  }
  149.                asetuid (0);
  150.  
  151.                if ((infile = fopen (fname, "r")) != NULL)
  152.                     if ((outfile = fopen (letter, "a")) != NULL)
  153.                       {
  154.                          asetuid (myuid);
  155.                          printf ("\nAppending file: %s\n\n", fname);
  156.                          c = *(command + 2) == ' '  ? '\0'  : *(command + 2);
  157.                          appendtext (infile, outfile, c, FALSE);
  158.                       }
  159.                     else
  160.                       {
  161.                          fclose (infile);
  162.                          printf ("%s%s", errmsg, reopen);
  163.                       }
  164.                else
  165.                     printf ("%scan't open file: %s\n", errmsg, fname);
  166.                break;
  167.  
  168.           /* ~m: append the message we're replying to */
  169.           case 'm':
  170.           case 'M':
  171.                asetuid (0);
  172.                if (message == NULL)
  173.                  {
  174.                     printf ("%sno message read yet\n", errmsg);
  175.                     break;
  176.                  }
  177.  
  178.                if ((infile = fopen (message, "r")) != NULL)
  179.                     if ((outfile = fopen (letter, "a")) != NULL)
  180.                       {
  181.                          asetuid (myuid);
  182.                          *from = *msgid = '\0';
  183.                       }
  184.                     else
  185.                       {
  186.                          fclose (infile);
  187.                          printf ("%s%s - %d", errmsg, reopen,errno);
  188.                          break;
  189.                       }
  190.                else
  191.                  {
  192.                     printf ("%scan't open: %s ...%d\n", errmsg, message,errno);
  193.                     break;
  194.                  }
  195.  
  196.                while (mfgets (doline, sizeof (dline), infile) != NULL)
  197.                  {
  198.                     if (*doline == '\0')
  199.                          break;
  200.                     else if (*doline == 'F'  && *from == '\0'
  201.                          && strnucmp (doline, "From: ", 6) == 0)
  202.                       {
  203.                          strncpy (from, &dline[6], sizeof (from));
  204.                          from[sizeof (from) - 1] = '\0';
  205.                       }
  206.                     else if (*doline == 'M'  &&  *msgid == '\0'
  207.                          && strnucmp (doline,"Message-Id: ",12) == 0)
  208.                       {
  209.                          strncpy (msgid, &dline[12], sizeof (msgid));
  210.                          msgid[sizeof (msgid) - 1] = '\0';
  211.                       }
  212.                     else if (*doline == 'R')
  213.                          if (strnucmp (doline, "Resent-From: ", 13) == 0)
  214.                            {
  215.                               strncpy (from, &dline[13], sizeof (from));
  216.                               from[sizeof (from) - 1] = '\0';
  217.                            }
  218.                          else if (strnucmp (doline, "Resent-Message-Id: ", 19)
  219.                                    == 0)
  220.                            {
  221.                               strncpy (msgid, &dline[19], sizeof (msgid));
  222.                               msgid[sizeof (msgid) - 1] = '\0';
  223.                            }
  224.                  }
  225.  
  226.                if (*msgid != '\0'  &&  *from != '\0' &&
  227.                       (strlen (msgid) + strlen (from)) < 70)
  228.                  {
  229.                     fprintf (outfile, "In %s, ", msgid);
  230.                     printf ("In %s, ", msgid);
  231.                  }
  232.  
  233.                if (*from != '\0')
  234.                  {
  235.                     sprintf (doline, "%s says:\n", skipspace (from));
  236.                     fputs (doline, outfile);
  237.                     fputs (doline, stdout);
  238.                  }
  239.  
  240.                /* if no quote character is given default is */
  241.                /* given in global quotechar.  Changed --REB */
  242.  
  243.                switch (*(command + 2))
  244.                  {
  245.                     case '\0':
  246.                     case '\n':
  247.                          c = quotechar;
  248.                          break;
  249.  
  250.                     case ' ':
  251.                          c = '\0';
  252.                          break;
  253.  
  254.                     default:
  255.                          c = *(command + 2);
  256.                          break;
  257.                  }
  258.  
  259.                appendtext (infile, outfile, c, TRUE);
  260.                break;
  261.  
  262.           /* ~h: help command */
  263.           case '?':
  264.           case 'h':
  265.           case 'H':
  266.                editor = getenv ("EDITOR");
  267. #ifndef TERMCAP
  268.                if (!t2flag)
  269.                     popdoublewindow (30, 0, 48, 15);
  270.  
  271.                putdashes (17);
  272.                fputs (" Tilde Help", stdout);
  273.                putdashes (17);
  274.                putchar ('\n');
  275. #else
  276.                puts ("\n================= Tilde Help =================");
  277. #endif
  278.                puts (" ~h, ~?       this help message");
  279.                puts (" ~m[c]        append message being replied to");
  280.                puts ("                preface each line with char c");
  281.                printf ("                default is %c\n", quotechar);
  282.                puts (" ~r[c] <file> append 'file', preface each line");
  283.                puts ("                with char c, uuencode binaries");
  284.                puts (" ~R[c] <file> same as ~r, 'file' NOT uuencoded");
  285.                puts (" ~v           edit message with vi");
  286.                printf (" ~e           edit message with %s\n",
  287.                        editor != NULL ? editor : "UNDEFINED");
  288.                puts (" ~q, ~x       exit immediately");
  289.                puts (" ~!           fork a shell");
  290.                puts (" ~a           abort sending current message");
  291.                puts (" ~u <file>    uuencode 'file' before appending");
  292.  
  293. #ifndef TERMCAP
  294.                if (!t2flag)
  295.                  {
  296.                     putdashes (46);
  297.                     read (0, &c, 1);
  298.                     closedoublewindow();
  299.                     CurUp();
  300.                     CurUp();
  301.                  }
  302. #else
  303.                putdashes (46);
  304.                puts ("\n");
  305. #endif
  306.                break;
  307.  
  308.           /* ~q, ~x: exit command.  Cleanup after ourself -- REB */
  309.           case 'q':
  310.           case 'x':
  311.                interrupt (SIGQUIT);
  312.  
  313.           /* ~!: fork a shell --REB */
  314.           case '!':
  315.                forkshell();
  316.                CurUp();
  317.                CurUp();
  318.                break;
  319.  
  320.           /* ~a: abort sending message --REB */
  321.           case 'a':
  322.           case 'A':
  323.                fputs ("Abort sending this message?  y/N ", stdout);
  324.                fflush (stdout);
  325.                read (0, &c, 1);
  326.  
  327.                if (tolower (c) == 'y')
  328.                  {
  329.                     putchar ('\n');
  330.                     exit (ABORT);
  331.                  }
  332.                CurUp();
  333.                putchar ('\n');
  334.                ErEOLine();
  335.                CurUp();
  336.                CurUp();
  337.                break;
  338.  
  339.           /* ~u: uuencode and append a file --REB */
  340.           case 'u':
  341.           case 'U':
  342.                if (*(command + 2))
  343.                     fname = skipspace (command + 3);
  344.                else
  345.                     *fname = '\0';
  346.  
  347.                if (*fname == '\0')
  348.                  {
  349.                     printf ("%s%s", errmsg, required);
  350.                     break;
  351.                  }
  352.  
  353.                if ((p = strchr (command, '\n')) != NULL)
  354.                     *p = '\0';
  355.  
  356.                if (uuencodeit (fname, letter) == FALSE)
  357.                     printf ("%scan't uuencode %s ...error %d\n",
  358.                              errmsg, fname, errno);
  359.                break;
  360.  
  361.           default:
  362.                puts ("Unrecognized tilde command");
  363.                break;
  364.        }
  365.      asetuid (myuid);
  366.      puts ("\nContinuing...type \".\" or <ESC> to end message...");
  367.      exit (0);
  368. }
  369.  
  370.  
  371.  
  372. /* Append message or different file to current outgoing mail.  If the file
  373.    larger than 500 bytes, only the first six lines are shown on the screen
  374.    Boisy Pitre suggested this idea. */
  375.  
  376. int appendtext (infile, outfile, quote, fixln)
  377. FILE *infile, *outfile;
  378. char quote;
  379. int fixln;
  380. {
  381.      register char *doline;
  382.      int linecount, showlines;
  383.      long filesize;
  384.  
  385.      linecount = SHOWLINES;
  386.      doline = dline;
  387.  
  388.      filesize = _gs_size (fileno (infile));
  389.      showlines = (filesize > 500L)  ?  FALSE : TRUE;
  390.  
  391.      while (mfgets (doline, sizeof (dline), infile) != NULL)
  392.        {
  393.           if (fixln)
  394.                fixline (dline);
  395.  
  396.           if (quote != '\0')
  397.                putc (quote, outfile);
  398.  
  399.           fprintf (outfile, "%s\n", doline);
  400.  
  401.           if (showlines)
  402.             {
  403.                if (quote != '\0')
  404.                     putc (quote, outfile);
  405.  
  406.                puts (doline);
  407.             }
  408.           else
  409.                if (linecount)
  410.                  {
  411.                     if (quote != '\0')
  412.                          putchar (quote);
  413.  
  414.                     puts (doline);
  415.                     --linecount;
  416.  
  417.                     if (linecount == 0)
  418.                       {
  419.                          fputs ("\n  [appending rest of text...", stdout);
  420.  
  421.                          if (filesize > 2000L)
  422.                               printf ("%ld bytes", filesize);
  423.  
  424.                          fputs ("]  ", stdout);
  425.                          fflush (stdout);
  426.                       }
  427.                  }
  428.        }
  429.      fclose (infile);
  430.      fclose (outfile);
  431.  
  432.      if (!showlines)
  433.           putchar ('\n');
  434. }
  435.  
  436.  
  437.  
  438. int putdashes (howmany)
  439. int howmany;
  440. {
  441.      register int i;
  442.  
  443.      putchar (' ');
  444.  
  445.      for (i = 0; i < howmany; ++i)
  446.           putchar ('=');
  447.  
  448.      fflush (stdout);
  449. }
  450.  
  451.  
  452.  
  453. int isbin (source, letter, ext)
  454. char *source, *ext, *letter;
  455. {
  456.      register char *p;
  457.      FILE *fp;
  458.      int extlen = strlen (ext);
  459.  
  460.      p = dline;
  461.      sprintf (p, "%s/bin.list", UUCPSYS);
  462.  
  463.      if ((fp = fopen (p, "r")) == NULL)
  464.           return (FALSE);
  465.  
  466.      while (mfgets (p, sizeof (dline), fp) != NULL)
  467.           if (strnucmp (p, ext, extlen) == 0)
  468.             {
  469.                fclose (fp);
  470.                return (uuencodeit (source, letter));
  471.             }
  472.      fclose (fp);
  473.      return (FALSE);
  474. }
  475.  
  476.  
  477.  
  478. int uuencodeit (source, letter)
  479. char *source, *letter;
  480. {
  481.      register int saveout;
  482.      int result;
  483.      char *p, *dash = "---------------";
  484.  
  485.      printf ("uuencoding %s...", source);
  486.      fflush (stdout);
  487.  
  488.      if (access (source, READ) == ERROR)
  489.           return (FALSE);
  490.  
  491.      /* save standard output */
  492.      saveout = dup (STDOUT);
  493.      
  494.      /* try to redirect standard output */
  495.      close (STDOUT);
  496.      
  497.      if (open (letter, WRITE) != STDOUT)
  498.        {
  499.           fprintf (stderr, "PANIC! can't redirect standard output to %s\n",
  500.                            letter);
  501.           dup (saveout);
  502.           close (saveout);
  503.           return (FALSE);
  504.        }
  505.  
  506.      lseek (STDOUT, _gs_size (STDOUT), FRONT);
  507.      p = strrchr (source, '/');
  508.      sprintf (dline, "%s %s %s\n", dash, p != NULL ? ++p : source, dash);
  509.      write (STDOUT, dline, strlen (dline));
  510.      sprintf (dline, "uuencode %s %s", source, source);
  511.      result = docmd_na (dline);
  512.      close (STDOUT);
  513.      dup (saveout);
  514.      close (saveout);
  515.      asetuid (myuid);
  516.      return (result == 0 ? TRUE : FALSE);
  517. }
  518.  
  519.  
  520.  
  521. int interrupt (sig)
  522. int sig;
  523. {
  524. #ifndef TERMCAP
  525.      if (winopen)
  526.           return;
  527. #endif
  528.      exit (sig);
  529. }
  530.  
  531.  
  532.  
  533. #ifndef TERMCAP
  534. /* open double overlay windows for keyboard user--white on red over black on
  535.    black.  Shouldn't be called if using CoCo TERMCAP.  */
  536.  
  537. int popdoublewindow (x, y, width, height)
  538. int x, y, width, height;
  539. {
  540.      char outstr[18];
  541.  
  542.      /* turn off the cursor */
  543.      CurOff();
  544.  
  545.      outstr[0] = outstr[9]  = 0x1b;
  546.      outstr[1] = outstr[10] = 0x22;
  547.      outstr[2] = outstr[11] = 1;
  548.      outstr[5] = outstr[14] = width;
  549.      outstr[6] = outstr[15] = height;
  550.  
  551.      /* bottom window */
  552.      outstr[3] = x + 1;                    /* offset bottom window */
  553.      outstr[4] = y + 1;
  554.      outstr[7] = 2;                        /* black on black */
  555.      outstr[8] = 2;
  556.  
  557.      /* top window */
  558.      outstr[12] = x;
  559.      outstr[13] = y;
  560.      outstr[16] = 0;                        /* white on red */
  561.      outstr[17] = 4;
  562.  
  563.      write (1, outstr, sizeof (outstr));
  564.  
  565. #ifndef TERMCAP
  566.      winopen = TRUE;
  567. #endif
  568. }
  569.  
  570.  
  571.  
  572. /* Close double overlay window */
  573.  
  574. int closedoublewindow()
  575. {
  576.      write (1, "\x1b\x23\x1b\x23", 4);
  577.      resetline();
  578.  
  579. #ifndef TERMCAP
  580.      winopen = FALSE;
  581. #endif
  582. }
  583.  
  584.  
  585.  
  586. int resetline()
  587. {
  588.      puts ("\b  ");
  589.      CurUp();
  590.      CurOn();
  591. }
  592. #endif
  593.