PennMUSH Community

root/1.8.3/trunk/src/filecopy.c

Revision 919, 9.0 kB (checked in by shawnw, 1 year ago)

1.8.3p3

Line 
1 /* File manipulation routines */
2 /* Author of Win32-specific bits: Nick Gammon */
3
4 #include "copyrite.h"
5 #include "config.h"
6
7 #include <stdlib.h>
8 #include <stdio.h>
9
10 #ifdef WIN32
11 #include <windows.h>
12 #include <process.h>
13 #include <direct.h>
14 #endif
15
16 #ifdef I_UNISTD
17 #include <unistd.h>
18 #endif
19
20 #include "conf.h"
21 #include "mushdb.h"
22 #include "match.h"
23 #include "externs.h"
24 #include "mymalloc.h"
25 #include "log.h"
26 #include "confmagic.h"
27
28 extern char confname[BUFFER_LEN];       /* From bsd.c */
29
30 #ifdef WIN32
31
32 /* This is bad, but only for WIN32, which is bad anyway... */
33 #define EMBEDDED_MKINDX
34 static char buff[1024];
35 BOOL
36 ConcatenateFiles(const char *path, const char *outputfile)
37 {
38   HANDLE filscan;
39   WIN32_FIND_DATA fildata;
40   BOOL filflag;
41   DWORD status;
42   FILE *fo = NULL;
43   FILE *f = NULL;
44   size_t bytes_in, bytes_out;
45   long total_bytes = 0;
46   int total_files = 0;
47   char directory[MAX_PATH];
48   char fullname[MAX_PATH];
49   char *p;
50
51   /* If outputfile is an empty string, forget it. */
52   if (!outputfile || !*outputfile)
53     return FALSE;
54
55 /* extract the directory from the path name */
56   strcpy(directory, path);
57   p = strrchr(directory, '\\');
58   if (p)
59     p[1] = 0;
60
61   else {
62     p = strrchr(directory, '/');
63     if (p)
64       p[1] = 0;
65   }
66
67 /* Open output file */
68   fo = fopen(outputfile, "wb");
69   if (!fo) {
70     do_rawlog(LT_ERR, T("Unable to open file: %s"), outputfile);
71     return FALSE;
72   }
73   do_rawlog(LT_ERR, T("Creating file: %s"), outputfile);
74
75 /* Find first file matching the wildcard */
76   filscan = FindFirstFile(path, &fildata);
77   if (filscan == INVALID_HANDLE_VALUE) {
78     status = GetLastError();
79     fclose(fo);
80     do_rawlog(LT_ERR, "**** No files matching: \"%s\" found.", path);
81     if (status == ERROR_NO_MORE_FILES)
82       return TRUE;
83
84     else
85       return FALSE;
86   }
87
88 /*
89    Now enter the concatenation loop.
90  */
91
92   do {
93     if (!(fildata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
94       do_rawlog(LT_ERR, "%s: %s, %ld %s", T("    Copying file"),
95                 fildata.cFileName, fildata.nFileSizeLow,
96                 fildata.nFileSizeLow == 1 ? T("byte") : T("bytes"));
97       strcpy(fullname, directory);
98       strcat(fullname, fildata.cFileName);
99
100 /* Open the input file */
101       f = fopen(fullname, "rb");
102       if (!f)
103         do_rawlog(LT_ERR, T("    ** Unable to open file: %s"), fullname);
104
105       else {
106         total_files++;
107
108         /* do the copy loop */
109         while (!feof(f)) {
110           bytes_in = fread(buff, 1, sizeof(buff), f);
111           if (bytes_in <= 0)
112             break;
113           bytes_out = fwrite(buff, 1, bytes_in, fo);
114           total_bytes += bytes_out;
115           if (bytes_in != bytes_out) {
116             do_rawlog(LT_ERR, T("Unable to write to file: %s"), outputfile);
117             fclose(f);
118             break;
119           }
120         }                       /* end of copy loop */
121         fclose(f);
122       }                         /* end of being able to open file */
123     }
124
125     /* end of not being a directory */
126     /* get next file matching the wildcard */
127     filflag = FindNextFile(filscan, &fildata);
128   } while (filflag);
129   status = GetLastError();
130   FindClose(filscan);
131   fclose(fo);
132   do_rawlog(LT_ERR, T("Copied %i %s, %ld %s"), total_files,
133             total_files == 1 ? T("file") : T("files"), total_bytes,
134             total_bytes == 1 ? T("byte") : T("bytes"));
135   if (status == ERROR_NO_MORE_FILES)
136     return TRUE;
137
138   else
139     return FALSE;
140 }
141
142 int
143 CheckDatabase(const char *path, FILETIME * modified, long *filesize)
144 {
145   HANDLE filscan;
146   WIN32_FIND_DATA fildata;
147   SYSTEMTIME st;
148   static char *months[] =
149     { ">!<", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
150     "Oct", "Nov", "Dec"
151   };
152   FILE *f;
153   size_t bytes;
154   filscan = FindFirstFile(path, &fildata);
155   if (filscan == INVALID_HANDLE_VALUE) {
156     do_rawlog(LT_ERR, "File \"%s\" not found.", path);
157     return FALSE;
158   }
159   *modified = fildata.ftLastWriteTime;
160   *filesize = fildata.nFileSizeLow;
161   FindClose(filscan);
162   FileTimeToSystemTime(&fildata.ftLastWriteTime, &st);
163   if (st.wMonth < 1 || st.wMonth > 12)
164     st.wMonth = 0;
165   do_rawlog(LT_ERR, T
166             ("File \"%s\" found, size %ld %s, modified on %02d %s %04d %02d:%02d:%02d"),
167             path, fildata.nFileSizeLow,
168             fildata.nFileSizeLow == 1 ? T("byte") : T("bytes"), st.wDay,
169             months[st.wMonth], st.wYear, st.wHour, st.wMinute, st.wSecond);
170   if (fildata.nFileSizeHigh == 0 && fildata.nFileSizeLow < 80) {
171     do_rawlog(LT_ERR, T("File is too small to be a MUSH database."));
172     return FALSE;
173   }
174
175 /* check file for validity */
176   f = fopen(path, "rb");
177   if (!f) {
178     do_rawlog(LT_ERR, T("Unable to open file %s"), path);
179     return FALSE;
180   }
181   if (fseek(f, -80, SEEK_END) != 0) {
182     do_rawlog(LT_ERR, T("Unable to check file %s"), path);
183     fclose(f);
184     return FALSE;
185   }
186   bytes = fread(buff, 1, 80, f);
187   fclose(f);
188   if (bytes != 80) {
189     do_rawlog(LT_ERR, T("Unable to read last part of file %s"), path);
190     return FALSE;
191   }
192   if (strstr(buff, "***END OF DUMP***") == 0) {
193     do_rawlog(LT_ERR, T("Database not terminated correctly, file %s"), path);
194     return FALSE;
195   }
196   return TRUE;
197 }                               /* end of  CheckDatabase */
198
199 void
200 Win32MUSH_setup(void)
201 {
202   int indb_OK, outdb_OK, panicdb_OK;
203   FILETIME indb_time, outdb_time, panicdb_time;
204   long indb_size, outdb_size, panicdb_size;
205
206 #ifndef _DEBUG
207   char FileName[256];
208   if (GetModuleFileName(NULL, FileName, 256) != 0) {
209     if (!strcasecmp(strrchr(FileName, '\\') + 1, "pennmush.exe")) {
210       if (CopyFile("pennmush.exe", "pennmush_run.exe", FALSE)) {
211         do_rawlog(LT_ERR, "Successfully copied executable, starting copy.");
212 #ifdef WIN32SERVICES
213         execl("pennmush_run.exe", "pennmush_run.exe", "/run", NULL);
214 #else
215         execl("pennmush_run.exe", "pennmush_run.exe", confname, NULL);
216 #endif
217       }
218     }
219   }
220 #endif                          /*  */
221   ConcatenateFiles("txt\\hlp\\*.hlp", "txt\\help.txt");
222   ConcatenateFiles("txt\\nws\\*.nws", "txt\\news.txt");
223   ConcatenateFiles("txt\\evt\\*.evt", "txt\\events.txt");
224   ConcatenateFiles("txt\\rul\\*.rul", "txt\\rules.txt");
225   ConcatenateFiles("txt\\idx\\*.idx", "txt\\index.txt");
226   indb_OK = CheckDatabase(options.input_db, &indb_time, &indb_size);
227   outdb_OK = CheckDatabase(options.output_db, &outdb_time, &outdb_size);
228   panicdb_OK = CheckDatabase(options.crash_db, &panicdb_time, &panicdb_size);
229   if (indb_OK) {                /* Look at outdb */
230     if (outdb_OK) {             /* Look at panicdb */
231       if (panicdb_OK) {         /* outdb or panicdb or indb */
232         if (CompareFileTime(&panicdb_time, &outdb_time) > 0) {  /* panicdb or indb */
233           if (CompareFileTime(&panicdb_time, &indb_time) > 0) { /* panicdb */
234             ConcatenateFiles(options.crash_db, options.input_db);
235           } else {              /* indb */
236           }
237         } else {                /* outdb or indb */
238           if (CompareFileTime(&outdb_time, &indb_time) > 0) {   /* outdb */
239             ConcatenateFiles(options.output_db, options.input_db);
240           } else {              /* indb */
241           }
242         }
243       } else {                  /* outdb or indb */
244         if (CompareFileTime(&outdb_time, &indb_time) > 0) {     /* outdb */
245           ConcatenateFiles(options.output_db, options.input_db);
246         } else {                /* indb */
247         }
248       }
249     } else {                    /* outdb not OK */
250       if (panicdb_OK) {         /* panicdb or indb */
251         if (CompareFileTime(&panicdb_time, &indb_time) > 0) {   /* panicdb */
252           ConcatenateFiles(options.crash_db, options.input_db);
253         } else {                /* indb */
254         }
255       } else {                  /* indb */
256       }
257     }
258   } else {                      /* indb not OK */
259     if (outdb_OK) {             /* look at panicdb */
260       if (panicdb_OK) {         /* out or panic */
261         if (CompareFileTime(&panicdb_time, &outdb_time) > 0) {  /* panicdb */
262           ConcatenateFiles(options.crash_db, options.input_db);
263         } else {                /* outdb */
264           ConcatenateFiles(options.output_db, options.input_db);
265         }
266       } else {                  /* outdb */
267         ConcatenateFiles(options.output_db, options.input_db);
268       }
269     } else {                    /* outdb not OK */
270       if (panicdb_OK) {         /* panicdb */
271         ConcatenateFiles(options.crash_db, options.input_db);
272       } else {                  /* NOTHING */
273         return;
274       }
275     }
276   }
277
278 /* Final failsafe - input database SHOULD still be OK. */
279   do_rawlog(LT_ERR, T("Verifying selected database."));
280   if (!CheckDatabase(options.input_db, &indb_time, &indb_size)) {
281     do_rawlog(LT_ERR, T("File corrupted during selection process."));
282     exit(-1);
283   } else {
284     do_rawlog(LT_ERR, T("Input database verified. Proceeding to analysis."));
285   }
286 }
287
288 #endif                          /* WIN32 */
289
290 /** Portably renames a file
291  * \param origname the orignal name of the file
292  * \param newname the new name of the file
293  * \return 0 on success, negative on failure
294  */
295 int
296 rename_file(const char *origname, const char *newname)
297 {
298   /* Windows can't rename over an existing file */
299 #ifdef WIN32
300   unlink(newname);
301 #endif
302   return rename(origname, newname);
303 }
Note: See TracBrowser for help on using the browser.