home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / dmail / commands.c next >
Encoding:
C/C++ Source or Header  |  1994-04-13  |  11.3 KB  |  621 lines

  1. /*
  2.  * COMMANDS.C
  3.  *
  4.  *  (C) Copyright 1985-1990 by Matthew Dillon,    All Rights Reserved.
  5.  *
  6.  *  Global Routines:    DO_QUIT()
  7.  *            DO_EXIT()
  8.  *            DO_CD()
  9.  *            DO_ECHO()
  10.  *            DO_GO()
  11.  *            DO_SOURCE()
  12.  *            DO_SHELL()
  13.  *            DO_WRITE()
  14.  *            DO_DELNEXT()
  15.  *            DO_NUMBER()
  16.  *            DO_NEXT()
  17.  *            DO_HEADER()
  18.  *            DO_TYPE()
  19.  *            DO_DELETE()
  20.  *            DO_UNDELETE()
  21.  *            DO_MARK()
  22.  *        DO_BREAK()
  23.  *
  24.  *  Static Routines:    None.
  25.  *
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <sys/file.h>
  31. #include "dmail.h"
  32.  
  33. #define LAST_TYPE   0
  34. #define LAST_HEADER 1
  35.  
  36. static int Last_operation;
  37. static int Last_deleted = -1;
  38. static char ScrBuf[1024];
  39.  
  40. Prototype int  do_quit      (char *garbage, int com);
  41. Prototype int  do_exit      (char *garbage, int com);
  42. Prototype int  do_cd      (char *garbage, int com);
  43. Prototype int  do_echo      (char *str,      int com);
  44. Prototype int  do_go      (char *garbage, int com);
  45. Prototype int  do_source  (char *scratch, int overide);
  46. Prototype int  do_shell   (char *str,      int com);
  47. Prototype int  do_write   (char *garbage, int com);
  48. Prototype int  do_delprev (char *garbage, int com);
  49. Prototype int  do_delnext (char *garbage, int com);
  50. Prototype int  do_number  (char *str,      int com);
  51. Prototype int  do_next      (char *str,      int com);
  52. Prototype int  do_header  (char *garbage, int com);
  53. Prototype int  do_type      (char *garbage, int com);
  54. Prototype int  do_mark      (char *garbage, int mask);
  55. Prototype int  do_unmark  (char *garbage, int mask);
  56. Prototype int  do_break   (char *garbage, int mask);
  57. Prototype int  do_ver      (char *garbage, int level);
  58.  
  59. int
  60. do_quit (char *garbage, int com)
  61. {
  62.     int fd, r, back;
  63.     char *str;
  64.  
  65.     push_break();
  66.     if (get_inode (mail_file) == get_inode (output_file)) {
  67.     back = save_file (0, 0, ST_DELETED | ST_STORED);
  68.     }
  69.     else {
  70.     r = write_file (output_file, O_CREAT, ST_READ, ST_DELETED | ST_STORED);
  71.     if (r < 0) {
  72.         printf ("Unable to write to %s\n", output_file);
  73.         back = save_file (0, 0, ST_DELETED | ST_STORED);
  74.     }
  75.     else {
  76.         back = save_file (0, 0, ST_READ | ST_DELETED | ST_STORED);
  77.     }
  78.     }
  79.     if (back < 0)
  80.     printf ("Unable to update %s\n", mail_file);
  81.     if (back > 0)
  82.     printf ("%d  kept in %s\n", back, mail_file);
  83.     sleep (1);
  84.  
  85.     /*
  86.      *    update access time (UNIX, so shell does not report new mail)
  87.      */
  88.  
  89.     if ((fd = open (mail_file, O_RDONLY, 0)) >= 0) {
  90.     read (fd, Buf, 1);
  91.     close (fd);
  92.     }
  93.     if (!com)
  94.     done (0);
  95.     free_entry();
  96.     if (av[1] == 0) {
  97.     if (!Silence)
  98.         puts ("NO FROM FILE SPECIFIED");
  99.     av[1] = mail_file;
  100.     av[2] = NULL;
  101.     }
  102.     Did_cd = 0;
  103.     mail_file = realloc (mail_file, strlen(av[1]) + 1);
  104.     strcpy (mail_file, av[1]);
  105.     str = (av[2]) ? av[2] : mail_file;
  106.     output_file = realloc (output_file, strlen(str) + 1);
  107.     strcpy (output_file, str);
  108.     initial_load_mail();
  109.     m_select (Nulav, M_RESET);
  110.     pop_break();
  111.     if (!Silence)
  112.     printf ("\nRF %-20s   WF %-20s\n", mail_file, output_file);
  113.     return 0;
  114. }
  115.  
  116. int
  117. do_exit (char *garbage, int com)
  118. {
  119.     char
  120.         *str;
  121.  
  122.     if (!com)
  123.         done (0);
  124.  
  125.     push_break ();
  126.     free_entry ();
  127.     if (av [1] == 0) {
  128.         if (!Silence)
  129.             puts ("NO FROM FILE SPECIFIED");
  130.         av [1] = mail_file;
  131.         av [2] = NULL;
  132.     }
  133.  
  134.     mail_file = realloc (mail_file, strlen (av [1]) + 1);
  135.     strcpy (mail_file, av [1]);
  136.     str = (av [2]) ? av [2] : mail_file;
  137.     output_file = realloc (output_file, strlen (str) + 1);
  138.     strcpy (output_file, str);
  139.     initial_load_mail ();
  140.     m_select (Nulav, M_RESET);
  141.     pop_break ();
  142.     if (!Silence)
  143.         printf ("\nRF %-20s   WF %-20s\n", mail_file, output_file);
  144.     return 0;
  145. }
  146.  
  147. int
  148. do_cd (char *garbage, int com)
  149. {
  150.     char
  151.         *dir = (ac < 2) ? home_dir : av [1];
  152.  
  153.     if (chdir (dir) < 0) {
  154.         printf ("Cannot CD to %s\n", dir);
  155.         return -1;
  156.     }
  157.  
  158.     ++Did_cd;
  159.     return 1;
  160. }
  161.  
  162. int
  163. do_echo (char *str, int com)
  164. {
  165.     puts (next_word (str));
  166.     fflush (stdout);
  167.     return 1;
  168. }
  169.  
  170. int
  171. do_go (char *garbage, int com)
  172. {
  173.     int
  174.         i;
  175.  
  176.     if (ac < 2) {
  177.         puts ("go to which article?");
  178.     }
  179.  
  180.     rewind_range (1);
  181.     i = get_range ();
  182.     if (i < 0) {
  183.         if (!Silence)
  184.             printf ("Message #%ld does not exist\n", i);
  185.         return -1;
  186.     }
  187.  
  188.     if (i == 0) {
  189.         if (!Silence)
  190.             puts ("No Message");
  191.         return -1;
  192.     }
  193.  
  194.     Current = indexof (i);
  195.     return 1;
  196. }
  197.  
  198. int
  199. do_source (char *scratch, int overide)
  200. {
  201.     volatile char
  202.         *comline = xmalloc (1024);
  203.     volatile FILE
  204.         *fi = NULL;
  205.  
  206.     if (ac < 2) {
  207.     puts ("No file argument to source");
  208.     free(comline);
  209.     return -1;
  210.     }
  211.     if (push_base()) {
  212.     push_break();
  213.     pop_base();
  214.     if (fi != NULL)
  215.         fclose (fi);
  216.     free(comline);
  217.     pop_break();
  218.     return -1;
  219.     }
  220.     push_break();
  221.     fi = fopen (av[1], "r");
  222.     pop_break();
  223.     if (fi == NULL) {
  224.     if (!overide)
  225.         printf ("Cannot open %s\n", av[1]);
  226.     free(comline);
  227.     return -1;
  228.     }
  229.     while (fgets (comline, 1024, fi) != NULL) {
  230.     comline[strlen(comline) - 1] = '\0';
  231.     if (comline[0] != '#')
  232.         exec_command (comline);
  233.     }
  234.     push_break();
  235.     fclose (fi);
  236.     fi = NULL;
  237.     free(comline);
  238.     pop_break();
  239.     pop_base();
  240.     return 1;
  241. }
  242.  
  243. int
  244. do_shell (char *str, int com)
  245. {
  246. #ifdef UNIX
  247.     int pid, ret;
  248. #endif
  249.     char *shell, *ptr;
  250.     char *args;
  251.  
  252. #ifdef AMIGA
  253.     shell = "";
  254. #else
  255.     shell = getenv("SHELL");
  256. #endif
  257.     if (shell == NULL)
  258.     shell = "/bin/sh";
  259.     ptr = shell + strlen(shell) - 1;
  260.     while (ptr > shell && *ptr && *ptr != '/')
  261.     --ptr;
  262.     args = (strcmp(ptr, "/sh"))? "-fc" : "-c";
  263.     push_break();
  264.     str = next_word (str);
  265. #ifdef UNIX
  266.     if (strlen (str)) {
  267.     if ((pid = vfork()) == 0) {
  268.         execl (shell, shell, args, str, NULL);
  269.         _exit (1);    /* ifdef UNIX */
  270.     }
  271.     }
  272.     else {
  273.     if ((pid = vfork()) == 0) {
  274.         execl (shell, shell, NULL);
  275.         _exit (1);    /* ifdef UNIX */
  276.     }
  277.     }
  278.     while ((ret = wait(0)) > 0) {
  279.     if (ret == pid)
  280.         break;
  281.     }
  282. #endif
  283. #ifdef AMIGA
  284.     Execute (str, 0, 0);
  285. #endif
  286.     pop_break();
  287.     return 1;
  288. }
  289.  
  290. int
  291. do_write (char *garbage, int com)
  292. {
  293.     char *file;
  294.     int r, count = 0;
  295.     register int i, j;
  296.  
  297.     if (ac < 2) {
  298.         puts ("You must specify at least a file-name");
  299.         return -1;
  300.     }
  301.  
  302.     file = av [1];
  303.     rewind_range (2);
  304.     push_break ();
  305.  
  306.     while (i = get_range ()) {
  307.         j = indexof (i);
  308.         if (j >= 0  &&    !(Entry [j].status & ST_DELETED)) {
  309.             Entry [j].status |= ST_STORED | ST_SCR;
  310.             ++count;
  311.         }
  312.     }
  313.     r = write_file (file, O_CREAT, ST_SCR, 0);
  314.     rewind_range (2);
  315.     if (r > 0) {
  316.         while (i = get_range ()) {
  317.             j = indexof (i);
  318.             if (j >= 0)
  319.                 Entry [j].status &= ~ST_SCR;
  320.         }
  321.         if (!Silence)
  322.             printf ("%d Items written\n", count);
  323.     }
  324.     else {
  325.         while (i = get_range ()) {
  326.             j = indexof (i);
  327.             if (j >= 0)
  328.                 Entry [j].status &= ~(ST_SCR | ST_STORED);
  329.         }
  330.         printf ("Could not write to file %s\n", file);
  331.     }
  332.  
  333.     pop_break ();
  334.     return 1;
  335. }
  336.  
  337. /*
  338.  * DB, added 3 Oct 1988
  339.  */
  340.  
  341. int
  342. do_delprev (char *garbage, int com)
  343. {
  344.     do_mark ("", ST_DELETED);
  345.  
  346.     if (Current)
  347.         return do_next ("", -1);
  348.  
  349.     return -1;
  350. }
  351.  
  352. int
  353. do_delnext (char *garbage, int com)
  354. {
  355.     static int
  356.         warning;
  357.  
  358.     if (!warning  &&  Last_operation == LAST_HEADER) {
  359.         ++warning;
  360.         puts ("Note that the next command is displaying headers only at");
  361.         puts ("this point.  (one-time warning, NOTHING deleted");
  362.         return -1;
  363.     }
  364.  
  365.     if (do_mark ("", ST_DELETED) > 0)
  366.         return do_next ("", 1);
  367.  
  368.     return -1;
  369. }
  370.  
  371. int
  372. do_number (char *str, int com)
  373. {
  374.     int
  375.         x;
  376.  
  377.     x = indexof (atoi (str));
  378.     if (x < 0) {
  379.         puts ("Non-existent message");
  380.         return -1;
  381.     }
  382.  
  383.     Current = x;
  384.     switch (Last_operation) {
  385.         case LAST_TYPE:
  386.             return do_type (NULL, 0);
  387.  
  388.         case LAST_HEADER:
  389.             return do_header (NULL, 0);
  390.  
  391.         default:
  392.             puts ("Internal Error NEXT");
  393.             return -1;
  394.     }
  395.     /* not reached */
  396. }
  397.  
  398. int
  399. do_next (char *str, int com)
  400. {
  401.     int
  402.         ok;
  403.  
  404.     push_break ();
  405.  
  406.     if (com > 0) {
  407.         if (++Current > Entries)
  408.             Current = Entries;
  409.         if (fix () < 0) {
  410.             puts ("End of file");
  411.             pop_break ();
  412.             return -1;
  413.         }
  414.         --com;
  415.     }
  416.  
  417.     if (com < 0) {
  418.         ++com;
  419.         ok = 0;
  420.         while (--Current >= 0) {
  421.             if (Entry [Current].no    &&  !(Entry [Current].status & ST_DELETED)) {
  422.                 ok = 1;
  423.                 break;
  424.             }
  425.         }
  426.         if (!ok) {
  427.             puts ("Start of file");
  428.             Current = 0;
  429.             fix ();
  430.             pop_break ();
  431.             return -1;
  432.         }
  433.     }
  434.  
  435.     pop_break ();
  436.     if (!com) {
  437.         switch (Last_operation) {
  438.             case LAST_TYPE:
  439.                 return do_type (NULL, 0);
  440.  
  441.             case LAST_HEADER:
  442.                 return do_header (NULL, 0);
  443.         }
  444.     }
  445.  
  446.     return 1;
  447. }
  448.  
  449. int
  450. do_header (char *garbage, int com)
  451. {
  452.     Last_operation = LAST_HEADER;
  453.     if (push_base()) {
  454.     push_break();
  455.     pop_base();
  456.     PAGER ((char *) -1);
  457.     rewind(m_fi);
  458.     fflush (stdout);
  459.     pop_break();
  460.     return (-1);
  461.     }
  462.     if (single_position() < 0)
  463.     return (-1);
  464.     if (Current < 0) {
  465.     fprintf (stderr, "Software error #commands.0\n");
  466.     exit (30);
  467.     }
  468.     PAGER (0);
  469.     sprintf (Puf, "MESSAGE HEADER #%d (%d) %s\n",
  470.         Entry[Current].no,
  471.         Current + 1,
  472.         (Entry[Current].status & ST_DELETED) ? "  DELETED" : "");
  473.     PAGER (Puf);
  474.     sprintf (Puf, "From %s\n", Entry[Current].from);
  475.     PAGER (Puf);
  476.     while (fgets (ScrBuf, 1024, m_fi) != NULL) {
  477.     FPAGER (ScrBuf);
  478.     if (*ScrBuf == '\n') {
  479.         PAGER ((char *) -1);
  480.         pop_base();
  481.         return (1);
  482.     }
  483.     }
  484.     PAGER ("END OF FILE ENCOUNTERED");
  485.     PAGER ((char *) -1);
  486.     pop_base();
  487.     return (-1);
  488. }
  489.  
  490. int
  491. do_type (char *garbage, int com)
  492. {
  493.     int i;
  494.  
  495.     Last_operation = LAST_TYPE;
  496.     if (push_base()) {
  497.     push_break();
  498.     pop_base();
  499.     PAGER ((char *) -1);
  500.     rewind(m_fi);
  501.     fflush (stdout);
  502.     pop_break();
  503.     return (-1);
  504.     }
  505.     if (single_position() < 0)
  506.     return (-1);
  507.     if (Current < 0) {
  508.     fprintf (stderr, "Software Error #commands.1\n");
  509.     exit (30);
  510.     }
  511.     if (skip_to_data (m_fi) < 0) {
  512.     printf ("Cannot find data for message %d\n", Entry[Current].no);
  513.     return (-1);
  514.     }
  515.     PAGER (0);
  516.     sprintf (Puf, "MESSAGE TEXT #%d (%d) %s\n",
  517.         Entry[Current].no,
  518.         Current + 1,
  519.         (Entry[Current].status & ST_DELETED) ? "  DELETED" : "");
  520.     PAGER (Puf);
  521.     for (i = 0; i < Listsize; ++i) {
  522.     if (*Entry[Current].fields[header[i]]) {
  523.         sprintf (Puf, "%-10s %s",
  524.             Find[header[i]].search,
  525.             Entry[Current].fields[header[i]]);
  526.         PAGER (Puf);
  527.     }
  528.     }
  529.     PAGER ("");
  530.     while ((fgets (ScrBuf, 1024, m_fi) != NULL)  &&  strncmp (ScrBuf, "From ", 5))
  531.     FPAGER (ScrBuf);
  532.     Entry[Current].status |= ST_READ;
  533.     PAGER ((char *) -1);
  534.     pop_base();
  535.     return (1);
  536. }
  537.  
  538. int
  539. do_mark (char *garbage, int mask)
  540. {
  541.     int count = 0;
  542.     register int i, j;
  543.  
  544.     rewind_range (1);
  545.     push_break();
  546.     while (i = get_range()) {
  547.     j = indexof (i);
  548.     if (j >= 0) {
  549.         if (mask & ST_DELETED)
  550.         Last_deleted = j;
  551.         if ((Entry[j].status & mask) != mask) {
  552.         Entry[j].status |= mask;
  553.         if (Entry[j].status & ST_DELETED)
  554.             Entry[j].status &= ~(ST_STORED | ST_READ | ST_TAG);
  555.         ++count;
  556.         }
  557.     }
  558.     }
  559.     if (!Silence)
  560.     printf ("%d  Items\n", count);
  561.     pop_break();
  562.     return (1);
  563. }
  564.  
  565. int
  566. do_unmark (char *garbage, int mask)
  567. {
  568.     int count = 0;
  569.     register int i, j;
  570.     register struct ENTRY *en;
  571.  
  572.     push_break();
  573.     if (ac == 1 && (mask & ST_DELETED) && Last_deleted != -1)  {
  574.     en = &Entry[Last_deleted];
  575.     if (en->no) {
  576.         en->status &= ~mask;
  577.         printf ("Undeleted last deleted message (# %d)\n", en->no);
  578.         Current = Last_deleted;
  579.         Last_deleted = -1;
  580.     } else {
  581.         printf ("Last deleted message not within current select bounds\n");
  582.         pop_break();
  583.         return (-1);
  584.     }
  585.     pop_break();
  586.     return (1);
  587.     }
  588.     rewind_range (1);
  589.     while (i = get_range()) {
  590.     j = indexof (i);
  591.     if (j >= 0) {
  592.         if (Entry[j].status & mask) {
  593.         Entry[j].status &= ~mask;
  594.         ++count;
  595.         }
  596.     }
  597.     }
  598.     if (!Silence)
  599.     printf ("%d  Items\n", count);
  600.     pop_break();
  601.     return (1);
  602. }
  603.  
  604. int
  605. do_break (char *garbage, int mask)
  606. {
  607.     if (mask)
  608.         pop_break ();
  609.     else
  610.         push_break ();
  611.  
  612.     return 1;
  613. }
  614.  
  615. int
  616. do_ver (char *garbage, int level)
  617. {
  618.     puts (DVERSION);
  619.     return 0;
  620. }
  621.