source: trunk/dll/copyf.c@ 689

Last change on this file since 689 was 551, checked in by Gregg Young, 19 years ago

Indentation cleanup

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