Annotation of coherent/g/usr/bin/vi/elvprsv.c, revision 1.1.1.1

1.1       root        1: /* elvprsv.c */
                      2: 
                      3: /* Author:
                      4:  *     Steve Kirkendall
                      5:  *     14407 SW Teal Blvd. #C
                      6:  *     Beaverton, OR 97005
                      7:  *     [email protected]
                      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
                     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
                    260:        /* expand any wildcards in the command line */
                    261:        _ct_init("");
                    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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.