source: trunk/dll/copyf.c@ 1439

Last change on this file since 1439 was 1439, checked in by Gregg Young, 16 years ago

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: copyf.c 1439 2009-07-12 21:57:04Z gyoung $
5
6 Copy functions
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2008 Steven H.Levine
10
11 14 Sep 02 SHL Drop obsolete debug code
12 14 Oct 02 SHL Drop obsolete debug code
13 10 Nov 02 SHL docopyf - don't forget to terminate longname
14 optimize longname logic
15 01 Aug 04 SHL Rework lstrip/rstrip usage
16 28 May 05 SHL Drop debug code
17 14 Jul 06 SHL Use Runtime_Error
18 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
19 01 Sep 07 GKY Use xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
20 29 Feb 08 GKY Use xfree where appropriate
21 19 Jul 08 GKY Modify MakeTempName for use making temp directory names
22 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
23 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
24 12 Jul 09 GKY Add xDosQueryAppType and xDoxAlloc... to allow FM/2 to load in high memory
25
26***********************************************************************/
27
28#include <stdlib.h>
29#include <string.h>
30#include <stdarg.h>
31#include <ctype.h>
32
33#define INCL_DOS
34#define INCL_DOSERRORS
35#define INCL_WIN
36#define INCL_LONGLONG
37
38#include "fm3dll.h"
39#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
40#include "killproc.h" // Data declaration(s)
41#include "notebook.h" // Data declaration(s)
42#include "info.h" // Data declaration(s)
43#include "init.h" // Data declaration(s)
44#include "arccnrs.h"
45#include "fm3str.h"
46#include "errutil.h" // Dos_Error...
47#include "strutil.h" // GetPString
48#include "copyf.h"
49#include "literal.h" // fixup
50#include "misc.h" // Broadcast
51#include "valid.h" // MakeFullName
52#include "wrappers.h" // xDosSetPathInfo
53#include "strips.h" // bstrip
54#include "fortify.h"
55#include "pathutil.h" // AddBackslashToPath
56
57static PSZ pszSrcFile = __FILE__;
58
59static CHAR *GetLongName(CHAR * oldname, CHAR * buffer);
60static CHAR *TruncName(CHAR * oldname, CHAR * buffer);
61
62//static CHAR default_disk(VOID);
63//static INT unlink_allf(CHAR * string, ...);
64
65#ifndef WinMoveObject
66HOBJECT APIENTRY WinMoveObject(HOBJECT hObjectofObject,
67 HOBJECT hObjectofDest, ULONG ulReserved);
68#endif
69#ifndef WinCopyObject
70HOBJECT APIENTRY WinCopyObject(HOBJECT hObjectofObject,
71 HOBJECT hObjectofDest, ULONG ulReserved);
72#endif
73
74char *MakeTempName(char *buffer, char *temproot, INT type)
75{
76 FILESTATUS3 fs3;
77 APIRET rc;
78 char *p, *o;
79
80
81 if (strlen(buffer) > 3) // && buffer[strlen(buffer) - 1] != '\\')
82 AddBackslashToPath(buffer);
83 //strcat(buffer, "\\");
84 p = o = buffer + strlen(buffer);
85 switch (type) {
86 case 0:
87 sprintf(p, "%08lx.%03lx", rand() & 4095L, mypid);
88 break;
89 case 1:
90 sprintf(p, "%s%04lx.%03lx", "$FM2", rand() & 4095L, mypid);
91 break;
92 case 2:
93 sprintf(p, "%s.%03x", temproot, (rand() & 4095));
94 break;
95 default:
96 break;
97 }
98 p = buffer + (strlen(buffer) - 1);
99 for (;;) {
100 DosError(FERR_DISABLEHARDERR);
101 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
102 if (rc == ERROR_DISK_CHANGE) {
103 DosError(FERR_ENABLEHARDERR);
104 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
105 }
106 if (rc)
107 break;
108 Loop:
109 if (p < o) {
110 *buffer = 0;
111 return NULL;
112 }
113 if ((*p) + 1 < 'Z' + 1) {
114 (*p)++;
115 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
116 (*p)++;
117 *p = toupper(*p);
118 }
119 else {
120 p--;
121 if (p >= o && *p == '.')
122 p--;
123 goto Loop;
124 }
125 }
126 return buffer;
127}
128
129CHAR *TruncName(CHAR * oldname, CHAR * buffer)
130{
131 CHAR *p, *f, *s, *o;
132 FILESTATUS3 fs3;
133 APIRET rc;
134
135 if (!buffer || !oldname || !*oldname) {
136 if (buffer)
137 *buffer = 0;
138 return NULL;
139 }
140 strcpy(buffer, oldname);
141 f = strrchr(buffer, '\\');
142 if (!f)
143 f = strrchr(buffer, '/');
144 if (!f)
145 f = buffer;
146 else
147 f++;
148 p = f;
149 o = p;
150 f = oldname + (f - buffer);
151 strupr(buffer);
152 while (*f == '.') /* skip leading '.'s */
153 f++;
154 s = f;
155 while (*f && *f != '.' && f < s + 8) { /* skip past rootname */
156 *p = toupper(*f);
157 p++;
158 f++;
159 }
160 while (*f == '.')
161 f++;
162 s = f;
163 f = strrchr(f, '.');
164 if (f) {
165 while (*f == '.')
166 f++;
167 }
168 if (f && *(f + 1))
169 s = f;
170 else
171 f = s;
172 if (*f) {
173 *p = '.';
174 p++;
175 while (*f && *f != '.' && f < s + 3) {
176 *p = toupper(*f);
177 p++;
178 f++;
179 }
180 }
181 *p = 0;
182
183 p = o;
184 while (*p) {
185 if (strchr("*?<>\":/\\|+=;,[] ", *p) || *p < 0x20)
186 *p = '_';
187 if (*p == '.' && *(p + 1) == '.')
188 *(p + 1) = '_';
189 p++;
190 }
191
192 p = o + (strlen(o) - 1);
193 for (;;) {
194 DosError(FERR_DISABLEHARDERR);
195 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
196 if (rc == ERROR_DISK_CHANGE) {
197 DosError(FERR_ENABLEHARDERR);
198 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
199 }
200 if (rc)
201 break;
202 Loop:
203 if (p < o) {
204 *buffer = 0;
205 return NULL;
206 }
207 if ((*p) + 1 < 'Z' + 1) {
208 (*p)++;
209 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
210 (*p)++;
211 *p = toupper(*p);
212 }
213 else {
214 p--;
215 if (p >= o && *p == '.')
216 p--;
217 goto Loop;
218 }
219 }
220 return buffer;
221}
222
223CHAR *GetLongName(CHAR * oldname, CHAR * longname)
224{
225 if (!longname)
226 return NULL;
227 *longname = 0;
228 if (!oldname || !*oldname)
229 return NULL;
230 if (IsFullName(oldname)) {
231
232 APIRET rc;
233 EAOP2 eaop;
234 PGEA2LIST pgealist;
235 PFEA2LIST pfealist;
236 PGEA2 pgea;
237 PFEA2 pfea;
238 CHAR *value;
239
240 strcpy(longname, oldname);
241 value = longname;
242 while (*value) {
243 if (*value == '/')
244 *value = '\\';
245 value++;
246 }
247 value = strrchr(longname, '\\');
248 if (value) {
249 value++;
250 *value = 0;
251 }
252 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
253 if (pgealist) {
254 pgea = &pgealist->list[0];
255 strcpy(pgea->szName, LONGNAME);
256 pgea->cbName = strlen(pgea->szName);
257 pgea->oNextEntryOffset = 0L;
258 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
259 pfealist = xmallocz(1536, pszSrcFile, __LINE__);
260 if (pfealist) {
261 pfealist->cbList = 1024;
262 eaop.fpGEA2List = pgealist;
263 eaop.fpFEA2List = pfealist;
264 eaop.oError = 0L;
265 DosError(FERR_DISABLEHARDERR);
266 rc = DosQueryPathInfo(oldname,
267 FIL_QUERYEASFROMLIST,
268 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
269 if (!rc) {
270 pfea = &eaop.fpFEA2List->list[0];
271 value = pfea->szName + pfea->cbName + 1;
272 value[pfea->cbValue] = 0;
273 if (*(USHORT *) value == EAT_ASCII)
274 strncat(longname,
275 value + (sizeof(USHORT) * 2),
276 CCHMAXPATH - strlen(longname));
277 longname[CCHMAXPATH - 1] = 0;
278 }
279 free(pfealist);
280 }
281 free(pgealist);
282 }
283 }
284 return longname;
285}
286
287BOOL ZapLongName(char *filename)
288{
289 return WriteLongName(filename, NullStr);
290}
291
292BOOL WriteLongName(CHAR * filename, CHAR * longname)
293{
294 APIRET rc;
295 EAOP2 eaop;
296 PFEA2LIST pfealist = NULL;
297 ULONG ealen;
298 USHORT len;
299 CHAR *eaval, *p;
300
301 if (!filename || !*filename || !longname)
302 return FALSE;
303 p = strrchr(longname, '\\');
304 if (p)
305 memmove(longname, p + 1, strlen(p + 1) + 1);
306 p = strrchr(longname, '/');
307 if (p)
308 memmove(longname, p + 1, strlen(p + 1) + 1);
309 bstrip(longname);
310 len = strlen(longname);
311 if (len)
312 ealen = sizeof(FEA2LIST) + 10 + len + 4;
313 else
314 ealen = sizeof(FEALIST) + 10;
315 rc = xDosAllocMem((PPVOID) & pfealist,
316 ealen + 32L, PAG_COMMIT | PAG_READ | PAG_WRITE,
317 pszSrcFile, __LINE__);
318 if (rc)
319 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
320 GetPString(IDS_OUTOFMEMORY));
321 else {
322 memset(pfealist, 0, ealen + 1);
323 pfealist->cbList = ealen;
324 pfealist->list[0].oNextEntryOffset = 0;
325 pfealist->list[0].fEA = 0;
326 pfealist->list[0].cbName = 9;
327 strcpy(pfealist->list[0].szName, LONGNAME);
328 if (len) {
329 eaval = pfealist->list[0].szName + 10;
330 *(USHORT *) eaval = (USHORT) EAT_ASCII;
331 eaval += sizeof(USHORT);
332 *(USHORT *) eaval = (USHORT) len;
333 eaval += sizeof(USHORT);
334 memcpy(eaval, longname, len);
335 pfealist->list[0].cbValue = len + (sizeof(USHORT) * 2);
336 }
337 else
338 pfealist->list[0].cbValue = 0;
339 eaop.fpGEA2List = (PGEA2LIST) 0;
340 eaop.fpFEA2List = pfealist;
341 eaop.oError = 0L;
342 DosError(FERR_DISABLEHARDERR);
343 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
344 &eaop, sizeof(eaop), DSPI_WRTTHRU);
345 DosFreeMem(pfealist);
346 if (rc)
347 return FALSE;
348 }
349 return TRUE;
350}
351
352BOOL AdjustWildcardName(CHAR * oldname, CHAR * newname)
353{
354 BOOL ret = FALSE;
355
356 /* NOTE: newname should be CCHMAXPATH chars long! */
357
358 if (strchr(newname, '*') || strchr(newname, '?')) {
359
360 CHAR srce[CCHMAXPATHCOMP], dest[CCHMAXPATHCOMP], result[CCHMAXPATHCOMP],
361 *p;
362
363 p = strrchr(newname, '\\');
364 if (p && *(p + 1)) {
365 strcpy(dest, p + 1);
366 p = strrchr(oldname, '\\');
367 if (p && *(p + 1)) {
368 strcpy(srce, p + 1);
369 DosError(FERR_DISABLEHARDERR);
370 if (!DosEditName(1L, srce, dest, (PBYTE)result, (ULONG)sizeof(result))) {
371 p = strrchr(newname, '\\');
372 p++;
373 strcpy(p, result);
374 ret = TRUE;
375 }
376 }
377 }
378 }
379 return ret;
380}
381
382#if 0 // JBS 11 Sep 08
383CHAR default_disk(VOID)
384{
385 ULONG ulDriveNum, ulDriveMap;
386
387 DosError(FERR_DISABLEHARDERR);
388 DosQCurDisk(&ulDriveNum, &ulDriveMap);
389 return (CHAR) toupper((INT) ulDriveNum) + '@';
390}
391#endif
392
393#ifdef NEVER
394
395APIRET docopyallf(INT type, CHAR * oldname, CHAR * newname, ...)
396{
397 FILEFINDBUF3 fb;
398 ULONG nm;
399 HDIR hdir;
400 APIRET rc = 0;
401 CHAR *enddir, fullname[CCHMAXPATH];
402
403 va_start(ap, newname);
404 vsprintf(fullname, newname, ap);
405 va_end(ap);
406
407 DosError(FERR_DISABLEHARDERR);
408 if (!DosFindFirst(oldname)) {
409 do {
410
411 /* build target name */
412
413 if (fb.attrFile & FILE_DIRECTORY) {
414 DosError(FERR_ENABLEHARDERR);
415 rc = DosCreateDir();
416 if (rc == ERROR_INVALID_NAME || rc == ERROR_FILENAME_EXCED_RANGE) {
417
418 /* truncate directory name */
419 /* create that directory */
420 /* update containers for name used */
421
422 }
423 rc = docopyallf(type,, "%s",); /* recurse */
424 }
425 else
426 // docopyf changed this won't work rc = docopyf(type,, "%s",); /* copy file */
427 DosError(FERR_DISABLEHARDERR);
428 } while (!rc && !DosFindNext());
429 DosFindClose(hdir);
430 }
431 else
432 rc = ERROR_FILE_NOT_FOUND;
433 return rc;
434}
435
436#endif
437
438APIRET docopyf(INT type, CHAR *oldname, CHAR *newname)
439{
440 /*
441 * returns:
442 * 0: success
443 * -1: bad string parameter(s)
444 * -2: source didn't exist
445 * -3: bad type
446 * anything else: API return
447 */
448
449 CHAR longname[CCHMAXPATH], shortname[CCHMAXPATH];
450 CHAR olddisk, newdisk, dir[CCHMAXPATH], *p, *pp;
451 APIRET ret = -1, rc;
452 FILESTATUS3L st, st2, dummy;
453 BOOL diskchange = FALSE, zaplong = FALSE;
454
455 *shortname = *dir = 0;
456
457 if (!oldname || !*oldname || !*newname) /* bad string args */
458 return (APIRET) - 1;
459
460 DosError(FERR_DISABLEHARDERR);
461 if (DosQueryPathInfo(oldname, FIL_STANDARDL, &st, sizeof(FILESTATUS3L)))
462 return (APIRET) - 2; /* no source */
463
464 AdjustWildcardName(oldname, newname);
465 MakeFullName(oldname);
466 MakeFullName(newname);
467 olddisk = toupper(*oldname); /* source drive */
468 newdisk = toupper(*newname); /* destination drive */
469 if (!(driveflags[toupper(*oldname) - 'A'] & DRIVE_NOLONGNAMES))
470 *longname = 0;
471 else {
472 GetLongName(oldname, longname);
473 if (*longname) {
474 p = RootName(longname);
475 if (p != longname)
476 memmove(longname, p, strlen(p) + 1);
477 }
478 }
479 /* If root name changed make sure longname EA goes away */
480 p = RootName(oldname);
481 pp = RootName(newname);
482 if (stricmp(p, pp)) {
483 zaplong = TRUE;
484 }
485
486 DosError(FERR_DISABLEHARDERR);
487 switch (type) {
488 case WPSMOVE:
489 {
490 HOBJECT hobjsrc;
491 HOBJECT hobjdest;
492
493 ret = ERROR_FILE_NOT_FOUND;
494 hobjsrc = WinQueryObject(oldname);
495 if (hobjsrc) {
496 strcpy(dir, newname);
497 p = strrchr(dir, '\\');
498 if (p < dir + 3)
499 p++;
500 *p = 0;
501 ret = ERROR_PATH_NOT_FOUND;
502 hobjdest = WinQueryObject(dir);
503 if (hobjdest) {
504 ret = ERROR_GEN_FAILURE;
505 hobjsrc = WinMoveObject(hobjsrc, hobjdest, 0);
506 if (hobjsrc)
507 ret = 0;
508 }
509 }
510 }
511 return ret;
512
513 case WPSCOPY:
514 {
515 HOBJECT hobjsrc;
516 HOBJECT hobjdest;
517
518 ret = ERROR_FILE_NOT_FOUND;
519 hobjsrc = WinQueryObject(oldname);
520 if (hobjsrc) {
521 strcpy(dir, newname);
522 p = strrchr(dir, '\\');
523 if (p < dir + 3)
524 p++;
525 *p = 0;
526 ret = ERROR_PATH_NOT_FOUND;
527 hobjdest = WinQueryObject(dir);
528 if (hobjdest) {
529 ret = ERROR_GEN_FAILURE;
530 hobjsrc = WinCopyObject(hobjsrc, hobjdest, 0);
531 if (hobjsrc)
532 ret = 0;
533 }
534 }
535 }
536 return ret;
537
538 case MOVE:
539 *dir = 0;
540 if (olddisk == newdisk) { /* same drive */
541 /* make temporary copy in case move fails */
542 if (IsFile(newname) != -1 && stricmp(oldname, newname)) {
543 strcpy(dir, newname);
544 AddBackslashToPath(dir);
545 //p = strrchr(dir, '\\');
546 //if (p)
547 // *p = 0;
548 //strcat(dir, "\\");
549 MakeTempName(dir, NULL, 0);
550 if (DosMove(newname, dir))
551 *dir = 0;
552 }
553 DosError(FERR_DISABLEHARDERR);
554 ret = DosMove(oldname, newname); /* move it */
555 if (ret && *dir) { /* failed -- clean up */
556 DosError(FERR_DISABLEHARDERR);
557 if (!DosMove(dir, newname))
558 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
559 }
560 else if (!ret && *dir) {
561 if (!IsFile(dir)) {
562 if (!strchr(dir, '?') && !strchr(dir, '*'))
563 wipeallf("%s\\*", dir);
564 DosError(FERR_DISABLEHARDERR);
565 if (DosDeleteDir(dir)) {
566 make_deleteable(dir);
567 DosDeleteDir(dir);
568 }
569 }
570 else if (IsFile(dir) > 0) {
571 DosError(FERR_DISABLEHARDERR);
572 if (DosForceDelete(dir)) {
573 make_deleteable(dir);
574 DosForceDelete(dir);
575 }
576 if (zaplong)
577 ZapLongName(dir);
578 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
579 }
580 }
581 }
582 else { /* different drives */
583 DosError(FERR_DISABLEHARDERR);
584 ret = DosCopy(oldname, newname, DCPY_EXISTING); /* <=-NOTE! */
585 if (ret == ERROR_DISK_CHANGE) {
586 DosError(FERR_ENABLEHARDERR);
587 ret = DosCopy(oldname, newname, DCPY_EXISTING);
588 diskchange = TRUE;
589 }
590 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
591 if (TruncName(newname, shortname)) { /* make 8.3 filename */
592 DosError(FERR_DISABLEHARDERR);
593 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
594 if (!ret) { /* success -- write longname ea */
595 WriteLongName(shortname, newname);
596 strcpy(newname, shortname);
597 /* broadcast fixup msg to windows */
598 Broadcast((HAB) 0,
599 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
600 }
601 }
602 }
603 else if (!ret && *longname) {
604
605 CHAR fixname[CCHMAXPATH];
606
607 strcpy(fixname, newname);
608 p = strrchr(fixname, '\\');
609 if (p) {
610 p++;
611 *p = 0;
612 }
613 strcat(fixname, longname);
614 DosError(FERR_DISABLEHARDERR);
615 DosMove(newname, fixname);
616 strcpy(newname, fixname);
617 if (zaplong)
618 ZapLongName(fixname);
619 Broadcast((HAB) 0,
620 hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
621 }
622 if (!ret) { /* double-check success */
623 DosError(FERR_DISABLEHARDERR);
624 rc = DosQueryPathInfo(newname,
625 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
626 if (rc == ERROR_DISK_CHANGE) {
627 DosError(FERR_ENABLEHARDERR);
628 rc = DosQueryPathInfo(newname,
629 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
630 }
631 if (!rc && st2.cbFile == st.cbFile) { /* seems to have worked... */
632 DosError(FERR_DISABLEHARDERR);
633 if (diskchange) {
634 DosError(FERR_ENABLEHARDERR);
635 DosQueryPathInfo(oldname, FIL_STANDARDL, &dummy, sizeof(FILESTATUS3L)); /* force disk change */
636 }
637 if (!(st2.attrFile & FILE_DIRECTORY)) /* erase file */
638 unlinkf(oldname);
639 else { /* remove directory */
640 wipeallf("%s\\*", oldname);
641 DosError(FERR_DISABLEHARDERR);
642 if (DosDeleteDir(oldname)) {
643 make_deleteable(oldname);
644 DosDeleteDir(oldname);
645 }
646 }
647 }
648 }
649 }
650 return ret;
651
652 case COPY:
653 DosError(FERR_DISABLEHARDERR);
654 ret = DosCopy(oldname, newname, DCPY_EXISTING); /* <=-NOTE! */
655 if (ret == ERROR_DISK_CHANGE) {
656 DosError(FERR_ENABLEHARDERR);
657 ret = DosCopy(oldname, newname, DCPY_EXISTING);
658 diskchange = TRUE;
659 }
660 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
661 if (TruncName(newname, shortname)) {
662 DosError((diskchange) ? FERR_ENABLEHARDERR : FERR_DISABLEHARDERR);
663 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
664 if (!ret) {
665 WriteLongName(shortname, newname);
666 strcpy(newname, shortname);
667 Broadcast((HAB) 0,
668 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
669 }
670 }
671 }
672 else if (!ret && *longname) {
673
674 CHAR fixname[CCHMAXPATH];
675
676 strcpy(fixname, newname);
677 p = strrchr(fixname, '\\');
678 if (p) {
679 p++;
680 *p = 0;
681 }
682 strcat(fixname, longname);
683 DosError(FERR_DISABLEHARDERR);
684 DosMove(newname, fixname);
685 if (zaplong)
686 ZapLongName(fixname);
687 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
688 }
689 return ret;
690
691 default: /* shouldn't happen */
692 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", type);
693 break;
694 }
695 return (APIRET) - 3; /* bad type */
696}
697
698INT make_deleteable(CHAR * filename)
699{
700 INT ret = -1;
701 FILESTATUS3 fsi;
702
703 DosError(FERR_DISABLEHARDERR);
704 if (!DosQueryPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi))) {
705 fsi.attrFile = 0;
706 DosError(FERR_DISABLEHARDERR);
707 if (!xDosSetPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi), 0))
708 ret = 0;
709 }
710 return ret;
711}
712
713INT wipeallf(CHAR *string, ...)
714{
715 /* unlink everything from directory on down... */
716
717 FILEFINDBUF3 *f;
718 HDIR search_handle;
719 ULONG num_matches;
720 CHAR *p, *ss, *str;
721 CHAR s[CCHMAXPATH], mask[257];
722 va_list ap;
723 INT rc;
724
725 va_start(ap, string);
726 vsprintf(s, string, ap);
727 va_end(ap);
728
729 if (!*s)
730 return -1;
731 p = s;
732 while ((p = strchr(p, '/')) != NULL) {
733 *p = '\\';
734 p++;
735 }
736
737 str = xstrdup(s, pszSrcFile, __LINE__);
738 if (!str)
739 return -1;
740
741 { /* safety net -- disallow deleting a root dir or partial name */
742 CHAR temp;
743
744 p = strrchr(str, '\\');
745 if (p) {
746 p++;
747 temp = *p;
748 *p = 0;
749 if (IsRoot(str) || !IsFullName(str)) {
750 /* under no circumstances! */
751 Runtime_Error(pszSrcFile, __LINE__, "bad name %s", str);
752 free(str);
753 return -1;
754 }
755 *p = temp;
756 }
757 }
758
759 p = s;
760 p = strrchr(s, '\\'); /* strip s to just path */
761 if (!p)
762 p = strrchr(s, ':');
763 if (p) {
764 p++;
765 strncpy(mask, p, 256);
766 mask[256] = 0;
767 *p = 0;
768 }
769 else {
770 *mask = 0;
771 *s = 0;
772 }
773
774 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
775 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
776 if (!ss || !f) {
777 xfree(ss, pszSrcFile, __LINE__);
778 xfree(f, pszSrcFile, __LINE__);
779 free(str);
780 return -1;
781 }
782
783 search_handle = HDIR_CREATE;
784 num_matches = 1;
785
786 DosError(FERR_DISABLEHARDERR);
787 if (!DosFindFirst(str, &search_handle, FILE_NORMAL | FILE_DIRECTORY |
788 FILE_SYSTEM | FILE_READONLY | FILE_HIDDEN | FILE_ARCHIVED,
789 f, sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
790
791 strcpy(ss, s);
792 p = &ss[strlen(ss)];
793
794 do {
795 strcpy(p, f->achName);
796 if (f->attrFile & FILE_DIRECTORY) {
797 if (strcmp(f->achName, ".") && strcmp(f->achName, "..")) {
798 wipeallf("%s/%s", ss, mask); /* recurse to wipe files */
799 DosError(FERR_DISABLEHARDERR);
800 if (DosDeleteDir(ss)) { /* remove directory */
801 make_deleteable(ss);
802 DosError(FERR_DISABLEHARDERR);
803 DosDeleteDir(ss);
804 }
805 }
806 }
807 else {
808 DosError(FERR_DISABLEHARDERR);
809 if (DosForceDelete(ss)) {
810 make_deleteable(ss);
811 DosError(FERR_DISABLEHARDERR);
812 rc = (INT) DosForceDelete(ss);
813 if (rc)
814 return rc;
815 }
816 }
817 num_matches = 1;
818 DosError(FERR_DISABLEHARDERR);
819 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
820 &num_matches));
821 DosFindClose(search_handle);
822 }
823
824 free(f);
825 free(ss);
826 free(str);
827 return 0;
828}
829
830#if 0 // JBS 11 Sep 08
831INT unlink_allf(CHAR * string, ...)
832{
833 /* wildcard delete */
834
835 FILEFINDBUF3 *f;
836 HDIR search_handle;
837 ULONG num_matches;
838 CHAR *p, *ss, *str;
839 CHAR s[CCHMAXPATH];
840 va_list ap;
841
842 va_start(ap, string);
843 vsprintf(s, string, ap);
844 va_end(ap);
845
846 if (!*s)
847 return -1;
848 p = s;
849 while ((p = strchr(p, '/')) != NULL) {
850 *p = '\\';
851 p++;
852 }
853
854 str = xstrdup(s, pszSrcFile, __LINE__);
855 if (!str)
856 return -1;
857
858 p = s;
859 p = strrchr(s, '\\'); /* strip s to just path */
860 if (!p)
861 p = strrchr(s, ':');
862 if (p) {
863 p++;
864 *p = 0;
865 }
866 else
867 *s = 0;
868
869 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
870 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
871 if (!ss || !f) {
872 xfree(ss, pszSrcFile, __LINE__);
873 xfree(f, pszSrcFile, __LINE__);
874 free(str);
875 return -1;
876 }
877
878 search_handle = HDIR_CREATE;
879 num_matches = 1;
880
881 DosError(FERR_DISABLEHARDERR);
882 if (!DosFindFirst(str, &search_handle, FILE_NORMAL, f,
883 sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
884
885 strcpy(ss, s);
886 p = &ss[strlen(ss)];
887
888 do {
889 strcpy(p, f->achName);
890 unlinkf("%s", ss);
891 num_matches = 1;
892 DosError(FERR_DISABLEHARDERR);
893 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
894 &num_matches));
895 DosFindClose(search_handle);
896 }
897
898 free(f);
899 free(ss);
900 free(str);
901 return 0;
902}
903#endif
904
905INT unlinkf(CHAR *string)
906{
907
908 if (!strstr(string, ArcTempRoot)) {
909 DosError(FERR_DISABLEHARDERR);
910 if (DosDelete(string)) {
911 make_deleteable(string);
912 DosError(FERR_DISABLEHARDERR);
913 return DosDelete(string);
914 }
915 }
916 else {
917 DosError(FERR_DISABLEHARDERR);
918 if (DosForceDelete(string)) {
919 make_deleteable(string);
920 DosError(FERR_DISABLEHARDERR);
921 return DosForceDelete(string);
922 }
923 }
924 return 0;
925}
926
927#pragma alloc_text(LONGNAMES,TruncName,GetLongName,WriteLongName)
928#pragma alloc_text(LONGNAMES,ZapLongName,AdjustWildcardName)
929#pragma alloc_text(COPYF,default_disk,docopyf,MakeTempName)
930#pragma alloc_text(UNLINKF,unlinkf,unlink_allf,make_deleteable,wipeallf)
Note: See TracBrowser for help on using the repository browser.