source: trunk/dll/copyf.c@ 1163

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

Ticket 187: Draft 1: Functions only

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