source: trunk/dll/copyf.c@ 1039

Last change on this file since 1039 was 1039, checked in by Gregg Young, 17 years ago

Removed unnecessary xfrees and included fortify.h where needed; moved several misplaced (x)frees;

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: copyf.c 1039 2008-07-05 22:16:21Z 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 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#include "fortify.h"
39
40static PSZ pszSrcFile = __FILE__;
41
42#ifndef WinMoveObject
43HOBJECT APIENTRY WinMoveObject(HOBJECT hObjectofObject,
44 HOBJECT hObjectofDest, ULONG ulReserved);
45#endif
46#ifndef WinCopyObject
47HOBJECT APIENTRY WinCopyObject(HOBJECT hObjectofObject,
48 HOBJECT hObjectofDest, ULONG ulReserved);
49#endif
50
51char *MakeTempName(char *buffer)
52{
53 FILESTATUS3 fs3;
54 APIRET rc;
55 char *p, *o;
56
57 p = o = buffer + strlen(buffer);
58 sprintf(p, "%08lx.%03lx", clock(), mypid);
59 p = buffer + (strlen(buffer) - 1);
60 for (;;) {
61 DosError(FERR_DISABLEHARDERR);
62 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
63 if (rc == ERROR_DISK_CHANGE) {
64 DosError(FERR_ENABLEHARDERR);
65 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
66 }
67 if (rc)
68 break;
69 Loop:
70 if (p < o) {
71 *buffer = 0;
72 return NULL;
73 }
74 if ((*p) + 1 < 'Z' + 1) {
75 (*p)++;
76 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
77 (*p)++;
78 *p = toupper(*p);
79 }
80 else {
81 p--;
82 if (p >= o && *p == '.')
83 p--;
84 goto Loop;
85 }
86 }
87 return buffer;
88}
89
90CHAR *TruncName(CHAR * oldname, CHAR * buffer)
91{
92 CHAR *p, *f, *s, *o;
93 FILESTATUS3 fs3;
94 APIRET rc;
95
96 if (!buffer || !oldname || !*oldname) {
97 if (buffer)
98 *buffer = 0;
99 return NULL;
100 }
101 strcpy(buffer, oldname);
102 f = strrchr(buffer, '\\');
103 if (!f)
104 f = strrchr(buffer, '/');
105 if (!f)
106 f = buffer;
107 else
108 f++;
109 p = f;
110 o = p;
111 f = oldname + (f - buffer);
112 strupr(buffer);
113 while (*f == '.') /* skip leading '.'s */
114 f++;
115 s = f;
116 while (*f && *f != '.' && f < s + 8) { /* skip past rootname */
117 *p = toupper(*f);
118 p++;
119 f++;
120 }
121 while (*f == '.')
122 f++;
123 s = f;
124 f = strrchr(f, '.');
125 if (f) {
126 while (*f == '.')
127 f++;
128 }
129 if (f && *(f + 1))
130 s = f;
131 else
132 f = s;
133 if (*f) {
134 *p = '.';
135 p++;
136 while (*f && *f != '.' && f < s + 3) {
137 *p = toupper(*f);
138 p++;
139 f++;
140 }
141 }
142 *p = 0;
143
144 p = o;
145 while (*p) {
146 if (strchr("*?<>\":/\\|+=;,[] ", *p) || *p < 0x20)
147 *p = '_';
148 if (*p == '.' && *(p + 1) == '.')
149 *(p + 1) = '_';
150 p++;
151 }
152
153 p = o + (strlen(o) - 1);
154 for (;;) {
155 DosError(FERR_DISABLEHARDERR);
156 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
157 if (rc == ERROR_DISK_CHANGE) {
158 DosError(FERR_ENABLEHARDERR);
159 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
160 }
161 if (rc)
162 break;
163 Loop:
164 if (p < o) {
165 *buffer = 0;
166 return NULL;
167 }
168 if ((*p) + 1 < 'Z' + 1) {
169 (*p)++;
170 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
171 (*p)++;
172 *p = toupper(*p);
173 }
174 else {
175 p--;
176 if (p >= o && *p == '.')
177 p--;
178 goto Loop;
179 }
180 }
181 return buffer;
182}
183
184CHAR *GetLongName(CHAR * oldname, CHAR * longname)
185{
186 if (!longname)
187 return NULL;
188 *longname = 0;
189 if (!oldname || !*oldname)
190 return NULL;
191 if (IsFullName(oldname)) {
192
193 APIRET rc;
194 EAOP2 eaop;
195 PGEA2LIST pgealist;
196 PFEA2LIST pfealist;
197 PGEA2 pgea;
198 PFEA2 pfea;
199 CHAR *value;
200
201 strcpy(longname, oldname);
202 value = longname;
203 while (*value) {
204 if (*value == '/')
205 *value = '\\';
206 value++;
207 }
208 value = strrchr(longname, '\\');
209 if (value) {
210 value++;
211 *value = 0;
212 }
213 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
214 if (pgealist) {
215 pgea = &pgealist->list[0];
216 strcpy(pgea->szName, LONGNAME);
217 pgea->cbName = strlen(pgea->szName);
218 pgea->oNextEntryOffset = 0L;
219 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
220 pfealist = xmallocz(1536, pszSrcFile, __LINE__);
221 if (pfealist) {
222 pfealist->cbList = 1024;
223 eaop.fpGEA2List = pgealist;
224 eaop.fpFEA2List = pfealist;
225 eaop.oError = 0L;
226 DosError(FERR_DISABLEHARDERR);
227 rc = DosQueryPathInfo(oldname,
228 FIL_QUERYEASFROMLIST,
229 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
230 if (!rc) {
231 pfea = &eaop.fpFEA2List->list[0];
232 value = pfea->szName + pfea->cbName + 1;
233 value[pfea->cbValue] = 0;
234 if (*(USHORT *) value == EAT_ASCII)
235 strncat(longname,
236 value + (sizeof(USHORT) * 2),
237 CCHMAXPATH - strlen(longname));
238 longname[CCHMAXPATH - 1] = 0;
239 }
240 free(pfealist);
241 }
242 free(pgealist);
243 }
244 }
245 return longname;
246}
247
248BOOL ZapLongName(char *filename)
249{
250 return WriteLongName(filename, "");
251}
252
253BOOL WriteLongName(CHAR * filename, CHAR * longname)
254{
255 APIRET rc;
256 EAOP2 eaop;
257 PFEA2LIST pfealist = NULL;
258 ULONG ealen;
259 USHORT len;
260 CHAR *eaval, *p;
261
262 if (!filename || !*filename || !longname)
263 return FALSE;
264 p = strrchr(longname, '\\');
265 if (p)
266 memmove(longname, p + 1, strlen(p + 1) + 1);
267 p = strrchr(longname, '/');
268 if (p)
269 memmove(longname, p + 1, strlen(p + 1) + 1);
270 bstrip(longname);
271 len = strlen(longname);
272 if (len)
273 ealen = sizeof(FEA2LIST) + 10 + len + 4;
274 else
275 ealen = sizeof(FEALIST) + 10;
276 rc = DosAllocMem((PPVOID) & pfealist,
277 ealen + 32L, OBJ_TILE | PAG_COMMIT | PAG_READ | PAG_WRITE);
278 if (rc)
279 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
280 GetPString(IDS_OUTOFMEMORY));
281 else {
282 memset(pfealist, 0, ealen + 1);
283 pfealist->cbList = ealen;
284 pfealist->list[0].oNextEntryOffset = 0;
285 pfealist->list[0].fEA = 0;
286 pfealist->list[0].cbName = 9;
287 strcpy(pfealist->list[0].szName, LONGNAME);
288 if (len) {
289 eaval = pfealist->list[0].szName + 10;
290 *(USHORT *) eaval = (USHORT) EAT_ASCII;
291 eaval += sizeof(USHORT);
292 *(USHORT *) eaval = (USHORT) len;
293 eaval += sizeof(USHORT);
294 memcpy(eaval, longname, len);
295 pfealist->list[0].cbValue = len + (sizeof(USHORT) * 2);
296 }
297 else
298 pfealist->list[0].cbValue = 0;
299 eaop.fpGEA2List = (PGEA2LIST) 0;
300 eaop.fpFEA2List = pfealist;
301 eaop.oError = 0L;
302 DosError(FERR_DISABLEHARDERR);
303 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
304 &eaop, sizeof(eaop), 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 FILESTATUS3L 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_STANDARDL, &st, sizeof(FILESTATUS3L)))
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_STANDARDL, &st2, sizeof(FILESTATUS3L));
589 if (rc == ERROR_DISK_CHANGE) {
590 DosError(FERR_ENABLEHARDERR);
591 rc = DosQueryPathInfo(fullnewname,
592 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
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_STANDARDL, &dummy, sizeof(FILESTATUS3L)); /* 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(fsi))) {
668 fsi.attrFile = 0;
669 DosError(FERR_DISABLEHARDERR);
670 if (!xDosSetPathInfo(filename, FIL_STANDARD, &fsi, sizeof(fsi), 0))
671 ret = 0;
672 }
673 return ret;
674}
675
676INT wipeallf(CHAR *string, ...)
677{
678 /* unlink everything from directory on down... */
679
680 FILEFINDBUF3 *f;
681 HDIR search_handle;
682 ULONG num_matches;
683 CHAR *p, *ss, *str;
684 CHAR s[CCHMAXPATH], mask[257];
685 va_list ap;
686 INT rc;
687
688 va_start(ap, string);
689 vsprintf(s, string, ap);
690 va_end(ap);
691
692 if (!*s)
693 return -1;
694 p = s;
695 while ((p = strchr(p, '/')) != NULL) {
696 *p = '\\';
697 p++;
698 }
699
700 str = xstrdup(s, pszSrcFile, __LINE__);
701 if (!str)
702 return -1;
703
704 { /* safety net -- disallow deleting a root dir or partial name */
705 CHAR temp;
706
707 p = strrchr(str, '\\');
708 if (p) {
709 p++;
710 temp = *p;
711 *p = 0;
712 if (IsRoot(str) || !IsFullName(str)) {
713 /* under no circumstances! */
714 Runtime_Error(pszSrcFile, __LINE__, "bad name %s", str);
715 free(str);
716 return -1;
717 }
718 *p = temp;
719 }
720 }
721
722 p = s;
723 p = strrchr(s, '\\'); /* strip s to just path */
724 if (!p)
725 p = strrchr(s, ':');
726 if (p) {
727 p++;
728 strncpy(mask, p, 256);
729 mask[256] = 0;
730 *p = 0;
731 }
732 else {
733 *mask = 0;
734 *s = 0;
735 }
736
737 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
738 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
739 if (!ss || !f) {
740 xfree(ss, pszSrcFile, __LINE__);
741 xfree(f, pszSrcFile, __LINE__);
742 free(str);
743 return -1;
744 }
745
746 search_handle = HDIR_CREATE;
747 num_matches = 1;
748
749 DosError(FERR_DISABLEHARDERR);
750 if (!DosFindFirst(str, &search_handle, FILE_NORMAL | FILE_DIRECTORY |
751 FILE_SYSTEM | FILE_READONLY | FILE_HIDDEN | FILE_ARCHIVED,
752 f, sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
753
754 strcpy(ss, s);
755 p = &ss[strlen(ss)];
756
757 do {
758 strcpy(p, f->achName);
759 if (f->attrFile & FILE_DIRECTORY) {
760 if (strcmp(f->achName, ".") && strcmp(f->achName, "..")) {
761 wipeallf("%s/%s", ss, mask); /* recurse to wipe files */
762 DosError(FERR_DISABLEHARDERR);
763 if (DosDeleteDir(ss)) { /* remove directory */
764 make_deleteable(ss);
765 DosError(FERR_DISABLEHARDERR);
766 DosDeleteDir(ss);
767 }
768 }
769 }
770 else {
771 DosError(FERR_DISABLEHARDERR);
772 if (DosForceDelete(ss)) {
773 make_deleteable(ss);
774 DosError(FERR_DISABLEHARDERR);
775 rc = (INT) DosForceDelete(ss);
776 if (rc)
777 return rc;
778 }
779 }
780 num_matches = 1;
781 DosError(FERR_DISABLEHARDERR);
782 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
783 &num_matches));
784 DosFindClose(search_handle);
785 }
786
787 free(f);
788 free(ss);
789 free(str);
790 return 0;
791}
792
793INT unlink_allf(CHAR * string, ...)
794{
795 /* wildcard delete */
796
797 FILEFINDBUF3 *f;
798 HDIR search_handle;
799 ULONG num_matches;
800 CHAR *p, *ss, *str;
801 CHAR s[CCHMAXPATH];
802 va_list ap;
803
804 va_start(ap, string);
805 vsprintf(s, string, ap);
806 va_end(ap);
807
808 if (!*s)
809 return -1;
810 p = s;
811 while ((p = strchr(p, '/')) != NULL) {
812 *p = '\\';
813 p++;
814 }
815
816 str = xstrdup(s, pszSrcFile, __LINE__);
817 if (!str)
818 return -1;
819
820 p = s;
821 p = strrchr(s, '\\'); /* strip s to just path */
822 if (!p)
823 p = strrchr(s, ':');
824 if (p) {
825 p++;
826 *p = 0;
827 }
828 else
829 *s = 0;
830
831 ss = xmalloc(CCHMAXPATH, pszSrcFile, __LINE__);
832 f = xmalloc(sizeof(FILEFINDBUF3), pszSrcFile, __LINE__);
833 if (!ss || !f) {
834 xfree(ss, pszSrcFile, __LINE__);
835 xfree(f, pszSrcFile, __LINE__);
836 free(str);
837 return -1;
838 }
839
840 search_handle = HDIR_CREATE;
841 num_matches = 1;
842
843 DosError(FERR_DISABLEHARDERR);
844 if (!DosFindFirst(str, &search_handle, FILE_NORMAL, f,
845 sizeof(FILEFINDBUF3), &num_matches, FIL_STANDARD)) {
846
847 strcpy(ss, s);
848 p = &ss[strlen(ss)];
849
850 do {
851 strcpy(p, f->achName);
852 unlinkf("%s", ss);
853 num_matches = 1;
854 DosError(FERR_DISABLEHARDERR);
855 } while (!DosFindNext(search_handle, f, sizeof(FILEFINDBUF3),
856 &num_matches));
857 DosFindClose(search_handle);
858 }
859
860 free(f);
861 free(ss);
862 free(str);
863 return 0;
864}
865
866INT unlinkf(CHAR * string, ...)
867{
868 CHAR buffer[CCHMAXPATH];
869 va_list ap;
870
871 va_start(ap, string);
872 vsprintf(buffer, string, ap);
873 va_end(ap);
874
875 if (!strstr(buffer, ArcTempRoot)) {
876 DosError(FERR_DISABLEHARDERR);
877 if (DosDelete(buffer)) {
878 make_deleteable(buffer);
879 DosError(FERR_DISABLEHARDERR);
880 return DosDelete(buffer);
881 }
882 }
883 else {
884 DosError(FERR_DISABLEHARDERR);
885 if (DosForceDelete(buffer)) {
886 make_deleteable(buffer);
887 DosError(FERR_DISABLEHARDERR);
888 return DosForceDelete(buffer);
889 }
890 }
891 return 0;
892}
893
894#pragma alloc_text(LONGNAMES,TruncName,GetLongName,WriteLongName)
895#pragma alloc_text(LONGNAMES,ZapLongName,AdjustWildcardName)
896#pragma alloc_text(COPYF,default_disk,docopyf)
897#pragma alloc_text(UNLINKF,unlinkf,unlink_allf,make_deleteable,wipeallf)
Note: See TracBrowser for help on using the repository browser.