source: trunk/dll/copyf.c@ 1469

Last change on this file since 1469 was 1469, checked in by Steven Levine, 16 years ago

Enhance compare directories - support AND'ed selections, rework CompSelect for size and speed,
allow fast cancel, drop unused reset logic, more context menu items

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