source: trunk/dll/copyf.c@ 1206

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

Ticket 187: Move datadevlarations/definitions out of fm3dll.h

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