retire nonsymbolic rootdev, dev2name
[minix.git] / commands / elvis / elvrec.c
blob4e9c389eae77a9fb230e32e017339bc5173b49ce
1 /* elvrec.c */
3 /* This file contains the file recovery program */
5 /* Author:
6 * Steve Kirkendall
7 * 14407 SW Teal Blvd. #C
8 * Beaverton, OR 97005
9 * kirkenda@cs.pdx.edu
13 #include <stdio.h>
14 #include "config.h"
15 #include "vi.h"
16 #include <sys/stat.h>
18 void recover(basename, outname)
19 char *basename; /* the name of the file to recover */
20 char *outname; /* the name of the file to write to */
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
33 /* convert basename to a full pathname */
34 if (basename)
36 #ifndef CRUNCH
37 # if MSDOS || TOS
38 if (!basename[0] || basename[1] != ':')
39 # else
40 if (basename[0] != SLASH)
41 # endif
43 ptr = getcwd(pathname, sizeof pathname);
44 if (ptr != pathname)
46 strcpy(pathname, ptr);
48 ptr = pathname + strlen(pathname);
49 *ptr++ = SLASH;
50 strcpy(ptr, basename);
52 else
53 #endif
55 strcpy(pathname, basename);
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.
67 from = fopen(PRSVINDEX, "r");
68 while (from && fgets(line, sizeof line, from))
70 /* strip off the newline from the end of the string */
71 line[strlen(line) - 1] = '\0';
73 /* parse the line into a "preserve" name and a "text" name */
74 for (ptr = line; *ptr != ' '; ptr++)
77 *ptr++ = '\0';
79 /* If the "preserve" file is missing, then ignore this line
80 * because it describes a file that has already been recovered.
82 if (stat(line, &st) < 0)
84 continue;
87 /* are we looking for a specific file? */
88 if (basename)
90 /* quit if we found it */
91 if (!strcmp(ptr, pathname))
93 break;
96 else
98 /* list this file as "available for recovery" */
99 puts(ptr);
103 /* file not found? */
104 if (!basename || !from || feof(from))
106 if (from != NULL) fclose(from);
107 if (basename)
109 fprintf(stderr, "%s: no recovered file has that exact name\n", pathname);
111 return;
113 if (from != NULL) fclose(from);
115 /* copy the recovered text back into the user's file... */
117 /* open the /usr/preserve file for reading */
118 from = fopen(line, "r");
119 if (!from)
121 perror(line);
122 exit(2);
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.
133 unlink(line);
134 setuid(getuid());
135 #endif
136 #if OSK
137 setuid(uid);
138 #endif
140 if (outname == NULL) return;
142 /* open the user's file for writing */
143 to = fopen(outname, "w");
144 if (!to)
146 perror(ptr);
147 exit(2);
150 /* copy the text */
151 while ((ch = getc(from)) != EOF)
153 putc(ch, to);
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
169 main(argc, argv)
170 int argc;
171 char **argv;
173 /* check arguments */
174 if (argc > 3)
176 fprintf(stderr, "usage: %s [preserved_file [recovery_file]]\n", argv[0]);
177 exit(1);
180 /* recover the requested file, or list recoverable files */
181 if (argc == 3)
183 /* recover the file, but write it to a different filename */
184 recover (argv[1], argv[2]);
186 else if (argc == 2)
188 /* recover the file */
189 recover(argv[1], argv[1]);
191 else
193 /* list the recoverable files */
194 recover((char *)0, (char *)0);
197 /* success! */
198 exit(0);