source: trunk/dll/copyf.c@ 793

Last change on this file since 793 was 793, checked in by Gregg Young, 18 years ago

Move #pragma alloc_text to end for OpenWatcom compat

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