|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.