|
|
1.1 root 1: /* elvrec.c */
2:
3: /* This file contains the file recovery program */
4:
5: /* Author:
6: * Steve Kirkendall
7: * 14407 SW Teal Blvd. #C
8: * Beaverton, OR 97005
9: * [email protected]
10: */
11:
12:
13: #include <stdio.h>
14: #include "config.h"
15: #include "vi.h"
16:
17: void recover P_((char *, char *));
18: void main P_((int, char **));
19:
20:
21: void recover(basename, outname)
22: char *basename; /* the name of the file to recover */
23: char *outname; /* the name of the file to write to */
24: {
25: char pathname[500]; /* full pathname of the file to recover */
26: char line[600]; /* a line from the /usr/preserve/Index file */
27: int ch; /* a character from the text being recovered */
28: FILE *from; /* the /usr/preserve file, or /usr/preserve/Index */
29: FILE *to; /* the user's text file */
30: char *ptr;
31: #if OSK
32: int uid;
33: #endif
34:
35: /* convert basename to a full pathname */
36: if (basename)
37: {
38: #ifndef CRUNCH
39: # if MSDOS || TOS
40: if (!basename[0] || basename[1] != ':')
41: # else
42: if (basename[0] != SLASH)
43: # endif
44: {
45: ptr = getcwd(pathname, sizeof pathname);
46: if (ptr != pathname)
47: {
48: strcpy(pathname, ptr);
49: }
50: ptr = pathname + strlen(pathname);
51: *ptr++ = SLASH;
52: strcpy(ptr, basename);
53: }
54: else
55: #endif
56: {
57: strcpy(pathname, basename);
58: }
59: }
60:
61: #if OSK
62: uid = getuid();
63: if(setuid(0))
64: exit(_errmsg(errno, "Can't set uid\n"));
65: #endif
66: /* scan the /usr/preserve/Index file, for the *oldest* unrecovered
67: * version of this file.
68: */
69: from = fopen(PRSVINDEX, "r");
70: while (from && fgets(line, sizeof line, from))
71: {
72: /* strip off the newline from the end of the string */
73: line[strlen(line) - 1] = '\0';
74:
75: /* parse the line into a "preserve" name and a "text" name */
76: for (ptr = line; *ptr != ' '; ptr++)
77: {
78: }
79: *ptr++ = '\0';
80:
81: /* If the "preserve" file is missing, then ignore this line
82: * because it describes a file that has already been recovered.
83: */
84: if (access(line, 0) < 0)
85: {
86: continue;
87: }
88:
89: /* are we looking for a specific file? */
90: if (basename)
91: {
92: /* quit if we found it */
93: if (!strcmp(ptr, pathname))
94: {
95: break;
96: }
97: }
98: else
99: {
100: /* list this file as "available for recovery" */
101: puts(ptr);
102: }
103: }
104:
105: /* file not found? */
106: if (!basename || !from || feof(from))
107: {
108: if (from != NULL) fclose(from);
109: if (basename)
110: {
111: fprintf(stderr, "%s: no recovered file has that exact name\n", pathname);
112: }
113: return;
114: }
115: if (from != NULL) fclose(from);
116:
117: /* copy the recovered text back into the user's file... */
118:
119: /* open the /usr/preserve file for reading */
120: from = fopen(line, "r");
121: if (!from)
122: {
123: perror(line);
124: exit(2);
125: }
126:
127: #if ANY_UNIX
128: /* Be careful about user-id. We want to be running under the user's
129: * real id when we open/create the user's text file... but we want
130: * to be superuser when we delete the /usr/preserve file. For UNIX,
131: * we accomplish this by deleting the /usr/preserve file *now*,
132: * when it is open but before we've read it. Then we revert to the
133: * user's real id.
134: */
135: unlink(line);
136: setuid(getuid());
137: #endif
138: #if OSK
139: setuid(uid);
140: #endif
141:
142: if (outname == NULL) return;
143:
144: /* open the user's file for writing */
145: to = fopen(outname, "w");
146: if (!to)
147: {
148: perror(ptr);
149: exit(2);
150: }
151:
152: /* copy the text */
153: while ((ch = getc(from)) != EOF)
154: {
155: putc(ch, to);
156: }
157:
158: #if !ANY_UNIX
159: #if OSK
160: fclose(from);
161: setuid(0);
162: #endif
163: /* delete the /usr/preserve file */
164: unlink(line);
165: #if OSK
166: setuid(uid);
167: #endif
168: #endif
169: }
170:
171: void
172: main(argc, argv)
173: int argc;
174: char **argv;
175: {
176: /* check arguments */
177: if (argc > 3)
178: {
179: fprintf(stderr, "usage: %s [preserved_file [recovery_file]]\n", argv[0]);
180: exit(2);
181: }
182:
183: /* recover the requested file, or list recoverable files */
184: if (argc == 3)
185: {
186: /* recover the file, but write it to a different filename */
187: recover (argv[1], argv[2]);
188: }
189: else if (argc == 2)
190: {
191: /* recover the file */
192: recover(argv[1], argv[1]);
193: }
194: else
195: {
196: /* list the recoverable files */
197: recover((char *)0, (char *)0);
198: }
199:
200: /* success! */
201: exit(0);
202: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.