home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / apps / text_ed / elv16b2 / st / elvprsv.c < prev    next >
C/C++ Source or Header  |  1992-05-13  |  7KB  |  296 lines

  1. /* elvprsv.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  8.  */
  9.  
  10.  
  11. /* This file contains the portable sources for the "elvprsv" program.
  12.  * "Elvprsv" is run by Elvis when Elvis is about to die.  It is also
  13.  * run when the computer boots up.  It is not intended to be run directly
  14.  * by the user, ever.
  15.  *
  16.  * Basically, this program does the following four things:
  17.  *    - It extracts the text from the temporary file, and places the text in
  18.  *    a file in the /usr/preserve directory.
  19.  *    - It adds a line to the /usr/preserve/Index file, describing the file
  20.  *    that it just preserved.
  21.  *    - It removes the temporary file.
  22.  *    -    It sends mail to the owner of the file, saying that the file was
  23.  *    preserved, and how it can be recovered.
  24.  *
  25.  * The /usr/preserve/Index file is a log file that contains one line for each
  26.  * file that has ever been preserved.  Each line of this file describes one
  27.  * preserved file.  The first word on the line is the name of the file that
  28.  * contains the preserved text.  The second word is the full pathname of the
  29.  * file that was being edited; for anonymous buffers, this is the directory
  30.  * name plus "/foo".
  31.  *
  32.  * If elvprsv's first argument (after the command name) starts with a hyphen,
  33.  * then the characters after the hyphen are used as a description of when
  34.  * the editor went away.  This is optional.
  35.  *
  36.  * The remaining arguments are all the names of temporary files that are
  37.  * to be preserved.  For example, on a UNIX system, the /etc/rc file might
  38.  * invoke it this way:
  39.  *
  40.  *    elvprsv "-the system went down" /tmp/elv_*.*
  41.  *
  42.  * This file contains only the portable parts of the preserve program.
  43.  * It must #include a system-specific file.  The system-specific file is
  44.  * expected to define the following functions:
  45.  *
  46.  *    char *ownername(char *filename)    - returns name of person who owns file
  47.  *
  48.  *    void mail(char *user, char *name, char *when)
  49.  *                    - tell user that file was preserved
  50.  */
  51.  
  52. #include <stdio.h>
  53. #include "config.h"
  54. #include "vi.h"
  55. #include "ctype.h"
  56.  
  57. void preserve P_((char *, char *));
  58. void main P_((int, char **));
  59.  
  60. #if AMIGA
  61. BLK tmpblk;
  62. # include "amiwild.c"
  63. # include "amiprsv.c"
  64. #endif
  65.  
  66. #if OSK
  67. # undef sprintf
  68. #endif
  69.  
  70. #if ANY_UNIX || OSK
  71. # include "prsvunix.c"
  72. #endif
  73.  
  74. #if MSDOS || TOS || MINT
  75. # include "prsvdos.c"
  76. # define WILDCARD_NO_MAIN
  77. # include "wildcard.c"
  78. #endif
  79.  
  80.  
  81. BLK    buf;
  82. BLK    hdr;
  83. BLK    name;
  84. int    rewrite_now;    /* boolean: should we send text directly to orig file? */
  85.  
  86.  
  87.  
  88. /* This function preserves a single file, and announces its success/failure
  89.  * via an e-mail message.
  90.  */
  91. void preserve(tname, when)
  92.     char    *tname;        /* name of a temp file to be preserved */
  93.     char    *when;        /* description of when the editor died */
  94. {
  95.     int    infd;        /* fd used for reading from the temp file */
  96.     FILE    *outfp;        /* fp used for writing to the recovery file */
  97.     FILE    *index;        /* fp used for appending to index file */
  98.     char    outname[100];    /* the name of the recovery file */
  99.     char    *user;        /* name of the owner of the temp file */
  100. #if AMIGA
  101.     char    *prsvdir;
  102. #endif
  103.     int    i;
  104.  
  105.     /* open the temp file */
  106.     infd = open(tname, O_RDONLY|O_BINARY);
  107.     if (infd < 0)
  108.     {
  109.         /* if we can't open the file, then we should assume that
  110.          * the filename contains wildcard characters that weren't
  111.          * expanded... and also assume that they weren't expanded
  112.          * because there are no files that need to be preserved.
  113.          * THEREFORE... we should silently ignore it.
  114.          * (Or loudly ignore it if the user was using -R)
  115.          */
  116.         if (rewrite_now)
  117.         {
  118.             perror(tname);
  119.         }
  120.         return;
  121.     }
  122.  
  123.     /* read the header and name from the file */
  124.     if (read(infd, hdr.c, BLKSIZE) != BLKSIZE
  125.      || read(infd, name.c, BLKSIZE) != BLKSIZE)
  126.     {
  127.         /* something wrong with the file - sorry */
  128.         fprintf(stderr, "%s: truncated header blocks\n", tname);
  129.         close(infd);
  130.         return;
  131.     }
  132.  
  133.     /* If the filename block contains an empty string, then Elvis was
  134.      * only keeping the temp file around because it contained some text
  135.      * that was needed for a named cut buffer.  The user doesn't care
  136.      * about that kind of temp file, so we should silently delete it.
  137.      */
  138.     if (name.c[0] == '\0' && name.c[1] == '\177')
  139.     {
  140.         close(infd);
  141.         unlink(tname);
  142.         return;
  143.     }
  144.  
  145.     if (rewrite_now)
  146.     {
  147.         /* we don't need to open the index file */
  148.         index = (FILE *)0;
  149.  
  150.         /* make sure we can read every block! */
  151.         for (i = 1; i < MAXBLKS && hdr.n[i]; i++)
  152.         {
  153.             lseek(infd, (long)hdr.n[i] * (long)BLKSIZE, 0);
  154.             if (read(infd, buf.c, BLKSIZE) != BLKSIZE)
  155.             {
  156.                 /* messed up header */
  157.                 fprintf(stderr, "%s: unrecoverable -- header trashed\n", name.c);
  158.                 close(infd);
  159.                 return;
  160.             }
  161.         }
  162.  
  163.         /* open the user's file for writing */
  164.         outfp = fopen(name.c, "w");
  165.         if (!outfp)
  166.         {
  167.             perror(name.c);
  168.             close(infd);
  169.             return;
  170.         }
  171.     }
  172.     else
  173.     {
  174.         /* open/create the index file */
  175.         index = fopen(PRSVINDEX, "a");
  176.         if (!index)
  177.         {
  178.             perror(PRSVINDEX);
  179.             exit(2);
  180.         }
  181.  
  182.         /* should be at the end of the file already, but MAKE SURE */
  183.         fseek(index, 0L, 2);
  184.  
  185.         /* create the recovery file in the PRESVDIR directory */
  186. #if AMIGA
  187.         prsvdir = &PRSVDIR[strlen(PRSVDIR) - 1];
  188.         if (*prsvdir == '/' || *prsvdir == ':')
  189.         {
  190.             sprintf(outname, "%sp%ld", PRSVDIR, ftell(index));
  191.         }
  192.         else
  193. #endif
  194.         sprintf(outname, "%s%cp%ld", PRSVDIR, SLASH, ftell(index));
  195.         outfp = fopen(outname, "w");
  196.         if (!outfp)
  197.         {
  198.             perror(outname);
  199.             close(infd);
  200.             fclose(index);
  201.             return;
  202.         }
  203.     }
  204.  
  205.     /* write the text of the file out to the recovery file */
  206.     for (i = 1; i < MAXBLKS && hdr.n[i]; i++)
  207.     {
  208.         lseek(infd, (long)hdr.n[i] * (long)BLKSIZE, 0);
  209.         if (read(infd, buf.c, BLKSIZE) != BLKSIZE)
  210.         {
  211.             /* messed up header */
  212.             fprintf(stderr, "%s: unrecoverable -- header trashed\n", name.c);
  213.             fclose(outfp);
  214.             close(infd);
  215.             if (index)
  216.             {
  217.                 fclose(index);
  218.             }
  219.             unlink(outname);
  220.             return;
  221.         }
  222.         fputs(buf.c, outfp);
  223.     }
  224.  
  225.     /* add a line to the index file */
  226.     if (index)
  227.     {
  228.         fprintf(index, "%s %s\n", outname, name.c);
  229.     }
  230.  
  231.     /* close everything */
  232.     close(infd);
  233.     fclose(outfp);
  234.     if (index)
  235.     {
  236.         fclose(index);
  237.     }
  238.  
  239.     /* Are we doing this due to something more frightening than just
  240.      * a ":preserve" command?
  241.      */
  242.     if (*when)
  243.     {
  244.         /* send a mail message */
  245.         mail(ownername(tname), name.c, when);
  246.  
  247.         /* remove the temp file -- the editor has died already */
  248.         unlink(tname);
  249.     }
  250. }
  251.  
  252. void main(argc, argv)
  253.     int    argc;
  254.     char    **argv;
  255. {
  256.     int    i;
  257.     char    *when = "the editor went away";
  258.  
  259. #if MSDOS || TOS || MINT
  260.     _ct_init("");
  261.     /* expand any wildcards in the command line */
  262.     argv = wildexpand(&argc, argv);
  263. #endif
  264.  
  265.     /* do we have a "when" argument? */
  266.     i = 1;
  267.     if (argc >= i + 1 && !strcmp(argv[i], "-R"))
  268.     {
  269.         rewrite_now = 1;
  270.         when = "";
  271.         i++;
  272. #if ANY_UNIX
  273.         setuid(geteuid());
  274. #endif
  275.     }
  276. #if OSK
  277.     else
  278.     {
  279.         setuid(0);
  280.     }
  281. #endif
  282.     if (argc >= i + 1 && argv[i][0] == '-')
  283.     {
  284.         when = argv[i] + 1;
  285.         i++;
  286.     }
  287.  
  288.     /* preserve everything we're supposed to */
  289.     while (i < argc)
  290.     {
  291.         preserve(argv[i], when);
  292.         i++;
  293.     }
  294.     exit(0);
  295. }
  296.