This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / elvisrecover / elvisrecover.c
CommitLineData
15637ed4
RG
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
f17f197a
AM
17void recover P_((char *, char *));
18void main P_((int, char **));
19
20
15637ed4
RG
21void 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
f17f197a 171void
15637ed4
RG
172main(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]);
f17f197a 180 exit(2);
15637ed4
RG
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}