source: trunk/dll/copyf.c@ 826

Last change on this file since 826 was 826, checked in by Gregg Young, 18 years ago

Add xDosSetPathInfo to work around FILESTATUSx buffer crossing 64k boundry

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