source: trunk/dll/copyf.c@ 1036

Last change on this file since 1036 was 1009, checked in by Steven Levine, 17 years ago

Add xfree xstrdup Fortify support
Add MT capable Fortify scope logic

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
Line 
1
2/***********************************************************************
3
4 $Id: copyf.c 1009 2008-05-10 07:51:58Z stevenhl $
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 29 Feb 08 GKY Use xfree where appropriate
21
22***********************************************************************/
23
24#include <stdlib.h>
25#include <string.h>
26#include <stdarg.h>
27#include <ctype.h>
28
29#define INCL_DOS
30#define INCL_DOSERRORS
31#define INCL_WIN
32#define INCL_LONGLONG
33
34#include "fm3str.h"
35#include "errutil.h" // Dos_Error...
36#include "strutil.h" // GetPString
37#include "fm3dll.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, sizeof(fs3));
62 if (rc == ERROR_DISK_CHANGE) {
63 DosError(FERR_ENABLEHARDERR);
64 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, 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, sizeof(fs3));
156 if (rc == ERROR_DISK_CHANGE) {
157 DosError(FERR_ENABLEHARDERR);
158 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, 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 xfree(pfealist, pszSrcFile, __LINE__);
240 }
241 xfree(pgealist, pszSrcFile, __LINE__);
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 = 0;
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, FIL_QUERYEASIZE,
303 &eaop, sizeof(eaop), DSPI_WRTTHRU);
304 DosFreeMem(pfealist);
305 if (rc)
306 return FALSE;
307 }
308 return TRUE;
309}
310
311BOOL AdjustWildcardName(CHAR * oldname, CHAR * newname)
312{
313 BOOL ret = FALSE;
314
315 /* NOTE: newname should be CCHMAXPATH chars long! */
316
317 if (strchr(newname, '*') || strchr(newname, '?')) {
318
319 CHAR srce[CCHMAXPATHCOMP], dest[CCHMAXPATHCOMP], result[CCHMAXPATHCOMP],
320 *p;
321
322 p = strrchr(newname, '\\');
323 if (p && *(p + 1)) {
324 strcpy(dest, p + 1);
325 p = strrchr(oldname, '\\');
326 if (p && *(p + 1)) {
327 strcpy(srce, p + 1);
328 DosError(FERR_DISABLEHARDERR);
329 if (!DosEditName(1L, srce, dest, result, (ULONG) sizeof(result))) {
330 p = strrchr(newname, '\\');
331 p++;
332 strcpy(p, result);
333 ret = TRUE;
334 }
335 }
336 }
337 }
338 return ret;
339}
340
341CHAR default_disk(VOID)
342{
343 ULONG ulDriveNum, ulDriveMap;
344
345 DosError(FERR_DISABLEHARDERR);
346 DosQCurDisk(&ulDriveNum, &ulDriveMap);
347 return (CHAR) toupper((INT) ulDriveNum) + '@';
348}
349
350#ifdef NEVER
351
352APIRET docopyallf(INT type, CHAR * oldname, CHAR * newname, ...)
353{
354 FILEFINDBUF3 fb;
355 ULONG nm;
356 HDIR hdir;
357 APIRET rc = 0;
358 CHAR *enddir, fullname[CCHMAXPATH];
359
360 va_start(ap, newname);
361 vsprintf(fullname, newname, ap);
362 va_end(ap);
363
364 DosError(FERR_DISABLEHARDERR);
365 if (!DosFindFirst(oldname)) {
366 do {
367
368 /* build target name */
369
370 if (fb.attrFile & FILE_DIRECTORY) {
371 DosError(FERR_ENABLEHARDERR);
372 rc = DosCreateDir();
373 if (rc == ERROR_INVALID_NAME || rc == ERROR_FILENAME_EXCED_RANGE) {
374
375 /* truncate directory name */
376 /* create that directory */
377 /* update containers for name used */
378
379 }
380 rc = docopyallf(type,, "%s",); /* recurse */
381 }
382 else
383 rc = docopyf(type,, "%s",); /* copy file */
384 DosError(FERR_DISABLEHARDERR);
385 } while (!rc && !DosFindNext());
386 DosFindClose(hdir);
387 }
388 else
389 rc = ERROR_FILE_NOT_FOUND;
390 return rc;
391}
392
393#endif
394
395APIRET docopyf(INT type, CHAR * oldname, CHAR * newname, ...)
396{
397 /*
398 * returns:
399 * 0: success
400 * -1: bad string parameter(s)
401 * -2: source didn't exist
402 * -3: bad type
403 * anything else: API return
404 */
405
406 CHAR fullnewname[CCHMAXPATH + 1], longname[CCHMAXPATH],
407 shortname[CCHMAXPATH];
408 CHAR olddisk, newdisk, dir[CCHMAXPATH], *p, *pp;
409 APIRET ret = -1, rc;
410 FILESTATUS3L st, st2, dummy;
411 BOOL diskchange = FALSE, zaplong = FALSE;
412 va_list ap;
413
414 *fullnewname = *shortname = *dir = 0;
415
416 va_start(ap, newname);
417 vsprintf(fullnewname, newname, ap);
418 va_end(ap);
419
420 if (!oldname || !*oldname || !*fullnewname) /* bad string args */
421 return (APIRET) - 1;
422
423 DosError(FERR_DISABLEHARDERR);
424 if (DosQueryPathInfo(oldname, FIL_STANDARDL, &st, sizeof(FILESTATUS3L)))
425 return (APIRET) - 2; /* no source */
426
427 AdjustWildcardName(oldname, fullnewname);
428 MakeFullName(oldname);
429 MakeFullName(fullnewname);
430 olddisk = toupper(*oldname); /* source drive */
431 newdisk = toupper(*fullnewname); /* destination drive */
432 if (!(driveflags[toupper(*oldname) - 'A'] & DRIVE_NOLONGNAMES))
433 *longname = 0;
434 else {
435 GetLongName(oldname, longname);
436 if (*longname) {
437 p = RootName(longname);
438 if (p != longname)
439 memmove(longname, p, strlen(p) + 1);
440 }
441 }
442 /* If root name changed make sure longname EA goes away */
443 p = RootName(oldname);
444 pp = RootName(fullnewname);
445 if (stricmp(p, pp)) {
446 zaplong = TRUE;
447 }
448
449 DosError(FERR_DISABLEHARDERR);
450 switch (type) {
451 case WPSMOVE:
452 {
453 HOBJECT hobjsrc;
454 HOBJECT hobjdest;
455
456 ret = ERROR_FILE_NOT_FOUND;
457 hobjsrc = WinQueryObject(oldname);
458 if (hobjsrc) {
459 strcpy(dir, fullnewname);
460 p = strrchr(dir, '\\');
461 if (p < dir + 3)
462 p++;
463 *p = 0;
464 ret = ERROR_PATH_NOT_FOUND;
465 hobjdest = WinQueryObject(dir);
466 if (hobjdest) {
467 ret = ERROR_GEN_FAILURE;
468 hobjsrc = WinMoveObject(hobjsrc, hobjdest, 0);
469 if (hobjsrc)
470 ret = 0;
471 }
472 }
473 }
474 return ret;
475
476 case WPSCOPY:
477 {
478 HOBJECT hobjsrc;
479 HOBJECT hobjdest;
480
481 ret = ERROR_FILE_NOT_FOUND;
482 hobjsrc = WinQueryObject(oldname);
483 if (hobjsrc) {
484 strcpy(dir, fullnewname);
485 p = strrchr(dir, '\\');
486 if (p < dir + 3)
487 p++;
488 *p = 0;
489 ret = ERROR_PATH_NOT_FOUND;
490 hobjdest = WinQueryObject(dir);
491 if (hobjdest) {
492 ret = ERROR_GEN_FAILURE;
493 hobjsrc = WinCopyObject(hobjsrc, hobjdest, 0);
494 if (hobjsrc)
495 ret = 0;
496 }
497 }
498 }
499 return ret;
500
501 case MOVE:
502 *dir = 0;
503 if (olddisk == newdisk) { /* same drive */
504 /* make temporary copy in case move fails */
505 if (IsFile(fullnewname) != -1 && stricmp(oldname, fullnewname)) {
506 strcpy(dir, fullnewname);
507 p = strrchr(dir, '\\');
508 if (p)
509 *p = 0;
510 strcat(dir, "\\");
511 MakeTempName(dir);
512 if (DosMove(fullnewname, dir))
513 *dir = 0;
514 }
515 DosError(FERR_DISABLEHARDERR);
516 ret = DosMove(oldname, fullnewname); /* move it */
517 if (ret && *dir) { /* failed -- clean up */
518 DosError(FERR_DISABLEHARDERR);
519 if (!DosMove(dir, fullnewname))
520 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
521 }
522 else if (!ret && *dir) {
523 if (!IsFile(dir)) {
524 if (!strchr(dir, '?') && !strchr(dir, '*'))
525 wipeallf("%s\\*", dir);
526 DosError(FERR_DISABLEHARDERR);
527 if (DosDeleteDir(dir)) {
528 make_deleteable(dir);
529 DosDeleteDir(dir);
530 }
531 }
532 else if (IsFile(dir) > 0) {
533 DosError(FERR_DISABLEHARDERR);
534 if (DosForceDelete(dir)) {
535 make_deleteable(dir);
536 DosForceDelete(dir);
537 }
538 if (zaplong)
539 ZapLongName(dir);
540 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(dir), MPVOID);
541 }
542 }
543 }
544 else { /* different drives */
545 DosError(FERR_DISABLEHARDERR);
546 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING); /* <=-NOTE! */
547 if (ret == ERROR_DISK_CHANGE) {
548 DosError(FERR_ENABLEHARDERR);
549 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING);
550 diskchange = TRUE;
551 }
552 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
553 if (TruncName(fullnewname, shortname)) { /* make 8.3 filename */
554 DosError(FERR_DISABLEHARDERR);
555 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
556 if (!ret) { /* success -- write longname ea */
557 WriteLongName(shortname, fullnewname);
558 strcpy(fullnewname, shortname);
559 /* broadcast fixup msg to windows */
560 Broadcast((HAB) 0,
561 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
562 }
563 }
564 }
565 else if (!ret && *longname) {
566
567 CHAR fixname[CCHMAXPATH];
568
569 strcpy(fixname, fullnewname);
570 p = strrchr(fixname, '\\');
571 if (p) {
572 p++;
573 *p = 0;
574 }
575 strcat(fixname, longname);
576 DosError(FERR_DISABLEHARDERR);
577 DosMove(fullnewname, fixname);
578 strcpy(fullnewname, fixname);
579 if (zaplong)
580 ZapLongName(fixname);
581 Broadcast((HAB) 0,
582 hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
583 }
584 if (!ret) { /* double-check success */
585 DosError(FERR_DISABLEHARDERR);
586 rc = DosQueryPathInfo(fullnewname,
587 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
588 if (rc == ERROR_DISK_CHANGE) {
589 DosError(FERR_ENABLEHARDERR);
590 rc = DosQueryPathInfo(fullnewname,
591 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
592 }
593 if (!rc && st2.cbFile == st.cbFile) { /* seems to have worked... */
594 DosError(FERR_DISABLEHARDERR);
595 if (diskchange) {
596 DosError(FERR_ENABLEHARDERR);
597 DosQueryPathInfo(oldname, FIL_STANDARDL, &dummy, sizeof(FILESTATUS3L)); /* force disk change */
598 }
599 if (!(st2.attrFile & FILE_DIRECTORY)) /* erase file */
600 unlinkf("%s", oldname);
601 else { /* remove directory */
602 wipeallf("%s\\*", oldname);
603 DosError(FERR_DISABLEHARDERR);
604 if (DosDeleteDir(oldname)) {
605 make_deleteable(oldname);
606 DosDeleteDir(oldname);
607 }
608 }
609 }
610 }
611 }
612 return ret;
613
614 case COPY:
615 DosError(FERR_DISABLEHARDERR);
616 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING); /* <=-NOTE! */
617 if (ret == ERROR_DISK_CHANGE) {
618 DosError(FERR_ENABLEHARDERR);
619 ret = DosCopy(oldname, fullnewname, DCPY_EXISTING);
620 diskchange = TRUE;
621 }
622 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
623 if (TruncName(fullnewname, shortname)) {
624 DosError((diskchange) ? FERR_ENABLEHARDERR : FERR_DISABLEHARDERR);
625 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
626 if (!ret) {
627 WriteLongName(shortname, fullnewname);
628 strcpy(fullnewname, shortname);
629 Broadcast((HAB) 0,
630 hwndMain, UM_UPDATERECORD, MPFROMP(shortname), MPVOID);
631 }
632 }
633 }
634 else if (!ret && *longname) {
635
636 CHAR fixname[CCHMAXPATH];
637
638 strcpy(fixname, fullnewname);
639 p = strrchr(fixname, '\\');
640 if (p) {
641 p++;
642 *p = 0;
643 }
644 strcat(fixname, longname);
645 DosError(FERR_DISABLEHARDERR);
646 DosMove(fullnewname, fixname);
647 if (zaplong)
648 ZapLongName(fixname);
649 Broadcast((HAB) 0, hwndMain, UM_UPDATERECORD, MPFROMP(fixname), MPVOID);
650 }
651 return ret;
652
653 default: /* shouldn't happen */
654 Runtime_Error(pszSrcFile, __LINE__, "bad case %u", type);
655 break;
656 }
657 return (APIRET) - 3; /* bad type */
658}
659
660INT make_deleteable(CHAR * filename)
661{
662 INT ret = -1;
663 FILESTATUS3 fsi;
664
665 DosError(FERR_DISABLEHARDERR);
666 if (!DosQueryPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi))) {
667 fsi.attrFile = 0;
668 DosError(FERR_DISABLEHARDERR);
669 if (!xDosSetPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi), 0))
670 ret = 0;
671 }
672 return ret;
673}
674
675INT wipeallf(CHAR *string, ...)
676{
677 /* unlink everything from directory on down... */
678
679 FILEFINDBUF3 *f;
680 HDIR search_handle;
681 ULONG num_matches;
682 CHAR *p, *ss, *str;
683 CHAR s[CCHMAXPATH], mask[257];
684 va_list ap;
685 INT rc;
686
687 va_start(ap, string);
688 vsprintf(s, string, ap);
689 va_end(ap);
690
691 if (!*s)
692 return -1;
693 p = s;
694 while ((p = strchr(p, '/')) != NULL) {
695 *p = '\\';
696 p++;
697 }
698
699 str = xstrdup(s, pszSrcFile, __LINE__);
700 if (!str)
701 return -1;
702
703 { /* safety net -- disallow deleting a root dir or partial name */
704 CHAR temp;
705
706 p = strrchr(str, '\\');
707 if (p) {
708 p++;
709 temp = *p;
710 *p = 0;
711 if (IsRoot(str) || !IsFullName(str)) {
712 /* under no circumstances! */
713 Runtime_Error(pszSrcFile, __LINE__, "bad name %s", str);
714 xfree(str, pszSrcFile, __LINE__);
715 return -1;
716 }
717 *p = temp;
718 }
719 }
720
721 p = s;
722 p = strrchr(s, '\\'); /* strip s to just path */
723 if (!p)
724 p = strrchr(s, ':');
725 if (p) {
726 p++;
727 strncpy(mask, p, 256);
728 mask[256] = 0;
729 *p = 0;
730 }
731 else {
732 *mask = 0;
733 *s = 0;
734 }
735
736 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
737 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
738 if (!ss || !f) {
739 xfree(ss, pszSrcFile, __LINE__);
740 xfree(f, pszSrcFile, __LINE__);
741 xfree(str, pszSrcFile, __LINE__);
742 return -1;
743 }
744
745 search_handle = HDIR_CREATE;
746 num_matches = 1;
747
748 DosError(FERR_DISABLEHARDERR);
749 if (!DosFindFirst(str, &search_handle, FILE_NORMAL | FILE_DIRECTORY |
750 FILE_SYSTEM | FILE_READONLY | FILE_HIDDEN | FILE_ARCHIVED,
751 f, sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
752
753 strcpy(ss, s);
754 p = &ss[strlen(ss)];
755
756 do {
757 strcpy(p, f->achName);
758 if (f->attrFile & FILE_DIRECTORY) {
759 if (strcmp(f->achName, ".") && strcmp(f->achName, "..")) {
760 wipeallf("%s/%s", ss, mask); /* recurse to wipe files */
761 DosError(FERR_DISABLEHARDERR);
762 if (DosDeleteDir(ss)) { /* remove directory */
763 make_deleteable(ss);
764 DosError(FERR_DISABLEHARDERR);
765 DosDeleteDir(ss);
766 }
767 }
768 }
769 else {
770 DosError(FERR_DISABLEHARDERR);
771 if (DosForceDelete(ss)) {
772 make_deleteable(ss);
773 DosError(FERR_DISABLEHARDERR);
774 rc = (INT) DosForceDelete(ss);
775 if (rc)
776 return rc;
777 }
778 }
779 num_matches = 1;
780 DosError(FERR_DISABLEHARDERR);
781 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
782 &num_matches));
783 DosFindClose(search_handle);
784 }
785
786 xfree(f, pszSrcFile, __LINE__);
787 xfree(ss, pszSrcFile, __LINE__);
788 xfree(str, pszSrcFile, __LINE__);
789 return 0;
790}
791
792INT unlink_allf(CHAR * string, ...)
793{
794 /* wildcard delete */
795
796 FILEFINDBUF3 *f;
797 HDIR search_handle;
798 ULONG num_matches;
799 CHAR *p, *ss, *str;
800 CHAR s[CCHMAXPATH];
801 va_list ap;
802
803 va_start(ap, string);
804 vsprintf(s, string, ap);
805 va_end(ap);
806
807 if (!*s)
808 return -1;
809 p = s;
810 while ((p = strchr(p, '/')) != NULL) {
811 *p = '\\';
812 p++;
813 }
814
815 str = xstrdup(s, pszSrcFile, __LINE__);
816 if (!str)
817 return -1;
818
819 p = s;
820 p = strrchr(s, '\\'); /* strip s to just path */
821 if (!p)
822 p = strrchr(s, ':');
823 if (p) {
824 p++;
825 *p = 0;
826 }
827 else
828 *s = 0;
829
830 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
831 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
832 if (!ss || !f) {
833 xfree(ss, pszSrcFile, __LINE__);
834 xfree(f, pszSrcFile, __LINE__);
835 xfree(str, pszSrcFile, __LINE__);
836 return -1;
837 }
838
839 search_handle = HDIR_CREATE;
840 num_matches = 1;
841
842 DosError(FERR_DISABLEHARDERR);
843 if (!DosFindFirst(str, &search_handle, FILE_NORMAL, f,
844 sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
845
846 strcpy(ss, s);
847 p = &ss[strlen(ss)];
848
849 do {
850 strcpy(p, f->achName);
851 unlinkf("%s", ss);
852 num_matches = 1;
853 DosError(FERR_DISABLEHARDERR);
854 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
855 &num_matches));
856 DosFindClose(search_handle);
857 }
858
859 xfree(f, pszSrcFile, __LINE__);
860 xfree(ss, pszSrcFile, __LINE__);
861 xfree(str, pszSrcFile, __LINE__);
862 return 0;
863}
864
865INT unlinkf(CHAR * string, ...)
866{
867 CHAR buffer[CCHMAXPATH];
868 va_list ap;
869
870 va_start(ap, string);
871 vsprintf(buffer, string, ap);
872 va_end(ap);
873
874 if (!strstr(buffer, ArcTempRoot)) {
875 DosError(FERR_DISABLEHARDERR);
876 if (DosDelete(buffer)) {
877 make_deleteable(buffer);
878 DosError(FERR_DISABLEHARDERR);
879 return DosDelete(buffer);
880 }
881 }
882 else {
883 DosError(FERR_DISABLEHARDERR);
884 if (DosForceDelete(buffer)) {
885 make_deleteable(buffer);
886 DosError(FERR_DISABLEHARDERR);
887 return DosForceDelete(buffer);
888 }
889 }
890 return 0;
891}
892
893#pragma alloc_text(LONGNAMES,TruncName,GetLongName,WriteLongName)
894#pragma alloc_text(LONGNAMES,ZapLongName,AdjustWildcardName)
895#pragma alloc_text(COPYF,default_disk,docopyf)
896#pragma alloc_text(UNLINKF,unlinkf,unlink_allf,make_deleteable,wipeallf)
Note: See TracBrowser for help on using the repository browser.