source: trunk/dll/copyf.c@ 959

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

Use xfree where appropriate. Check that buffer exists following all xmallocs. Stopped at eas.c with xfree checking. One remaining xmalloc without test in dirsize.c

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