source: trunk/dll/copyf.c@ 1082

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

Changes so FM2 will use TMP/TEMP directory for all temp files; Replaced save_dir2 with global variable so BldFullPathName could easily replace code that performed the same function; Added #ifdef FORTIFY to free_ function that are only used when fortified.

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