source: trunk/dll/copyf.c@ 1200

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

Improved comment on new "#if 0" lines.

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