source: trunk/dll/copyf.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: copyf.c 1438 2009-06-28 20:47:00Z 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 08 Mar 09 GKY Removed variable aurguments from docopyf and unlinkf (not used)
23 28 Jun 09 GKY Added AddBackslashToPath() to remove repeatative code.
24
25***********************************************************************/
26
27#include <stdlib.h>
28#include <string.h>
29#include <stdarg.h>
30#include <ctype.h>
31
32#define INCL_DOS
33#define INCL_DOSERRORS
34#define INCL_WIN
35#define INCL_LONGLONG
36
37#include "fm3dll.h"
38#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
39#include "killproc.h" // Data declaration(s)
40#include "notebook.h" // Data declaration(s)
41#include "info.h" // Data declaration(s)
42#include "init.h" // Data declaration(s)
43#include "arccnrs.h"
44#include "fm3str.h"
45#include "errutil.h" // Dos_Error...
46#include "strutil.h" // GetPString
47#include "copyf.h"
48#include "literal.h" // fixup
49#include "misc.h" // Broadcast
50#include "valid.h" // MakeFullName
51#include "wrappers.h" // xDosSetPathInfo
52#include "strips.h" // bstrip
53#include "fortify.h"
54#include "pathutil.h" // AddBackslashToPath
55
56static PSZ pszSrcFile = __FILE__;
57
58static CHAR *GetLongName(CHAR * oldname, CHAR * buffer);
59static CHAR *TruncName(CHAR * oldname, CHAR * buffer);
60
61//static CHAR default_disk(VOID);
62//static INT unlink_allf(CHAR * string, ...);
63
64#ifndef WinMoveObject
65HOBJECT APIENTRY WinMoveObject(HOBJECT hObjectofObject,
66 HOBJECT hObjectofDest, ULONG ulReserved);
67#endif
68#ifndef WinCopyObject
69HOBJECT APIENTRY WinCopyObject(HOBJECT hObjectofObject,
70 HOBJECT hObjectofDest, ULONG ulReserved);
71#endif
72
73char *MakeTempName(char *buffer, char *temproot, INT type)
74{
75 FILESTATUS3 fs3;
76 APIRET rc;
77 char *p, *o;
78
79
80 if (strlen(buffer) > 3) // && buffer[strlen(buffer) - 1] != '\\')
81 AddBackslashToPath(buffer);
82 //strcat(buffer, "\\");
83 p = o = buffer + strlen(buffer);
84 switch (type) {
85 case 0:
86 sprintf(p, "%08lx.%03lx", rand() & 4095L, mypid);
87 break;
88 case 1:
89 sprintf(p, "%s%04lx.%03lx", "$FM2", rand() & 4095L, mypid);
90 break;
91 case 2:
92 sprintf(p, "%s.%03x", temproot, (rand() & 4095));
93 break;
94 default:
95 break;
96 }
97 p = buffer + (strlen(buffer) - 1);
98 for (;;) {
99 DosError(FERR_DISABLEHARDERR);
100 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
101 if (rc == ERROR_DISK_CHANGE) {
102 DosError(FERR_ENABLEHARDERR);
103 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
104 }
105 if (rc)
106 break;
107 Loop:
108 if (p < o) {
109 *buffer = 0;
110 return NULL;
111 }
112 if ((*p) + 1 < 'Z' + 1) {
113 (*p)++;
114 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
115 (*p)++;
116 *p = toupper(*p);
117 }
118 else {
119 p--;
120 if (p >= o && *p == '.')
121 p--;
122 goto Loop;
123 }
124 }
125 return buffer;
126}
127
128CHAR *TruncName(CHAR * oldname, CHAR * buffer)
129{
130 CHAR *p, *f, *s, *o;
131 FILESTATUS3 fs3;
132 APIRET rc;
133
134 if (!buffer || !oldname || !*oldname) {
135 if (buffer)
136 *buffer = 0;
137 return NULL;
138 }
139 strcpy(buffer, oldname);
140 f = strrchr(buffer, '\\');
141 if (!f)
142 f = strrchr(buffer, '/');
143 if (!f)
144 f = buffer;
145 else
146 f++;
147 p = f;
148 o = p;
149 f = oldname + (f - buffer);
150 strupr(buffer);
151 while (*f == '.') /* skip leading '.'s */
152 f++;
153 s = f;
154 while (*f && *f != '.' && f < s + 8) { /* skip past rootname */
155 *p = toupper(*f);
156 p++;
157 f++;
158 }
159 while (*f == '.')
160 f++;
161 s = f;
162 f = strrchr(f, '.');
163 if (f) {
164 while (*f == '.')
165 f++;
166 }
167 if (f && *(f + 1))
168 s = f;
169 else
170 f = s;
171 if (*f) {
172 *p = '.';
173 p++;
174 while (*f && *f != '.' && f < s + 3) {
175 *p = toupper(*f);
176 p++;
177 f++;
178 }
179 }
180 *p = 0;
181
182 p = o;
183 while (*p) {
184 if (strchr("*?<>\":/\\|+=;,[] ", *p) || *p < 0x20)
185 *p = '_';
186 if (*p == '.' && *(p + 1) == '.')
187 *(p + 1) = '_';
188 p++;
189 }
190
191 p = o + (strlen(o) - 1);
192 for (;;) {
193 DosError(FERR_DISABLEHARDERR);
194 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
195 if (rc == ERROR_DISK_CHANGE) {
196 DosError(FERR_ENABLEHARDERR);
197 rc = DosQueryPathInfo(buffer, FIL_STANDARD, &fs3, sizeof(fs3));
198 }
199 if (rc)
200 break;
201 Loop:
202 if (p < o) {
203 *buffer = 0;
204 return NULL;
205 }
206 if ((*p) + 1 < 'Z' + 1) {
207 (*p)++;
208 while (strchr("*?<>\":/\\|+=;,[]. ", *p))
209 (*p)++;
210 *p = toupper(*p);
211 }
212 else {
213 p--;
214 if (p >= o && *p == '.')
215 p--;
216 goto Loop;
217 }
218 }
219 return buffer;
220}
221
222CHAR *GetLongName(CHAR * oldname, CHAR * longname)
223{
224 if (!longname)
225 return NULL;
226 *longname = 0;
227 if (!oldname || !*oldname)
228 return NULL;
229 if (IsFullName(oldname)) {
230
231 APIRET rc;
232 EAOP2 eaop;
233 PGEA2LIST pgealist;
234 PFEA2LIST pfealist;
235 PGEA2 pgea;
236 PFEA2 pfea;
237 CHAR *value;
238
239 strcpy(longname, oldname);
240 value = longname;
241 while (*value) {
242 if (*value == '/')
243 *value = '\\';
244 value++;
245 }
246 value = strrchr(longname, '\\');
247 if (value) {
248 value++;
249 *value = 0;
250 }
251 pgealist = xmallocz(sizeof(GEA2LIST) + 32, pszSrcFile, __LINE__);
252 if (pgealist) {
253 pgea = &pgealist->list[0];
254 strcpy(pgea->szName, LONGNAME);
255 pgea->cbName = strlen(pgea->szName);
256 pgea->oNextEntryOffset = 0L;
257 pgealist->cbList = (sizeof(GEA2LIST) + pgea->cbName);
258 pfealist = xmallocz(1536, pszSrcFile, __LINE__);
259 if (pfealist) {
260 pfealist->cbList = 1024;
261 eaop.fpGEA2List = pgealist;
262 eaop.fpFEA2List = pfealist;
263 eaop.oError = 0L;
264 DosError(FERR_DISABLEHARDERR);
265 rc = DosQueryPathInfo(oldname,
266 FIL_QUERYEASFROMLIST,
267 (PVOID) & eaop, (ULONG) sizeof(EAOP2));
268 if (!rc) {
269 pfea = &eaop.fpFEA2List->list[0];
270 value = pfea->szName + pfea->cbName + 1;
271 value[pfea->cbValue] = 0;
272 if (*(USHORT *) value == EAT_ASCII)
273 strncat(longname,
274 value + (sizeof(USHORT) * 2),
275 CCHMAXPATH - strlen(longname));
276 longname[CCHMAXPATH - 1] = 0;
277 }
278 free(pfealist);
279 }
280 free(pgealist);
281 }
282 }
283 return longname;
284}
285
286BOOL ZapLongName(char *filename)
287{
288 return WriteLongName(filename, NullStr);
289}
290
291BOOL WriteLongName(CHAR * filename, CHAR * longname)
292{
293 APIRET rc;
294 EAOP2 eaop;
295 PFEA2LIST pfealist = NULL;
296 ULONG ealen;
297 USHORT len;
298 CHAR *eaval, *p;
299
300 if (!filename || !*filename || !longname)
301 return FALSE;
302 p = strrchr(longname, '\\');
303 if (p)
304 memmove(longname, p + 1, strlen(p + 1) + 1);
305 p = strrchr(longname, '/');
306 if (p)
307 memmove(longname, p + 1, strlen(p + 1) + 1);
308 bstrip(longname);
309 len = strlen(longname);
310 if (len)
311 ealen = sizeof(FEA2LIST) + 10 + len + 4;
312 else
313 ealen = sizeof(FEALIST) + 10;
314 rc = xDosAllocMem((PPVOID) & pfealist,
315 ealen + 32L, OBJ_TILE | PAG_COMMIT | PAG_READ | PAG_WRITE);
316 if (rc)
317 Dos_Error(MB_CANCEL, rc, HWND_DESKTOP, pszSrcFile, __LINE__,
318 GetPString(IDS_OUTOFMEMORY));
319 else {
320 memset(pfealist, 0, ealen + 1);
321 pfealist->cbList = ealen;
322 pfealist->list[0].oNextEntryOffset = 0;
323 pfealist->list[0].fEA = 0;
324 pfealist->list[0].cbName = 9;
325 strcpy(pfealist->list[0].szName, LONGNAME);
326 if (len) {
327 eaval = pfealist->list[0].szName + 10;
328 *(USHORT *) eaval = (USHORT) EAT_ASCII;
329 eaval += sizeof(USHORT);
330 *(USHORT *) eaval = (USHORT) len;
331 eaval += sizeof(USHORT);
332 memcpy(eaval, longname, len);
333 pfealist->list[0].cbValue = len + (sizeof(USHORT) * 2);
334 }
335 else
336 pfealist->list[0].cbValue = 0;
337 eaop.fpGEA2List = (PGEA2LIST) 0;
338 eaop.fpFEA2List = pfealist;
339 eaop.oError = 0L;
340 DosError(FERR_DISABLEHARDERR);
341 rc = xDosSetPathInfo(filename, FIL_QUERYEASIZE,
342 &eaop, sizeof(eaop), DSPI_WRTTHRU);
343 DosFreeMem(pfealist);
344 if (rc)
345 return FALSE;
346 }
347 return TRUE;
348}
349
350BOOL AdjustWildcardName(CHAR * oldname, CHAR * newname)
351{
352 BOOL ret = FALSE;
353
354 /* NOTE: newname should be CCHMAXPATH chars long! */
355
356 if (strchr(newname, '*') || strchr(newname, '?')) {
357
358 CHAR srce[CCHMAXPATHCOMP], dest[CCHMAXPATHCOMP], result[CCHMAXPATHCOMP],
359 *p;
360
361 p = strrchr(newname, '\\');
362 if (p && *(p + 1)) {
363 strcpy(dest, p + 1);
364 p = strrchr(oldname, '\\');
365 if (p && *(p + 1)) {
366 strcpy(srce, p + 1);
367 DosError(FERR_DISABLEHARDERR);
368 if (!DosEditName(1L, srce, dest, (PBYTE)result, (ULONG)sizeof(result))) {
369 p = strrchr(newname, '\\');
370 p++;
371 strcpy(p, result);
372 ret = TRUE;
373 }
374 }
375 }
376 }
377 return ret;
378}
379
380#if 0 // JBS 11 Sep 08
381CHAR default_disk(VOID)
382{
383 ULONG ulDriveNum, ulDriveMap;
384
385 DosError(FERR_DISABLEHARDERR);
386 DosQCurDisk(&ulDriveNum, &ulDriveMap);
387 return (CHAR) toupper((INT) ulDriveNum) + '@';
388}
389#endif
390
391#ifdef NEVER
392
393APIRET docopyallf(INT type, CHAR * oldname, CHAR * newname, ...)
394{
395 FILEFINDBUF3 fb;
396 ULONG nm;
397 HDIR hdir;
398 APIRET rc = 0;
399 CHAR *enddir, fullname[CCHMAXPATH];
400
401 va_start(ap, newname);
402 vsprintf(fullname, newname, ap);
403 va_end(ap);
404
405 DosError(FERR_DISABLEHARDERR);
406 if (!DosFindFirst(oldname)) {
407 do {
408
409 /* build target name */
410
411 if (fb.attrFile & FILE_DIRECTORY) {
412 DosError(FERR_ENABLEHARDERR);
413 rc = DosCreateDir();
414 if (rc == ERROR_INVALID_NAME || rc == ERROR_FILENAME_EXCED_RANGE) {
415
416 /* truncate directory name */
417 /* create that directory */
418 /* update containers for name used */
419
420 }
421 rc = docopyallf(type,, "%s",); /* recurse */
422 }
423 else
424 // docopyf changed this won't work rc = docopyf(type,, "%s",); /* copy file */
425 DosError(FERR_DISABLEHARDERR);
426 } while (!rc && !DosFindNext());
427 DosFindClose(hdir);
428 }
429 else
430 rc = ERROR_FILE_NOT_FOUND;
431 return rc;
432}
433
434#endif
435
436APIRET docopyf(INT type, CHAR *oldname, CHAR *newname)
437{
438 /*
439 * returns:
440 * 0: success
441 * -1: bad string parameter(s)
442 * -2: source didn't exist
443 * -3: bad type
444 * anything else: API return
445 */
446
447 CHAR longname[CCHMAXPATH], shortname[CCHMAXPATH];
448 CHAR olddisk, newdisk, dir[CCHMAXPATH], *p, *pp;
449 APIRET ret = -1, rc;
450 FILESTATUS3L st, st2, dummy;
451 BOOL diskchange = FALSE, zaplong = FALSE;
452
453 *shortname = *dir = 0;
454
455 if (!oldname || !*oldname || !*newname) /* bad string args */
456 return (APIRET) - 1;
457
458 DosError(FERR_DISABLEHARDERR);
459 if (DosQueryPathInfo(oldname, FIL_STANDARDL, &st, sizeof(FILESTATUS3L)))
460 return (APIRET) - 2; /* no source */
461
462 AdjustWildcardName(oldname, newname);
463 MakeFullName(oldname);
464 MakeFullName(newname);
465 olddisk = toupper(*oldname); /* source drive */
466 newdisk = toupper(*newname); /* destination drive */
467 if (!(driveflags[toupper(*oldname) - 'A'] & DRIVE_NOLONGNAMES))
468 *longname = 0;
469 else {
470 GetLongName(oldname, longname);
471 if (*longname) {
472 p = RootName(longname);
473 if (p != longname)
474 memmove(longname, p, strlen(p) + 1);
475 }
476 }
477 /* If root name changed make sure longname EA goes away */
478 p = RootName(oldname);
479 pp = RootName(newname);
480 if (stricmp(p, pp)) {
481 zaplong = TRUE;
482 }
483
484 DosError(FERR_DISABLEHARDERR);
485 switch (type) {
486 case WPSMOVE:
487 {
488 HOBJECT hobjsrc;
489 HOBJECT hobjdest;
490
491 ret = ERROR_FILE_NOT_FOUND;
492 hobjsrc = WinQueryObject(oldname);
493 if (hobjsrc) {
494 strcpy(dir, newname);
495 p = strrchr(dir, '\\');
496 if (p < dir + 3)
497 p++;
498 *p = 0;
499 ret = ERROR_PATH_NOT_FOUND;
500 hobjdest = WinQueryObject(dir);
501 if (hobjdest) {
502 ret = ERROR_GEN_FAILURE;
503 hobjsrc = WinMoveObject(hobjsrc, hobjdest, 0);
504 if (hobjsrc)
505 ret = 0;
506 }
507 }
508 }
509 return ret;
510
511 case WPSCOPY:
512 {
513 HOBJECT hobjsrc;
514 HOBJECT hobjdest;
515
516 ret = ERROR_FILE_NOT_FOUND;
517 hobjsrc = WinQueryObject(oldname);
518 if (hobjsrc) {
519 strcpy(dir, newname);
520 p = strrchr(dir, '\\');
521 if (p < dir + 3)
522 p++;
523 *p = 0;
524 ret = ERROR_PATH_NOT_FOUND;
525 hobjdest = WinQueryObject(dir);
526 if (hobjdest) {
527 ret = ERROR_GEN_FAILURE;
528 hobjsrc = WinCopyObject(hobjsrc, hobjdest, 0);
529 if (hobjsrc)
530 ret = 0;
531 }
532 }
533 }
534 return ret;
535
536 case MOVE:
537 *dir = 0;
538 if (olddisk == newdisk) { /* same drive */
539 /* make temporary copy in case move fails */
540 if (IsFile(newname) != -1 && stricmp(oldname, newname)) {
541 strcpy(dir, newname);
542 AddBackslashToPath(dir);
543 //p = strrchr(dir, '\\');
544 //if (p)
545 // *p = 0;
546 //strcat(dir, "\\");
547 MakeTempName(dir, NULL, 0);
548 if (DosMove(newname, dir))
549 *dir = 0;
550 }
551 DosError(FERR_DISABLEHARDERR);
552 ret = DosMove(oldname, newname); /* move it */
553 if (ret && *dir) { /* failed -- clean up */
554 DosError(FERR_DISABLEHARDERR);
555 if (!DosMove(dir, newname))
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, newname, DCPY_EXISTING); /* <=-NOTE! */
583 if (ret == ERROR_DISK_CHANGE) {
584 DosError(FERR_ENABLEHARDERR);
585 ret = DosCopy(oldname, newname, DCPY_EXISTING);
586 diskchange = TRUE;
587 }
588 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
589 if (TruncName(newname, 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, newname);
594 strcpy(newname, 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, newname);
606 p = strrchr(fixname, '\\');
607 if (p) {
608 p++;
609 *p = 0;
610 }
611 strcat(fixname, longname);
612 DosError(FERR_DISABLEHARDERR);
613 DosMove(newname, fixname);
614 strcpy(newname, 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(newname,
623 FIL_STANDARDL, &st2, sizeof(FILESTATUS3L));
624 if (rc == ERROR_DISK_CHANGE) {
625 DosError(FERR_ENABLEHARDERR);
626 rc = DosQueryPathInfo(newname,
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(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, newname, DCPY_EXISTING); /* <=-NOTE! */
653 if (ret == ERROR_DISK_CHANGE) {
654 DosError(FERR_ENABLEHARDERR);
655 ret = DosCopy(oldname, newname, DCPY_EXISTING);
656 diskchange = TRUE;
657 }
658 if (ret == ERROR_INVALID_NAME || ret == ERROR_FILENAME_EXCED_RANGE) {
659 if (TruncName(newname, shortname)) {
660 DosError((diskchange) ? FERR_ENABLEHARDERR : FERR_DISABLEHARDERR);
661 ret = DosCopy(oldname, shortname, DCPY_EXISTING);
662 if (!ret) {
663 WriteLongName(shortname, newname);
664 strcpy(newname, 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, newname);
675 p = strrchr(fixname, '\\');
676 if (p) {
677 p++;
678 *p = 0;
679 }
680 strcat(fixname, longname);
681 DosError(FERR_DISABLEHARDERR);
682 DosMove(newname, 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
906 if (!strstr(string, ArcTempRoot)) {
907 DosError(FERR_DISABLEHARDERR);
908 if (DosDelete(string)) {
909 make_deleteable(string);
910 DosError(FERR_DISABLEHARDERR);
911 return DosDelete(string);
912 }
913 }
914 else {
915 DosError(FERR_DISABLEHARDERR);
916 if (DosForceDelete(string)) {
917 make_deleteable(string);
918 DosError(FERR_DISABLEHARDERR);
919 return DosForceDelete(string);
920 }
921 }
922 return 0;
923}
924
925#pragma alloc_text(LONGNAMES,TruncName,GetLongName,WriteLongName)
926#pragma alloc_text(LONGNAMES,ZapLongName,AdjustWildcardName)
927#pragma alloc_text(COPYF,default_disk,docopyf,MakeTempName)
928#pragma alloc_text(UNLINKF,unlinkf,unlink_allf,make_deleteable,wipeallf)
Note: See TracBrowser for help on using the repository browser.