source: trunk/minix/commands/elvis/elvrec.c@ 11

Last change on this file since 11 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

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