source: trunk/dll/copyf.c@ 1222

Last change on this file since 1222 was 1222, checked in by John Small, 17 years ago

Ticket 187: Moved typedef's and some #define's from fm3dll.h

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